1 / 22

An Embedded Software Primer

An Embedded Software Primer. David E. Simon. Chapter 8: Basic Design Using a Real-Time Operating System. Overview Principles An Example Encapsulating Semaphores and Queues Hard Real-Time Scheduling Considerations Saving Memory Space Saving Power. Overview.

ycurran
Download Presentation

An Embedded Software Primer

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. An Embedded Software Primer David E. Simon

  2. Chapter 8: Basic Design Using a Real-Time Operating System • Overview • Principles • An Example • Encapsulating Semaphores and Queues • Hard Real-Time Scheduling Considerations • Saving Memory Space • Saving Power

  3. Overview • For a RT system, its function as well as response time are required. • Criticality of meeting deadlines is also important and based on whether it is a hard or soft RT system. • Knowledge of system hardware – e.g. if a serial port receives 1K characters/sec and each character causes an interrupt, system should be able to handle it. • Software design in accordance with previous chapters i.e. structure, modularity, encapsulation and maintainability to be accounted for. Principles General Operation • RTOS tasks normally are idle until an external event occurs or until the next period of operation starts. The event might be freeing of a semaphore or a message sent by another task which releases the task from its blocked state.

  4. Principles (contd.) • An e.g. Telegraph system is shown below (Fig. 8.1 – Simon)

  5. Principles (contd.) Write Short ISRs • ISRs should be short mainly because • Longer ISRs translate to slower task-code response • ISRs are more bug-prone and harder to debug • Common practice to make ISRs do the critical actions and pass on the rest to the tasks. • Suppose a system has following requirements • Commands come from a serial port • Commands end with a carriage return. • Next command only arrives after system responds to previous one • Characters at the serial port are not buffered • System can respond to commands relatively slowly • A bad design would be to implement everything in the ISR. • A better way would be to have ISR buffer received characters until it finds a carriage return, then send the buffered characters to another (command parsing) task through a mailbox • This keeps the ISR short and simple

  6. Principles (contd.) How Many Tasks? • Work needs to be divided among an optimum number of tasks • Following are some advantages and disadvantages of having a large no. of tasks Advantages • More control over response times. Critical tasks can be given higher priority as opposed to a single task doing the entire work. • More modularity, cleaner code • Better data encapsulation. e.g. only the task for a network connection needs the status of the network interface Disadvantages • More tasks  more shared data  more semaphore  more semaphore bugs and corresponding handling time • Same problem with mailboxes, pipes, queues etc. • More stack space (memory) • Increases context switching, hence less throughput • More tasks  more RTOS calls  slower system. Often advisable to call RTOS functions as less as possible • Conclusion – Tasks should be as less as possible. More tasks should be added only when necessary

  7. Principles (contd.) You Need Tasks for Priority • An e.g. where multiple tasks are needed is when some parts of the work have tighter response times than others like in an embedded system, a task handling power failure can be given higher priority than the one performing mathematical calculations You Need Tasks for Encapsulation • More sense in having a task for hardware shared by other tasks • E.g. a printer display is used to respond to the user, report paper empty, paper jams etc. • A separate display task ensures messages displayed in correct order, stay long enough to be read • Fig. 8.3 shows this diagrammatically • Similarly when several system parts need to store data in a flash memory, a task can be assigned for the purpose • Task can allow one write at a time and set/reset a flag to indicate when next write can take place

  8. Principles (contd.) Other Tasks You Might or Might Not Need • Many small tasks, simpler code • Trade-off – more shared data and context switching • Separate tasks for work that is in response to separate stimuli • Trade-off – same as above

  9. Principles (contd.) Recommended Task Structure • Fig. 8.5 shows the pseudo-code for a recommended task structure

  10. Principles (contd.) • Task waits for a system signal (through a queue) in an infinite queue Advantages • Task only blocks in one place • Tasks blocked when idle so no processor time used • Task uses private data so no semaphores needed • Structure similar to a window routine in MSWindows. • Embedded systems tasks often modeled as state machines – state variables stored in private variables in task Avoid Creating and Destroying Tasks • Two reasons to avoid doing this while system running • These functions are the most time-consuming. Nothing constructive done so throughput reduced • Destroying a task often leaves bugs. If killed task holding a semaphore, all tasks waiting for it blocked forever unless the RTOS handles this automatically • Hence better to create all tasks at system startup and block idle tasks. Only thing wasted is task stack space and a small overhead for tracking the task.

  11. Principles (contd.) Turning Time-Slicing OFF • Time-Slicing done in some RTOSs when 2 ready tasks have same priority. • If allowed consider turning this option off • Normally embedded systems have several compute-intensive tasks and in most cases • Either they have different urgency levels and hence given different priorities • All have equal importance  either one can finish first • Time-Slicing not helpful in both cases • More context switches  less throughput • Conclusion – Unless there is an advantage, avoid using it Restricting RTOS Use • Most RTOSs allow scaling to reduce memory. • Hence if user code uses 10 pipes and 1 queue, it might be advisable to replace queue with a 11th pipe and scale off the RTOS queue code • Better to limit accesses to pipes, mailboxes etc. to reduce chances of bugs. • Many RTOSs consist of an outer shell around actual RTOS. User can only access this. • Makes code portable, only shell needs to be rewritten when moving to another OS

  12. An Example Underground Tank Monitoring System • System monitors up to 8 underground tanks by reading thermometers and levels of floats in them. • Float level is read by sending a command to the hardware which on obtaining the level interrupts the microprocessor for later reading • Temperature can be read anytime. • Both temperature and float level used to find gasoline volume (gallons) • Monitor tanks – set flag and set off alarm when level dropping consistently (leak), or when level rising rapidly during tank refueling (overflow). • User Interface – consists of a 16-button keypad, 20-char LCD and a thermal printer. • Keypad used to give commands like displaying levels, request reports, histories etc.. Buttons interrupt the microprocessor • A connector to an alarm bell to warn about system leaks or overflows. Turned off through one of the keypad buttons • Printer interrupts after printing each line, indicating it is ready for the next • Display shows most recent data. Retains data on screen until changed by the processor

  13. An Example (contd.) Resolving a Timing Problem • System needs to check tanks with rising floats several times per second. • Also it takes 4-5 sec to calculate the gasoline quantity after the read which is a problem • Resolved by detecting overflows based on float levels alone and not calculating the gasoline volume Deciding to Use an RTOS • 4-5 sec gasoline quantity calculation is the most time consuming and must be pre-empted when other processing is required to be done • Without an RTOS, ISRs required to do tasks. • Possible to manage with ISRs in current case but RTOS is a better option Dividing Work into Tasks • Following are the tasks needed Level Calculation Task • Calculates gasoline volume in each tank based on temperature and float level • Takes 4-5 sec, hence modeled as a low priority task

  14. An Example (contd.) • One task for all tanks Overflow Detection Task • Higher priority than level calculation task and leak detection Float Hardware Task • Tasks requiring the float level send requests to it Button Handling Task • Uses a state machine to keep track of buttons already pressed Display Task • Prevents tasks from interfering with each others displays. Alarm Bell Task • Shared hardware as several of the tasks can turn it on or off. Print Formatting Task • Lower priority than button handling task since it might take more than 1/10th of a second to format reports which must not interfere with the button response • Using interrupts is the most common way to signal tasks to start or stop

  15. An Example (contd.) Dealing with Shared Data • Gasoline level is shared by several tasks (level calculation, display, print etc. tasks) • Can be dealt with either by having a semaphore or a separate task • If a semaphore is used, longest time a task will hold onto it is 1-2 ms – print formatting task, assuming all needed data is first copied to its private variables. • Hence no need for added complication of extra task • Fig. 8.9 shows the final task division and message flow

  16. An Example (contd.)

  17. Encapsulating Semaphores and Queues Encapsulating Semaphores • Done by hiding the semaphore and corresponding shared data in a module. • Removes semaphore bugs • Fig. 8.10 below shows an e.g., shared variable lSecondsToday can only be read through the function lSecondsSinceMidnight • If lSecondsToday is read directly it will lead to bugs. Encapsulating Queues • If direct access is given to queues, following problems might occur. • Task might accidentally delete the queue • Wrong format sent through the queue • Programmer writes data intended for a task to the wrong queue. • Solution – same as above, encapsulate queue in a module. • If a function is used to encapsulate the queue, all shared data must be protected by semaphores and function must be reentrant

  18. Encapsulating Semaphores and Queues (contd.)

  19. Hard Real-Time Scheduling Considerations • System must guarantee hard deadlines are met. • Some simplifying assumptions, • Task n restarts every Tn units of time (period), hence it must complete before Tn • Worst-case execution time: Cn • Priority: Pn • Tasks don’t block for semaphores, events etc. • Deadline: Dn (in some cases ≠ Tn) • Jitter: Jn • All these used to determine whether system meets deadlines • Being predictable more important then being fast, so that Cn well defined. • This to be considered while writing subroutines – they need to have relatively constant execution times • Buffer allocation time should be constant, independent of the number of buffers (all or none) allocated. Hence malloc should be avoided since its execution time depends on current amount of free memory

  20. Saving Memory Space • Code stored in ROM, data in RAM • If an RTOS is used, stack size needs to be decided on. • This is determined by no. of function calls, function parameters and local variables. The RTOS needs some space for itself • For worst-case, also include nesting of ISRs • An experimental way to determine stack space – fill stack with recognizable data pattern at startup, run for certain time, see amount of data overwritten • Following are some ways to save code space: • Check if 2 functions not doing same task. E.g. if code calls memcpy at 20 places and memmove once, try removing this one call with memcpy and removing memmove from program • Check development tools. If memcpy calling causes tools to call memmove, memset, strcpy etc. try writing your own function that does not do this. • Scale down RTOS as much as possible • Check if C code doesn’t translate into too many assembly instructions e.g. each of the following 3 methods to initialize a struct variable result in different no. of assembly instructions

  21. Saving Memory Space (contd.) struct sMyStruct aMyData[3]; struct sMyStruct *pMyData[3]; int i; // Method 1 aMyData[0].iMember = 0; aMyData[1].iMember = 5; aMyData[2].iMember = 10; // Method 2 for(i=0;i<3;i++) aMyData[i].iMember = i*5; // Method 3 i=0; pMyData = aMyData; Do { pMyData ->iMember = i; i +=5; pMyData++; }while (i<10);

  22. Saving Memory Space (contd.) • Use static variables instead of stack ones as the read and write translates to fewer assembly instructions in most microprocessors • Use char instead of int for 8-bit processors. • As last option, write code directly in assembly Saving Power • Several embedded systems run on batteries so power is an important issue. • Most have at least one power saving mode (sleep mode, idle mode, standby mode etc.) • Common power-saving mode, one where processor stops executing instructions, stops clock and any built-in peripherals • Drawback – system needs to be restarted to function again  program starts again from the beginning unless necessary measures taken by software • Another mode – microprocessor stops executing instructions but on-board peripherals continue to operate. An interrupt resumes operation from next instruction after it was put to sleep • Saves less power than 1st method, but no special h/w or s/w required. Other things continue to function, e.g. DMA can continue to send data to a UART • Another method – turn entire system off, user will turn it back on when needed. Values that might be needed at restart again need to be stored in non-volatile memory (EEPROM or flash)

More Related