FreeRTOS Lecture 33 – Using MCU peripherals and implementing initialization codes

 

Using MCU peripherals and implementing initialization codes

 

 

Now let’s learn more about how FreeRTOS schedules the FreeRTOS related tasks, how exactly the task executes, and for how many durations each task executes. You will understand all these topics as you make progress.

Our goal was to create two tasks and use semihosting to print some logs. But the semihosting is not that great idea. It is definitely helpful when you do debugging. But in order to get the logs using semihosting or printf’s, you have to keep the board into debug mode. Then only it will work. Otherwise, it won’t work.

In this article, let’s use the UART peripheral of the microcontroller to send logs to the computer over serial communication.

Now let’s see how we can configure the UART peripheral and how to use that in the FreeRTOS scenario.

For that, we are going to use the standard peripheral driver given by the STMicroelectronics. We will be using various driver files like UART driver, clock driver, and GPIO driver to configure the UART peripheral.

 

Let’s create one function called prvSetupHardware to configure the UART peripheral, where prv means private. This is a private function. You can even make it static, as shown below.

It is a private function in order to implement all hardware-specific configurations. Hardware means microcontroller or board. All board-related initialization or any peripheral related initialization we can do in this function.

So, let’s keep all the microcontroller peripheral specific initialization inside this prvSetupHardware function.

void vTask2_handler(void *params)
{
    while(1)
    {
         printf("Hello-world: From Task-2\n");
    }
}

static void prvSetupUart(void)
{

}

Function to setup the hardware

 

Now let’s give the prototype of the prvSetupHardware function, as shown in Figure 1.

Figure 2. Prototype of prvSetupHardware function.
Figure 1. Prototype of prvSetupHardware function.

 

Let’s call the prvSetupHardware function from main, as shown in Figure 2.

Figure 2. Call for the prvSetupHardware function.

 

Instead of removing semihosting related calls, manage them using preprocessor macros, as shown below. Now the semihosting related calls are used only if the ifdef is defined.

#include<stdio.h>
#include<stdint.h>
#include<string.h>
#include "stm32f4xx.h"

#include "FreeRTOS.h"
#include "task.h"

TaskHandle_t xTaskHandle1=NULL;
TaskHandle_t xTaskHandle2=NULL;

//Task functions prototypes
void vTask1_handler(void *params);
void vTask2_handler(void *params);

#ifdef USE_SEMIHOSTING
//used for semihosting
extern void initialise_monitor_handles();
#endif

static void prvSetupHardware(void);

int main(void)
{

#ifdef USE_SEMIHOSTING
     initialise_monitor_handles();
     printf("This is hello world example code\n");
#endif

Use of preprocessor macros to manage the semihosting related calls

 

Remove the semihosting related printf’s in the task handlers, as shown in Figure 3. You can replace it with UART-related printf’s later.

Using MCU peripherals and implementing initialization codes
Figure 3. Removing semihosting related codes from the task handlers.

 

Build this code and see whether it builds successfully or not (Figure 4). It builds successfully without any errors.

Using MCU peripherals and implementing initialization codes
Figure 4. Building the project.

 

If you want to use semihosting, then you have to define the macro USE_SEMIHOSTING in the project settings. Let’s see how we can do that.

Just copy that macro and go to the project, select properties (Figure 5), after that go to C/ C++ build, go to settings (Figure 6), go to MCU GCC compiler, and then go to the preprocessor (Figure 7).

After that, click on the add option marked in Figure 8. You will see a popup; there, you paste the macro and click ok (Figure 9). Then apply those changes and click ok (Figure 10). If you don’t want to use the semihosting, then you just disable that.

Using MCU peripherals and implementing initialization codes
Figure 5. Properties of the current STM32 project.

 

Using MCU peripherals and implementing initialization codes
Figure 6. C/ C++ build settings.

 

Using MCU peripherals and implementing initialization codes
Figure 7. Preprocessor of MCU GCC compiler.

 

Using MCU peripherals and implementing initialization codes
Figure 8. Option to add the preprocessor macro.

 

Using MCU peripherals and implementing initialization codes
Figure 9. Adding the preprocessor macro USE_SEMIHOSTING.

 

Using MCU peripherals and implementing initialization codes
Figure 10. Applying the changes.

 

Now let’s see whether it builds properly or not (Figure 11). The project builds successfully without any problems.

Using MCU peripherals and implementing initialization codes
Figure 11. Building the project.

 

But for this example, we don’t need semihosting; therefore, let’s remove that, as shown in Figure 12. After that, apply changes and click ok.

Using MCU peripherals and implementing initialization codes
Figure 12. Removing preprocessor macro USE_SEMIHOSTING.

 

FastBit Embedded Brain Academy Courses

https://fastbitlab.com/course1

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.