Zigbee协议栈开发笔记(一)
<h2>前排提示:新坑,详情请看下一篇文章</h2><h2>osal_start_system函数</h2><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c138430739752054.png" alt=""/></p><p>tasksCnt——任务总个数</p><p>tasksEvent——指针,指向事件表首地址</p><p>tasksArr——数组,每一项都指向事件处理函数</p><p>=<img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c16061d884883555.png" alt=""/></p><p>idx——变量,用来在事件表中索引</p><p>查看是否有事件发生,如果有,tasksEvents[idx]会不为零,则跳出循环。</p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c185694840747180.png" alt=""/></p><p>11-12读取事件</p><p>13 事件表中清零</p><p>14 调用事件处理函数,其中tasksArr[idx]</p><p> </p><p> </p><h2>GenericApp_ProcessEvent函数</h2><p> </p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c1ab66b098394385.png" alt=""/><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c1d7b83297376190.png" alt=""/></p><p> </p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c20edf8082596789.png" alt=""/><span style="color:#5b9bd5"></span></p><p><a href="http://nevel.cnblogs.com/p/6370264.html">http://nevel.cnblogs.com/p/6370264.html</a><span style="color:#5b9bd5"></span></p><p><span style="color:#5b9bd5"><em>看函数名前面的指针*号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。</em></span></p><p><span style="color:#5b9bd5"><em>是函数指针</em></span></p><p> </p><p><span style="color:#5b9bd5"><em><strong>指针函数</strong>是指带指针的函数,即<strong>本质是一个函数</strong>,函数返回类型是某一类型的<strong>指针</strong>。</em></span></p><p><span style="color:#5b9bd5"><em>类型标识符 函数名(参数表)</em></span></p><p><span style="color:#5b9bd5"><em>int f(x,y);</em></span></p><p><span style="color:#5b9bd5"><em>首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。</em></span></p><p><span style="color:#5b9bd5"><em>表示:</em></span></p><p><span style="color:#5b9bd5"><em>float fun();</em></span></p><p><span style="color:#5b9bd5"><em>float p;</em></span></p><p><span style="color:#5b9bd5"><em>p = fun(a);</em></span></p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c23a06c331275631.png" alt=""/><span style="color:#5b9bd5"></span></p><p><span style="color:#5b9bd5"><em>接受一个数据包并将其地址赋给MSGpkt</em></span></p><p> </p><p> </p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c262c22660322907.png" alt=""/><span style="color:#5b9bd5"></span></p><p> </p><h2>OSAL添加新任务</h2><p>在OSAL_GenericApp.c文件中操作</p><p>要添加新任务,需要编写两个函数1)新任务的初始化函数2)新任务的事件处理函数</p><p>将事件初始化函数添加在osalInitTasks函数的最后</p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c2913b4526979123.png" alt=""/></p><p> </p><p> </p><p>将事件处理函数的地址加入tasksArr[]数组</p><p> </p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c2be5e9664984048.png" alt=""/></p><p>注意,1)tasksArr数组里个时间处理函数的排序要与osalInitTasks函数中顺序保持一致</p><p>2)为了保存osalInitTasks函数所分配的任务ID需要给每一个任务定义一个全局变量</p><h2>串口收发基础实验</h2><p>新增代码有:</p><pre class="prism-highlight prism-language-c">unsigned char uartbuf[128];
static void rxCB(uint8 port,uint8 event);//串口相关
halUARTCfg_t uartConfig;//定义串口配置结构体
一下部分对串口进行配置,如是否打开串口,波特率,是否使用流控等
uartConfig.configurde = TRUE;
uartConfig.baudRate = HAL_UART_BR_115200;
uartConfig.flowControl = FALSE;
uartConfig.callBackFunc = rxCB;
HalUARTOpen(0,&uartConfig);//最后使用HalUARTOpen对串口进行初始化
static void rxCB(uint8 port,uint8 event)
{
HalUARTRead(0,uartbuf,16);//调用函数,从串口读取数据并存放在uartbuf中
if(osal_memcmp(uartbuf,"ldztzrh",7))//判断接受到的数据,如果是,返回TURE
{
HalUARTWrite(0,uartbuf,16);//调用该函数,发送收到的数据
}
}
//osal_memcmp()经常使用,是一个回调函数,在 uartConfig.callBackFunc = rxCB; 处
//将rxCB传递给了成员callBackFunc,是一个函数指针,也就是将函数的地址传给callBackFunc
//这样就可以通过callBackFunc成员函数来调用rxCB()函数了。
//回调函数是在特定条件或事件发生时,由另一方调用的,用于响应</pre><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c30a36e001002173.png" alt=""/></p><p>随后,在下载到板子之前,还需要针对条件编译对IAR做出一些设置,</p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c3309a6885931240.png" alt=""/></p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c358c62815942590.png" alt=""/></p><p>总结:</p><p>启用串口功能须按照GalDriverInit要求开启宏定义,TRUE不要输错</p><p>下载程序前看工程目前是协调器版本还是终端版本</p><p>开发板上有绿灯表示串口上行和下行状态</p><p>发送字符串后板子居然无线重复的发回信息,不会自动停下,不知道这例程怎么编成这样的</p><h2>串口原理剖析</h2><p>主要使用三个函数:HalUARTOpen()、HALUARTRead()、HALUARTWrite()</p><p>HalUARTOpen():初始化,特别需要注意halUARTCfg_t结构体,</p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c388b5a117111558.png" alt=""/></p><p>加粗部分,baudRata即为波特率</p><p>读写部分,TI将串口和DMA结合在了一起,因此读数据函数实际上是堵DMA缓冲区数据。</p><h2>串口应用扩展实验</h2><p>流程:终端发送字符串到协调器,协调器串口到pc</p><p>协调器修改例程,参考书上,主要修改了消息处理函数:</p><pre class="prism-highlight prism-language-c">osal_memcpy(buffer,pkt->cmd.Data,10);//使用osal_memcpy函数将接收到的数据拷贝到buffer中
HalUARTWrita(0,buffer,10);//串口写函数</pre><p>终端编程</p><ol class=" list-paddingleft-2"><li><div style="text-align: justify">需要定时函数周期性的发送数据,使用osal_start_timerEx函数,有三个参数,见图</div></li></ol><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5cae03c3b64b9108305254.png" alt=""/></p><ol class=" list-paddingleft-2"><li><div style="text-align: justify">添加新的事件,此例中:#define SEND_DATA_EVENT 0x01</div></li><li><div style="text-align: justify">此时,定时器函数的参数便可确定,详细参考修改的代码</div></li><li><div style="text-align: justify">接下来,添加事件的处理函数</div><p>因此,可修改终端代码</p></li></ol>
Q.E.D.