目录
一、中断定义
中断是指在程序执行的过程中,突然发生了某种事件,需要立即停止当前正在执行的程序,并转而处理这个事件,处理完后再回到原来的程序执行点继续执行的过程。
中断可以是硬件中断(由硬件设备触发)或软件中断(由程序执行中断指令触发)。
中断可以提高计算机的响应速度和效率,使得计算机可以同时处理多个任务。
二、中断优先级
任何中断的优先级都大于任务!
在我们的操作系统,中断同样是具有优先级的,并且我们也可以设置它的优先级,但是他的优先 级并不是从 0~15 ,默认情况下它是从 5~15 ,0~4 这 5 个中断优先级不是 FreeRTOS 控制的(5是 取决于 configMAX_SYSCALL_INTERRUPT_PRIORITY,一般默认为5)。
三、中断相关函数
注意:
1. 在中断中必需使用中断相关的函数;
2. 中断服务函数运行时间越短越好。
1.队列
xQueueReceiveFromISR()
- 在中断中从队列头部读取消息,并删除消息
xQueuePeekFromISR()
- 在中断中从队列头部读取消息
2.信号量
xSemaphoreGiveFromISR()
- 在中断中释放信号量
xSemaphoreTakeFromISR()
- 在中断中获取信号量
3.事件标志组
xEventGroupClearBitsFromISR()
- 在中断中清零事件标志位
xEventGroupSetBitsFromISR()
- 在中断中设置事件标志位
4.任务通知
xTaskNotifyFromISR()
- 在中断中发送任务通知
xTaskNotifyAndQueryFromISR()
- 在中断中发送任务通知
vTaskNotifyGiveFromISR()
- 在中断中发送任务通知
5、软件定时器
xTimerStartFromISR()
- 在中断中开启软件定时器定时
xTimerStopFromISR()
- 在中断中停止软件定时器定时
xTimerResetFromISR()
- 在中断中复位软件定时器定时
xTimerChangePeriodFromISR()
- 在中断中更改定时超时时间
四、中断管理实操
1、实验需求
创建一个队列及一个任务,按下按键 KEY1 触发中断,在中断服务函数里向队列里发送数据,任务则阻塞接收队列数据。
2、CubeMX配置
这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。
查看原理图配置按键引脚
由于是按键1按下触发中断,所以应配置成GPIO_EXTI。
在NVIC使能中断
创建任务和队列
3、代码实现
uart.c 重定向printf
#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并修改代码
用到的中断函数
- xQueueSendFromISR()
#include "cmsis_os.h" // 增加CubeMX封装好的头文件
extern osMessageQId myQueue01Handle;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
uint32_t send = 1;
xQueueSendFromISR(myQueue01Handle, &send, NULL);//最后一个参数通常为NULL
}
打开freertos.c并修改代码
void StartDefaultTask(void const * argument)
{
uint32_t receive = 0;
for(;;)
{
if (xQueueReceive(myQueue01Handle, &receive, portMAX_DELAY) == pdTRUE)//阻塞等待队列发送数据
printf("receive = %d\r\n", receive);
osDelay(1);
}
}
任务里调用读队列函数卡死等待队列发送数据,按键1按下就会读取成功。