compile-time-init-build icon indicating copy to clipboard operation
compile-time-init-build copied to clipboard

How to port coroutine-style code & event loops to CIB ?

Open antonysigma opened this issue 3 years ago • 1 comments
trafficstars

Hi I have just watched the seminar on the cib.hpp library. I like how we can modularize hardware functions as services, and bind them with external commands, without runtime overhead.

Following #30 , how do I refactor a FreeRTOS-style code from the following LED blinker example to cib.hpp? Here, there are two co-routines performing their own initializations, and then enters their own event loops iterating at 1000ms and 200ms correspondingly. I am assuming a single-thread application compiled by either avr-gcc or stm32-aarch64-gcc.

volatile bool is_led_on = false;

void loopLED() noexcept {
   setupLED();
   bool led_blink_state = true;
   for(;;) {
         if(is_led_on) {
              digitalWrite(led_blink_state);
              led_blink_state = ! led_blink_state;
         } else {
              digitalWrite(false);
         }
             
         using std::chrono_literal;
         Rtos.resume_after(1000ms);
   }
   teardownLED();
}

void loopButton() noexcept {
    setupButton();
    for (;;) {
        if (button1.is_pressed()) {
            is_led_on = ! is_led_on;
        }
        using std::chrono_literal;
        Rtos.resume_after(200ms);
    }
    teardownButton();
}

In particular, how do I refactor the above setup -> event loop -> teardown code to utilize CIB's compile time init() flow builder? How do I bind the button press event to the LED service? I hope to watch and learn how it is done in the CIB style.

antonysigma avatar Nov 18 '22 18:11 antonysigma

Note to self: cib is a composition library for "gluing" MCU drivers together. It works with co-routines e.g. FreeRTOS, and does not replace it. The above coroutine code can be integrated with CIB by:

--- before.cpp	2024-01-20 13:31:38.323275734 -0800
+++ after.cpp	2024-01-20 13:32:55.599034010 -0800
@@ -1,16 +1,12 @@
 void loopLED() noexcept {
-   setupLED();
-   bool led_blink_state = true;
+   nexus.service<SetupLED>();
    for(;;) {
-         if(is_led_on) {
-              digitalWrite(led_blink_state);
-              led_blink_state = ! led_blink_state;
-         } else {
-              digitalWrite(false);
-         }
+	 // internal state "led_blink_state" handled by device library,
+	 // e.g. by Boost::SML
+	 nexus.service<BlinkLED>();
              
          using std::chrono_literal;
          Rtos.resume_after(1000ms);
    }
-   teardownLED();
+   nexus.service<TeardownLED>();
 }

Although it begs the question how the advanced message passing interfaces of FreeRTOS (e.g. send messages among services, semaphores, instances of services) can be integrated with CIB.

References:

  • https://github.com/intel/compile-time-init-build/discussions/103#discussioncomment-3461046
  • https://github.com/intel/compile-time-init-build/discussions/237

antonysigma avatar Jan 20 '24 21:01 antonysigma