1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Introduction to real time operating systems

492 1.2K 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Cấu trúc

  • ELEC371 CLASS NOTES- INTRODUCTION TO REAL-TIME OPERATING SYSTEMS (2001) by Robert Betz

  • Table of Contents

  • List of Figures

  • Chapter 1 INTRODUCTION TO OPERATING SYSTEMS

    • References

    • What is an Operating system?

    • What is Multi-programming?

    • Why were Multi-programming Systems Developed?

    • Definition of an Operating System

    • Types of Operating Systems

    • Some more definitions – Processors, Programs and Tasks

    • Hierarchical Structure of Operating Systems.

    • A digression – the role of interrupts in Operating Systems.

      • What is an interrupt?

      • Why are interrupts crucial to Operating Systems?

      • Example: Producer-Consumer Problem

  • Chapter 2 PRINCIPLES OF SOFTWARE DESIGN

    • Problems with Real Time Design

    • Some Suggestions on Program Structure

    • The efficiency trap

  • Chapter 3 OVERVIEW OF MULTI-TASKING

    • Coroutines

    • Tasks

    • Anatomy of an Operating System Kernel

      • The Dispatcher

      • Synchronization Primitives

    • Protected and Non-protected Operating Systems

      • Brief Discussion of Memory Management

      • Brief Discussion of Supervisor Mode

  • Chapter 4 SEMAPHORES

    • Basic Concepts

    • Wait and Signal

    • Semaphores as Resource Counters

    • Task Synchronization

    • Consumer-Producer Problem Revisited

    • More Complex Synchronization Problems

      • Multiple unit resource allocation

      • Dining philosophers problem

      • Readers and Writers problem

    • Variations on the semaphore

      • Logic semaphores

      • Timed semaphores, sleeping tasks and simulated task suspension

      • Semaphores and priorities

    • Other synchronization primitives

      • Event primitives

      • Monitors

      • A practical semaphore structure

    • Deadlock and Starvation

      • Resource types

        • Reusable resources

        • Consumable resources

      • The conditions for deadlock

      • Techniques to handle deadlock

        • Deadlock prevention

        • Deadlock detection

        • Deadlock avoidance

          • Task initiation denial:

          • Resource Allocation Denial:

      • Summarizing

  • Chapter 5 TASK MANAGEMENT

    • Task descriptors

    • Kernel Queues

    • Description of UNOS-V1.5

      • Unos-V1.5 Task Control Block (TCB) and Semaphore Structures

      • Queue Operation in UNOS-V1.5

      • UNOS-V1.5 task creation

      • The Dispatcher

        • The UNOS-V1.5 Dispatcher

        • The task switch operation

        • The UNOS-V1.5 task switch

      • Subtasks and Interrupt Tasks

      • Time-slicing

        • Unos time slicing

      • Task suspension

    • Dynamic Priorities

      • Definitions Useful for Priority Inheritance

      • A General Priority Inheritance Algorithm

        • An Implementation of Priority Inheritance

      • Some Explicit Implementations

        • The Inherit1 Algorithm

        • The Inherit2 Algorithm

        • The Inherit3 Algorithm

      • Interesting Benefit

    • Higher Order Scheduling

    • Some Definitions and Background

    • Basic Rate-Monotonic Analysis

      • Fundamental Results

      • Rate-Monotonic Scheduling

        • Utilisation Bound

        • Completion Time Test

        • Deadline-Monotonic Scheduling

    • Relaxing the Assumptions – Generalised Rate-Monotonic Analysis

      • Task Synchronisation

      • Release Jitters

      • Arbitrary Deadlines

  • Chapter 6 TASK COMMUNICATION AND TIMING

    • Intertask Communications

      • Common Data Buffer Technique

      • Circular Buffer Technique

      • Mail Box Technique

      • Pointer Transfer Technique

      • Examples of Intertask Communication in Some Real Operating Systems

        • Unix

        • UNOS

    • Timing in Real-time Systems

      • Time Delays

        • UNOS timers

        • UNOS timer creation

        • UNOS timer queues

        • UNOS timer maintenance routines

        • UNOS user interface routines

        • UNOS timed semaphore wait

        • Applications of UNOS timers

    • UNOS Heap Management

  • Chapter 7 INTERRUPTS

    • Basic interrupt mechanism

    • Finer details of the interrupt mechanism

    • Hardware structure of interrupts

    • Other types of interrupts

    • Interrupt priorities

    • Interrupt tasks

    • Interrupt handlers and the dispatcher

    • Relaxing the “no task switch” condition

  • Chapter 8 DEVICE DRIVERS

    • What is a device driver?

    • Structure of a device driver

    • Design objectives and implications

    • Anatomy of an I/O request

    • The device handler

    • Buffering

    • Issues related to efficiency

  • Chapter 9 AN INTRODUCTION TO FILE SYSTEMS

    • Logical Structure of File Systems

      • Basic Implementation

        • Sequential Files

        • Indexed Sequential Access Method (ISAM)

        • Indexed file

      • Directories

        • Symbolic Naming

        • Access Rights

    • Physical Structure of File Systems

      • Physical Structure of Disks

      • Disk allocation table

      • Record blocking

      • File allocation table

      • Some examples

        • MS-DOS file allocation

      • FAT32 File System

        • UNIX file allocation

    • Miscellaneous File System Issues

      • Links

      • File System Consistency

      • Real-time issues

  • Chapter 10 VIRTUAL MEMORY AND PROTECTION

    • Virtual addressing - basic concepts.

    • Virtual memory models

    • Segmentation - basic principles

    • Paging - basic principles

    • Some implementation issues

    • The best of both worlds - combined paging and segmentation

  • Chapter 11 CASE STUDY - THE 80386-DX PROCESSOR

    • Application Programmer’s Register Model

    • System Programmer’s Register Model

      • System Flags

      • Memory-Management Registers

      • Control Registers

    • Segmented Address Models in the 80386

      • Flat Model

      • Protected Flat Model

      • Multi-Segment Model

      • Segment Translation in the 80386

        • Segment Selectors

        • Segment Descriptors

    • Paging in the 80386

      • Translation Lookaside Buffer.

    • Combined Segment and Page Translation

      • The Flat Paging Model – Getting rid of Segmentation

      • Segmentation and Paging Together

    • Protection in the 80386 Processor

    • Segment-level Protection

      • Segment Descriptors and Protection

        • Type Checking

        • Limit Checking

        • Privilege Levels

      • Restricting Access

        • Restricting Access to Data

        • Restricting Control Transfers

      • Gate Descriptors

        • Stack Switching

        • Returning from a Procedure

    • Pointer Validation

      • Descriptor Validation

      • Pointer Integrity and RPL

    • Page Level Protection

      • Restriction of Addressable Domain

    • Multitasking Support in the 80386

      • Task State Segment

      • TSS Descriptor

      • Task Register

      • Task Gate Descriptor

      • Task Switching

      • Task Linking

        • Busy Bit

      • Task Address Space

    • Protected Input/Output

      • I/O Addressing in the 80386

      • Protection and I/O

        • I/O Privilege Level

        • I/O Permission Bit Map

    • Conclusion

  • Appendix A UNOS-V2.0 TUTORIAL

    • Introduction

    • General Layout of UNOS Based Software

    • Detailed Example of the Use of UNOS

      • The Main Module

      • The Initunos Module

      • Usertask Module

      • Task Modules

        • Task0 Module

        • Task1 Module

        • Task 2 Module

      • Header Files

        • unos.h

        • general.h

      • Common Header Files for User Tasks

        • comdec.h

        • pcscrn.h

        • tasks.h

        • time.h

      • Other important header files

        • hwpc.h

        • config_os.h

  • Appendix B A SIMPLE WINDOW SYSTEM

    • Introduction

    • User Functions

    • How to Use the Windowing System

      • A Note on Setting Character Attributes

    • Reference Section

    • The Point Class

      • POINT::POINT DESCRIPTION

      • POINT::OPERATOR= DESCRIPTION

      • POINT::MOVETO DESCRIPTION

      • POINT::SET_ATTRIBUTES DESCRIPTION

      • POINT::WRITE_TO_PT DESCRIPTION

      • POINT::RETURN_ATTRIBUTES

    • The Screen Class

      • SCREEN::SCREEN DESCRIPTION

      • SCREEN::PRINT DESCRIPTION

      • SCREEN::CLR_LINE DESCRIPTION

      • SCREEN::CLR_EOL DESCRIPTION

      • SCREEN::CLR_BOL DESCRIPTION

      • SCREEN::CLR_SCR DESCRIPTION

      • SCREEN::SET_SCRN_BACKGRD DESCRIPTION

      • SCREEN::DRAW_BOX DESCRIPTION

      • SCREEN::DRAW_HORIZ_LINE DESCRIPTION

      • SCREEN::DRAW_VERT_LINE DESCRIPTION

      • SCREEN::SCROLL DESCRIPTION

    • Window Class

      • WINDOW::WINDOW DESCRIPTION

      • WINDOW::CLEAR_WINDOW DESCRIPTION

      • WINDOW::SET_WINDOW_BACKGRD_COLOUR DESCRIPTION

      • WINDOW::PAINT_WINDOW_BACKGRD DESCRIPTION

      • WINDOW::GO_WINDOW_XY DESCRIPTION

      • WINDOW::PRINT DESCRIPTION

      • WINDOW::PRINT DESCRIPTION

      • WINDOW::SET_STRING_COLOUR DESCRIPTION

      • WINDOW::SET_STRING_BACKGRD_COLOUR DESCRIPTION

      • WINDOW::SCROLL_WINDOW DESCRIPTION

      • WINDOW::WINDOW_CLEAR_LINE DESCRIPTION

      • WINDOW::GET_TOP/BOT_LEFT/RIGHT/XY DESCRIPTIONS

      • WINDOW::DRAW_HORIZ_LINE DESCRIPTION

      • WINDOW::DRAW_VERT_LINE DESCRIPTION

  • Appendix C UNOS-V2.0 REFERENCE MANUAL

    • INTRODUCTION

    • KEY FEATURES

    • REAL-TIME SERVICES

    • HARDWARE REQUIREMENTS

    • INTRODUCTION TO UNOS-V2.0 KERNEL PRIMITIVES

      • Kernel Initialisation

        • setup_os_data_structures

      • Task Management

        • create_task

        • change_task_priority

        • rtn_task_priority

        • start_tasks

        • rtn_current_task_num

        • rtn_current_task_name_ptr

        • chg_task_tick_delta

      • Task scheduling management

        • preemptive_schedule

        • reschedule

        • start_time_slice

        • stop_time_slice

        • chg_base_ticks_per_time_slice

      • Time management

        • create_timer

        • start_timer

        • reset_timer

        • stop_timer

      • Intertask communication and synchronization

        • create_semaphore

        • init_semaphore

        • wait

        • timed_wait

        • usignal

        • return_semaphore_value

        • create_lock

        • lock

        • unlock

        • send_mess

        • send_qik_mess

        • rcv_mess

        • size_mbx

        • size_mbx_mess

        • free_mbx

        • used_mbx

        • flush_mbx

      • Memory Management

        • umalloc

        • ucalloc

        • ufree

        • ret_free_mem

      • Miscellaneous

        • return_interrupt_status

    • DETAILED DESCRIPTION OF USER INTERFACE

    • Kernel Initialisation Functions

      • SETUP_OS_DATA_STRUCTURES DESCRIPTION

    • Task Management Functions

      • CREATE_TASK DESCRIPTION

      • CHANGE_TASK_PRIORITY DESCRIPTION

      • RTN_TASK_PRIORITY DESCRIPTION

      • START_TASKS DESCRIPTION

      • RTN_CURRENT_TASK_NUM DESCRIPTION

      • RTN_CURRENT_TASK_NAME_PTR DESCRIPTION

      • CHG_TASK_TICK_DELTA DESCRIPTION

    • Task Scheduling Management Functions

      • PREEMPTIVE_SCHEDULE DESCRIPTION

      • RESCHEDULE DESCRIPTION

      • START_TIME_SLICE DESCRIPTION

      • STOP_TIME_SLICE DESCRIPTION

      • CHG_BASE_TICKS_PER_TIME_SLICE DESCRIPTION

    • Time Management Functions

      • CREATE_TIMER DESCRIPTION

      • START_TIMER DESCRIPTION

      • RESET_TIMER DESCRIPTION

      • STOP_TIMER DESCRIPTION

    • Intertask Communication and Synchronization Functions

      • CREATE_SEMAPHORE DESCRIPTION

      • INIT_SEMAPHORE DESCRIPTION

      • WAIT DESCRIPTION

      • TIMED_WAIT DESCRIPTION

      • USIGNAL DESCRIPTION

      • RETURN_SEMAPHORE_VALUE DESCRIPTION

      • CREATE_LOCK DESCRIPTION

      • LOCK DESCRIPTION

      • UNLOCK DESCRIPTION

      • DESTROY_LOCK DESCRIPTION

      • SEND_MESS DESCRIPTION

      • SEND_MESS MACRO DESCRIPTION

      • SEND_MESS_NB MACRO DESCRIPTION

      • SEND_QIK_MESS DESCRIPTION

      • RCV_MESS DESCRIPTION

      • SIZE_MBX DESCRIPTION

      • SIZE_MBX_MESS DESCRIPTION

      • FREE_MBX DESCRIPTION

      • USED_MBX DESCRIPTION

      • FLUSH_MBX DESCRIPTION

    • Memory Management Functions

      • UMALLOC DESCRIPTION

      • UCALLOC DESCRIPTION

      • UFREE DESCRIPTION

      • RET_FREE_MEM DESCRIPTION

    • Miscellaneous Functions

      • RETURN_INTERRUPT_STATUS DESCRIPTION

  • Appendix D THE KEYBOARD SYSTEM

    • Introduction

    • Organisation and Use

  • Appendix E UNOS SERIAL HANDLERS

    • INTRODUCTION

    • USER INTERFACE

    • SETTING UP AND USING THE SERIAL CHANNELS

      • The header files

    • USER INTERFACE DESCRIPTION

      • CREATE_SERIAL DESCRIPTION

  • Appendix F COMMAND DECODER

    • Introduction

    • Basic Data Structures

      • Decoder Tables - How to use them

        • Example

  • Appendix G UNOS ALARM HANDLING

    • Features

    • Data structures used in the Alarm System

      • The Alarm Number Array

      • The Alarm Structure.

      • Ancillary Data Structures

    • Low Level User Interface to the Alarm System

      • finCreateAlarm Description

      • fulgAlarm Description

      • fulgRetNumUnresetAlarms Description

      • fulgResetAlarm Description

      • fvdStopConseqSuppr Description

      • fulgResetAllAlarmsClearOnce Description

      • fulgRetCumulAlarms Description

      • finRetCumulStartTimeDate Description

      • finRetFirstUnresetAlarmTimeDate Description

      • finRetLastUnrestAlarmTimeDate Description

      • finClearCumulAlarms Description

    • Some Notes About Usage

  • Appendix H UNOS-V2.0 LISTING

    • CONDITIONS OF USE OF THE UNOS KERNEL

    • MISCELLANEOUS INFORMATION

    • FULL KERNEL LISTING

  • BIBLIOGRAPHY

Nội dung

(/(& &/$66 127(6 ,1752'8&7,21 72 5($/7,0( 23(5$7,1* 6mess_addr = task_num; mbx_ptr->mbx_type = mbx_type; mbx_ptr->q_size = num_mess; H-83 Appendix H — UNOS-V2.0 LISTING mbx_ptr->mess_size = mess_size; mbx_ptr->spce_avail_sema = spce_avail_sema; mbx_ptr->mess_avail_sema = mess_avail_sema; mbx_ptr->free = num_mess; mbx_ptr->used = 0; mbx_ptr->get_ptr = 0; mbx_ptr->put_ptr = 0; mbx_ptr->qik_mess_flag = FALSE; /* now allocate the quick message envelope */ mbx_ptr->qik_mess_ptr = ( envelope* )umalloc ( sizeof ( envelope ) ); /* now allocate the message queue envelopes */ mbx_ptr->mess_q_ptr =( envelope* )ucalloc ( num_mess, sizeof ( envelope ) ); /* check to see if the allocation for the envelopes has been successful */ if ( ( mbx_ptr->qik_mess_ptr == NULL_PTR ) || ( mbx_ptr->mess_q_ptr == NULL_PTR ) ) return ( mbx* )NULL_PTR; /* now allocate the message buffers for each of the envelope structures */ mbx_ptr->qik_mess_ptr->message_ptr = ( char* )ucalloc ( mess_size, sizeof ( char ) ); for ( i = 0; i < num_mess; i++ ) { mbx_ptr->mess_q_ptr [ i ].message_ptr = ( char* )ucalloc ( mess_size, sizeof ( char ) ); if ( mbx_ptr->mess_q_ptr [ i ].message_ptr == NULL_PTR ) allocation_problem = TRUE; } /* for */ /* now check if the allocation of the message buffers for each of the envelopes has been successful */ if ( ( mbx_ptr->qik_mess_ptr->message_ptr == NULL_PTR ) || allocation_problem ) return ( mbx* )NULL_PTR; else return mbx_ptr; } /* if */ else { cprintf ( “Mail Box allocation problem\n” ); return ( mbx* )NULL_PTR; } /* else */ } /* end create_mbx */ /* -*/ /* ============================================================================ | | mail_exchange | | The purpose of this function is to match the pointer to a task name to the | task number This matching operation is required in the mail system to | allow the address of a task to be independent of its task number The | mapping from the pointer value to the task number is implemented using | a chained hashing algorithm The hash table is initialised during the H-84 FULL KERNEL LISTING | task creation process The hash table itself contains pointers to linked | lists of taskname_map structures The index into the table is calculated | using a simple (but effective) modulus based hashing scheme | | If the pointer address hashes to a table entry which has no taskname_map | structure pointer then one is attempting to send data to an undefined | task This is indicated by a hash_table entry being NULL_PTR The routine | in this case returns the task number as the contents of num_of_tasks | (which is actually one more than the number of the last task number) | | Parameter :- pointer to a character string | | Entry via :- send_mess function | ============================================================================ */ static unsigned int mail_exchange ( char *mess_addr_ptr ) { unsigned int hash_table_index; taskname_map *taskname_struc_ptr; unsigned int task_number = 0xffff; /* firstly hash the pointer */ hash_table_index = hash_taskname_ptr ( mess_addr_ptr ); /* now look into the hash table */ if ( hash_table [ hash_table_index ] != NULL_PTR ) { taskname_struc_ptr = hash_table [ hash_table_index ]; { if ( taskname_struc_ptr->task_name_ptr == mess_addr_ptr ) { task_number = taskname_struc_ptr->task_number; taskname_struc_ptr = NULL_PTR; } /* if */ else { taskname_struc_ptr = taskname_struc_ptr->nxt_taskname_map; } /* else */ } while ( taskname_struc_ptr != NULL_PTR ); } /* if */ /* now check to see if a legal task number has been found */ if ( task_number == 0xffff ) { /* illegal task number found */ return num_of_tasks; } /* if */ else { return task_number; } /* else */ } /* end of mail_exchange */ /* -*/ /* H-85 Appendix H — UNOS-V2.0 LISTING ============================================================================== | | send_mess | | This function puts a message into a mail box for a particular task The | can be called in two modes - blocking mode and non-blocking mode In blocking | mode if the mail box is full then the calling task is blocked on a semaphore | In non-blocking mode, if the mail box is full then control is returned to | the calling task, along with a return code to indicate that the message was | not sent (FULL_MBX) | | In order to make the address of the message independent of task numbering | message addresses consist of a pointer to a string describing the task The | connection between this pointer and the task number is created at task | creation time In order to make it fast to obtain the task number from | the string pointer a hash table is used This mapping is carried out by the | mail exchange which implements a chained hashing algorithm | | NOTE : this routine currently does not handle priority mail boxes | | Note that interrupts are disabled for a large part of this routine in order | to make the message indivisible | | Parameters : - pointer to the message to be sent | - length of the message to be sent | - address of the receiver of the message This is a pointer to | a character string that contains the name of the task The | pointer value is actually used as address of the task and | the contents of the character string | - a number indicating whether the caller should be blocked or | not on the mail box semaphore A zero indicates that the | caller should be blocked (BLOCK_SM), a one indicates that | if the mail box is full then control should be returned to | the caller (NO_BLOCK_SM) | | Returns: - a TRUE if the message is successfully sent | - a FALSE if the message is too big for the mail box, or an | attempt is made to send a message to a non-existent task | - a FULL_MBX is returned if the mailbox is full and the routine | is called with the block_action parameter set to NO_BLOCK_SM | | Entry via : - multiple places | ============================================================================== */ int send_mess ( unsigned char* mess_ptr, unsigned int mess_lgth, char *mess_addr_ptr, int block_action ) { unsigned int mess_addr, sender_task_num; char *sender_addr_ptr; char int_status; unsigned int i; /* firstly call the mail exchange to establish which task number is being addressed, and then check to see if the task that the message is being sent to actually exists If it doesn’t then return with a FALSE */ if ( ( ( mess_addr = mail_exchange ( mess_addr_ptr ) ) >= num_of_tasks)) { return FALSE; /* non-existent task being addressed */ } /* if */ /* now check whether the message will fit in the message buffer */ if ( mess_lgth > mbx_table [ mess_addr ]->mess_size ) return FALSE; /* does not fit in the message buffer */ int_status = return_interrupt_status ( ); disable ( ); H-86 FULL KERNEL LISTING /* Now check whether this should block or not */ if (block_action == NO_BLOCK_SM) { /* No blocking allowed so check to see if the mail box has space */ if ( mbx_table [ mess_addr ]->spce_avail_sema == ) { /* Will get blocked so return with a return code */ if (int_status) { enable (); } /* if */ return (FULL_MBX); } /* if */ } /* if */ /* Enter at this point if the call is a blocking call, or the calling task will not get blocked */ wait ( mbx_table [ mess_addr ]->spce_avail_sema ); sender_task_num = rtn_current_task_num ( ); /* now get the name of the sending task by looking in the tcb of the task */ sender_addr_ptr = tcb [ sender_task_num ]->task_name_ptr; /* copy the message into the correct mail box envelope */ for ( i = 0; i < mess_lgth; i++ ) mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ].message_ptr [ i ] = mess_ptr [ i ]; /* now complete the rest of the envelope structure */ mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ] mess_lgth = mess_lgth; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ] rtn_addr_ptr = sender_addr_ptr; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ] sender_pri = tcb [ sender_task_num ]->priority; /* now update the mail box accounting locations */ mbx_table [ mess_addr ]->put_ptr++; if ( mbx_table [ mess_addr ]->put_ptr >= mbx_table [ mess_addr ]->q_size ) mbx_table [ mess_addr ]->put_ptr = 0; mbx_table [ mess_addr ]->free ; mbx_table [ mess_addr ]->used++; if ( int_status ) enable ( ); usignal ( mbx_table [ mess_addr ]->mess_avail_sema ); return TRUE; /* indicate that message successfully sent */ } /* end of send_mess */ /* */ /* H-87 Appendix H — UNOS-V2.0 LISTING ========================================================================== | | send_qik_mess | | This function sends a quick message to a mail box for a particular task | A quick or express message is different from a normal message in that | it should be the next message read from the mail box regardless of the | other messages that may be stored in the mail box This is generally | achieved by putting the quick message just prior to the next message to | be read from the buffer and then adjusting the get_ptr appropriately | If the message queue is full however this cannot be done, and in fact the | task generating the message could become blocked (depending on how this | situation was handled) For this reason the mail box contains a special | envelope to store quick messages If the situation arises where the special | mail box is full also then the routine returns immediately with a return | code equal to which indicates this condition A return code of (usually | corresponding to a FALSE) indicates that the message is too big for the | size of the message buffers A return code of (usually corresponding to | a TRUE) indicates a successful message sent | | Parameters : - pointer to the message to be sent | - message length | - address where message is to be sent - a pointer to the | task name | | Entry via : - multiple places | =========================================================================== */ int send_qik_mess ( unsigned char* mess_ptr, unsigned int mess_lgth, char * mess_addr_ptr ) { char int_status; unsigned int mess_addr, i; /* firstly call the mail exchange to establish which task number is being addressed, and then check to see if the task that the message is being sent to actually exists If it doesn’t then return with a FALSE */ if ( ( ( mess_addr = mail_exchange ( mess_addr_ptr ) ) >= num_of_tasks)) { return FALSE; /* non-existent task being addressed */ } /* if */ /* check if the message will fit in the message buffer */ if ( mess_lgth > mbx_table [ mess_addr ]->mess_size ) { return FALSE; /* message too big for the buffer */ } /* if */ int_status = return_interrupt_status ( ); disable ( ); /* now check to see if there is room in the normal message queue for the express message */ if ( mbx_table [ mess_addr ]->free == ) { /* enter here if there is no room in the normal message buffer so now check to see if there is room in the special qik message buffer If there is no room here then return with the appropriate return code */ if ( mbx_table [ mess_addr ]->qik_mess_flag ) { /* qik message envelope full so reset interrupts and return to the calling program */ if ( int_status ) H-88 FULL KERNEL LISTING enable ( ); return 2; } /* if */ else { /* there is room in the qik message envelope */ for ( i = 0; i < mess_lgth; i++ ) mbx_table [ mess_addr ]->qik_mess_ptr->message_ptr [ i ] = mess_ptr [ i ]; mbx_table [ mess_addr ]->qik_mess_ptr->rtn_addr_ptr = tcb [ rtn_current_task_num ( )]->task_name_ptr; mbx_table [ mess_addr ]->qik_mess_ptr->sender_pri = tcb [ mess_addr ]->priority; mbx_table [ mess_addr ]->qik_mess_ptr->mess_lgth = mess_lgth; mbx_table [ mess_addr ]->qik_mess_flag = TRUE; } /* else */ } /* if */ else { /* there are free locations in the message queue so put the qik message at the head if this queue If the message queue is empty then put the message in it at the put_ptr location */ if ( mbx_table [ mess_addr ]->used == ) { /* now write the message into the envelope in the envelope queue */ for ( i = 0; i < mess_lgth; i++ ) mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ].message_ptr [ i ] = mess_ptr [ i ]; /* now update the other components of the envelope */ mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ].rtn_addr_ptr = tcb [ rtn_current_task_num ( ) ]->task_name_ptr; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ].sender_pri = tcb [ mess_addr ]->priority; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->put_ptr ].mess_lgth = mess_lgth; mbx_table [ mess_addr ]->put_ptr++; if ( mbx_table [ mess_addr ]->put_ptr >= mbx_table [ mess_addr ]->q_size ) mbx_table [ mess_addr ]->put_ptr = 0; } /* if */ else { if ( mbx_table [ mess_addr ]->get_ptr == ) mbx_table [ mess_addr ]->get_ptr = mbx_table [ mess_addr ]-> q_size - 1; else mbx_table [ mess_addr ]->get_ptr ; /* now write the message into the envelope in the envelope queue */ for ( i = 0; i < mess_lgth; i++ ) mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]-> get_ptr ].message_ptr [ i ] = mess_ptr [ i ]; /* now update the other components of the envelope */ mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->get_ptr ].rtn_addr_ptr = tcb [ rtn_current_task_num ( ) ]->task_name_ptr; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->get_ptr ].sender_pri = tcb [ mess_addr ]->priority; mbx_table [ mess_addr ]->mess_q_ptr [ mbx_table [ mess_addr ]->get_ptr ].mess_lgth = mess_lgth; } /* else */ H-89 Appendix H — UNOS-V2.0 LISTING /* now update the used and free locations */ mbx_table [ mess_addr ]->free ; mbx_table [ mess_addr ]->used++; } /* else */ if ( int_status ) enable ( ); /* now signal that data is available in the mail box */ usignal ( mbx_table [ mess_addr ]->mess_avail_sema ); return TRUE; } /* end of send_qik_mess */ /* -*/ /* ============================================================================= | | rcv_mess | | This routine receives a message from a mail box associated with a particular | task There is no need to specify the mail box since the mail box from | which the message is read from is that associated with the task | One important feature of this routine is that the receiving task can | indicate how long it will wait for the message by passing a time limit to the | routine If a value of zero is passed for the time limit then the time limit | is deemed to be infinite | | The function returns the address of the sending task if the timeout period | has not expired Note that this address is returned as a pointer to the | character string which names the task If the timeout period has expired | without a message being received it will return NULL_PTR If the return is | due to the fact that a timer is not available for the timed_wait operation | then the return code is 0xffff:000f | | Parameters : - pointer to the memory area where the message will be stored | - pointer to the integer where the message length will be | stored | - time limit value | | Entry via : - multiple places | ============================================================================= */ char *rcv_mess ( unsigned char* mess_ptr, unsigned int* mess_lgth, unsigned long time_limit ) { unsigned int mbx_addr; char *rtn_addr_ptr; int wait_result = 0; char int_status; unsigned int i; unsigned int *mess_lgth_ptr; char *qik_mess_ptr; char *mbx_mess_ptr; mbx_addr = rtn_current_task_num ( ); H-90 FULL KERNEL LISTING /* firstly check what type of wait has to be carried out */ if ( time_limit == ) wait ( mbx_table [ mbx_addr ]->mess_avail_sema ); else wait_result = timed_wait ( mbx_table [ mbx_addr ]-> mess_avail_sema, time_limit ); /* now check the value of the wait_result If zero then the wait has been terminated by a signal condition or no wait has occurred If the wait result is non-zero then some error condition has occurred the type of error condition is determined by the value:- 1=>wait terminated due to a timeout on the semaphore; 2=>a timer was not available for the timed_wait */ if ( wait_result ) { if ( wait_result == ) return NULL_PTR; /* timeout occurred */ return ( (char*)MK_FP ( 0xffff, 0x000f ) ); /* no timer available */ } /* if */ int_status = return_interrupt_status ( ); disable ( ); /* enter this section of the code if there is a message to receive Now check to see if the message is in the qik message envelope If so then retrieve it from there, else get the message from the message envelope queue */ if ( mbx_table [ mbx_addr ]->qik_mess_flag ) { /* message in the qik envelope */ /* now setup pointers to the appropriate variables so that the compiler will be forced to produce efficient code */ mess_lgth_ptr = &mbx_table [ mbx_addr ]->qik_mess_ptr->mess_lgth; qik_mess_ptr = mbx_table [ mbx_addr ]->qik_mess_ptr->message_ptr; for ( i = 0; i < *mess_lgth; i++ ) { mess_ptr [ i ] = *(qik_mess_ptr + i); } /* for */ *mess_lgth = *mess_lgth_ptr; mbx_table [ mbx_addr ]->qik_mess_flag = FALSE; rtn_addr_ptr = mbx_table [ mbx_addr ]->qik_mess_ptr->rtn_addr_ptr; } /* if */ else { /* message must be in the normal message queue so retrieve from here */ /* firstly assign the key variables to pointers to force the compiler to produce efficient code */ mess_lgth_ptr = &mbx_table [ mbx_addr ]->mess_q_ptr [ mbx_table [ mbx_addr ]->get_ptr ].mess_lgth; mbx_mess_ptr = mbx_table [ mbx_addr ]->mess_q_ptr [ mbx_table [ mbx_addr ]->get_ptr ].message_ptr; for ( i = 0; i < *mess_lgth_ptr; i++ ) { mess_ptr [ i ] = *(mbx_mess_ptr + i); } /* for */ *mess_lgth = mbx_table [ mbx_addr ]->mess_q_ptr [ mbx_table [ mbx_addr ]->get_ptr ].mess_lgth; rtn_addr_ptr = mbx_table [ mbx_addr ]->mess_q_ptr [ mbx_table [ mbx_addr ]->get_ptr ].rtn_addr_ptr; mbx_table [ mbx_addr ]->get_ptr++; if ( mbx_table [ mbx_addr ]->get_ptr >= mbx_table [ mbx_addr ]-> q_size ) H-91 Appendix H — UNOS-V2.0 LISTING { mbx_table [ mbx_addr ]->get_ptr = 0; } /* if */ mbx_table [ mbx_addr ]->free++; mbx_table [ mbx_addr ]->used ; } /* else */ /* now signal that space is available in the mail box */ usignal ( mbx_table [ mbx_addr ]->spce_avail_sema ); if ( int_status ) enable ( ); return rtn_addr_ptr; } /* end of rcv_mess */ /* */ /* ============================================================================= | | size_mbx | | This function returns the size of the message queue for a particular mail | box If one tries to look at an illegal mail box then a zero is returned, | else the size of the mail box is returned | | Parameters : - mail box address - which is the task name with which it is | associated | | Entry via : - multiple places | ============================================================================= */ unsigned int size_mbx ( char *mbx_addr_ptr ) { unsigned int mbx_num; unsigned int mbx_size; /* carry out the mapping between the mail box name (which is the task name) and the mail box number */ if ( ( mbx_num = mail_exchange ( mbx_addr_ptr ) ) >= num_of_tasks ) { /* trying to look at an illegal mail box */ mbx_size = 0; } /* if */ else { /* address OK */ mbx_size = mbx_table [ mbx_num ]->q_size; } /* else */ return mbx_size; } /* end of size_mbx */ H-92 FULL KERNEL LISTING /* */ /* ============================================================================= | | size_mbx_mess | | This function returns the maximum size of a message which can be sent to a | mail box (i.e the size of each of the message slots in the message queue | If the mail box address is illegal then the routine returns a value of | 0, else the length of the messages is returned | | Parameters : - address of the mail box (i.e task name with which it is | associated) whose size is to be determined | | Entry via : - multiple places | ============================================================================= */ unsigned int size_mbx_mess ( char *mbx_addr_ptr ) { unsigned int mbx_num; unsigned int size_mbx_mess; /* carry out the mapping between the mail box name (which is the task name) and the mail box number */ if ( ( mbx_num = mail_exchange ( mbx_addr_ptr ) ) >= num_of_tasks ) { /* trying to look at an illegal mail box */ size_mbx_mess = 0; } /* if */ else { /* address OK */ size_mbx_mess = mbx_table [ mbx_num ]->mess_size; } /* else */ return size_mbx_mess; } /* end of size_mbx_mess */ /* -*/ /* ============================================================================== | | free_mbx | | This function returns the number of free message slots in a mail box If | the mail box number is illegal then the routine returns a 0xffff value, else | it returns the number of free locations | | Parameters : - address of the mail box (i.e task name pointer with which | it is associated) whose free space is to be determined H-93 Appendix H — UNOS-V2.0 LISTING | | Entry via : - multiple places | ============================================================================= */ unsigned int free_mbx ( char *mbx_addr_ptr ) { char int_status; unsigned int mbx_num; unsigned int free; int_status = return_interrupt_status ( ); disable ( ); /* carry out the mapping between the mail box name (which is the task name) and the mail box number */ if ( ( mbx_num = mail_exchange ( mbx_addr_ptr ) ) >= num_of_tasks ) { /* trying to look at an illegal mail box */ free = 0xffff; } /* if */ else { /* address OK */ free = mbx_table [ mbx_num ]->free; } /* else */ if ( int_status ) enable ( ); return free; } /* end of free_mbx */ /* -*/ /* ============================================================================== | | used_mbx | | This function returns the number of used message slots in a mail box If the | mail box number is illegal then the number returned is 0xffff | | Parameters : - address of the mail box (i.e the task nmae pointer with | which the mail box is associated) whose used space is to | be determined | | Entry via : - multiple places | ============================================================================== */ unsigned int used_mbx ( char *mbx_addr_ptr ) { char int_status; unsigned int mbx_num; unsigned int used; int_status = return_interrupt_status ( ); disable ( ); H-94 ... this to be an example of a real time operating system Engineers on the other hand would not consider this to a a real time operating system A real time operating system to an engineer has hard time. .. Chapter — INTRODUCTION TO OPERATING SYSTEMS The static/dynamic classification often corresponds to the real time/ non -real time as described above Real time applications of operating systems are... operating systems • non -real time operating systems There is some debate as to what constitutes a real time operating system For example, is an airline booking system a real time operating system?

Ngày đăng: 08/03/2016, 11:34

TỪ KHÓA LIÊN QUAN