中断管理

其实,关于中断的概念和定义在之前已经反复学习和实践了,这节主要讲和FreeRTOS相关的中断知识。

中断优先级

任何中断的优先级都大于任务!

在我们的操作系统,中断同样是具有优先级的,并且我们也可以设置它的优先级,但是他的优先 级并不是从 0~15 ,默认情况下它是从 5~15 ,0~4 这 5 个中断优先级不是 FreeRTOS 控制的(5是取决于 configMAX_SYSCALL_INTERRUPT_PRIORITY)。

相关注意!!!

  • 在中断中必需使用中断相关的函数
  • 中断服务函数运行时间越短越好

实操演示

需求:创建一个队列及一个任务,按下按键 KEY1 触发中断,在中断服务函数里向队列里发送数据,任务则阻塞接收队列数据。

在 C:\mjm_CubeMX_proj 路径下,复制一份Cube的母版并重命名为 :mjm_freeRTOS_inter:

打开相应的Cube文件:

1. 将按钮配置为中断:

1.1 在左侧的NVIC中 打开并设置中断优先级:

中断管理_第1张图片

2. 找到左侧的Middleware --> FREERTOS,然后在下方找到"Task and Queues",创建一个队列:

中断管理_第2张图片

中断管理_第3张图片

3. 生成代码打开Keil:

 在stm32f1xx_it.c -> EXTI0_IRQHandler -> HAL_GPIO_EXTI_IRQHandler() -> HAL_GPIO_EXTI_Callback

HAL_GPIO_EXTI_Callback就是可以覆写的中断回调函数:

中断管理_第4张图片

3.1 在stm32f1xx_it.c中对Callback函数进行重写:

由于使用了其他freertos.c文件的句柄变量且涉及到了freeRTOS的函数,所以要申明extern变量添加"cmsis_os.h"库

#include "cmsis_os.h"

extern osMessageQId myQueueHandle;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	uint32_t snd = 1; //要向队列中发送的信息
	
	xQueueSendFromISR(myQueueHandle, &snd, NULL); //注意要用中断相关的队列发送函数
//第一个参数是句柄;第二个参数是要传输的值;第三个变量一般设置为NULL
}

3.2 在freertos.c中写任务的内容: 

#include "stdio.h"

void StartDefaultTask(void const * argument)
{
	uint32_t rev = 0;

  for(;;)
  {
		if (xQueueReceive(myQueueHandle, &rev, portMAX_DELAY) == pdTRUE){ //队列的接收不再中断中,不需要使用中断相关的函数
			printf("rev = %d\r\n", rev);
		}
    osDelay(1);
  }
}

实现效果

 打开串口助手并按下KEY1:

可见,成功触发了中断并在回调函数中向队列成功发送了信息被任务成功接收

你可能感兴趣的:(单片机,linux,stm32,c语言,FreeRTOS)