shir

    1. 4. 当你改到有文件路径的地方,比如“C/C++ compiler ==> preprocessor”,这个时候,先跳过去,把其它改好再回来改这个。因为这些地方都是编译器要寻找文件的地方,我们必须要确保里面指定的文件在硬盘的文件夹里能找得到,否则编译会出错。同时,这些地方也告诉我们这个项目到底用到了哪些文件,增加了我们对项目全局的了解。 例如,如上的“preprocessor”中: $PROJ_DIR$\..\SOURCE $PROJ_DIR$\..\..\..\ZMAIN\TI2430DB $PROJ_DIR$\..\..\..\..\..\COMPONENTS\MT ... 在如上的路径中,$PROJ_DIR$指的是IAR的工程文件夹,就是上面我们建的“IAR Project”,“\..”是代表向上一级,那么我们就找到SOURCE、ZMAIN和COMPONENTS这三个必须的文件夹,把SOURCE拷到二级BeginApp文件夹中,另外两个拷到一级BeginApp根目录下,同时上述相应的文件夹位置也要按照新的结构来更改,如$PROJ_DIR$\..\..\..\ZMAIN\TI2430DB就要改为$PROJ_DIR$\..\..\ZMAIN\TI2430DB,以此类推。注:这个文件夹的命名和位置都是不固定的,完全可以按照你的想法来做,我这样命名的目的只是为了区别TI的“库”和我们的“应用”。 另外,在“C/C++ compiler ==> extra options”中,我们又找到了“tools”;在“linker ==> extra options”中我们又找到了这个Libraries,这两个必须的文件夹,也拷到一级BeginApp根目录下。好了,至此,项目需要的文件我们已经按照自己喜欢的方式排列好啦~~~ 5. 这一步是最麻烦的,就是按照“GenericApp”里“workspace”下的文件夹和文件一个个添加文件了。这中间遇到“EB”的我们可以不管,因为我们用的是“DB”。 6. 编译。如果上面工作做得仔细,这一步应该是一次性成功。但是又有一个问题:虽然编译成功了,但是我们编译出来的结果和原来的是不是一样的呢?(毕竟我们第一步的目的是造一个一模一样的轮子~~) code size!对,如果编译的代码大小一样的话,那基本上能保证完全相同了吧? 那code size及RAM的使用情况等信息在哪里找得到呢? \BeginApp\BeginApp\IAR Project\Coordinator\List这里面有个“BeginApp.map”文件,打开它,在最底部看一下                 ****************************************                 *                                      *                 *        END OF CROSS REFERENCE        *                 *                                      *                 **************************************** 74 598 bytes of CODE  memory      18 bytes of DATA  memory (+ 67 absolute )   3 627 bytes of XDATA memory     192 bytes of IDATA memory       8 bits  of BIT   memory Errors: none Warnings: none 就是这里啦,对比一下是不是和原来的一样就OK啦~ 7. 增加自己的“应用”,在source文件夹中,仿照GenericApp里的源文件,增加三个文件BeginApp.c/BeginApp.h/OSAL_BeginApp.c,然后写自己想写的东西罗~ 做为最原始的程序,本教程中,采用了一个按键(P0_0)来控制一个LED(P2_0),按一次取一次反。当然,由于开发板的差异性,这个具体的IO定义要根据您的硬件进行修改了。 8. 运行,把上面的程序下载到你自己的板子中,看到LED在“眨眼”了吗~~~ 至此,我们就有了一个属于自己的“最小化”项目了,回想一下这个项目里的文件,是不是觉得比看别人给做好的更清爽了呢? 由于本教程不是单片机的入门教程,至于“应用”中的源代码就不再累述了,回头把我做好的整个项目文件共享出来,需要的请自行下载,不过记得雁过留名哦!
    2. 第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, 还有一个更厉害的还在外面呢,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是如何向上级应用程序发送消息的。终于要讲消息量的数据结构了,好像绕得有点远。。。。还是先上图 在理解了消息量的数据链表后,再来理解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 [ 本帖最后由 shir 于 2010-6-21 15:19 编辑 ]
    3. 奥特曼的zigbee读书笔记(一) 19/13044 无线连接 2010-06-21
      附英文原文: 1.9 ZigBee Networking Topologies The network formation is managed by the ZigBee networking layer. The network must be in one of two networking topologies specified in IEEE 802.15.4: star and peer-to-peer. In the star topology , shown in Figure 1.6 , every device in the network can communicate only with the PAN coordinator. A typical scenario in a star network formation is that an FFD, programmed to be a PAN coordinator, is activated and starts establishing its network. The first thing this PAN coordinator does is select a unique PAN identifier that is not used by any other network in its radio sphere of influence —the region around the device in which its radio can successfully communicate with other radios. In other words, it ensures that the PAN identifier is not used by any other nearby network. In a peer-to-peer topology (see Figure 1.7 ), each device can communicate directly with any other device if the devices are placed close enough together to establish a successful communication link. Any FFD in a peer-to-peer network can play the role of the PAN coordinator. One way to decide which device will be the PAN coordinator is to pick the first FFD device that starts communicating as the PAN coordinator. In a peer-to-peer network, all the devices that participate in relaying the messages are FFDs because RFDs are not capable of relaying the messages. However, an RFD can be part of the network and communicate only with one particular device (a coordinator or a router) in the network. A peer-to-peer network can take different shapes by defining restrictions on the devices that can communicate with each other. If there is no restriction, the peer-to-peer network is known as a mesh topology . Another form of peer-to-peer network ZigBee supports is a tree topology (see Figure 1.8 ). In this case, a ZigBee coordinator (PAN coordinator) establishes the initial network. ZigBee routers form the branches and relay the messages. ZigBee end devices act as leaves of the tree and do not participate in message routing. ZigBee routers can grow the network beyond the initial network established by the ZigBee coordinator. Figure 1.8 also shows an example of how relaying a message can help extend the range of the network and even go around barriers. For example, device A needs to send a message to device B, but there is a barrier between them that is hard for the signal to penetrate. The tree topology helps by relaying the message around the barrier and reach device B. This is sometimes referred to as multihopping because a message hops from one node to another until it reaches its destination. This higher coverage comes at the expense of potential high message latency. An IEEE 802.15.4 network, regardless of its topology, is always created by a PAN coordinator. The PAN coordinator controls the network and performs the following minimum duties: ● Allocate a unique address (16-bit or 64-bit) to each device in the network. ● Initiate, terminate, and route the messages throughout the network. ● Select a unique PAN identifier for the network. This PAN identifier allows the devices within a network to use the 16-bit short-addressing method and still be able to communicate with other devices across independent networks. There is only one PAN coordinator in the entire network. A PAN coordinator may need to have long active periods; therefore, it is usually connected to a main supply rather than a battery. All other devices are normally battery powered. The smallest possible network includes two devices: a PAN coordinator and a device.

最近访客

< 1/1 >

统计信息

已有86人来访过

  • 芯积分:--
  • 好友:--
  • 主题:4
  • 回复:3

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言