搜索
bottom↓
回复: 7

谈谈嵌入式系统的可靠性(三)

[复制链接]

出0入0汤圆

发表于 2012-8-3 23:00:23 | 显示全部楼层 |阅读模式
本帖最后由 djyos 于 2012-8-4 17:07 编辑

3.        明确易用的中断编程,增加应用程序可靠性
本文不详细讲解djyos的中断系统实现原理,有兴趣的,可参考相关文档。
传统RTOS,中断处理在ISR中进行,有经验的程序员,只在ISR中处理少量必须立即完成的工作,然后,一般会通过信号量或者消息通知一个线程,由线程接着完成后续工作。但也有些初级程序员,在ISR中完成冗长的工作。传统RTOS,对ISR例程会有较大限制,许多操作系统服务是不允许在ISR中使用的,一不小心就会中招。文档完善的操作系统,会有一个长长的清单,说明哪些服务不允许在ISR中使用,哪些是允许的。文档不完善的呢?你只有自己看着办了。墨菲定律告诉我们,就算你文档很完善,只要存在ISR中误用系统服务的可能,就一定会有人这样做。
这样做的后果是什么呢?遗憾的是,没有人能准确描述,上帝也只能说“不可预知后果”;
这样的bug会在什么时候爆发呢?只有上帝知道;你不知道中断什么时候发生,只要不发生在“不该发生的时间”,系统就平安无事,天知道什么时候会中断会发生在“不该发生的时间”。
嵌入式产品中,什么问题是最可怕的呢?调试和测试不出来,会到达用户手上,且不可预知后果的问题,是最可怕的!那些运行数月,内存莫名其妙地被误改的问题,很可能跟它有关。
ISR中误用系统服务就属于这种“上帝才知道答案”的问题。
然而,墨菲先生对djyos却无可奈何,djyos把中断分为两类,一类叫异步信号,对应于并非紧急的中断,例如键盘,异步信号的响应函数中,允许调用全部系统服务;另一类叫实时中断,对应需要紧急处理的中断事件,在实时中断的处理函数中,则禁止使用所有的系统服务。看官,这里没有模棱两可的地方,要么就全部允许,要么就都不允许。
对于普通的中断(异步信号),是允许使用全部系统调用的,只要你养成良好编程习惯,检查系统调用的返回值,就不会出错。程序员根本没有机会犯在ISR中误用系统服务这种错误。
对于实时中断,则完全禁止使用系统服务,最明确的东西,也就是最不容易搞错的。不像传统操作系统,有些系统服务可用,有些不可用,很模糊,程序员很容易混淆。
3.1.        Djyos中断编程方法
3.1.1.        实时中断编程模型
1、        编写ISR服务程序,像普通C函数一样编写即可。
u32 __uart1_int(ufast_t uart_int_line)
{
}
2、        使用下列语句序列设置中断:
    int_isr_connect(cn_int_line_uart1,__uart1_int);
    int_setto_real(cn_int_line_uart1);
    int_echo_line(cn_int_line_uart1);
    int_restore_real_line(cn_int_line_uart1);
第一句,把ISR函数跟中断线联系起来。
第二句,把相应中断设置成实时中断。
第三句,假响应一下,以免硬件的初始化状态影响。
第四句,使能中断
上述初始化过程,来自一个实际应用,该应用的mcu使用lpc1225,主频40Mhz,flash速度20Mhz,实际运行速度在20Mhz~40Mhz之间。但要实现2.5Mbps baud的串口通信,如果不能再接收中断发生5uS内响应中断的话,必然丢数据。因此,该应用使用了djyos的实时中断机制,实测下来,中断响应时间小于1.5uS,效果很理想。
3.1.2.        异步信号的事件模式编程
这是djyos推荐的编程模型。
1、        编写事件处理函数。
void uart1_event(void)
{
                While(1)
                {
                        //do something
                        djy_wait_evtt_pop(djy_my_evtt_id(),1,cn_timeout_forever);
}
}
2、        登记事件类型,用于异步信号处理的事件,一般设为关联型事件。
uart1_evtt = djy_evtt_regist(enum_correlative,100,0,1, uart1_event,0x1000,NULL);
3、        按照下列指令序列初始化中断号:
    int_evtt_connect(cn_int_line_USART1,uart1_evtt);
    int_setto_asyn_signal(cn_int_line_USART1);
    int_echo_line(cn_int_line_USART1);
    int_restore_asyn_line(cn_int_line_USART1);
第一句,把事件类型与中断号联系起来。
第二句,把中断号设为异步信号。
第三句,假响应一下,以免硬件的初始化状态影响。
第四句,使能中断。
此后,只要发生uart中断,就会自动弹出uart1_evtt类型的事件。第一次弹出事件后,uart1_event将被执行,处理完相应的事务后,将会在djy_wait_evtt_pop( )函数处阻塞,直到下一次中断的到来。应用程序完全不需要写ISR程序,由于uart1_event是普通的事件处理函数,它跟普通事件处理函数一样,可以得到所有OS服务。
3.1.3.        异步信号的ISR模式编程
这种编程模型,与传统RTOS相似,不同的是,djyos的ISR可以调用全部系统服务,唯一的限制是,不能发生实际阻塞。比如,可以在ISR中调用malloc,但如果内存不足,在线程中调用的话,将会被阻塞,在ISR中调用的话,将返回NULL,不会被阻塞。只要养成良好的编程习惯,检查系统调用的返回值,就不会出错。

1、        编写ISR服务程序,像普通C函数一样编写即可。
u32 __uart1_int(ufast_t uart_int_line)
{
}
2、        使用下列语句序列设置中断:
    int_isr_connect(cn_int_line_uart1,__uart1_int);
    int_setto_asyn_signal(cn_int_line_uart1);
    int_echo_line(cn_int_line_uart1);
    int_restore_asyn_signal_line(cn_int_line_uart1);
第一句,把ISR函数跟中断线联系起来。
第二句,把相应中断设置成异步信号中断。
第三句,假响应一下,以免硬件的初始化状态影响。
第四句,使能中断
这个过程,跟实时中断非常相似,就是函数名不一样而已,但实现过程是有很大差别的。这种方式下,__uart1_int函数中是可以使用全部系统服务的。
3.1.4.        异步信号的ISR和事件混合模式编程
1、        编写事件处理函数。
void uart1_event(void)
{
                While(1)
                {
                        //do something
                        djy_wait_evtt_pop(djy_my_evtt_id(),1,cn_timeout_forever);
}
}
2、        登记事件类型,用于异步信号处理的事件,一般设为关联型事件。
uart1_evtt = djy_evtt_regist(enum_correlative,100,0,1, uart1_event,0x1000,NULL);
3、        编写ISR服务程序,像普通C函数一样编写即可。
u32 __uart1_int(ufast_t uart_int_line)
{
}
4、        按照下列指令序列初始化中断号:
    int_evtt_connect(cn_int_line_USART1,uart1_evtt);
    int_isr_connect(cn_int_line_uart1,__uart1_int);
    int_setto_asyn_signal(cn_int_line_USART1);
    int_echo_line(cn_int_line_USART1);
    int_restore_asyn_line(cn_int_line_USART1);
第一句,把事件类型与中断号联系起来。
第二句,把ISR函数与中断号联系起来。
第三句,把中断号设为异步信号。
第四句,假响应一下,以免硬件的初始化状态影响。
第五句,使能中断。
此后,只要发生uart中断,就会先调用__uart1_int函数,然后自动弹出uart1_evtt类型的事件。可以在__uart1_int( )函数中处理比较紧急的事务,比如copy硬件缓冲区,把其他事情留给uart1_event( )做。第一次弹出事件后,uart1_event将被执行,处理完相应的事务后,将会在djy_wait_evtt_pop( )函数处阻塞,直到下一次中断的到来。
这种玩法,功能有点类似于linux的中断上半部和下半部的功能,但比linux更简洁易用。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出100入0汤圆

发表于 2012-8-3 23:35:27 | 显示全部楼层
传说中的沙发?

出100入0汤圆

发表于 2012-8-3 23:35:43 | 显示全部楼层
板凳?

出100入0汤圆

发表于 2012-8-3 23:36:03 | 显示全部楼层
地板

出0入0汤圆

发表于 2012-8-4 00:38:34 | 显示全部楼层
仍然似懂非懂。

出0入0汤圆

发表于 2014-11-1 10:12:25 | 显示全部楼层
怎么感觉研究可靠性的不多呢

出0入0汤圆

发表于 2014-12-3 12:14:31 | 显示全部楼层
顶                    

出0入0汤圆

发表于 2015-1-24 11:43:12 | 显示全部楼层
为了通用吗? 用的GNU 编译器
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 22:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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