【嵌入式FreeRTOS#7】中断管理实验
接下来给大家一个中断管理的代码框架,以供学习。
代码示例
(1)config文件
/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY (15<<4)
//设置FreeRTOS的中断优先级,一般拉到最低
#注意:此时pendSV和主时钟会被强制拉到最低,即使你Cube里提前设置过了
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (5<<4)
//设置中断辖区,超过阈值的在辖区内/* equivalent to 0xb0, or priority 11. */
(2)main.c
/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim1);HAL_TIM_Base_Start_IT(&htim2);#记得提前使能定时器中断freertos_start();#进入freertos系统
//HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,1);/* USER CODE END 2 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* USER CODE BEGIN Callback 0 */if (htim==&htim1){printf("TIM1 is running\r\n");#中断1正在执行的提醒}if (htim==&htim2){printf("TIM2 is running\r\n");#中断2正在执行的提醒}/* USER CODE END Callback 0 */if (htim->Instance == TIM7) {HAL_IncTick();}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}
(3)freertos文件
#include "freertos_demo.h"
/*necc header files*/
#include "FreeRTOS.h"
#include "task.h"
#include "gpio.h"/*start tack config*/
#define START_TASK_STACK 128
#define STACK_TASK_PRIORITY 1
void start_task(void * pvParameters);
TaskHandle_t start_task_handle;/* task1 config*/
#define START_TASK1_STACK 128
#define STACK_TASK1_PRIORITY 2
void task1(void * pvParameters);
TaskHandle_t start_task1_handle;/*State Mech*/
uint8_t status_key1;
uint8_t status_key0;
char pcBuffer[500];/*start task*/
void freertos_start(void){/* 1.creat the start files*///进入入口函数创建启动任务xTaskCreate((TaskFunction_t) start_task,(char*) "start_task",(configSTACK_DEPTH_TYPE) START_TASK_STACK,(void*) NULL,(UBaseType_t) STACK_TASK_PRIORITY,(TaskHandle_t *) &start_task_handle); /* 2.run the switcher*/vTaskStartScheduler();
}void start_task(void * pvParameters){//创建task1时尽量不要被其他中断打扰,所以建立隔离区taskENTER_CRITICAL();printf("FreeRTOS Task Started \r\n");xTaskCreate((TaskFunction_t) task1,(char*) "task1",(configSTACK_DEPTH_TYPE) START_TASK1_STACK,(void*) NULL,(UBaseType_t) STACK_TASK1_PRIORITY,(TaskHandle_t *) &start_task1_handle);taskEXIT_CRITICAL();vTaskDelete(NULL);
}void task1(void * pvParameters){while(1){#此时不能进入隔离区,因为会屏蔽掉haldelay,而我们需要用hal库的delay做延迟if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0){HAL_Delay(40);if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0){portENABLE_INTERRUPTS();}}else if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0){HAL_Delay(40);if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0){portDISABLE_INTERRUPTS();}}HAL_Delay(500);#这里必须用HAL库的delay做延迟,如果用FreeRTOS时钟延迟的话又会强制打开中断}
}
注意事项
(1)确保SYSTICK在FreeRTOS辖区之外,而两个TIM中断在辖区内
(2)PendSV和主时钟(会转化为软件时钟)中断优先级最低
(3)当中断被屏蔽后,避免有FreeRTOS时钟操作,否则会重开中断。建议使用systick的HAL库中断进行延迟。