OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6002|回复: 5

FreeRTOS中CAN中断重复进入导致其他任务无法运行

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2018-11-30
在线时间
0 小时
发表于 2018-11-30 13:02:21 | 显示全部楼层 |阅读模式
1金钱
用freeRTOS时,只打开了CAN1的FIFO0消息挂号中断(CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);),用于接收电机的转速反馈。电机反馈频率为每秒4000次,波特率是1M。后来将电机反馈频率降到每秒1000次还是会出现CAN中断不断进入导致其他任务卡死的情况,有点蒙...

FreeRTOS中断分组用的是4,CAN中断优先级是13,也符合FreeRTOS的优先级配置。在中断中没有进行消息处理,代码比较精简,只有设置事件标志组的操作。
void CAN1_RX0_IRQHandler(void)
{
        BaseType_t pxHigherPriorityTaskWoken,xResult;
       
        pxHigherPriorityTaskWoken = pdFALSE;
       
        xResult=event_CanRxOK(&pxHigherPriorityTaskWoken);        //标志can接收到消息了
       
        if( xResult != pdFAIL )
        {
               portYIELD_FROM_ISR( pxHigherPriorityTaskWoken );
        }
       
        CAN_ClearITPendingBit(CAN1 , CAN_IT_FMP0);
}


为诡异的一点是,CAN一旦接收到一次消息后,我将电机断电,此时CAN线上已经没有消息了,但是CAN接收中断还是不断进入!讲真不知道为什么此时的中断是由什么引起的...


附CAN配置:
void Can_Init_Base(u16 IDHigh16,u16 IDLow16,u16 MaskHigh16,u16 MaskLow16)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        CAN_InitTypeDef   CAN_InitStructure;
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;
        NVIC_InitTypeDef  NVIC_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟       
       
  //初始化GPIO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
       
        //引脚复用映射配置
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
       
        //CAN单元设置
  CAN_InitStructure.CAN_TTCM=DISABLE;        //非时间触发通信模式   
  CAN_InitStructure.CAN_ABOM=DISABLE;        //软件自动离线管理          
  CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  CAN_InitStructure.CAN_NART=ENABLE;        //禁止报文自动传送
  CAN_InitStructure.CAN_RFLM=DISABLE;        //报文不锁定,新的覆盖旧的  
  CAN_InitStructure.CAN_TXFP=DISABLE;        //优先级由报文标识符决定
  CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;         //模式设置        
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;        //重新同步跳跃宽度(Tsjw),对波特率误差的容忍
  CAN_InitStructure.CAN_BS1=CAN_BS1_9tq; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;//Tbs2范围CAN_BS2_1tq ~        CAN_BS2_8tq
  CAN_InitStructure.CAN_Prescaler=3;  //(Prescaler+1)/时钟频率等于一个tq的时间
  CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1
        //可得出通讯波特率为1M
       
        //配置过滤器
  CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//ID列表模式
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
  CAN_FilterInitStructure.CAN_FilterIdHigh=IDHigh16;////32位ID
  CAN_FilterInitStructure.CAN_FilterIdLow=IDLow16;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=MaskHigh16;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=MaskLow16;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
  CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
       
  CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    

  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13;     // 主优先级为1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2018-11-30
在线时间
0 小时
 楼主| 发表于 2018-11-30 13:06:44 | 显示全部楼层
额,中断优先级那里的注释打错了...主优先级不是1,是13
回复

使用道具 举报

26

主题

1533

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6369
金钱
6369
注册时间
2015-8-25
在线时间
1004 小时
发表于 2018-11-30 13:19:44 | 显示全部楼层
1s1000次CAN中断?厉害了,你的系统定时器及保证任务切换的中断才1000Hz即1ms中断一次,而且系统定时器的中断优先级最低,那你不是每次都是CAN中断进入抢占系统定时器中断,你的任务绝对跑不起来的
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2018-11-30
在线时间
0 小时
 楼主| 发表于 2018-11-30 13:32:26 | 显示全部楼层
szczyb1314 发表于 2018-11-30 13:19
1s1000次CAN中断?厉害了,你的系统定时器及保证任务切换的中断才1000Hz即1ms中断一次,而且系统定时器的中 ...

嗯嗯,我已开始也是以为CAN中断太频繁了导致程序跑不起来,但是有一个关键的问题是我把电机都关了CAN中断还是不断地进入,这时候的中断是咋来的我很郁闷..
回复

使用道具 举报

26

主题

1533

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6369
金钱
6369
注册时间
2015-8-25
在线时间
1004 小时
发表于 2018-11-30 14:29:27 | 显示全部楼层
坡子埃纽拉 发表于 2018-11-30 13:32
嗯嗯,我已开始也是以为CAN中断太频繁了导致程序跑不起来,但是有一个关键的问题是我把电机都关了CAN中断 ...

CAN_ClearITPendingBit(CAN1 , CAN_IT_FMP0);里面的参数CAN_IT_FMP0用错了,这个函数里的参数断言里没有申明这个CAN_IT_FMP0参数,看原子的例程是用CAN_Receive接收并清除标志位的


CAN1->RF0R |= CAN_RF0R_RFOM0; //用这个试试吧
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-11-30 17:28:39 | 显示全部楼层
我认为并不是中断过于频繁的原因,FreeRTOS做任务堆栈检测的时候需要开一个50us中断一次的定时器,运作起来也毫无压力。建议在你的CAN中断里最好做个临界保护再试试!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 23:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表