STM32WB BLE SW Application Sequencer Architecture Overview
The STM32WB BLE SW Application Sequencer is a specialized framework that optimizes while loop bare-metal implementations to avoid race conditions, especially in low power modes. It is not intended to compete with standard operating systems but rather with bare-metal implementations. The sequencer allows for task registration, priority management, event waiting, and more. Various utility functions such as task registration, task setting, task pausing, and task resuming are provided to enhance the efficiency of program execution within a while loop environment.
Download Presentation
Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
E N D
Presentation Transcript
STM32WB BLE SW Application Architecture Sequencer Revision 1
Sequencer 2 The sequencer is NOT an operating system It does not intend to compete versus standard OS but versus standard bare metal implementation It is an optimized packaging of a while loop bare metal classic implementation It allows to avoid race conditions which are most of the time faced in bare metal implementation especially when low power mode are implemented ST Confidential
Sequencer 3 The sequencer provides the following features: Up to 32 tasks registered Request a task to be executed Pause and Resume a task Wait for a specific event (might be not blocking) Priority on tasks ST Confidential
UTIL_SEQ_Run() / UTIL_SEQ_Idle() 4 While(1) { While(1) { UTIL_SEQ_Run() implements the code that is running within a while loop block if(flag1) { UTIL_SEQ_Run(); } flag1 = 0; Fct1(); } if (flag2) { flag2 = 0; Fct2(); } __disable_irq(); If (! (flag1 || flag2)) { UTIL_SEQ_Idle(); } __enable_irq(); } ST Confidential
UTIL_SEQ_RegTask() 5 While(1) { UTIL_SEQ_RegTask( flag1, Fct1()); if(flag1) { UTIL_SEQ_RegTask() adds in the while loop the support of a new function UTIL_SEQ_RegTask( flag2, Fct2()); flag1 = 0; Fct1(); } if (flag2) { flag2 = 0; Fct2(); } __disable_irq(); If (! (flag1 || flag2)) { UTIL_SEQ_Idle(); } __enable_irq(); } ST Confidential
UTIL_SEQ_SetTask() 6 While(1) { if(flag1) { UTIL_SEQ_SetTask() sets the flag dedicated to the function to be executed in the while loop UTIL_SEQ_SetTask( flag1); => flag1 = 1 flag1 = 0; Fct1(); } if (flag2) { flag2 = 0; Fct2(); } __disable_irq(); If (! (flag1 || flag2)) { UTIL_SEQ_Idle(); } __enable_irq(); } ST Confidential
UTIL_SEQ_PauseTask() / UTIL_SEQ_ResumeTask () 7 While(1) { if(flag1) { UTIL_SEQ_PauseTask() prevents the function to be executed in the while loop whatever is the value of the related flag UTIL_SEQ_PauseTask( flag1); While loop does not evaluate the dedicated code flag1 = 0; Fct1(); } UTIL_SEQ_ResumeTask( flag1); While loop evaluates again the dedicated code if (flag2) { This does not prevent UTIL_SEQ_SetTask() to be operationnal flag2 = 0; Fct2(); UTIL_SEQ_ResumeTask() allows again the function to be executed if the related flag is set } __disable_irq(); If (! (flag1 || flag2)) { UTIL_SEQ_Idle(); } __enable_irq(); } ST Confidential
UTIL_SEQ_WaitEvt / UTIL_SEQ_SetEvt () 8 UTIL_SEQ_WaitEvt(Evt_Id) does not return to the caller until UTIL_SEQ_SetEvt (Evt_Id) is called ST Confidential
Overview 9 Main( void ) { HAL_Init(); . . . UTIL_SEQ_RegTask ( Id1, Task1); UTIL_SEQ_RegTask ( Id2, task2); . . . while(1) { UTIL_SEQ_Run (); } } Register a task to be executed in the background at any time / any place in the firmware ( before it is requested to be executed) Register tasks to be executed in the background Enter low power mode when there is nothing to schedule Request the sequencer to execute a task according to priority in the background. The request may be done at any time / any place in the firmware ( from interrupt handler, function, etc ) void UTIL_SEQ_Idle ( void ) { UTIL_LPM_EnterLowPower (); } List of API Enter low power mode when there is nothing to schedule UTIL_SEQ_Idle() UTIL_SEQ_PreIdle() UTIL_SEQ_PostIdle() UTIL_SEQ_Run() UTIL_SEQ_RegTask() UTIL_SEQ_SetTask() void fct ( void ) { UTIL_SEQ_SetTask ( Id1, Prio0); } Request the sequencer to execute Task1 in the background UTIL_SEQ_PauseTask() UTIL_SEQ_ResumeTask() UTIL_SEQ_WaitEvt() UTIL_SEQ_SetEvt() UTIL_SEQ_IsEvtPend() UTIL_SEQ_EvtIdle() void fct_IT ( void ) { UTIL_SEQ_SetTask ( Id2, Prio1); } Request the sequencer to execute Task2 in the background ST Confidential
Scheduling 10 When F = 1, the sequencer executes the task Prior execution, the sequencer sets back F to 0 Priority P0 is the highest UTIL_SEQ_RegTask(Id0) UTIL_SEQ_RegTask(Id1) UTIL_SEQ_RegTask(Id2) Id2 F = 0 Id2 F = 0 Id2 F = 0 Id0 F = 0 UTIL_SEQ_SetTask(Id0, P1) UTIL_SEQ_SetTask(Id1, P0) Id0 F = 1 Id0 F = 1 Execution Id1 While Loop While Loop While Loop While Loop Id1 F = 0 Id1 F = 0 Id1 F = 1 Id0 F = 1 Id0 F = 0 Id2 F = 0 Id2 F = 0 Id0 F = 0 UTIL_SEQ_SetTask(Id0, P0) UTIL_SEQ_SetTask(Id1, P1) Id2 F = 0 UTIL_SEQ_PauseTask(Id0) Execution Id0 While Loop While Loop While Loop Id1 F = 1 Id1 F = 0 Id1 F = 0 Id0 F = 1 Id2 F = 0 Id0 F = 0 Id0 F = 1 Id2 F = 0 Id2 F = 0 UTIL_SEQ_ResumeTask(Id0) Execution Id1 Execution Id0 While Loop While Loop While Loop Id1 F = 0 Id1 F = 0 Id1 F = 0 ST Confidential
Priority 11 P0 is higher priority than P1 Evt2 While loop F0() Evt1 F1() F2() UTIL_SEQ_SetTask( F0, P1) Evt0 While F0() is running with priority P1, it is not preempted when F2() is requested with priority P0. UTIL_SEQ_SetTask( F1, P1) P1 UTIL_SEQ_SetTask( F2, P0) F0() does not stop When F0() is finished, the while loop selects the next task according to priority P0 P1 The priority is set when the task is requested by the user and could be changed on each request ST Confidential
round robin 12 The round robin mechanism as implemented in the while loop makes sure there is no case that a task (F1) is never executed because a task with the same priority (F0) is always pending at the same time. All tasks have the same priority While loop F0() F1() Evt0 UTIL_SEQ_SetTask( F0 ) UTIL_SEQ_SetTask( F0, F1 ) ST Confidential
Event (1/2) Enhanced blocking feature Fct0() UTIL_SEQ_EvtIdle( ) Evt0 13 Fct0() waits for event Id0 before moving forward. Blocking call until event Id0 is received UTIL_SEQ_WaitEvt( Id0) The blocking call is instantiated with UTIL_SEQ_WaitEvt () Run any code or enter Low Power Mode The CPU is looping in UTIL_SEQ_Idle () until the event Id0 is received UTIL_SEQ_SetEvt( Id0) The application may run any code in UTIL_SEQ_Idle () or enter Low Power Mode. ST Confidential
Fct1() Evt0 Fct0() Evt1 SCH_EvtIdle ( ) Event (2/2) Enhanced blocking feature 14 SCH_WaitEvt ( Id0) Fct0() waits for event Id0 before moving forward. UTIL_SEQ_EvtIdle() while waiting for event Id0 and calls Fct1() Fct1() waits for event Id1 before moving forward. SCH_WaitEvt ( Id1) UTIL_SEQ_EvtIdle() loops until event Id1 is received Event Id0 is received but is not currently waited by UTIL_SEQ_EvtIdle () SCH_SetEvt ( Id0) Event Id1 is received and UTIL_SEQ_EvtIdle () returns to Fct1(). SCH_SetEvt ( Id1) When Fct1() is over, it returns to UTIL_SEQ_EvtIdle () which is now waiting for event Id0. As event Id0 has already been received, UTIL_SEQ_EvtIdle() returns to Fct0() ST Confidential