RTOS中断管理的简单应用

2023-12-21 08:45:47

我们在stm32f103c8t6单片机上验证RTOS中断管理,利用stm32cube进行RTOS的配置。裸机的时钟源默认是 SysTick,但是开启 FreeRTOS 后,FreeRTOS会占用 SysTick (用来生成1ms 定时,用于任务调度),所以我们开启TIM2当做裸机的时钟源,为其他总线提供另外的时钟源。

验证的功能比较简单,选择V1 版本的内核完全够用。

一、验证的思路以及需要使用的函数及简单介绍

1.验证思路

创建 1 个任务:Task。

任务要求如下:

按下KEY1,在中断里调用xQueueSendFromISR()函数,向队列的尾部写入消息;在入口函数StartTask中接收接受消息并显示。

其实很简单,就是相当于在我们在51和32单片机那里一样,特定的条件下触发中断,并在中断里执行一些操作。但是在RTOS里很有意思的是,明明都是向队列发送消息,却还要进行区分,如下表格

xQueueSend()

往队列的尾部写入消息

xQueueSendFromISR()

在中断中往队列的尾部写入消息

如果你在中断中执行操作,就要要执行与中断相关的API函数。

2.需要用到的函数

xQueueSendFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken)

该队列写入函数有三个参数

xQueue:队列的句柄

pvItemToQueue:写入数据(如果你在该参数下按F12进去,该参数实际是个指针类型的)

pxHigherPriorityTaskWoken:这里我们设置为NULL

BaseType_t xQueueReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait )

该读出队列有3个参数:

xQueue:待读取的队列句柄

pvItemToQueue:数据读取缓冲区

xTicksToWait:阻塞超时时间

返回值: 成功返回 pdTRUE,否则返回 pdFALSE。

二、stm32cube的配置

SYS

RCC

GPIO

PA0设置为GPIO_EXTI0

NVIC

RTOS

创建任务和队列,所有的参数配置默认即可

三、代码部分

usart.c

#include "stdio.h"

int fputc(int ch, FILE *f)

{?????

?????? unsigned char temp[1]={ch};

?????? HAL_UART_Transmit(&huart1,temp,1,0xffff);?

?????? return ch;

}

stm32f1xx_it.c

中断回调函数里向队列发送数据

extern osMessageQId myQueueHandle;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

?????? uint32_t send=1;

?????? xQueueSendFromISR(myQueueHandle,&send,NULL);

}

freertos.c

在StartTask函数里接收数据,并通过串口显示出来

#include "FreeRTOS.h"

#include "task.h"

#include "main.h"

#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include "stdio.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN Variables */

/* USER CODE END Variables */

osThreadId TaskHandle;

osMessageQId myQueueHandle;

/* Private function prototypes -----------------------------------------------*/

/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartTask(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */

static StaticTask_t xIdleTaskTCBBuffer;

static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )

{

? *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;

? *ppxIdleTaskStackBuffer = &xIdleStack[0];

? *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;

? /* place for user code */

}

/* USER CODE END GET_IDLE_TASK_MEMORY */

/**

? * @brief? FreeRTOS initialization

? * @param? None

? * @retval None

? */

void MX_FREERTOS_Init(void) {

? /* USER CODE BEGIN Init */

? /* USER CODE END Init */

? /* USER CODE BEGIN RTOS_MUTEX */

? /* add mutexes, ... */

? /* USER CODE END RTOS_MUTEX */

? /* USER CODE BEGIN RTOS_SEMAPHORES */

? /* add semaphores, ... */

? /* USER CODE END RTOS_SEMAPHORES */

? /* USER CODE BEGIN RTOS_TIMERS */

? /* start timers, add new ones, ... */

? /* USER CODE END RTOS_TIMERS */

? /* Create the queue(s) */

? /* definition and creation of myQueue */

? osMessageQDef(myQueue, 16, uint16_t);

? myQueueHandle = osMessageCreate(osMessageQ(myQueue), NULL);

? /* USER CODE BEGIN RTOS_QUEUES */

? /* add queues, ... */

? /* USER CODE END RTOS_QUEUES */

? /* Create the thread(s) */

? /* definition and creation of Task */

? osThreadDef(Task, StartTask, osPriorityNormal, 0, 128);

? TaskHandle = osThreadCreate(osThread(Task), NULL);

? /* USER CODE BEGIN RTOS_THREADS */

? /* add threads, ... */

? /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_StartTask */

/**

? * @brief? Function implementing the Task thread.

? * @param? argument: Not used

? * @retval None

? */

/* USER CODE END Header_StartTask */

void StartTask(void const * argument)

{

? /* USER CODE BEGIN StartTask */

? uint32_t rev = 0;

/* Infinite loop */

for(;;)

{

if (xQueueReceive(myQueueHandle, &rev, portMAX_DELAY) == pdTRUE)

printf("rev = %d\r\n", rev);

osDelay(1);

? /* USER CODE END StartTask */

}

}

结果如下图所示,按下KEY1触发中断,向队列发送一,同时队列接收并通过串口打印出来。

文章来源:https://blog.csdn.net/weixin_51374594/article/details/135050010
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。