Presentation is loading. Please wait.

Presentation is loading. Please wait. 1 Embedded Systems Lecture 9: Operating Systems, buffered i/o Ian McCrumRoom 5B18, Tel: 90 366364.

Similar presentations

Presentation on theme: " 1 Embedded Systems Lecture 9: Operating Systems, buffered i/o Ian McCrumRoom 5B18, Tel: 90 366364."— Presentation transcript:

1 1 Embedded Systems Lecture 9: Operating Systems, buffered i/o Ian McCrumRoom 5B18, Tel: 90 366364 voice mail on 6 th ring Email: Web site:

2 Operating Systems In a conventional PC, an Operating systems allows easy access to the resources of the computer Disk drives, Optical, magnetic and solidstate (e.g SD) Printers, Serial ports, USB and RS232 Ethernet/WifI interfaces, Sound generations and playback, Screens and keyboard. Memory In a modern windowing environment it manages access to the screen, allows multiple programs to run at once, including hidden programs running in the background 2

3 Embedded Operating Systems Again, it manages the resources of the (micro)computer; memory. i/o and CPU access. Task & Resource management When you execute a program the OS creates a task A task can not “hog” a resource (memory/serial port/timer) Normally we consider multi-tasking but even single tasking systems can use an OS – e.g –to manage memory (malloc() and free() ) –To abstract hardware, (printf or a network socket connection) –This offers portability, we would not want to write a malloc function for every system that could run our code. 18/11/133

4 Multitasking Gives the appearance of doing two (or more) things at once A simple example would use interrupts and have a “main” program and a “interrupt routine” A more managed system might have a timer interrupt only and give each task a 20 millisecond slice of time. (c.f co-routines) –Wasteful if a task is waiting for an i/o, e.g a ADC to complete –Better if a task takes its slice or hands it back, better if the OS handles all i/o and knows if a task can run or not. Early windows give a task a time-slice but let the task itself relinquish control – or not! If it hung or waited forever for a human to do something. We could call this “co-operative non-preemptive multitasking. In practice tasks call system calls often and the OS intervenes More efficient to allow the OS or a task to preempt another and get the CPU resource, maybe because data has arrived that a task was waiting for. For this to work the i/o must be buffered 18/11/134

5 Scheduling From 18/11/13 18/11/135

6 Scheduling Here we only briefly mention this, c.f Meng module on RTOSs. Co-operative is straight forward to implement Preemptive can have different strategies; –Round Robin –Priority-Based Round Robin –Shortest Process Next –Lottery Scheduling –First Come First Served –Shortest Job First (SJF) –Shortest Remaining Time Next –Highest Response Ratio Next –Rate Monotonic Scheduling –Earliest Deadline First 18/11/136

7 Round Robin Each time the scheduler has to decide which task to run it goes searches a queue. Imagine the queue is circular and its starting point varies – just after the last task to run. With Priority-Based Round Robin a number of queues are used. If there are tasks in the high priority queue ready to run they get picked first. 18/11/137

8 Classification of OSes Non Real time, a task will get to run at some time in the future Soft Real time, a task will run in the future, nearly always before a deadline Hard Real time, a task will run by a deadline, guaranteed! The Issue is not speed, it is predictability and deterministic responses that are needed. Often a mixture is used, non-critical tasks mop up spare cpu or resources but are pre-empted if necessary. Use of a Hardware Abstraction Layer gives a more robust system, portable and fault tolerant. 18/11/138

9 Other features of OSes Memory management – Virtual memory helps Interrupt management – top half/bottom half Protection, Kernel space and User space, privilege levels Security and auditing Inter Task Communication is important – – Sempahores (counting and single) – Other types of flags, mutexes and event flags – Pipes, Queues, buffers and shared memory – Sockets and Streams 18/11/139

10 Issues Tasks can be “Ready”,”Running” or “Waiting” (aka Blocked) modern OSes use Queues and Lists to manage these, and we also need Per Process Data Area blocks of memory (PPDA tables) So memory is needed The source of the Linux Kernel has 35 different tables! The kernel must ideally be in protected memory so user processes cannot access and corrupt these. Interrupt latency, context switch time and jitter affect performance All i/o must be buffered and managed. Implies interrupts all handled by the OS and tasks cannot interrupt. Potential snags still possible – deathly embrace, deadlock must be monitored for, as well as memory “faults” when a task attempts to get at memory it does not own. Virtual memory made this much easier. Security is now also very important, to protect against rogue code, by accident or design! 18/11/1310

11 Buffered i/o is useful A user does not read hardware registers directly A user accesses a buffer in memory E.g typical serial input functions are kbhit() and getch(). For buffered i/p we do not use these We can test to see if the buffer has data in it and we can get data from the buffer. 18/11/1311

12 Incoming data – e,g UART We arrange an interrupt to occur when data arrives We get the incoming char and place it in the buffer (if there is room) There is some housekeeping to do. There are some data structures and variables needed (and a couple of ways of implementing ring buffers) 18/11/1312

13 18/11/1313 Taken from 18/11/13

14 18/11/1314 Beware! Some implementations have head pointing one beyond the end of the data, at the next empty space, liekwise for tail so make sure you are clear which convention is in effect.

15 Ring buffers (assume an array) Need a head pointer – holds last data written – Alternative implementations point it at the next empty space, Need a tail pointer - holds oldest data yet to be read Need to know when the buffer is full – either keep a count variable or check pointer values When putting data into the buffer we advance the head pointer, if it is beyond the end of the buffer we point it at the beginning of the buffer. We might check first to see if there is room When reading data we see if there is data there, we use the tail pointer, get the array contents and increment the tail pointer, if is beyonf the end of the array we reset it to the beginning of the array. 18/11/1315

16 #define BUFSIZE 256 // make this a power of 2 unsigned char buffer[ BUFSIZE]; // better to use a struct to hold the array and variables // here we will just use global variables to make the code simpler // could use pointers or just ints to hold array index, ints simpler to understand int head; // holds index of last byte put into the array, used to store data after incrementing int tail; // holds index of the last data read from the array, one past the next one to get // alternative code might do this differently, // do we need to post increment or preincrement the indexes – think and check! int count; // zero means full, if equal to BUFSIZE then the array is full void initbuffer(void); int putdata(unsigned char data); // typically used by ISR to plant data in the array, return 0/-1 // should check to see if buffer full (count==BUFSIZE) or empty (count==0) int getdata (); /./ returns 0 to 255 for a character or -1 if buffer empty 18/11/1316 Ring buffer in C

17 Functions for ringbuffer void initbuffer(void){ tail=0; head=0; count=0; memset(buffer,0,sizeof(buffer);// optional, clear array } int putdata(unsigned char data){ if(count0){ // there is data to be read c=buffer[]; // go read it! tail++; if(tail==BUFSIZE)tail=0; // postincrement tail count--; // no need to check it less than zero… return(c); // gets promoted to int, and it will be positive } return(-1); // lets the caller know the buffer was empty, but they should have checked first! } 18/11/1317

18 Variations on a theme The reason for making the buffer a power of two is to allow making the code more efficient. Instead of using if statements to correct the pointers you can use the mod function (or the OR function in assembler) (head++)%256; forces head to be 0..0xFF 18/11/1318

19 Most prfessional C programmers avoid arrays and use pointers, this allows use of malloc and dynamic memory allocation – more portable. Also collections of objects that are related are often put in a struct. By writing functions that take a struct pointer you can use the same ring buffer code with different ring buffers – you might have half a dozen in a big system. 18/11/1319 Variations on a theme

20 from at 18/11/13 18/11/1320

21 18/11/1321 from at 18/11/13

22 18/11/1322 from at 18/11/13

23 18/11/1323 from at 18/11/13

24 Other types of buffer - case study I once worked with a system that collected sporadic data from an ADC but needed to write a block of data to a floppy disk. We used two buffers, one was always filling and one was emptying (it sometimes took a good fraction of a second to write a sector to the disk) We used a boolean variable flag, if it held 0 the current buffer for writing was buffer0 and if 1 then the current buffer was buffer1. We still used head and tail pointers, rather than a count variable we used tail==head to indicate empty and head=tail-1 to indicate full. We also conceived of having more buffers and “chaining” them together to allow a human to change a floppy A good programmer should know about data structures and algorithms – single and double linked lists, hashing, binary trees and search and sort methods as well as compression. 18/11/1324

25 Tutorials You have seen code that uses interrupts. Modify it to put numbers into a buffer every second. Each time a pushbutton is pressed read out the number on an LED. Use the other LEDs to indicate empty half full and overfull (blink rapidly) Use the uart working and use it for o/p, gather data from ADC, put it in the buffer once a second. When a button is pressed, empty the buffer using the UART to send a value to the PC 18/11/1325

26 Bonus, outputting numbers on one LED Morse code uses a 5 value system (not binary!) A dah (dash) is three times longer than a dit (dot). A dit delay is used between symbols in a letter or digit. A dah delay is used between letters or digits A 5 dit time delay is used between words. Digits are exactly 5 symbols long and have a regular pattern. ‘1’ is dit dah dah dah dah [ — — — — ] ‘2’ is dit dit dah dah dah[ — — — ] … ‘5’ is dit dit dit dit dit[ ] ‘6’ is dah dit dit dit dit[ — ] ‘7’ is dah dah dit dit dit[ — — ] … ‘9’ is dah dah dah dah dit[ — — — — ] ‘0’ is dah dah dah dah dah[ — — — — — ] 18/11/1326

27 18/11/1327 There are longer codes for punctuation symbols [., ? ] and abbreviations are used a lot

28 Old C PIC code… (from CCS compiler) 18/11/1328 You will need to write a delay routine (maybe __delayms() is available). Also the output_high and output_low needs changed for your compiler

Download ppt " 1 Embedded Systems Lecture 9: Operating Systems, buffered i/o Ian McCrumRoom 5B18, Tel: 90 366364."

Similar presentations

Ads by Google