Download presentation
Presentation is loading. Please wait.
Published byLoren Lawrence Modified over 9 years ago
1
CSCI1600: Embedded and Real Time Software Lecture 15: Advanced Programming Concepts Steven Reiss, Fall 2015
2
Task Loop Tasks are modeled as automata Code consists of executing each task periodically What is the main loop void loop() { task1(); task2(); taskn(); } What are the problems
3
Task Loop Coding Issues Some tasks are periodic Should be run every k milliseconds Some tasks are sporadic Run when needed, not other times Tasks don’t know about other tasks Timing demands for example Tasks need to communicate Tasks have different priorities
4
Example Suppose we have 3 tasks One should be run every 6 ms One should be run every 10 ms One should be run when a flag is set
5
Timed Task Loop long last_time = 0; int cycle_counter = 0; boolean run_task = false; const int PERIOD = 2000; void loop() { long time = micros(); if ((time – last_time) >= PERIOD) { last_time = time; cycle_counter = (cycle_counter+1)%15; if (cycle_counter%3 == 0) taskA(); if (cycle_counter%5 == 0) taskB(); } if (run_task) taskC(); }
6
Other Alternatives Wait at the end for next cycle to begin Use a (priority) queue of tasks to run Tasks can be added/removed from queue Main loop Pop top task off queue, execute it Task can add itself back to queue if periodic Priority can be when the task needs to be run This looks a lot like scheduling
7
Coding a Task Given a FSA model, what should the code do The code should be designed to be quick State actions should never wait The code should take the next step, no more Any actions it does should be fast Setting output, reading input, setting flags It shouldn’t do any waiting Long computations should be broken up
8
Coding a Task enum State { S1, S2, … Sn } State cur_state = S1; void taskA() { switch (cur_state) { case S1 : // check for transitions, set cur_state if so // also, do any action associated with transition case S2 : … } switch (cur_state) { case S1 : // Do any action associated with state }
9
Coding Timing Information Suppose a state has a timeout transition How should this be coded Example: beep for 5 seconds What’s wrong here: Turn on tone() wait(5000) Turn off tone() go to next state
10
Coding a Timer Transition Keep track of time of state entry Static variable (global or static for function) Set to current time when entering a state with a timeout Or to timeout time Code for the state checks if current time>last_time+TO If so, it transitions to the next state
11
Coding a Timer Transition If task is periodic with fixed period Runs every 10 ms for example Use the task timing in place of the real clock Can model the delay as a set of interim states Or just have a counter of the number of runs since you entered the current state
12
Light Array Task What should this task look like? What is the appropriate model?
13
Floating Point Problem: computations sometimes need real numbers Floating point is slow Integers aren’t accurate enough Solution Use fixed point arithmetic Essentially scaled integers
14
Fixed Point Suppose we want to add 10.234 + 5.1 We could use integers scaled by 10^3 Add 10234 + 5100 = 15334 === 15.334 Multiplying is slightly more complex Mutliply 10234 * 5100 = 52193400 Divide by 10^3 = 52193.400 = 52193 === 52.193 Actually want to round (52193400+500) / 1000 What do you do for division?
15
Fixed Point Arithmetic Suppose we want to divide 10.234 / 5.1 Multiple 10234 * 10^3 = 10234000 Divide by 5100 = 2006 with remainder 3400 3400 > 5100/2 so set result to 2007 === 2.007 Can also multiply by 10^4 to get more accuracy and scale back Can also take (10234*10^3 + 5100/2)/5100 Computers don’t do this with powers of 10 Why not? Do it with powers of two (eg 8 bit fraction, 24 bit int)
16
Simplifying Computations Embedded systems deal with limited domain We can use this to simplify coding Suppose we know angle to a degree Want to compute next position in x,y coordinates This requires sin/cos computation How to compute sin and cos These require multiple floating point computations Taylor series approximation
17
Look Up Tables Instead of computing it as needed, precompute it We only need it for 90 values (0..90) Set up a table sin_data[90] with the result for each degree sin and cos then can be done with table lookup cos(X) = sin(X+90) sin(X+90) = 1-sin(X-90) sin(X+180) = -sin(X) … This can often be used for complex computations
18
Look up Tables How could you use look up tables in tic-tac-toe?
19
Tasks Need to Communicate Simple communication is one-way Task A decides what lights should be on Task B just displays what it is told Global variable Written only by task A Read by task B This is safe as long as there is only one writer Why care about multiple writers?
20
Problem to Consider Keypad for entering alarm code Task to read the keypad Determine when a button has been pushed Want to check a sequence of button presses against known code(s) Task that does the checking How do these communicate?
21
Making Communication Simple
22
Handshake Communication The previous depended on timing to some extent What should we do when tasks need to synchronize Task A sends a request to Task B Task A needs to know when Task B is done In order to send another request Ensure no new button is pressed until current one is processed Can use 2 variables rather than one Task A owns variable REQ Task B owns variable ACK
23
Handshake Communication Code A: set REQ, wait for ACK, clear REQ, wait for ~ACK B: wait for REQ, do action, set ACK, wait for ~REQ, clear ACK Sequence A: set REQ B: wait for REQ, do action, set ACK A: wait for ACK, clear REQ, wait for ~ACK B: wait for ~REQ, clear ACK
24
Communicating Arduinos Suppose you want to have two Arduinos talk to each other Just simple message back and forth (sequence of bits) How would you do this?
25
Communication: Queues More complex communication involves multiple requests Model railroad: multiple switches can be triggered But only one can be activated at a time This is generally implemented as a queue Allows the two tasks to be asynchronous
26
Queue-based Tasks
27
Queue Implementation Queues in embedded programs Are generally fixed in size Often sized so they never overflow How to program a queue?
28
Simple Queue byte queue[10]; int qp = 0; void push(byte x) [ TASK A ] if qp < 10, then queue[qp++] = x else exception byte pop() [ TASK B ] if (qp == 0) exception rslt = queue[0]; for (i = 1; i < qp; ++i) queue[i-1] = queue[i] qp = qp-1 return rslt What’s wrong with this?
29
Circular Buffer Queue Use a single array Maintain a start and end pointer Treat the array as a circular buffer Element beyond the last is the first, etc. Maintain two pointers Head (read): pointer to the first element to extract Tail (write): pointer to the next place to insert
30
Circular Buffer Pop: if read == write then exception result = buf[read]; read = (read + 1) % size
31
Circular Buffer Push(data): If read == write then exception buf[write] = data write = (write + 1)%size
32
Circular Buffer Advantages Little data movement Pointers are only changed by one task Queue cells are safely read/written Code is simpler Extensions Can read/write multiple things at once Data stream or communications channel
33
Circular Buffers and Handshakes What happens with a circular buffer of size one?
34
Homework Read Chapter 10
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.