搜索
bottom↓
回复: 0

高效实时操作系统原理以及实践-中断下半部

[复制链接]

出0入0汤圆

发表于 2013-11-16 18:58:07 | 显示全部楼层 |阅读模式
本帖最后由 lulu爱 于 2013-11-17 11:19 编辑

中断上下半部原理以及实践

中断一般可以分成上半部以及下半部,所谓中断上半部cpu通常是关中断的,这个时候主要是从硬件那里接收一些数据,然后触发中断下半部。一出中断后,根据相应的中断下半部的优先级去执行相应的中断下半部。中断下半部主要用于数据的处理,数据的处理过程一般比较缓慢,所以这个时候中断往往是打开的。为什么要有中断上下半部的原因主要有如下:

如果中断函数内处理的事情非常多的话,意味着中断运行时间过长。这个时候cpu 通常是关中断的,这样会无法及时相应其它的中断,造成其他中断数据丢失。对于cortex-m系列的cpu进入中断后是开着中断的,但是中断运行时间太长的话,其它低优先级的中断也得不到运行,因为被高优先级的任务占着中断不放,通常也会引发低优先级中断的数据丢失。所以尽量,尽可能减低中断内处理的时间,是刻不容缓,非常重要的事情,直接决定了整个系统的实时性。

中断下半部是人为的划分,这个时候是处于任务环境下,所以可以响应中断。中断下半部的划分主要是首先判断某具体中断内的执行时间,如果时间很长的话,就需要把数据以及数据处理部分人为的划分开来,接收数据部分往往叫中断上半部,处理数据部分往往叫中断下半部。

中断的下半部处理是可以是有优先级的,有的硬件设备的中断数据处理可以延迟处理,但是有的必须马上要处理,事情处理有轻重缓急之分,这也是为什么中断下半部有task 0 和workqueue, idle event的原因。

下图是raw os中可能使用到的中断流程:


raw os支持的中断下半部方法有task 0 以及work queue, task 0 的优先级要高于work queue。work queue的优先级是高于idle event 的。task 0 和work queue的区别是task 0 运行的时候不能调用能引起睡眠的函数,但是work queue是能调用引起睡眠的函数的, idle event是基于事件驱动的,优先级是最低的,也可以做为中断下半部去使用,如果这个中断的处理优先级是很低的话, idle event也是不能允许睡眠的。

raw os的中断下半部最具特色的是支持上半部向下半部传递数据,这一点非常重要,把数据接收和数据处理彻底的分割开来。有些系统比如linux,上半部是无法向下半部传递数据的,因为内核的api不支持这个特性。

综上所述,raw os为软件化的区分中断优先级提供了有效地手段,即task 0,workqueue以及idle event。对于系统的快速中断响应有了根本的保障。

task 0 api 使用

1 RAW_U16 raw_task_0_post(EVENT_HANLDER *p, TASK_0_EVENT_TYPE ev, void *event_data)

函数功能:
往任务0发出一个事件消息,此函数必须在中断里使用,用来触发中断下半部task 0。使用此函数必须注意任务事件信息被耗尽的情况,一旦发生被耗尽的情况,函数会返回RAW_TASK_0_EVENT_EXHAUSTED,交给用户去处理。一般情况下,可以开大MAX_TASK_EVENT 的定义,如果还是不行的话,说明系统中断太快,task 0任务处理不了,只能丢弃信息。需要注意的是,此函数会发往task 0 事件队列的尾部。

此函数的参数有3个,分别含义如下:

p:为事件触发函数
ev:为事件触发类型
event_data:为事件的私有数据

函数的返回值:
RAW_NOT_CALLED_BY_TASK:此函数应该使用在中断里面。
RAW_TASK_0_EVENT_EXHAUSTED:task 0 任务的事件信息被耗尽。
RAW_SUCCESS:函数调用成功。

2 RAW_U16 raw_task_0_front_post(EVENT_HANLDER *p, TASK_0_EVENT_TYPE ev, void *event_data)

函数功能:
往任务0 发出一个事件消息,此函数必须在中断里使用,用来触发中断下半部task 0。使用此函数必须注意任务事件信息被耗尽的情况,一旦发生被耗尽的情况,函数会返回RAW_TASK_0_EVENT_EXHAUSTED,交给用户去处理。一般情况下,可以开大MAX_TASK_EVENT 的定义,如果还是不行的话,说明系统中断太快,task 0任务处理不了,只能丢弃信息。需要注意的是,此函数会发往task 0 事件队列的头部,做为紧急事件去处理。

此函数的参数有3个,分别含义如下:

p:为事件触发函数
ev:为事件触发类型
event_data:为事件的私有数据

函数的返回值:
RAW_NOT_CALLED_BY_TASK:此函数应该使用在中断里面。
RAW_TASK_0_EVENT_EXHAUSTED:task 0 任务的事件信息被耗尽。
RAW_SUCCESS:函数调用成功。


3 void task_0_tick_post()

函数功能:
此函数在系统定时器中使用.如果CONFIG_RAW_TASK_0 使能打开,系统时钟函数必须使用task_0_tick_post, 反之使用raw_time_tick。

函数的返回值:
RAW_NOT_CALLED_BY_TASK:此函数应该使用在中断里面。


task 0 系统内部api

1 void task_0_tick_handler(RAW_U8 ev, RAW_VOID  *event_data)

函数功能:
task 0 内部的系统时钟函数。

此函数的参数有2个,分别含义如下:

ev:为事件触发类型
event_data:为事件的私有数据
函数的返回值:



2 static void task_0_switch()

函数功能:
task 0 内部调度切换

函数的返回值:



3 static void task_0_process(void *pa)

函数功能:
task 0 任务主体,主要来处理中断那里来的事件,没有事件处理的时候,就切换给其他任务继续运行。

此函数的参数有1个,含义如下:

pa:无效参数

函数的返回值:



4 void int_msg_handler(RAW_U8 ev, RAW_U8 *msg_data)

函数功能:
task 0 任务中处理中断发过来的事件,这些事件都是中断内部使用到的raw os api.

此函数的参数有2个,分别含义如下:

ev:为事件触发类型
msg_data:为事件的私有数据

函数的返回值:


5 void int_msg_init()

函数功能:
task 0 内部消息初始化。

函数的返回值:



6 RAW_U16 int_msg_post(RAW_U8 type, void *p_obj, void *p_void, RAW_U32 msg_size, RAW_U32 flags, RAW_U8 opt)

函数功能:
raw os 内部api 在中断里面的消息发送,消息发送给task 0, 出中断后系统如果没有关抢占的话,task 0 会去处理消息。

函数的返回值:



7 void raw_task_0_init()

函数功能:

task 0 使用前必须的初始化,有CONFIG_RAW_TASK_0 使能。

函数的返回值:




task 0 使用总结

raw os 中的task 0 相当于linux 中的software irq 和tasklet,属于高优先级的中断下半部,需要注意的是task 0 内部的事件处理函数是不能睡眠的,这一点和linux中的software irq 和tasklet是完全一致的。


以上代码在中断中触发一个work queue的下半部,出了中断后将会在未来一定时间运行此work queue的注册函数。


work queue 原理以及实践

task 0 是中端下半部中优先级最高的,而且有不能睡眠的特点。有的时候往往中断下半部的处理不需要很急,如果都往task 0 内部去做的话,会很大的增加系统任务最大延迟时间,对实时性损害很大。这个时候workqueue是最好的选择,可以创建一到几个系统的work queue, 专门用来处理系统中的下半部。由于work queue可以指定优先级,比task 0 要灵活的多, 更重要的是work queue内部允许睡眠。

以下是演示work queue代码使用:

以下代码初始化了整个work queue系统。

void task1(void * arg)
{
  global_work_queue_init();                         (1)
  work_queue_create();                              (2)

}

以下代码注册了用户的work queue回调函数,当这个回调函数执行时会动态传入两个参数一个指针以及一个RAW_U32 的数据。

static void user_handler(RAW_U32 arg, void *msg)   
{

        /*doing something*/                             (3)

}       

以下代码在中断中触发了事先注册的work queue。
isr()
{
  sche_work_queue(arg1,arg2,arg3,arg4);                       (4)

}

以上(1)处代码是使用work queue 之前必须要初始化work queue 系统。(2)处代码的地方创建一个work queue供使用。(4)处代码在中断内会触发事先注册的work queue,(3)处代码会获得执行。

raw os 的work queue设计灵活之处是,调用sche_work_queue可以动态的传入参数,像linux这样的系统也不具备像work queue 动态传入参数的能力。

work queue api 使用

1 void global_work_queue_init(OBJECT_WORK_QUEUE_MSG *work_queue_msg, RAW_U32 size)

函数功能:
初始化整个workqueue的系统,用户使用workqueue之前必须先调用此函数。

此函数的参数有2个,分别含义如下:
work_queue_msg为类型为OBJECT_WORK_QUEUE_MSG的空间起始位置。
size为有多少个work_queue_msg。
函数的返回值:



2 RAW_U16 work_queue_create(WORK_QUEUE_STRUCT *wq, RAW_U8 work_task_priority, RAW_U32 work_queue_stack_size, PORT_STACK *work_queue_stack_base, RAW_VOID **msg_start, RAW_U32 work_msg_size)

函数功能:
创建一个workqueue供中断下半部来使用,workqueue 内部的函数可以睡眠。这个是和task 0所不同的。

此函数的参数有6个,分别含义如下:
wq为work queue的控制块地址。
work_task_priority为work queue内部任务的优先级。
work_queue_stack_size为work queue内部任务的栈大小。
work_queue_stack_base为work queue内部任务的栈起始地址。
msg_start为work queue内部queue的消息起始地址。
work_msg_size为work queue内部queue的消息长度。

函数的返回值:
RAW_SUCCESS:成功创建work queue。


3 RAW_U16 sche_work_queue(WORK_QUEUE_STRUCT *wq, RAW_U32 arg, void *msg, WORK_QUEUE_HANDLER handler)

函数功能:
触发调度一个work queue,此函数会唤醒外部的一个work queue任务,并传递消息给外部的handler去处理。

此函数的参数有4个,分别含义如下:
wq为work queue的控制块地址。
arg为传递给handler的参数。
Msg为传递给handler的参数。
handler为该work queue的处理函数。

函数的返回值:
RAW_WORK_QUEUE_MSG_MAX:work queue 内部消息耗完,用户可能要增加消息总空间。
RAW_SUCCESS:成功触发调度一个work queue。



work queue内部api

1 static void work_queue_task(void *pa)
函数功能:
work queue内部任务,用来实现work queue的功能。

此函数的参数有1个,含义如下:
pa为无效参数,可以忽略。
函数的返回值:
无。

raw os 官网地址为:www.raw-os.org

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-25 22:11

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

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