终有花开见月明 2022-11-17 10:35 采纳率: 75%
浏览 90

学习消息队列,调用freeRtos中断API函数时,出现了问题,困扰了许久。

问题遇到的现象和发生背景

学习freerots,在学习消息队列时,遇到了一个问题,在调用xQueueReceiveFromISR()时,串口打印一下错误:
Error:..\FreeRTOS\queue.c,1440
Error:..\FreeRTOS\portable\RVDS\ARM_CM3\port.c,696

我使用的是正点原子的例程,实验内容如下:
串口 1 接收中断:接收串口发送过来的数据,并将接收到的数据发送到队列 Message_Queue 中。
定时器 2 中断:定时周期设置为 500ms,在定时中断中读取队列 Message_Queue 中的消息,并将其显示在 LCD 上

main函数中:
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//中断分组为4
delay_init();
uart_init(115200);
LED_Init();
KEY_Init();
LCD_Init();
TIM3_Int_Init(5000,7200-1);
xTaskCreate(Start_task,"start",Start_task_Size,NULL,Start_task_Prio,&Start_Handle);
vTaskStartScheduler();
}

首先在Start_task任务中创建了一个消息队列:

Mes_queHandle = xQueueCreate(4,50);

串口相关的代码:
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7;//抢占优先级7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

接收中断发送消息队列:

USART_RX_STA|=0x8000; //接收完成了
xQueueSendFromISR(Mes_queHandle,USART_RX_BUF,&xHigherPriorityTaskWoken);//发送消息队列
if(xHigherPriorityTaskWoken == pdTRUE)//是否进行任务调度
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
memset(USART_RX_BUF,0,USART_REC_LEN); //USART_REC_LEN 为 50
USART_RX_STA = 0;

定时器相关代码:
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; //先占优先级8级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器

定时器接收消息对列:
extern QueueHandle_t Mes_queHandle;
u8 Rxbuf[50];
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
BaseType_t xHigherPriorityTaskWoken;
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
xQueueReceiveFromISR(Mes_queHandle,Rxbuf,&xHigherPriorityTaskWoken); //问题所在,程序卡死在这里
LCD_ShowString(30,90,16,Rxbuf,0);
memset(Rxbuf,0,50);
if(xHigherPriorityTaskWoken == pdTRUE)
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}

断言错误的地方:

queue.c第1440行:

img


翻译如下:
/*支持中断嵌套的RTOS端口具有最大系统调用(或最大API调用)中断优先级的概念。高于最大系统调用优先级的中断被永久启用,即使当RTOS内核处于临界区,但不能调用FreeRTOS API函数。如果在FreeRTosconfig.h中定义了configASSERT(),那么如果从一个被分配了高于配置的最大系统调用优先级的中断调用FreeRTOS API函数,则portASSERT_IF_INTERRUPT_PRIORITY_INVALID()将导致断言失败。只有以FromISR结尾的FreeRTOS函数才能从被分配的优先级等于或(逻辑上)低于最大系统调用中断优先级的中断调用。FreeRTOS维护一个独立的中断安全API,以确保中断入口尽可能快速和简单。下面提供了更多的信息(尽管是特定于皮质m的)freertos org/RTOS-cortex-M)

port.c 第696行:

img


翻译如下:
/*优先级分组:中断控制器(NVIC)允许定义每个中断优先级的位被划分为定义中断优先级的位和定义中断子优先级的位。为简单起见,必须将所有位定义为抢占优先位。如果不是这种情况(如果某些位代表子优先级),下面的断言将失败如果应用程序只使用CMSIS库进行中断配置,那么通过调用NVIC_SetPriorityGrouping(e)可以在所有的Cortex-M设备上实现正确的设置;在启动调度程序之前。但是请注意,一些特定于供应商的外围库假设优先级组设置为非零,在这种情况下,使用值为零将导致不可预测的行为。*

FreeRotsConfig.h中,我的中断配置:
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系统可管理的最高中断优先级

按理说Time中断的抢占优先级与串口中断都优先级都低于5,为什么还会出现这种错误呢?

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-11-17 12:07
    关注
    评论

报告相同问题?

问题事件

  • 创建了问题 11月17日

悬赏问题

  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,
  • ¥15 angular项目错误
  • ¥20 需要帮我远程操控一下,运行一下我的那个代码,我觉得我无能为力了
  • ¥20 有偿:在ubuntu上安装arduino以及其常用库文件。