例程学习之SampleApp--SPIMgr.c(MT层) SPIMgr_ProcessZToolData()
来源:互联网 发布:php utf8转换为gbk 编辑:程序博客网 时间:2024/06/05 02:28
学习协议栈的一个重要原因就是要通过协议栈和pc进行通信,而要完成通信过程需要对协议栈的MT层有一定的了解。MT层的SPIMgr.c文件主要处理串口相关的应用。串口这个概念之前听到过很多次,现在终于对它有了一些了解,欣慰啊~但是做出实物才是硬道理,程序只是看明白还是不够滴,修改成功才是王道~废话不多说,下面来看程序。
halUARTCfg_t uartConfig;/halUARTCfg_t应该是一个关于串口的结构体,可以查查具体是怎么定义的
App_TaskID = 0;
配置串口相关的参数,包括波特率、流控制、接收缓存区、发送缓存区等 uartConfig.configured = TRUE; uartConfig.baudRate = SPI_MGR_DEFAULT_BAUDRATE; uartConfig.flowControl = SPI_MGR_DEFAULT_OVERFLOW; uartConfig.flowControlThreshold = SPI_MGR_DEFAULT_THRESHOLD; uartConfig.rx.maxBufSize = SPI_MGR_DEFAULT_MAX_RX_BUFF; uartConfig.tx.maxBufSize = SPI_MGR_DEFAULT_MAX_TX_BUFF; uartConfig.idleTimeout = SPI_MGR_DEFAULT_IDLE_TIMEOUT; uartConfig.intEnable = TRUE; uartConfig.callBackFunc = SPIMgr_ProcessZToolData; uartConfig.callBackFunc = SPIMgr_ProcessZAppData; uartConfig.callBackFunc = NULL;
打开串口 HalUARTOpen (SPI_MGR_DEFAULT_PORT, &uartConfig);/突然发现在串口收发过程中起关键作用的还是HalUARTXXXX系列,例如HalUARTRead、HalUARTWrite以及这里的HalUARTOpen (void)uartConfig;
SPIMgr_MaxZAppBufLen = 1; SPIMgr_ZAppRxStatus = SPI_MGR_ZAPP_RX_READY;
uint8 ch;/设置一个字节的变量,从串口读入的数据首先放入这个变量中
if (event == HAL_UART_TX_FULL)/这里就是传说中串口写数据的地方了,我之前以为会有一个专门 /的函数处理发送数据,没想到在协议栈里居然是个空~函~数~ 泪奔~o(>_<)o ~~ 自定义串口发送数据的 /时候应该自行添加HalUARTWrite()函数,具体我还没有尝试 { // Do something when TX if full return; }
if (event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT))/接收数据 { while (Hal_UART_RxBufLen(SPI_MGR_DEFAULT_PORT)) { HalUARTRead (SPI_MGR_DEFAULT_PORT, &ch, 1) ;/用HalUARTRead()函数将串口的数据一个字节一个字节的读入变量ch中 switch (state) { case SOP_STATE: if (ch == SOP_VALUE) state = CMD_STATE1; break;
case CMD_STATE1: CMD_Token[0] = ch; state = CMD_STATE2; break;
case CMD_STATE2: CMD_Token[1] = ch; state = LEN_STATE; break;
case LEN_STATE: LEN_Token = ch; if (ch == 0) state = FCS_STATE; else state = DATA_STATE;
tempDataLen = 0;
SPI_Msg = (mtOSALSerialData_t *)osal_msg_allocate( sizeof ( mtOSALSerialData_t ) + 2+1+LEN_Token ); if (SPI_Msg) { 构造数据包 SPI_Msg->hdr.event = CMD_SERIAL_MSG; SPI_Msg->msg = (uint8*)(SPI_Msg+1); SPI_Msg->msg[0] = CMD_Token[0]; SPI_Msg->msg[1] = CMD_Token[1]; SPI_Msg->msg[2] = LEN_Token; } else { state = SOP_STATE; return; }
break;
case DATA_STATE: SPI_Msg->msg[3 + tempDataLen++] = ch; if ( tempDataLen == LEN_Token ) state = FCS_STATE; break;
case FCS_STATE:
FSC_Token = ch;
if ((SPIMgr_CalcFCS ((uint8*)&SPI_Msg->msg[0], 2 + 1 + LEN_Token) == FSC_Token)) { osal_msg_send( MT_TaskID, (byte *)SPI_Msg );/将数据发送至MT层 } else { osal_msg_deallocate ( (uint8 *)SPI_Msg); }
state = SOP_STATE;
break;
default: break; }
} }
首先是串口的初始化函数:
void SPIMgr_Init ()
{
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)/如果设置了ZTOOL,就将数据发往MT层处理
#elif defined (ZAPP_P1) || defined (ZAPP_P2)/把数据送往应用任务App_TaskID
#else
#endif
SPIMgr_ProcessZToolData以及SPIMgr_ProcessZAppData这两个回调函数十分重要,在接下来的程序中就是在这两个函数中完成串口数据收发的工作。其中SPIMgr_ProcessZToolData中接收数据部分还完成了对接收到的数据进行打包并发送至MT层的任务(这部分占据了整个文档将近1/3的篇幅,重要性可见一斑哦~)。先在这里提个醒,具体内容在碰到程序时具体分析咯~
#if defined (SPI_MGR_DEFAULT_PORT)
#else
#endif
#if defined (ZAPP_P1) || defined (ZAPP_P2)
#endif
}
接下来上场的就是刚刚强调过的uart回调函数之一:SPIMgr_ProcessZToolRxData ~\(≧▽≦)/~
在下面的函数brief里面介绍了数据包的构造:一个字节的SOP(数据包起始字节),两个字节的命令标记,一个字节的数据长度(这个之后是具体数据,但是没有标记出来)以及一个字节的奇偶校验位。
void SPIMgr_ProcessZToolData ( uint8 port, uint8 event )
{
下面的state参数当初让我纠结了好久,在研究了半天程序之后自以为得到了一个差不多合理的解释,现在记录下来,如果有理解不正确的地方希望能早日更正~
state参数的值包括:
#define SOP_STATE 0x00
#define CMD_STATE1 0x01
#define CMD_STATE2 0x02
#define LEN_STATE 0x03
#define DATA_STATE 0x04
#define FCS_STATE 0x05
之后在程序的开始部分定义了state:
uint8 state;
个人的理解是,初始化后之后默认state的值为0,即上述的 CMD_STATE1
SOP_STATE
,所以下面的switch()函数一开始就进入
case SOP_STATE,在判断读入的字节为数据包起始字节(SOP)之后,让state变为 并跳出函数,接着判断下一个字节。
在此处抛一个链接,小峰博主对于SPI_Msg及一下的程序有很精辟的解释,在此感谢博主~
http://wjf88223.blog.163.com/blog/static/35168001201052772511674/
归纳:msg[0]和msg[1]是两字节命令标记;msg[2]是数据长度标记;msg[3]是EP号;msg[4]开始就是长度为msg[2]-1的具体数据了。
}
#endif //ZTOOL
SPIMgr_ProcessZToolData函数就介绍完了,接下来是SPIMgr_ProcessZAppData()函数。因为目前没有用到这部分,所以下次再具体学习了。
0 0
- 例程学习之SampleApp--SPIMgr.c(MT层) SPIMgr_ProcessZToolData()
- TI协议栈例程GenericApp SampleApp SimpleAp 区别
- TI协议栈例程GenericApp SampleApp SimpleAp 区别
- MEI例程之 notify.c
- OpenCV学习之例程详解(02):经典C与现代C++方式播放视频
- Halcon学习之coherence_enhancing_diff例程学习
- zigbee学习:示例程序SampleApp中按键工作流程
- zigbee学习:示例程序SampleApp中通讯流程
- zigbee学习:示例程序SampleApp中按键工作流程
- MT机器学习面试
- W7100例程学习之ADC应用
- zigbee学习笔记---通信例程之GenericApp
- jrtplib学习之example1例程分析
- StarterWare学习之编译移植UART例程
- C++例程学习之 堆与栈
- EmguCV学习之例程详解(01):HelloWorld
- OpenCV学习之例程详解(01):HelloWorld
- jrtplib学习之example1例程分析
- C++标准库---仿函数
- android 图像淡入淡出资源问题(Button can't be cast to ImageView)
- substring 函数
- STM32F0xx IAP实现之中断向量表重定义
- Matlab各种分布的函数
- 例程学习之SampleApp--SPIMgr.c(MT层) SPIMgr_ProcessZToolData()
- JAVA读取和操作PDF系列《三》
- protoc 文件android报错的原因
- 揭秘jbpm流程引擎内核设计思想及构架
- 利用Solr搭建企业搜索平台之一-Solr运行
- Matlab各种排序函数
- static详解
- leetcode:Spiral Matrix II
- 11月份学习总结