Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission

1. Development Software: CubeIDE.2. Hardware Involved: STM32F103C8T6 minimum system board, ST-LINK v2 (STM8 & STM32), USB TO TTL (CH340). As shown below (for reference only):Connection Circuit Diagram:(1) STM32F103C8T6 <—> ST-LINK v2SWCLK <—> SWCLK; SWD <—> SWDIO ;3V3 <—> 3.3V ; GND <—> GND.(2)STM32F103C8T6 <—> USB TO TTLA10 <—> TXD ; A9 <—> RXD;3V3 <—> 3V3 ; GND <—> GND.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission3. The practical steps are as follows:1.Basic Settings. For FreeRTOS settings, refer to the previous article on the steps to port FreeRTOS to STM32F103C8T6. This article focuses on creating tasks, semaphores, and setting up the serial port (USART1) interrupt.2.Serial Port Parameter Configuration. As shown in the figure, set Mode to “Asynchronous”, and the Parameter Setting to default, i.e., baud rate: 115200, 8N1, data length 8 bits, no parity, 1 stop bit. Data direction: both transmit and receive.Using Semaphores in FreeRTOS for STM32F103 Serial Data TransmissionAlso enable the serial port interrupt, check “NVIC Setting”, as shown in the figure.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission3.Modify Interrupt Priority. In the “System Core” under “NVIC”, set the priority of the serial port “USART1 global Interrupt” to a Preemption Priority of 5 or higher (this must be set).Using Semaphores in FreeRTOS for STM32F103 Serial Data TransmissionThis is because FreeRTOS requires that the priority for calling its API from an interrupt be at least 5, and the value of “LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY” is set to 5, which can be modified. See the figure below.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission4.Create Task. Modify the default task as shown in the figure, setting the “Task Name”, “Priority”, “Stack Size”, and “Entry Function”, then click “OK” to create a task with a stack size of 512*4 bytes, with medium priority, for receiving data sent from the serial port.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission5.Create Binary Semaphore. In “Timers and Semaphores”, select “Binary Semaphores” and click “Add”. In the pop-up, modify the “Semaphore Name” for the serial port, as shown in the figure, and set the initial state to valid.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission6.Generate Code. Modify the HAL library base time as in step 1, and click Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission to generate the code.7.Add Header Files. In the “freertos.c” file, add the header files, as shown in the code and figure below.

#include "semphr.h"
#include "usart.h"
#include "string.h"

Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission8.Define Serial Port Data Reception Array (Buffer).In the “freertos.c” file, add the code.

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define MAX_USART_RECV_LEN 16
/* USER CODE END PD */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
uint8_t RECV_Data[MAX_USART_RECV_LEN] = {0};
/* USER CODE END Variables */

9.Serial Port Interrupt Service Function and Data Reception Task Function (Semaphore Driven).In the “freertos.c” file, add the code, find the “Func_Usart_Recv_Task” function and add the following code between “/* USER CODE BEGIN Application */” and “/* USER CODE END Application */” for the interrupt service function. The screenshot is as follows.

/* USER CODE BEGIN Header_Func_Usart_Recv_Task *//** * @brief  Function implementing the Usart_Recv_Task thread. * @param  argument: Not used * @retval None *//* USER CODE END Header_Func_Usart_Recv_Task */
void Func_Usart_Recv_Task(void *argument) {
/* USER CODE BEGIN Func_Usart_Recv_Task */
	HAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, RECV_Data, MAX_USART_RECV_LEN); // Start receiving data (variable length) idle interrupt
	/* Infinite loop */
	for (;;) {
		BaseType_t xSem = xSemaphoreTake( Usart_Recv_BinarySemHandle,portMAX_DELAY ); // Get semaphore
		if(xSem == pdTRUE) {
			HAL_UART_Transmit(&amp;huart1, RECV_Data, MAX_USART_RECV_LEN,100);// Block send
			memset(RECV_Data,0,MAX_USART_RECV_LEN); // Clear reception data buffer
			HAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, RECV_Data, MAX_USART_RECV_LEN);// Restart receiving data interrupt
		}
	}
/* USER CODE END Func_Usart_Recv_Task */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
	if (huart-&gt;Instance == USART1) {
		if(Size&gt;0) {
			BaseType_t xHigherPriorityTaskWoken = pdFALSE;
			xSemaphoreGiveFromISR( Usart_Recv_BinarySemHandle, &amp;xHigherPriorityTaskWoken );// Release semaphore
			portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); // Automatically request context switch based on priority
		}
	}
}
/* USER CODE END Application */

Using Semaphores in FreeRTOS for STM32F103 Serial Data TransmissionNote: The logic for using binary semaphores is that this article uses serial port interrupts, hence the Give function calls the interrupt API.Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission10.Debugging Test Function. Click compile Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission. After no errors, click Using Semaphores in FreeRTOS for STM32F103 Serial Data Transmission to download to the STM32F103C8T6 microcontroller (ST-LINKv2 debugging), using a serial debugging assistant for testing data transmission, as shown in the figure.Using Semaphores in FreeRTOS for STM32F103 Serial Data TransmissionThus, the task is complete./*————————-The followingis an advertisement——————————-*/

Please open in the WeChat client

Leave a Comment