STMicroelectronics / STM32CubeWL

STM32Cube MCU Full FW Package for the STM32WL series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on boards provided by ST (Nucleo boards)
Other
107 stars 54 forks source link

Sequencer: how does it work? #39

Closed zubel7 closed 1 year ago

zubel7 commented 2 years ago

I have been trying to work with the sequencer (tasks and events) for a few days already, but I can not understand, in totality, the way it works. Is there any document, video or good example to learn more about it?

gbThreepwood commented 2 years ago

I spent some time trying to understanding the sequencer in order to better understand the LoRaWan examples. Here are some notes I wrote while it was at it. They are not complete unfortunately, but I hope they can be of help.

The example software provided by ST uses a simple sequencer library for scheduling the various tasks which should be performed. Since we would like to fully understand the examples, we will also be using that sequencer in the following implementation. You are certainly not required to use this sequencer in your own applications, use whatever framework, RTOS, etc. that you are comfortable with.

The sequencer library is simple, but our needs are even simpler and we will only be using a small subset of the supported functions in the library.

Before using the sequencer it must be initialized by a call to the function :code:UTIL_SEQ_Init( void ).

The sequencer uses function pointers to call specified functions in sequence. A function is registered as a task in the sequencer by means of the function: UTIL_SEQ_RegTask( UTIL_SEQ_bm_t TaskId_bm, uint32_t Flags, void (*Task)( void ) );. The first parameter is the task ID and is a 32-bit value where only one bit should be set, i.e. the maximum number of tasks is 32. The second parameter is not used for anything by the library, and the third parameter is a pointer to the function which should be called when it is time for the task to run.

UTIL_SEQ_RegTask((1 << 4), UTIL_SEQ_RFU, my_task_function);

The function UTIL_SEQ_SetTask( UTIL_SEQ_bm_t TaskId_bm , uint32_t Task_Prio ); is used to request a task to be executed. The first parameter is the same task ID as was used when you registered the task, and the second parameter is the priority of the task.

  UTIL_SEQ_SetTask((1 << 4), CFG_SEQ_Prio_0);

The function UTIL_SEQ_Run( UTIL_SEQ_bm_t Mask_bm ); is responsible for executing all the registered tasks. It should normally be called from an infinite loop.

Javadbolboli commented 1 year ago

Also this info can help you and others: The sequencer is a program that runs a series of tasks in a defined order.

The main functionality of the sequencer is implemented in the UTIL_SEQ_Run function. This function is called by the main program loop and receives a bit mask as a parameter. The bit mask determines which tasks are enabled to run. The function iterates over the enabled tasks and executes each one in the order of their priority. If no tasks are enabled, the function enters a low-power idle state.

The sequencer maintains a list of registered tasks in the TaskCb array, which contains pointers to the functions that implement each task. The TaskSet and TaskMask bitmaps are used to keep track of which tasks are enabled or disabled, respectively. The SuperMask bitmap is used to temporarily mask out higher-priority tasks during the execution of a lower-priority task.

The sequencer also provides event management capabilities through the EvtSet and EvtWaited bitmaps. Tasks can wait for events by setting the corresponding bit in EvtWaited, and other tasks can trigger events by setting the corresponding bit in EvtSet.

The sequencer is implemented in a platform-independent way and can be customized by redefining the macros and configuration parameters in utilities_conf.h.

ASELSTM commented 1 year ago

Hi @zubel7,

Thank you @gbThreepwood and @Javadbolboli for the details you have provided

Indeed, the sequencer provides a robust and easy framework to execute tasks in the background and enters low-power mode when there is no more activity. It implements a mechanism to prevent race conditions.

You can find more details within the "9.1 Sequencer" section of the application note AN5406. You may also refer to this MOOC where you can find extra information.

I hope this is of some use to you, please allow me thus to close this thread.

With regards,

FathiMahdi commented 11 months ago

Hi I know this issue was closed but I am asking how I can keep my tasks running I have two tasks but they get executed only one time

gbThreepwood commented 11 months ago

Hi I know this issue was closed but I am asking how I can keep my tasks running I have two tasks but they get executed only one time

Are you calling UTIL_SEQ_Run( UTIL_SEQ_bm_t Mask_bm ); in an infinite loop.?

FathiMahdi commented 10 months ago

Yes

`void MX_APPE_Process(void) { / USER CODE BEGIN MX_APPE_Process_1 /

/ USER CODE END MX_APPE_Process_1 / UTIL_SEQ_Run(UTIL_SEQ_DEFAULT); / USER CODE BEGIN MX_APPE_Process_2 /

/ USER CODE END MX_APPE_Process_2 / }`

I have two tasks but they get executed only once:

UTIL_SEQ_RegTask(1<<CFG_TASK_START_SCAN_ID, UTIL_SEQ_RFU, Scan_Request); UTIL_SEQ_SetTask(1<<CFG_TASK_START_SCAN_ID, 0); UTIL_SEQ_RegTask(1<<3, UTIL_SEQ_RFU, BS_PCK_PUBLISHER); UTIL_SEQ_SetTask(1<<3, 1);

gbThreepwood commented 10 months ago

Sorry for my late reply. I have not really used this library in a while, so there could be some tricks which I have forgotten, but as I remember, it was quite straight forward to get it working.

FathiMahdi commented 10 months ago

I think my all issue is around the user event and how I can register my event. From what I understand the Task get called if and event raised, I am investigation how I can register my event and how to link then with the task if I am not mistaken.