The objective of this documentation is to explain the code generation mechanism used by Waijung2.
This documentation assumes the reader has a basic understanding of FreeRTOS functionality. Click here to learn more about FreeRTOS types, functions, and macros.
The Waijung 2 block set is designed to program an ESP32 microcontroller board using FreeRTOS. The rest of this documentation will describe how the Waijung 2 block set implements the features of FreeRTOS when generating code for your model file.
In all model files where the Waijung 2 blocks are used, the Target Setup Block should be present in order to configure Simulink to generate and upload the generated code to an ESP32 microcontroller. The Target Setup Block would acquire necessary data to create the base rate task. The base rate task is the default FreeRTOS Task created by Waijung 2 to place the generated code. If all the blocks in the model have the same sample time, it will be executed within this task and the execution rate of the task will be determined by the sample time used.
When a model consists of more than one sample time, Waijung 2 generates a separate task for each unique sample time in a way that the block gets executed according to the specified frequency. If two blocks share the same sample time the code generated by the two blocks will be executed within the same task created for that specific sample time.
Another way to create a task is to use the FreeRTOS Task Block. The input to the FreeRTOS Task Block can be of two types.
1.Function-Call Generator Block (from Matlab)
2.Timer Interrupt Block (from the Waijung 2 block set)
When using the FreeRTOS Task Block, the block sequence that is connected to the output port of that block will be encapsulated in a single task that is activated through a binary semaphore. When using the Function-Call Generator Block, this semaphore will be passed from the task created for the sample time specified in the Function-Call Generator Block mask. If this sample time is used for another block in the same model, and that block carries a blocking process (a process that is waiting for some event, such as a resource becoming available or the completion of an I/O operation), it will affect the execution frequency of the block sequence connected to the FreeRTOS Task Block as well. Therefore, when having timer critical tasks, the input of the FreeRTOS Task Block should be a Timer Interrupt Block. This way the semaphore will be passed from the Interrupt Service Routine (ISR) of the timer.
Let's analyze the model shown below with the information above. Block sequence 1,2 and 3 sample times are determined by the sample time specified in the Constant block. In block sequence 4, FreeRTOS Task Block takes the input drive from a Function-Call Generator Block while block sequence 5 FreeRTOS Task Block takes the input drive from a Timer Interrupt Block.
Here Waijung2 will create 5 tasks. Three tasks for each unique sample time (2 seconds, 3 seconds, and 4 seconds) and two created by the FreeRTOS Task Blocks. The task created for the 4 seconds sample time will consist of code for sequence 3 and the code to pass the semaphore for the task created by the FreeRTOS Task Block in sequence 4. Therefore, if sequence 3 has a blocking process, it could affect the execution frequency of sequence 4 as well. As a solution in sequence 5, which is also expected to be run at a sample time of 4 seconds, is driven from a Timer Interrupt Block. Hence, the semaphore for the task created by the FreeRTOS Task Block in sequence 5 will be released from timer ISR. This ensures that the execution frequency of sequence 5 is unaffected by sequence 3.
The sample times of the compatible blocks can be changed from the Sample time parameter in the block mask.