ADC_DMA程序移植FreeRTOS出现在configASSERT行卡死的情况

问题1:利用现有的HC32F448的例程ADC_DMA,按照FreeRTOS的步骤增加于现有程序,但是一运行程序就跑飞了,调试栏中点击暂停会发现程序卡在configASSERT(pxQueue)【来自于文件queue.c的函数xQueueSendFromISR的第一行】。

void DMA_IRQ_HANDLER(void)
{BaseType_t pxHigherPriorityTaskWoken;
  uint32_t ulReturn;
  /* 进入临界段,临界段可以嵌套 */
  ulReturn = taskENTER_CRITICAL_FROM_ISR();
  if (DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG) == SET)
   {
        DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
        m_u8AdcValUpdated = 1U;
        xQueueSendFromISR(Test_Queue, /* 消息队列的句柄 */
			(void *)&m_u8AdcValUpdated,/* 发送的消息内容 */
			&pxHigherPriorityTaskWoken);
         portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
    }
   taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}
static void AppTaskCreate(void)
{	
  BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
  taskENTER_CRITICAL();           //进入临界区
  Test_Queue=xQueueCreate(1,sizeof(uint32_t));
  if(NULL != Test_Queue)
    printf("创建Test_Queue消息队列成功!\r\n");
  xReturn = xTaskCreate((TaskFunction_t )ADC_Task, /* 任务入口函数 */
                        (const char*    )"ADC_Task",/* 任务名字 */
                        (uint16_t       )100,   /* 任务栈大小 */
                        (void*          )NULL,	/* 任务入口函数参数 */
                        (UBaseType_t    )3,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&ADC_Task_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
  vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
  taskEXIT_CRITICAL();            //退出临界区 
}

分析:pxQueue即消息队列没有创建成功,但是任务内的确使用了函数xQueueCreate(),两者矛盾。可能的原因是DMA中断服务函数早于消息队列的创建

解决方法:函数void DMA_IRQ_HANDLER(void)在发送消息时先判断是否存在消息队列。

if(Test_Queue!=NULL)
        { xQueueSendFromISR(Test_Queue, /* 消息队列的句柄 */
            (void *)&m_u8AdcValUpdated,/* 发送的消息内容 */
            &pxHigherPriorityTaskWoken);
        }

问题2:解决问题1后,再次运行程序,结果程序再次卡死于configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );【来自于文件port.c的函数void vPortValidateInterruptPriority(void)】

分析:下面的文章表述很清楚,DMA中断的优先级和FreeRTOS管理中断的矛盾。

嵌入式FreeRTOS操作系统中断优先级配置(重要)_freertos nvic_irqchannelsubpriority-CSDN博客

解决方法:FreeRTOSConfig.h文件的configMAX_SYSCALL_INTERRUPT_PRIORITY数值为0x50左移动4位后仍然为5.DMA的中断优先级数值为3(低于5),导致它不受FreeRTOS管理。

#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

直接将 configMAX_SYSCALL_INTERRUPT_PRIORITY改为2(或者1)。再次运行结果正常。

#define configMAX_SYSCALL_INTERRUPT_PRIORITY     2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值