SAE J1939 协议源代码分析(二)-程序移植

SAE J1939 协议源代码分析(二)-程序移植预备知识1.熟悉CAN2.0B协议,及相关硬件驱动开发2.熟悉SAEJ1939协议程序移植流程CreatedwithRaphaël2.1.0将代码加载到你的工程打开配置文件J1939_Config.h明白默认地址和标识符配置规则?了解J1939支持的功能配置使用

大家好,又见面了,我是你们的朋友全栈君。

预备知识

1.熟悉CAN2.0B协议,及相关硬件驱动开发
2.熟悉SAE J1939协议<http://blog.csdn.net/xietongxueflyme/article/details/74276702/>

程序移植流程

Created with Raphaël 2.1.0 将代码加载到你的工程 打开配置文件J1939_Config.h 明白默认地址和 标识符配置规则? 了解J1939支持的 功能配置使用的功能 熟悉AN2.0B驱动编写 按J1939_Config.h文件提示说 明,移植相关的函数功能 移植完成 练习CAN2.0B扩展帧驱动编写 参考J1939-21 查阅J1939附录B( 地址和标识符分配) yes no yes no yes no

移植示例(demo)

以下示例,对德国英飞凌XMC4500(MCU)芯片自带的CAN模块上移植J1939协议源代码,代码中can驱动函数,can的驱动结构体,可供移植参考

#ifndef __J1939_Config_H 
#define __J1939_Config_H 

#include "J1939.H"

#include "../UserApp/includes.h"//用户,自己工程必要的声明头文件
/******************************J1939地址和标识符配*********************************/ //设备默认的地址(地址命名是有规定的,参考J1939的附录B 地址和标识符的分配) #define J1939_STARTING_ADDRESS 243 //如果声明不为0,表示我们的ECU(电子控制单元)支持网络中申请的任意地址,(参考J1939的网络层) #define J1939_ARBITRARY_ADDRESS 0x00 #define J1939_INDUSTRY_GROUP 0 #define J1939_VEHICLE_INSTANCE 0 #define J1939_CA_NAME7 (J1939_ARBITRARY_ADDRESS | (J1939_INDUSTRY_GROUP << 4) | J1939_VEHICLE_INSTANCE) #define J1939_VEHICLE_SYSTEM 0 #define J1939_CA_NAME6 (J1939_VEHICLE_SYSTEM << 1) #define J1939_FUNCTION 0 #define J1939_CA_NAME5 J1939_FUNCTION #define J1939_FUNCTION_INSTANCE 0 #define J1939_ECU_INSTANCE 0 #define J1939_CA_NAME4 ((J1939_FUNCTION_INSTANCE << 3) | J1939_ECU_INSTANCE) #define J1939_MANUFACTURER_CODE 0 #define J1939_IDENTITY_NUMBER 50 #define J1939_CA_NAME3 (J1939_MANUFACTURER_CODE >> 3) #define J1939_CA_NAME2 (((J1939_MANUFACTURER_CODE & 0x07) << 5) | (J1939_IDENTITY_NUMBER >> 16)) #define J1939_CA_NAME1 ((J1939_IDENTITY_NUMBER >> 8) & 0xFF) #define J1939_CA_NAME0 (J1939_IDENTITY_NUMBER & 0xFF) /******************************J1939功能配置******************************************/ //是否使用接受协议(对TP协议的支持,参考J1939-21) #define J1939_ACCEPT_CMDADD J1939_FALSE #define J1939_RX_QUEUE_SIZE 3 //当mcu来不及处理消息,接收消息列队是否允许被新的消息覆盖 #define J1939_OVERWRITE_RX_QUEUE J1939_FALSE #define J1939_TX_QUEUE_SIZE 3 //当mcu来不及处理消息,发送消息列队是否允许被新的消息覆盖 #define J1939_OVERWRITE_TX_QUEUE J1939_FALSE //是否使用轮询模式(否则使用中断模式) #define J1939_POLL_ECAN J1939_TRUE #define J1939_PRIORITIZED_INT J1939_TRUE /******************************J1939移植配置函数******************************************/ #define Port_CAN_Transmit(MsgPtr) J1939_CAN_Transmit(MsgPtr) #define Port_CAN_Receive(MsgPtr) J1939_CAN_Receive(MsgPtr) #define Port_SetAddressFilter(Address) J1939_SetAddressFilter(Address) #define Port_RXinterruptEnable() J1939_RXinterruptEnable() #define Port_RXinterruptDisable() J1939_RXinterruptDisable() #define Port_TXinterruptEnable() J1939_TXinterruptEnable() #define Port_TXinterruptDisable() J1939_TXinterruptDisable() /******************************J1939CAN驱动接口函数************************************/ void J1939_SetAddressFilter(unsigned char Ps_Address) { CAN_NODE3_DEBUG.lmobj_ptr[0]->mo_ptr->can_id_mask &=0XFFFF00FF; CAN_NODE3_DEBUG.lmobj_ptr[0]->mo_ptr->can_id_mask |= (Ps_Address<<8); CAN_NODE_MO_Init(CAN_NODE3_DEBUG.lmobj_ptr[0]); } void ChangeGroupIDofLMO(const CAN_NODE_LMO_t *lmo_ptr,J1939_MESSAGE *MsgPtr) { int _i=0; lmo_ptr->mo_ptr->can_identifier = 0; for(_i=0;_i<4;_i++) { lmo_ptr->mo_ptr->can_identifier = (lmo_ptr->mo_ptr->can_identifier << 8) + MsgPtr->Array[_i]; } // 在线修改lmo配置 CAN_NODE_MO_Init(lmo_ptr); } /*从MsgPtr加载到CAN自带的结构体中*/ void J1939_CAN_Transmit(J1939_MESSAGE *MsgPtr) { CAN_NODE_LMO_t *lmo_ptr = CAN_NODE3_DEBUG.lmobj_ptr[1]; /*加载29ID*/ ChangeGroupIDofLMO((const CAN_NODE_LMO_t * const)(CAN_NODE3_DEBUG.lmobj_ptr[1]),MsgPtr); /*加载数据长度*/ lmo_ptr->mo_ptr->can_data_length = MsgPtr->Mxe.DataLength; CAN_NODE_MO_Init(lmo_ptr); /*加载数据*/ lmo_ptr->mo_ptr->can_data_byte[0] = MsgPtr->Mxe.Data[0]; lmo_ptr->mo_ptr->can_data_byte[1] = MsgPtr->Mxe.Data[1]; lmo_ptr->mo_ptr->can_data_byte[2] = MsgPtr->Mxe.Data[2]; lmo_ptr->mo_ptr->can_data_byte[3] = MsgPtr->Mxe.Data[3]; lmo_ptr->mo_ptr->can_data_byte[4] = MsgPtr->Mxe.Data[4]; lmo_ptr->mo_ptr->can_data_byte[5] = MsgPtr->Mxe.Data[5]; lmo_ptr->mo_ptr->can_data_byte[6] = MsgPtr->Mxe.Data[6]; lmo_ptr->mo_ptr->can_data_byte[7] = MsgPtr->Mxe.Data[7]; /*加载RTR*/ //你的代码 //开始发送数据 (CAN_NODE_STATUS_t) CAN_NODE_MO_Transmit(lmo_ptr) ; } //将设备CAN中的数据取出,存入J1939_MESSAGE结构体中 int J1939_CAN_Receive(J1939_MESSAGE *MsgPtr) { uint32_t receive_status=0; uint32_t _id=0; receive_status = CAN_NODE_MO_GetStatus( ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]); if ( receive_status & XMC_CAN_MO_STATUS_RX_PENDING) //XMC_CAN_MO_STATUS_NEW_DATA { // 清除接受标识位 CAN_NODE_MO_ClearStatus(((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0],XMC_CAN_MO_RESET_STATUS_RX_PENDING); // 读取数据 CAN_NODE_MO_Receive( ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]); //将29位标志位(can_identifier)写入J1939的结构中 _id = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_identifier; MsgPtr->Array[0] = _id>>(8*3); MsgPtr->Array[1] = _id>>(8*2); MsgPtr->Array[2] = _id>>(8*1); MsgPtr->Array[3] = _id>>(8*0); //读取数据长度 MsgPtr->Mxe.DataLength = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_length; if (MsgPtr->Mxe.DataLength > 8) MsgPtr->Mxe.DataLength = 8; //读取数据 MsgPtr->Mxe.Data[0] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[0]; MsgPtr->Mxe.Data[1] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[1]; MsgPtr->Mxe.Data[2] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[2]; MsgPtr->Mxe.Data[3] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[3]; MsgPtr->Mxe.Data[4] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[4]; MsgPtr->Mxe.Data[5] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[5]; MsgPtr->Mxe.Data[6] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[6]; MsgPtr->Mxe.Data[7] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[7]; return 1; }else { return 0;//没有消息 } } void J1939_RXinterruptEnable() { INTERRUPT_Enable(&CAN_RInterrupt_DEBUG); } void J1939_RXinterruptDisable() { INTERRUPT_Disable(&CAN_RInterrupt_DEBUG); } void J1939_TXinterruptEnable() { ; } void J1939_TXinterruptDisable() { ; } #endif

备注

J1939与CAN2.0B驱动接口函数在后面,将逐一的分析。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132771.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月10日 上午11:16
下一篇 2022年6月10日 上午11:16


相关推荐

  • Java实体映射工具:MapStruct

    Java实体映射工具:MapStruct当我们需要进行 JavaModel 之间的拷贝时 或者项目要求 JavaModel 需要严格区分为数据对象 DO 数据传输对象 DTO 和展示对象 VO 的时候 我们就不得不把一个实体中的属性映射到另一个实体中 最简单的做法就是写一个工具类 进行不断的 getter setter 这样虽然能完成要求但却写了很多冗余代码 维护起来相当恶心 所以这个时候就需要一款能自动映射实体属性的工具了 Spring 自带的 BeanUtils 工具类算是一款 但是它却不能自定义映射规则 ModelMapper 也是一款映射工具

    2025年12月7日
    5
  • java 分布式计算框架_java分布式系统框架的分类「建议收藏」

    java 分布式计算框架_java分布式系统框架的分类「建议收藏」鲁班学院java架构师成长路线随着电商行业的崛起,越来越多的人为了省事更习惯网购,今天我们就来熟悉Java分布式系统中的Dubbo,Dubbo就是来解决Java分布式系统中间的子系统之间相互调用相互协作的一个框架。在Dubbo之前就有一个Java分布式系统框架RPC(远程过程调用),多个子系统之间需要实现相互调用必须要借助网络来表达调用的语义和传达调用的数据,RPC采用客户机/服务器模式。请求程序…

    2022年5月31日
    58
  • 某企业ERP实施WBS分解

    某企业ERP实施WBS分解阶段 步骤 工作内容 负责方 双方分工 现场人天 可利用工具 输出成果 项目准备 项目组织 建立 ERP 外部顾问顾问项目小组 ERP 外部顾问 ERP 外部顾问公司负责建立 ERP 外部顾问项目小组 项目组织导论及项目建议书 ERP 外部顾问项目小组清单 建立客户方项目小组 ERP 应用企业 ERP 应用企业组建 ERP 应用企业项目小组 ERP 应用企业项目小组清单 项目调研 制订调研计划

    2026年3月17日
    2
  • ajax实现跨域_js跨域请求的三种方法

    ajax实现跨域_js跨域请求的三种方法跨域的概念跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域。例如:about.haorooms.com和www.haorooms.com都会构成跨域。总结起来只要协议、域名、端口有任何一个不同,都被当作是不同的域。下面举例,每两个一组。URL说明是否允许通信http://www.haorooms.com/a.jshtt

    2022年8月24日
    6
  • #Android单元测试学习总结「建议收藏」

    #Android单元测试学习总结「建议收藏」文章目录一、本地单元测试1.创建测试类2.Assert类中的常用断言方法3.运行测试类4.运行单个测试方法或多个测试类二、Mockito测试框架的使用1.Mock概念的理解2

    2022年7月3日
    48
  • JVM常量池和运行时常量池「建议收藏」

    JVM常量池和运行时常量池「建议收藏」一、类的二进制字节码包含哪些信息要理解常量池是什么,先看看类的二进制字节码包含哪些信息!!!常量池类的基本信息(比如:类的访问权限、类的名称、实现了哪些接口)类的方法定义(包含了虚拟机指令,也就是把我们代码编译为了虚拟机指令)二、通过反编译字节码验证1、测试代码将下面的测试代码使用javac编译为*.class文件publicclassHelloWorld{publicstaticvoidmain(String[]args){System

    2025年10月10日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号