3683|0

420

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

多对象的阻塞(内核高级功能) [复制链接]

在多任务同步的章节里面我们看到多个任务可以阻塞在同一个内核对象上。例如多个任务可以阻塞在信号量以及队列或者事件标志上。在这个一章节会阐述单个任务如何阻塞在多个内核对象上。目前raw os支持任务同时阻塞在队列(queue)或者信号量(semaphore)上。

raw os实现多对象阻塞的功能主要是通过函数通知的功能来实现的。通过此项技术能够简洁的实现单任务阻塞在多个内核对象上的功能。
函数通知的功能能够通过注册一个回调函数,使得释放信号量以及发送消息到队列上的时候调用这个注册的函数。

怎么样注册一个函数通知功能的回调函数呢?举例如下:
raw_semphore_send_notify(&sem1,notify_function)通过此函数调用可以注册一个回调函数notify_function到信号量sem1上,当用户使用函数raw_semaphore_put的时候就可以触发此回调函数。

同样对于队列也有此功能。raw_queue_send_notify(&queue1,  notify_function)通过此函数可以注册一个回调函数notify_function到queue1上。当用户使用函数raw_queue_end_post时会触发此注册的回调函数。
下图中演示的是一个实际中的案例:


上图(1)处任务1需要等待queue1或者queue2有消息才能继续运行。queue1或者queue2没有消息的话,任务1就阻塞住。(2)和(3)处说明queue1 或者queue2来消息了,任务1需要去接收,(4)和(5)处说明任务1接收了消息后继续运行。
下图演示的是raw os 对于上面问题的解决方式,不同的操作系统有不同的解决方式,无疑通过函数通知这种实现是最简洁的。


上图(1)处任务1阻塞在网关处,当sem1的内部计数器值为0时说明queue1和queue2都没有消息,当不为0时说明queue1或者queue2有消息。(2)和(3)处说明queue1 或者queue2来消息了,任务1需要去接收,(4)和(5)处说明任务1接收了消息后继续运行。
以上过程只是比前面一个图多了一个sem1的网关,确是解决问题的关键所在。下面总结描述下解决方案。
1 queue1 以及queue2上注册一个通知函数,通知函数的内容是发送一个信号量。
2 任务阻塞在sem1上,当queue1以及queue2获得消息时,会唤醒任务1,然后接收相应的消息。

具体的代码演示如下:
queue1以及queue2上注册一个通知函数notify_queue,代码如下所示:
raw_queue_send_notify(&queue1, notify_queue);
raw_queue_send_notify(&queue2, notify_queue);

通知函数内容如下:
void notify_queue(RAW_QUEUE *ptr)
{
    raw_semaphore_put(&sem1);
}

可以看到只要queue1和queue2里面一有消息就会触发notify_queue回调函数。回调函数会释放一个信号量,同时会打开网关sem1,进而唤醒任务1。

任务1的代码如下:

raw_semaphore_get(&sem1, RAW_WAIT_FOREVER);
ret = raw_queue_receive (&queue1, RAW_NO_WAIT, (RAW_VOID**)&msg_app2);
if (ret == RAW_SUCCESS) {
    /*Access queue1 msg*/;
}

ret = raw_queue_receive (&queue2, RAW_NO_WAIT, (RAW_VOID**)&msg_app2);
if (ret == RAW_SUCCESS) {
    /*Access queue2 msg*/;
}

上述代码中可以看到任务1阻塞在sem1上,当queue1以及queue2上有消息的时候会触发notify_queue这个回调函数,回调函数内会释放一个信号量,进而唤醒任务1。需要注意的是调用raw_queue_receive时需要采用没有消息立马返回的功能,即超时参数为RAW_NO_WAIT。
以上从理论到实际演示了一个完整的任务阻塞在多内核对象上的过程,这个过程是挺复杂的,具体的验证可以上VC或者keil平台验证。


[ 本帖最后由 jorya_txj 于 2013-11-10 16:28 编辑 ]
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表