RTOS中断管理的简单应用

我们在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

RTOS中断管理的简单应用_第1张图片

GPIO

PA0设置为GPIO_EXTI0

NVIC

RTOS中断管理的简单应用_第2张图片

RTOS

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

RTOS中断管理的简单应用_第3张图片

三、代码部分

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触发中断,向队列发送一,同时队列接收并通过串口打印出来。

RTOS中断管理的简单应用_第4张图片

你可能感兴趣的:(RTOS,stm32cube,中断)