SAE J1939 协议源代码分析(三)-程序应用分析
来源:互联网 发布:少年ma的奇幻 知乎 编辑:程序博客网 时间:2024/06/05 20:49
预备知识
1.熟悉CAN2.0B协议,及相关硬件驱动开发
2.熟悉SAE J1939协议http://blog.csdn.net/xietongxueflyme/article/details/74276702/
J1939协议栈的功能
1.消息发送
2.消息广播
3.消息请求
4.消息确认,响应
5.群功能
6.专用传输A
7.专用传输B
8.地址声明竞争
9.远程地址配置
10.自动重新分配地址
11.多帧传输协议TP
接口函数简介
协议接口demo
API –> J1939_Initialization (BOOL);【初始化一些全局变量,向总线声明地址(默认地址)】
int main(){ //初始化can驱动 init_can(); //初始化J1939协议栈 J1939_Initialization( TRUE ); //等待地址超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //运行到这里,说明地址已经声明好在系统总线上(设备已挂载到总线上) while(1) { ; }}
API –> J1939_EnqueueMessage (J1939_MESSAGE *MsgPtr);【将传入的消息(*MsgPtr),复制到发送列队中】
void main( void ){ J1939_MESSAGE Msg; /*在CAN驱动初始化中,请配置好滤波,说明参考移植函数(滤波函数)*/ /* can_init(); */ J1939_Initialization( TRUE ); //等待地址超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //运行到这里,说明地址已经声明好(设备已挂载到总线上) while (1) { /********发送数据(参考J1939的ID组成填充下面)***********/ Msg.Mxe.DataPage = 0; Msg.Mxe.Priority = J1939_CONTROL_PRIORITY; Msg.Mxe.DestinationAddress = 0x0f; Msg.Mxe.DataLength = 8; Msg.Mxe.PDUFormat = 0xfe; Msg.Mxe.Data[0] = 1; Msg.Mxe.Data[1] = 2; Msg.Mxe.Data[2] = 3; Msg.Mxe.Data[3] = 4; Msg.Mxe.Data[4] = 5; Msg.Mxe.Data[5] = 6; Msg.Mxe.Data[6] = 7; Msg.Mxe.Data[7] = 8; while (J1939_EnqueueMessage( &Msg ) != RC_SUCCESS) J1939_Poll(5); J1939_Poll(20); }}
API –> J1939_DequeueMessage (J1939_MESSAGE *MsgPtr);【从接受列队中复制接收消息到传入的内存中(*MsgPtr)】
int main(){ J1939_MESSAGE Msg; /*在CAN驱动初始化中,请配置好滤波,说明参考移植函数(滤波函数)*/ /* can_init(); */ J1939_Initialization( TRUE ); //等待地址超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //运行到这里,说明地址已经声明好(设备已挂载到总线上) while(1) { /***********************处理接受数据*************************/ while (RXQueueCount > 0) { J1939_DequeueMessage( &Msg ); if (Msg.PDUFormat == 0x01) //你的功能码; else if (Msg.PDUFormat == 0x02) //你的功能码; } J1939_Poll(20); /********************j1939心跳函数*************************/ J1939_Poll(20); }}
API –>J1939_TP_TX_Message(unsigned int PGN,unsigned char SA,char *data,unsigned short data_num)【当我们需要发送字节数大于8字节的数据,调用这个函数启用TP协议将数据发送出去】
void main( void ){ char data[100] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7}; /*在CAN驱动初始化中,请配置好滤波,说明参考移植函数(滤波函数)*/ /* can_init(); */ J1939_Initialization( TRUE ); // 等待地址声明超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //地址已经声明好(设备已挂载到总线上) while(1) { /*发送一个长帧 data*/ while(J1939_TP_TX_Message(65259,0XF1,data,sizeof(data))==RC_SUCCESS) J1939_Poll(5); osDelay(10); J1939_Poll(20); }}
API –>J1939_TP_RX_Message(char *data,unsigned short data_num)【接收网络中TP协议的数据,并将数据存入data缓存】
void main( void ){ //建议初始化缓存大小用 J1939_TP_MAX_MESSAGE_LENGTH char data[J1939_TP_MAX_MESSAGE_LENGTH] = {0}; /*在CAN驱动初始化中,请配置好滤波,说明参考移植函数(滤波函数)*/ /* can_init(); */ J1939_Initialization( TRUE ); // 等待地址声明超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //地址已经声明好(设备已挂载到总线上) //最简单的示例 while(1) { /*读取TP接受数据*/ while(J1939_TP_RX_Message( data,sizeof(data))==RC_SUCCESS) J1939_Poll(5); osDelay(1); //基本单位为10ms * 1; J1939_Poll(20); } //完整的接受逻辑示例 while(1) { /*判断有没有接受的TP到来*/ if(TP_RX_MSG.tp_rx_msg.byte_count >0) { /*判断数据是否是我们想要的PGN*/ if(TP_RX_MSG.tp_rx_msg.PGN == 我们想要的PGN) { while(J1939_TP_RX_Message( data,sizeof(data))==RC_SUCCESS) J1939_Poll(5); } } osDelay(1); //基本单位为10ms * 1; J1939_Poll(20); }}
示例1—轮询模式
备注:接受处理,不是标准的接受处理。这里只是测试接受
void main( void ){ J1939_MESSAGE Msg; can_init(); J1939_Initialization( TRUE ); //等待地址超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //设备确认总线上没有,竞争地址的设备存在 while (1) { /***********************发送数据***************************/ Msg.Mxe.DataPage = 0; Msg.Mxe.Priority = J1939_CONTROL_PRIORITY; Msg.Mxe.DestinationAddress = OTHER_NODE; Msg.Mxe.DataLength = 8; Msg.Mxe.PDUFormat = 0xfe; Msg.Mxe.Data[0] = 0xFF; Msg.Mxe.Data[1] = 0xFF; Msg.Mxe.Data[2] = 0xFF; Msg.Mxe.Data[3] = 0xFF; Msg.Mxe.Data[4] = 0xFF; Msg.Mxe.Data[5] = 0xFF; Msg.Mxe.Data[6] = 0xFF; Msg.Mxe.Data[7] = 0xFF; while (J1939_EnqueueMessage( &Msg ) != RC_SUCCESS) J1939_Poll(5); /***********************处理接受数据*************************/ while (RXQueueCount > 0) { J1939_DequeueMessage( &Msg ); if (Msg.Mxe.PDUFormat == 0x01) //你的功能码; else if (Msg.Mxe.PDUFormat == 0x02) //你的功能码; } J1939_Poll(20); }}
示例2—中断模式
void main(){ can_init(); J1939_Initialization( TRUE ); //等待地址超时 while (J1939_Flags.WaitingForAddressClaimContention) J1939_Poll(5); //设备确认总线上没有,竞争地址的设备存在 while (1) { //判断接受列队中,存在多少个接受消息(RXQueueCount ) while (RXQueueCount > 0) { //读取接受列队中的数据到Msg (出队) J1939_DequeueMessage( &Msg ); /*判断是否是数据请求帧*/ if (Msg.Mxe.PDUFormat == J1939_PF_REQUEST) { //判断参数群是否被本设备支持 if ((Msg.Mxe.Data[0] == J1939_PGN0_REQ_ENGINE_SPEED) && (Msg.Mxe.Data[1] == J1939_PGN1_REQ_ENGINE_SPEED) && (Msg.Mxe.Data[2] == J1939_PGN2_REQ_ENGINE_SPEED)) { if (某种原因不能响应) { /*********发送不能响应(参考J1939-21)*************/ Msg.Mxe.Priority = J1939_ACK_PRIORITY; Msg.Mxe.DataPage = 0; Msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT; Msg.Mxe.DestinationAddress = Msg.SourceAddress; Msg.Mxe.DataLength = 8; Msg.Mxe.Data[0] = J1939_NACK_CONTROL_BYTE; Msg.Mxe.Data[1] = 0xFF; Msg.Mxe.Data[2] = 0xFF; Msg.Mxe.Data[3] = 0xFF; Msg.Mxe.Data[4] = 0xFF; Msg.Mxe.Data[5] = J1939_PGN0_REQ_ENGINE_SPEED; Msg.Mxe.Data[6] = J1939_PGN1_REQ_ENGINE_SPEED; Msg.Mxe.Data[7] = J1939_PGN2_REQ_ENGINE_SPEED; } else { /*******************上传相关的参数群*****************/ Msg.Mxe.Priority = J1939_INFO_PRIORITY; Msg.Mxe.DataPage = J1939_PGN2_REQ_ENGINE_SPEED & 0x01; Msg.Mxe.PDUFormat = J1939_PGN1_REQ_ENGINE_SPEED; Msg.Mxe.GroupExtension = J1939_PGN0_REQ_ENGINE_SPEED; Msg.Mxe.DataLength = 1; Msg.Mxe.Data[0] = EngineSpeed; } while (J1939_EnqueueMessage( &Msg ) != RC_SUCCESS); } } } }}
阅读全文
4 0
- SAE J1939 协议源代码分析(三)-程序应用分析
- SAE J1939 协议源代码分析(二)-程序移植
- SAE J1939 协议源代码分析(零)-源代码下载
- SAE J1939 协议源代码分析(一)-程序结构框架
- SAE J1939 协议源代码分析(五)-ChangeGroupIDofLMO()
- SAE J1939 协议源代码分析(六)-J1939_CAN_Transmit(J1939_MESSAGE *MsgPtr)
- SAE J1939 协议源代码分析(七)-J1939_CAN_Receive(J1939_MESSAGE *MsgPtr)
- SAE J1939 协议源代码分析(四)-J1939_SetAddressFilter(unsigned char Ps_Address)
- SAE J1939 协议源代码分析(八)-4大中断使能与使能
- SAE J1939协议
- SAE J1939学习笔记(三)
- VC++中如何实现基于CAN的SAE J1939协议
- SAE J1939 协议入门前须知(一)
- aodv协议源代码分析
- aodv协议源代码分析
- aodv协议源代码分析
- SAE J1939介绍
- MTD源代码分析(三)
- 个人学习之提取app以及Assets.car包中的素材
- MTK Android Driver :key
- 【GDOI2018模拟7.10】C
- Linux账号管理简单命令
- python之高阶函数
- SAE J1939 协议源代码分析(三)-程序应用分析
- Horizon 二次开发
- 音频播放
- Windows下 Django部署到Apache
- 女孩吐槽 IT 男:有钱自大无聊 约会竟爱谈工作
- struts2 2.3xxx 升级至 2.5.10.1中遇到的问题
- 不仅仅是截图--截取整个scrollView的内容
- left join、right join、inner join的区别
- 关于BitmapFactory.decodeResource会导致oom