Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCI1600: Embedded and Real Time Software Lecture 15: Advanced Programming Concepts Steven Reiss, Fall 2015.

Similar presentations


Presentation on theme: "CSCI1600: Embedded and Real Time Software Lecture 15: Advanced Programming Concepts Steven Reiss, Fall 2015."— Presentation transcript:

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


Download ppt "CSCI1600: Embedded and Real Time Software Lecture 15: Advanced Programming Concepts Steven Reiss, Fall 2015."

Similar presentations


Ads by Google