OpenEdv-开源电子网

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

OSIntEnter()和OSIntExit()什么时候可以不用?

[复制链接]

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
发表于 2015-7-8 10:04:29 | 显示全部楼层 |阅读模式
5金钱

我看周慈航老师的书上说:在使用操作系统时,中断处理函数中使用OSIntEnter()和OSIntExit()用来让系统掌握当前中断的嵌套深度,我看原子的例子中有一些ISR处理函数没加,那这个在用户编写的ISR函数中是必须的吗,或者什么条件下必须加,什么条件下可以不加?

是否只要ISR中没有调用事件(信号量、邮箱、消息队列等)就可以不加?

最佳答案

查看完整内容[请看2#楼]

只要使用UCOS,那么中断服务函数里面都得加这两个函数,有些例程是从裸机改的,中断服务函数中可能忘了加这两个。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-7-8 10:04:30 | 显示全部楼层
只要使用UCOS,那么中断服务函数里面都得加这两个函数,有些例程是从裸机改的,中断服务函数中可能忘了加这两个。
开往春天的手扶拖拉机
回复

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
 楼主| 发表于 2015-7-8 13:24:13 | 显示全部楼层
回复【2楼】zuozhongkai:
-------------------------------
我看周慈航书上说如果ISR中没有调用任何操作系统的服务函数(如发送信号量之类函数),在不需要操作系统干预的情况下,可以不加这两个,我不太确定。
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-7-8 14:52:18 | 显示全部楼层
回复【3楼】善良的二哥:
---------------------------------
最好都加上,
开往春天的手扶拖拉机
回复

使用道具 举报

2

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
214
金钱
214
注册时间
2014-12-29
在线时间
36 小时
发表于 2015-7-8 16:04:18 | 显示全部楼层
ucosIII的中断分两种;
1是直接提交给内核处理(直接发布)
2是发送一个消息给中断管理任务处理(延时发布)
延时调用的过程是系统响应MCU的硬件中断,发送一个消息给中断管理任务,退出中断状态,如果同时还有有其他中断再响应,再发送消息;完毕后进入中断处理任务,根据中断优先级调用用户编写的ISR函数处理具体的中断任务;
这样的好处是时减少关中断的时间,及时响应硬件中断,方便中断处理优先级的管理;不好的是由于增加的系统管理这一环节,具体的中断响应会稍有延时。

延时处理预定义开关在os_cfg.h中
#define OS_CFG_CALLED_FROM_ISR_CHK_EN   1u   //定义为非零值允许延时发布,定义为0值就是直接发布

若启用延时发布,你的中断服务函数不需要做任何处理,除函数名要按照启动文件的函数名称外,其他和普通函数的写法没有什么区别。
因为延时函数是通过这个函数调用的,他已经给你写好了
static  void  BSP_IntHandler (CPU_DATA  int_id)
{
    CPU_FNCT_VOID  isr;
    CPU_SR_ALLOC();
    CPU_CRITICAL_ENTER();                                  
    OSIntEnter();
    CPU_CRITICAL_EXIT();
    //延时发布的中断处理,这里调用你编写的ISR
    if (int_id < BSP_INT_SRC_NBR) {
        isr = BSP_IntVectTbl[int_id];
        if (isr != (CPU_FNCT_VOID)0) {
            isr();
        }
    }
    OSIntExit();               
}

推荐的方法是打开延时调用,将你认为需要及时处理的中断写成直接调用的型式;
直接调用需要修改的地方有两个
1,ISR中断处理函数的映射
以FPU为例
默认的延时发布至这样的
void  BSP_IntHandlerFPU(void)  { BSP_IntHandler(BSP_INT_ID_FPU);}
当中断来临,调用的是 BSP_IntHandler(BSP_INT_ID_FPU)这个函数,并输入BSP_INT_ID_FPU这个FPU中断号码作为参数;也就是使用的上面写的static  void  BSP_IntHandler (CPU_DATA  int_id)这个函数

所以呢,这里直接改成
void  BSP_IntHandlerFPU(void)
{
    CPU_SR_ALLOC();
    CPU_CRITICAL_ENTER();                                  
    OSIntEnter();
    CPU_CRITICAL_EXIT();
    
    /*你的中断处理*/
    
    OSIntExit(); 
}

也可以参开systick的处理,这个不管你有没有打开延时发布的开关都是直接发布处理的
void  OS_CPU_SysTickHandler (void)
{
    CPU_SR_ALLOC();
    CPU_CRITICAL_ENTER();
    OSIntNestingCtr++;     //在这个函数OSIntEnter()中有OSIntNestingCtr++,  在函数OSIntExit()中会有OSIntNestingCtr--,使用这个值判断是不是所有的中断都处理完了
    CPU_CRITICAL_EXIT();

    /*
     你的中断处理
    //OSTimeTick();
    */                                       

    OSIntExit();  
}
回复

使用道具 举报

4

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-1-25
在线时间
16 小时
发表于 2019-3-16 10:55:26 | 显示全部楼层
什么叫发布,发到哪里?发什么东西?不发又怎么样?
诚交各路大侠
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-24 04:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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