FreeRTOS使用中断相关的函数导致程序卡死解决办法

文章讨论了在FreeRTOS中,如何在串口中断服务函数中使用xTaskGenericNotifyFromISR发送任务通知时遇到的问题,问题在于中断优先级设置过低导致程序卡死。作者通过调整中断优先级至5-15级范围内解决了这个问题。
摘要由CSDN通过智能技术生成

1.现象

想在串口中断中实现任务通知的功能,所以在串口中断服务函数中使用了xTaskGenericNotifyFromISR()函数来发送通知,发现一进入中断服务函数,程序就卡死了。下边是串口初始化和中断服务函数:

void Usart_Init_U(uint32_t BaudRate)
{
	//配置时钟
	……
	//配置输出脚:USART0_Tx
	……
	//配置输入脚:USART0_Rx
	……
	
	usart_baudrate_set(USART_PORT, BaudRate);					//波特率
	usart_parity_config(USART_PORT, USART_PM_NONE);             //无校验
	usart_word_length_set(USART_PORT, USART_WL_8BIT);           //有效数据:8bit
	usart_stop_bit_set(USART_PORT, USART_STB_1BIT);             //停止位长度:1bit
	usart_transmit_config(USART_PORT, USART_TRANSMIT_ENABLE);   //使能发送
	usart_receive_config(USART_PORT, USART_RECEIVE_ENABLE);     //使能接收
	
	usart_enable(USART_PORT);                                   //使能串口
	
	nvic_irq_enable(USARTx_IRQn, 2, 0);							//启用NVIC请求:配置中断通道和优先级
	
	usart_interrupt_enable(USART_PORT,USARTx_IT);			//设置串口触发中断的标志
}
void USARTx_IRQHandler(void)
{
	BaseType_t flag = pdFALSE;
	uint32_t Num = 6;
	uint32_t Num1 = 0;
	if(usart_interrupt_flag_get(USART_PORT,USARTx_IT_FLAG) == SET)
	{
		
		Rx_Data = usart_data_receive(USART_PORT);
		usart_data_transmit(USART_PORT,Rx_Data);
//		Value = 1;
		
		flag = xTaskGenericNotifyFromISR(LED1Task_Handler,Num,eSetValueWithOverwrite,&Num1,&xHigherPriorityTaskWoken);
		if(flag == pdTRUE)
			printf("发送成功\r\n");
		
		 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
		
		
		usart_interrupt_flag_clear(USART_PORT,USARTx_IT_FLAG);
	}
}

由上边两段代码可以看到:

  1. 串口中断的优先级为2(4位抢占,0位响应)。
  2. 执行代码,程序就会卡在flag = xTaskGenericNotifyFromISR(LED1Task_Handler,Num,eSetValueWithOverwrite,&Num1,&xHigherPriorityTaskWoken);这一句,而不会去执行下一句代码,也不会出中断,完完全全卡死在这里。

2.解决办法

我先试了不用中断的任务通知(定义两个任务,用一个任务去通知另一个任务),发现完全没有问题。所以问题就出在中断上,而能出问题的地方就只能是中断的优先级。通过查找资料可知FreeRTOS操作系统内核使用最低优先级,操作系统所能调用管理的最高优先级为5~15级。所以在定义外设的中断优先级时,要想FreeRTOS能够正常运行,必须将优先级设置在5-15级之间。

void Usart_Init_U(uint32_t BaudRate)
{
	//配置时钟
	……
	//配置输出脚:USART0_Tx
	……
	//配置输入脚:USART0_Rx
	……
	
	usart_baudrate_set(USART_PORT, BaudRate);					//波特率
	usart_parity_config(USART_PORT, USART_PM_NONE);             //无校验
	usart_word_length_set(USART_PORT, USART_WL_8BIT);           //有效数据:8bit
	usart_stop_bit_set(USART_PORT, USART_STB_1BIT);             //停止位长度:1bit
	usart_transmit_config(USART_PORT, USART_TRANSMIT_ENABLE);   //使能发送
	usart_receive_config(USART_PORT, USART_RECEIVE_ENABLE);     //使能接收
	
	usart_enable(USART_PORT);                                   //使能串口
	
	nvic_irq_enable(USARTx_IRQn, 6, 0);							//启用NVIC请求:配置中断通道和优先级
	
	usart_interrupt_enable(USART_PORT,USARTx_IT);			//设置串口触发中断的标志
}

将优先级改为7,就能在中断服务函数中正常发送任务通知了。
在这里插入图片描述

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于 FreeRTOS 程序运行一段间后卡死的问题,可能有多种原因导致。以下是一些常见的排查步骤和解决方法: 1. 内存问题:检查程序是否有内存泄漏或堆栈溢出的情况,这可能导致系统崩溃。可以通过检查任务的堆栈大小是否合适以及使用 FreeRTOS 提供的内存管理功能来解决。 2. 任务优先级:确保任务的优先级设置正确。如果任务之间存在优先级反转,可能会导致系统死锁或卡死。可以通过调整任务的优先级来解决。 3. 资源竞争:检查任务之间是否存在对共享资源的竞争访问。如果多个任务同访问共享资源,可能会导致死锁或卡死。可以使用信号量、互斥锁等机制来保护共享资源的访问。 4. 中断处理:检查中断处理程序是否正确地释放资源并及完成。如果中断处理程序执行间过长,可能会导致系统卡死。可以优化中断处理程序的执行间,确保尽快完成并释放资源。 5. 调度器问题:检查调度器的配置和使用方式是否正确。如果调度器配置错误或使用不当,可能会导致系统异常或卡死。可以参考 FreeRTOS 的文档和示例代码来确认配置和使用方法。 6. 硬件问题:如果以上排查步骤都没有找到问题,可能是硬件相关的问题。可以检查硬件外设的驱动程序是否正确,以及硬件是否正常工作。 请根据具体情况逐步排查,并采取适当的解决方法。如果问题仍然存在,可以提供更多的细节和代码片段,以便更好地帮助您解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值