co concurr rrent programming in in c constrain ained d
play

Co Concurr rrent Programming in in C Constrain ained D Devic - PowerPoint PPT Presentation

Co Concurr rrent Programming in in C Constrain ained D Devic vices 01219335 Data Acquisition and Integration Chaiporn J Chaipo n Jaik aikae aeo De Department of f Computer Engineering Kasetsart Unive versity Revised 2020-09-09


  1. Co Concurr rrent Programming in in C Constrain ained D Devic vices 01219335 Data Acquisition and Integration Chaiporn J Chaipo n Jaik aikae aeo De Department of f Computer Engineering Kasetsart Unive versity Revised 2020-09-09

  2. Ou Outline • Handling concurrency • Example of concurrent tasks • Event-driven programming • Multithreading • Coroutines • Concurrency and MQTT 2

  3. Ha Handl ndling ng C Conc ncur urrenc ency • IoT applications tend to get too complex to be implemented as a sequential program • E.g., the app needs to ◦ Monitor various sensor status ◦ Wait for and respond to user switch ◦ Wait for and respond to requests from the network 3

  4. Ex Example: ample: C Conc ncur urren ent T Task asks • Create an application that performs the following subtasks concurrently ◦ Subtask #1 repeatedly blinks the red LED for a short time period (100 ms) every 2 seconds ◦ Subtask #2 when switch S1 is pressed, toggles the green LED 4

  5. Su Subtas ask # #1 O Only ly (No C (No Con oncurrency) blinks red LED shortly (100 ms) every 2 seconds START from machine import Pin import time led_red = Pin(2, Pin.OUT) Turn red LED on while True: led_red.value(0) # turn LED on Wait 100 ms time.sleep_ms(100) led_red.value(1) # turn LED off time.sleep_ms(1900) Turn red LED off Wait 1900 ms 5

  6. Su Subtas ask # #2 O Only ly (No C (No Con oncurrency) Toggle green LED when S1 is pressed from machine import Pin START led_green = Pin(12, Pin.OUT) sw1 = Pin(16, Pin.IN, Pin.PULL_UP) while True: # wait until S1 is pressed Wait until S1 is pressed while sw1.value() == 1: pass # toggle LED Toggle green LED led_green.value(1-led_green.value()) # wait until S1 is released Wait until S1 is released while sw1.value() == 0: pass 6

  7. Attempt to Combine Subtasks At • Cannot just put one subtask after another This will not from machine import Pin work! Why? import time led_red = Pin(2, Pin.OUT) led_green = Pin(12, Pin.OUT) sw1 = Pin(16, Pin.IN, Pin.PULL_UP) while True: # subtask #1 blocking led_red.value(0) # turn LED on time.sleep_ms(100) led_red.value(1) # turn LED off blocking time.sleep_ms(1900) # subtask #2 blocking while sw1.value() == 1: # wait until S1 is pressed pass led_green.value(1-led_green.value()) blocking while sw1.value() == 0: # wait until S1 is released pass 7

  8. Co Concurr rrency y Programming Mo Models • Event driven • Multithreading • Coroutines 8

  9. (1) Even (1) E ent-Dr Driven Mod odel • Also known as reactive programming • Perform regular processing or be idle • React to events when they happen immediately • To save power, CPU can be put to sleep during idle network event sensor event Idle/regular processing Sensor event Network event handler handler 9

  10. Ev Event Sources • Hardware (external) interrupts ◦ E.g., pin logic changes ◦ Use Pin.irq() method to set up a callback • Software interrupts ◦ E.g., Timer, incoming network messages https://lastminuteengineers.com/handling-esp32-gpio-interrupts-tutorial/ 10

  11. Ev Event-Dr Driven Cod ode import time def switch_pressed(pin): from machine import Timer, Pin led_green.value(1-led_green.value()) led_red = Pin(2, Pin.OUT) timer = Timer(0) led_green = Pin(12, Pin.OUT) blink1(timer) sw1 = Pin(16, Pin.IN, Pin.PULL_UP) sw1.irq(trigger=Pin.IRQ_FALLING, handler=switch_pressed) def blink1(timer): led_red.value(0) # turn LED on while True: timer.init(period=100, time.sleep(1) mode=Timer.ONE_SHOT, callback=blink2) def blink2(timer): led_red.value(1) # turn LED off timer.init(period=1900, mode=Timer.ONE_SHOT, callback=blink1) 11

  12. Pr Problems with Eve vent-Dr Driven Mod odel • Unstructured code flow • Requires global variables to keep track of task's states Very much like programming with GOTOs! 12

  13. (2) M (2) Mult ultit ithr hreading eading M Model del Execute subtask#1 Execute subtask#2 • Based on interrupts, context switching • Difficulties ◦ Too many context switches ◦ Each process required its own stack • Not much of a problem on modern microcontrollers OS-mediated context switching 13

  14. Mu Multithreading Co Code import _thread def switch_toggle(): Thread #2 import time while True: from machine import Timer, Pin # wait until sw is pressed while sw1.value() == 1: led_red = Pin(2, Pin.OUT) pass led_green = Pin(12, Pin.OUT) sw1 = Pin(16, Pin.IN, Pin.PULL_UP) # toggle LED led_green.value(1-led_green.value()) def blink_led(): Thread #1 while True: # wait until sw1 is released led_red.value(0) while sw1.value() == 0: time.sleep_ms(100) pass led_red.value(1) time.sleep_ms(1900) # create and run threads _thread.start_new_thread(blink_led, []) _thread.start_new_thread(switch_toggle, []) while True: time.sleep(1) 14

  15. Pr Problems with Threads • Code employing multithreads must ensure thread-safe operations • A function may be interrupted in the middle of its execution where it shouldn’t be, causing race conditions ◦ Use a Lock object to create a mutex 15

  16. (3) C (3) Corout utines ines • Generalized subroutines ◦ Allow multiple entry points for suspending and resuming execution at certain locations • Can be used to implement Cooperative Multitasking • As coroutines do not return, tasks' states can be kept inside local variables • No worry about thread-safe operations • May be known by different names in some languages: ◦ Green threads ◦ Fibers 16

  17. Su Subrou outin ines v vs. C . Cor orou outin ines “Subroutines are a special case of coroutines.” --Donald Knuth Fundamental Algorithms. The Art of Computer Programming Routine 1 Routine 2 Routine 1 Routine 2 yield yield call return yield return yield call Subroutines Coroutines 17

  18. Co Coroutines s in Mi MicroPython • Can be achieved using the uasyncio module with async/await pattern • The uasyncio module needs to be installed separately ◦ Already built into the course's MicroPython firmware 18

  19. Coroutines: Co s: Co Code import uasyncio as asyncio async def switch_toggle(): Coroutine #2 import time while True: from machine import Timer, Pin # wait until sw is pressed while sw1.value() == 1: await asyncio.sleep_ms(0) led_red = Pin(2, Pin.OUT) led_green = Pin(12, Pin.OUT) sw1 = Pin(16, Pin.IN, Pin.PULL_UP) # toggle LED led_green.value(1-led_green.value()) async def blink_led(): Coroutine #1 # wait until sw1 is released while True: led_red.value(0) while sw1.value() == 0: await asyncio.sleep_ms(100) await asyncio.sleep_ms(0) led_red.value(1) await asyncio.sleep_ms(1900) # create and run coroutines loop = asyncio.get_event_loop() loop.create_task(blink_led()) loop.create_task(switch_toggle()) loop.run_forever() 19

  20. Pr Problems with Coroutines/as asyncio io • Usually run on a single thread and not employ multiple cores • Due to their cooperative nature, long-running function calls render all other coroutines unresponsive ◦ May miss some hardware events 20

  21. MQ MQTT T and Co Concurr rrency • To handle incoming messages, umqtt requires check_msg() method to be called regularly • A subtask (thread or coroutine) can be created to ensure check_msg() is continuously called ◦ In case of coroutines, do not forget to yield, e.g., async def check_mqtt(): while True: mqtt.check_msg() await asyncio.sleep_ms(0) 21

  22. Co Conclusi sion • Complex tasks often require concurrency • Three concurrency programming models ◦ Event-driven ◦ Multithreading ◦ Coroutines 22

  23. As Assignment 5.1: IoT Light Control • Make a device to allow lamp control from (1) a local switch, and (2) the Internet ◦ When the local switch is pressed, the lamp's state is toggled ◦ Publish lamp state to ku/daq2020/ <nickname> /lamp only when it is changed ◦ Payload 0 → Lamp is off ◦ Payload 1 → Lamp is on ◦ Also subscribe to ku/daq2020/ <nickname> /lamp to allow controlling the LED from the Internet http://clipart-library.com/clipart/1168222.htm 23

Recommend


More recommend