pdf

2-OSAL系统框架专题

  • 1星
  • 日期: 2018-07-19
  • 大小: 338.31KB
  • 所需积分:1分
  • 下载次数:5
  • favicon收藏
  • rep举报
  • 分享
  • free评论
标签: 物联网

物联网是新一代信息技术的重要组成部分,也是“信息化”时代的重要发展阶段。其英文名称是:“Internet of things(IoT)”。利用局部网络或互联网等通信技术把传感器、控制器、机器、人员和物等通过新的方式联在一起,形成人与物、物与物相联,实现信息化、远程管理控制和智能化的网络。物联网是互联网的延伸,它包括互联网及互联网上所有的资源,兼容互联网所有的应用,但物联网中所有的元素(所有的设备、资源及通信等)都是个性化和私有化。

2-OSAL系统框架专题

文档内容节选

原创奥特曼Zigbee读书日记二OSAL系统框架专题 本站原创教程 Page 1 of 7 首页 论坛 搜索 帮助 导航 淘宝小店 飞比Zigbee论坛 本站原创教程 原创奥特曼Zigbee读书日记二OSAL系统框架专题 ltway 提醒 短消息 个人中心 退出 管理员 回 复 发 帖 返回列表 1 2 3 4 5 下一页 outman 发表于 201048 2104 只看该作者 打印 字体大小 倒序看帖 跳转到 1 原创奥特曼Zigbee读书日记二OSAL系统框架专题 9 TI协议栈所用系统框架探讨 51的系统往往不是太大,但是几十K的程序,也足以让一个初学者望而却步我们首先忽略 C语言本身的难度,光是系统框 架也让生手读起来很吃力,再加上这种到处是API跟define的程序,还没有正式学习协议部分就已经让人在丛林中迷 路了 在接下来的一段时间内,我会以TI所用的系统框架为主线进行 学习,希望大家共同探讨 注:本文源自wwwfeibitcom飞比Zigbee论坛,为尊重劳动者成果,如需转载请保留此行 ......

[原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 - 本站原创教程 - “... Page 1 of 7 首页 论坛 搜索 帮助 导航 淘宝小店 “飞比”Zigbee论坛 » 本站原创教程 » [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 ltway | 提醒 短消息 | 个人中心 退出 管理员 回 复 发 帖 返回列表 1 2 3 4 5 下一页 outman 发表于 2010-4-8 21:04 | 只看该作者 打印 字体大小: 倒序看帖 跳转到 » 1 # [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 9. TI协议栈所用系统框架探讨。 51的系统往往不是太大,但是几十K的程序,也足以让一个初学者望而却步。我们首先忽略 C语言本身的难度,光是系统框 架也让生手读起来很吃力,再加上这种到处是API跟"define"的程序,还没有正式学习协议部分就已经让人在丛林中“迷 路”了。 在接下来的一段时间内,我会以TI所用的系统框架为主线进行 学习,希望大家共同探讨。。。 [注:本文源自www.feibit.com--“飞比”Zigbee论坛,为尊重劳动者成果,如需转载请保留此行] 在层层迷雾中摸索了两天,终于拨云见日,那个心情啊,怎一个“爽”字了得~~~ 可是怎么能把这么复杂的一个问题讲得清楚呢?嗯。。。还是先上图吧 注:为了便于直观,以下涉及到数据地址的地方都是由上而下,地址由高变低 第1节、各个任务是如何被调用到的? 我们还是先从main()函数开始,看看各个任务之间是如何协调工作的。 插播一句广告:在一切都看不清的时候,忽略次要,看主要因素 -- by outman from feibit.com 我们直接进入主循环的核心部分,看一下系统 中的几个主要的任务是如何被调用,并开始自己的使命的? 看一段程序的时候,往往要从它的数据结构入手。我们先看一下,主循环中的两个关键数组,*tasksEvents与 *tasksArr,从图一中我们可以看出来,tasksEvents这个数组存放的是从序号为0到tasksCnt,每个任务在本次循环中是 否要被运行,需要运行的任务其值非0(用橙色表示),否则为0。而tasksArr数组则存放了对应每个任务的入口地址,只 有在tasksEvents中记录的需要运行的任务,在本次循环中才会被调用到。--这节讲完了。。。 又有同学举手?什么?还没明白?恩。。。好像是不能讲这么短的。。。 那好吧,把main函数贴过来,我们一点一点看 初始化过程“先不管”,我们先看 主循环(dead loop) for(;;) // Forever Loop { http://www.feibit.com/bbs/viewthread.php?tid=16&extra=page%3D1 2010-12-11 [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 - 本站原创教程 - “... Page 2 of 7 uint8 idx = 0; Hal_ProcessPoll(); // 先不管1 do { if (tasksEvents[idx]) // 寻找最高优先级的任务来运行 { break; } } while (++idx < tasksCnt); if (idx < tasksCnt) // 如果有任务需要运行 { uint16 events; halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); events = tasksEvents[idx]; tasksEvents[idx] = 0; // 本任务运行完了,要对其清空,为后面要运行的任务让路 HAL_EXIT_CRITICAL_SECTION(intState); events = (tasksArr[idx])( idx, events );// 最关键的一句话,如图一中,运行对应的任务 HAL_ENTER_CRITICAL_SECTION(intState); tasksEvents[idx] |= events; // 本任务可能没完全完成,如果是这样,再次设置标志位,在下一次循环中继续执行 HAL_EXIT_CRITICAL_SECTION(intState); } } 第2节、系统时间 我们知道,每个操作系统(虽然我不认为OSAL是一个标准的操作系统,但我们先这么叫着吧)都有一个“节拍”-tick, 就像每一个“活人”都有心跳一样。那么OSAL的心跳有多快呢?--1ms。当然这个速度是可以设置的,在 osal_timer_activate函数中开启了系统节拍,用TICK_TIME来定义其速度 #define TICK_TIME 1000 // Timer per tick - in micro-sec 注意:这个1000是micro-sec(微秒),而不是milli-sec(毫秒)!我刚开始的时候就是误以为是1000ms而耽误了不少 时间。 那这个心脏是怎么跳动起来的呢? 这得从“定时器”说起,由于本文的重点不是讲单片机基础的,如果对这个名字还陌生的同学,那还是回去先看看基础再来 看这个吧。2430有4个定时/计数器,其中timer4用来做系统计时。如果认为是timer2的同学请看一下halTimerRemap这 个函数。在上述osal_timer_activate 函数中,开启了系统计时,并将timer4的初始设为TICK_TIME(1000),这样 timer4就开始了从1000开始的减计数,减到0以后呢?寄存器TIMIF会产生一个溢出标志,那么它会立即产生中断并进入 中断服务程序吗?不会的。 我们看一下第1节主函数里的“Hal_ProcessPoll(); // 先不管1”(不管的东西早晚要管的,只是时间的问题而已) 这个 函数里调用了HalTimerTick,这个函数就是专门来检查是否有硬件定时器溢出的,如果有的话会调用 halTimerSendCallBack 这个函数,对溢出事件做处理。 回过头来说系统节拍,那timer4在计数满1000(即1ms)后做了些什么事呢,那我们看一下halTimerSendCallBack 这 个函数 void halTimerSendCallBack (uint8 timerId, uint8 channel, uint8 channelMode) { uint8 hwtimerid; hwtimerid = halTimerRemap (timerId); if (halTimerRecord[hwtimerid].callBackFunc) (halTimerRecord[hwtimerid].callBackFunc) (timerId, channel, channelMode); } 这里面调用了“callBackFunc”函数,也就是说每个定时器溢出后都有一个callBackFunc 函数,它在哪里呢,我们再看一 下HalTimerConfig这个函数,它可以对每个定时器进行定义。那什么时候定义的呢?--InitBoard,即板子上电初始化 的时候就做了这个定义的。我说什么来?“先不管”的东西,“后要管”的。。。 我们看到timer4的callBackFunc函数是Onboard_TimerCallBack ,最终指向osalTimerUpdate ,这个函数厉害了~ 从上面的分析中我们知道它是每1ms被调用一次的,这样它就为应用程序提供了一个ms计时器,应用程序所用的定时往往 以ms为单位足够了,这样的话就不用另外再占用硬件计时器了,毕竟只有4个嘛。。。同时这个函数还提供了一个系统时钟 -osal_systemClock,看看它能计时多久吧,它是“uint32”型的,也就是2^32ms=49.7天,怎么样?你不会让这个系 统时钟overflow吧:) http://www.feibit.com/bbs/viewthread.php?tid=16&extra=page%3D1 2010-12-11 [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 - 本站原创教程 - “... Page 3 of 7 第3节、系统的消息处理机制 结合第1、2节中的内容,让我们一起进入到系统最核心的部分-消息处理中来吧(这个句型怎么这么耳熟~~~) 第1节中我们说了,tasksEvents数组存放了一个任务是否该被运行的序列,但是这个序列是如何产生的呢?如果了解了这 个问题,那也就知道了OSAL系统的运作方式。 再插句广告:在浩如烟海的程序中搜索最重要的东西,就像大浪淘沙,其实也是蛮享受的一件事情--by outman from feibit.com source insight "ctr+/" ,整个项目搜索,我们发现了一个“osal_set_event”的函数是专门来设置tasksEvents的,但是 似乎并不能帮到我们。继续搜!有两个很重要的地方引起了我们的注意:osalTimerUpdate 和osal_msg_send 这两个函数 osalTimerUpdate ,这个称得上“厉害”的函数还记得吧?它会去设置tasksEvents?那不就是说,它可以让任务在主循 环中被运行到?答对了,这就是它“厉害”的地方。。。那看看它运行任务的条件吧? // When timeout, execute the task if ( srchTimer->timeout == 0 ) { osal_set_event( srchTimer->task_id, srchTimer->event_flag ); ... ... 也就是说,计时器溢出--恩。。。不多说了,我们埋个伏笔,先介绍另一个朋友-osal_start_timerEx,先看下它的自 我介绍 /********************************************************************* * @fn osal_start_timerEx * * @brief * * This function is called to start a timer to expire in n mSecs. * When the timer expires, the calling task will get the specified event. * * @param byte taskID - task id to set timer for * @param UINT16 event_id - event to be notified with * @param UNINT16 timeout_value - in milliseconds. * * @return ZSUCCESS, or NO_TIMER_AVAIL. */ byte osal_start_timerEx( byte taskID, UINT16 event_id, UINT16 timeout_value ) 也就是说,它会开始一个timeout_value(ms)的计时器,当这个计时器溢出时,则会对taskID这个task,设置一个 event_id,让这个任务在后面的主循环中运行到,但是是怎么实现的呢?还是要请osalTimerUpdate来帮忙。。。 那位同学说啥?复杂了,听不懂? 唉,还是上图吧 还是先从数据结构说起吧,不知道啥是“数据链表”的同学,把谭老师的书拿过来再读几遍。。。 这个表就是osalTimerUpdate函数的“任务表”,上面不是说过这个函数给应用程序提供了“软计时”了吗?就是体现在 这里,osal_start_timerEx通过osalAddTimer向链表里添加了“定时任务”,由osalTimerUpdate来以ms为单位对这些 “软定时器”减计数,溢出时,即调用osal_set_event,实现主循环里对任务的调用。 好了,到此讲了上面提到的"set event"函数中的一个osal_start_timerEx, 还有一个更厉害的还在外面呢, http://www.feibit.com/bbs/viewthread.php?tid=16&extra=page%3D1 2010-12-11 [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 - 本站原创教程 - “... Page 4 of 7 osal_msg_send ,这就渐入佳境,进入最重要的消息处理机制了。。。 -- by outman from feibit.com 2010-4-14 18:00 下班啦,老婆在家等着回去一起做饭哪~~~晚上见~~~ 为了更好地说明这个问题,还是拿一个具体的例子来讲比较直观。不过在这个笔记中,我尽量不涉及具体开发板,而讲一些 通用的知识,因为这样会让更多的人受益。在TI官方zstack 2006中有4个例子,其中一个叫GenericApp最基本的通信的 例程,如果没有安装zstack的同学可以到“本站专用下载贴”中下载。当然由于讲的是些比较通用的东西,所以手头有开发 板的同学可以用自己的开发板来试验,效果更好。。。 在这样的通信例程中,一般会有一个按键触发,然后会和相邻的模块进行通信,当然由于这部分是讲OSAL的系统框架的, 我们先不涉及通信的内容,只是看一下按键是如何产生的,及如何调用相应的接口程序。 按OSAL的模块定义,按键可能在哪层来?硬件服务相关的,恩。。。是不是在HAL层呢?到Hal_ProcessEvent 看看?有 个HalKeyPoll函数不是?恩,这就是检测按键的地方~~不过,我可不是像上面这样这么容易猜出来的,这几句话足足用了 我大半个钟头呢。。。过程我不细说了,有兴趣的话我可以再补充一下。 在HalKeyPoll函数中,无论按键是ADC方式,或者是扫描IO口的方式,最后都会生成一个键值keys, 然后通过下面的语句 来调用按键服务程序 /* Invoke Callback if new keys were depressed */ if (keys && (pHalKeyProcessFunction)) { (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); } 这里调用的服务程序,在InitBoard中被初始化为OnBoard_KeyCallback ,这个函数又通过OnBoard_SendKeys运行下 面语句 { // Send the address to the task msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) ); if ( msgPtr ) { msgPtr->hdr.event = KEY_CHANGE; msgPtr->state = state; msgPtr->keys = keys; osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr ); } return ( ZSuccess ); } 下面我们就看下osal_msg_send是如何向上级应用程序发送消息的。终于要讲消息量的数据结构了,好像绕得有点 远。。。。还是先上图 http://www.feibit.com/bbs/viewthread.php?tid=16&extra=page%3D1 2010-12-11 [原创]奥特曼Zigbee读书日记(二)--OSAL系统框架专题 - 本站原创教程 - “... Page 5 of 7 在理解了消息量的数据链表后,再来理解osal_msg_send里的语句就不难了 OSAL_MSG_ID( msg_ptr ) = destination_task;// 设置消息数据对应是属于哪个任务的 // 将要发送的消息数据链接到以osal_qHead开头的数据链表中 osal_msg_enqueue( &osal_qHead, msg_ptr ); // 通知主循环有任务等待处理 osal_set_event( destination_task, SYS_EVENT_MSG ); 这样用户任务GenericApp_ProcessEvent 就收到一个按键的处理任务,并通过GenericApp_HandleKeys 来执行相应的操 作。 好了,现在应该对OSAL的消息处理机制有个了解了吧?我们再来复习一下这个按键的处理过程:任务驱动层 Hal_ProcessEvent 负责对按键进行持续扫描,发现有按键事件后OnBoard_KeyCallback 函数向应用层 GenericApp_ProcessEvent 发送一个有按键需要处理的消息,最终由GenericApp_HandleKeys来负责执行具体的操作。 让我们再回到最初的问题,任务处理表tasksEvents是怎么被改动的呢?初始化程序、其他任务或者本任务主要通过下面几 种方式对其操作: 1、设置计时器,当其溢出时,触发事件处理 2、直接通过任务间的消息传递机制触发 3、...(等我想到了再补充) -- by outman from feibit.com 2010.4.15 00:18 该睡觉啦~~~ 本主题由 品味开心茶 于 2010-4-30 14:53 解除置顶 收藏 分享 世界上还有不“偷菜”的人吗? 有,我就是-----传说中的奥特曼--outman 回复 引用 apple 发表于 2010-4-13 13:03 | 只看该作者 翘首等待…… 报告 使用道具 2 # 新手上路 管理员 回复 引用 outman 发表于 2010-4-13 15:23 | 只看该作者 报告 使用道具 TOP 3 # 多谢支持,我也正在学习,框架基本理清楚了,但要写出来还是差点火候。。。 世界上还有不“偷菜”的人吗? 有,我就是-----传说中的奥特曼--outman 回复 引用 outman 发表于 2010-4-14 15:18 | 只看该作者 报告 使用道具 TOP 4 # http://www.feibit.com/bbs/viewthread.php?tid=16&extra=page%3D1 2010-12-11
更多简介内容

推荐帖子

【树莓派4B测评】树莓派4的各个功能查看和测试
【树莓派4B测评】树莓派4的各个功能查看和测试 分为以下几个部分: 1,检查树莓派版本 2,CPU查看 3,内存查看 4,CPU温度查看 5,GPIO查看和测试 6,3.5耳机口测试 7,USB3.0端口测试 8,网络连接速率查看和测试 9,总结     1,检查树莓派版本 在Raspbian中打开终端,输入“dm
tagetage 开发板测评专版
【ESK32-360测评】三,LCD显示汉字
本次例程是没有汉字显示的。于是我就加了个汉字显示函数。这个函数是在显示字符改过来的可累死我了。总是左右反显。后来改了显示顺序才出来。 首先用字库生成软件产生要显示的字库。 这个得小心,程序得依这个软件而改动。就是这块费了好多劲。   上程序: void LCD_ChianDraw(u32 X_Location, u32 Y_Location) {
ddllxxrr 国产芯片交流
TI KeyStone C66x系列多核架构定点/浮点TMS320C6678设计的评估板串口
CPU处理器 TI TMS320C6678是一款TI KeyStone C66x多核定点/浮点DSP处理器,集成了8个C66x核,每核心主频高达1.0/1.25GHz,支持高性能信号处理应用,拥有多种工业接口资源,以下是TMS320C6678 CPU功能框图: 创龙TL6678-EasyEVM是一款基于TI KeyStone C66x系列多核架构定点/浮点TMS320C6678设计的高
Jacktang 微控制器 MCU
TI KeyStone C66x系列多核架构定点/浮点TMS320C6678设计的评估板串口
CPU处理器 TI TMS320C6678是一款TI KeyStone C66x多核定点/浮点DSP处理器,集成了8个C66x核,每核心主频高达1.0/1.25GHz,支持高性能信号处理应用,拥有多种工业接口资源,以下是TMS320C6678 CPU功能框图: 创龙TL6678-EasyEVM是一款基于TI KeyStone C66x系列多核架构定点/浮点TMS320C6678设计的高
Jacktang 微控制器 MCU
DSP28335 SCI通信问题总结以及问题总结
在学习的过程中难免会遇到一些问题,我希望通过把这些问题写出来,一方面希望各位大神指点;也希望通过这种方式帮助后面的新学者一种提示吧,开始第一步始终是很难的,我是深有体会的;最后也希望大家踊跃讨论,集思广益嘛,互相学习。     进入正题:最近几天一直在学习SCI通信,自己以为应该不难,以前有51的串口经验。但是事实上,并没有想象中的那么容易。    1、首先是非FIFO模式的中断设置服
Jacktang DSP 与 ARM 处理器
示波器通道耦合与触发耦合的区别
在电子电路中,将前级电路(或信号源)的输出信号送至后级电路(或负载)称为耦合。耦合的作用就是把某一电路的能量输送(或转换)到其他的电路中去。   在示波器中,存在两种耦合设置,一种是通道的耦合方式,另外一种是触发的耦合方式,今天我们来详细说说这两种耦合设置的功能以及差别。   先来说示波器通道的耦合方式,一般打开示波器的通道菜单,就可以看到示波器有三种通道耦合方式的设置,分
Micsig麦科信 测试/测量

评论

学习一下123
感谢分享!!!
2019-05-10 22:36:32回复
登录/注册

意见反馈

求资源

回顶部

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

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
$(function(){ var appid = $(".select li a").data("channel"); $(".select li a").click(function(){ var appid = $(this).data("channel"); $('.select dt').html($(this).html()); $('#channel').val(appid); }) })