1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783 |
- /*********************************************************************
- *
- * J1939 Main Source Code
- *
- *********************************************************************
- *
- * 本程序是由XieTongXueFlyMe对现有的J1939协议文档分析,和对前辈的贡献总结,
- * 写出的一套开源的J1939驱动。
- * 本协议特点:
- * 1.易移植(不针对特定的CAN硬件,只要满足CAN2.0B即可)
- * 2.轻量级(可适应低端的MCU)
- * 3.支持多任务调用接口(可用于嵌入式系统)
- * 4.双模式(轮询或者中断,逻辑更加简单明了)
- * 5.不掉帧(数据采用收发列队缓存)
- *
- * 源代码下载:
- * https://github.com/XeiTongXueFlyMe/J1939
- * 源代码临时手册Web站点:
- * https://xeitongxueflyme.github.io/j1939doc.github.io/
- *
- * Version Date Description
- * -------------------------------------------------------------------
- * v1.0.0 2017/06/04 首个版本 Version 1 测试版发布
- * v1.0.1 2017/08/04 完善功能
- * v1.1.0 2017/11/22 Version 1 稳定发布版
- * v2.0.1 2017/11/24 Version 2 测试版发布
- * v2.0.2 2018/01/03 解决V2.0.1 遗留问题
- * v2.1.0 2018/01/20 Version 2 稳定发布版
- * Author Date changes
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *XeiTongXueFlyMe 7/06/04 首个版本
- *XeiTongXueFlyMe 7/08/04 增加对TP的支持
- *XeiTongXueFlyMe 7/11/24 增加对多路CAN硬件的收发,和报文处理
- *XeiTongXueFlyMe 7/11/29 增加请求和响应API
- *XeiTongXueFlyMe 7/12/07 重做TP接受API函数
- *XeiTongXueFlyMe 7/12/08 增加软件滤波器
- *XeiTongXueFlyMe 8/01/03 重做接受发送API,简化协议栈初始化调用逻辑
- **********************************************************************/
- #ifndef __J1939_SOURCE
- #define __J1939_SOURCE
- #include "queue.h"
- #include <stdint.h>
- #endif
- #include "J1939.H"
- #include "J1939_config.H"
- #define J1939_TRUE 1 /**< 代表函数正确返回*/
- #define J1939_FALSE 0 /**< 代表函数错误返回*/
- #define ADDRESS_CLAIM_TX 1 /**< 进入地址竞争发送处理模式*/
- #define ADDRESS_CLAIM_RX 2 /**< 进入地址竞争接受处理模式*/
- // 全局变量。
- /** 设备的标称符
- *
- * 我们需要在"J1939_config.H"中配置
- * @note 在初始化中赋值,赋值参考参考1939-81文档
- */
- j1939_uint8_t CA_Name[J1939_DATA_LENGTH];
- j1939_uint8_t CommandedAddress;
- j1939_uint8_t J1939_Address;
- J1939_FLAG J1939_Flags;
- J1939_MESSAGE OneMessage;
- CAN_NODE Can_Node;
- // 节点地址
- j1939_uint8_t NodeAddress_1;
- j1939_uint8_t NodeAddress_2;
- j1939_uint8_t NodeAddress_3;
- j1939_uint8_t NodeAddress_4;
- // 接受列队全局变量(CAN_NODE_1)
- j1939_uint8_t RXHead_1;
- j1939_uint8_t RXTail_1;
- j1939_uint8_t RXQueueCount_1;
- J1939_MESSAGE RXQueue_1[J1939_RX_QUEUE_SIZE];
- // 发送列队全局变量 (CAN_NODE_1)
- j1939_uint8_t TXHead_1;
- j1939_uint8_t TXTail_1;
- j1939_uint8_t TXQueueCount_1;
- J1939_MESSAGE TXQueue_1[J1939_TX_QUEUE_SIZE];
- // 接受列队全局变量(CAN_NODE_2)
- j1939_uint8_t RXHead_2;
- j1939_uint8_t RXTail_2;
- j1939_uint8_t RXQueueCount_2;
- J1939_MESSAGE RXQueue_2[J1939_RX_QUEUE_SIZE];
- // 发送列队全局变量 (CAN_NODE_2)
- j1939_uint8_t TXHead_2;
- j1939_uint8_t TXTail_2;
- j1939_uint8_t TXQueueCount_2;
- J1939_MESSAGE TXQueue_2[J1939_TX_QUEUE_SIZE];
- // 接受列队全局变量(CAN_NODE_3)
- j1939_uint8_t RXHead_3;
- j1939_uint8_t RXTail_3;
- j1939_uint8_t RXQueueCount_3;
- J1939_MESSAGE RXQueue_3[J1939_RX_QUEUE_SIZE];
- // 发送列队全局变量 (CAN_NODE_3)
- j1939_uint8_t TXHead_3;
- j1939_uint8_t TXTail_3;
- j1939_uint8_t TXQueueCount_3;
- J1939_MESSAGE TXQueue_3[J1939_TX_QUEUE_SIZE];
- // 接受列队全局变量(CAN_NODE_4)
- j1939_uint8_t RXHead_4;
- j1939_uint8_t RXTail_4;
- j1939_uint8_t RXQueueCount_4;
- J1939_MESSAGE RXQueue_4[J1939_RX_QUEUE_SIZE];
- // 发送列队全局变量 (CAN_NODE_4)
- j1939_uint8_t TXHead_4;
- j1939_uint8_t TXTail_4;
- j1939_uint8_t TXQueueCount_4;
- J1939_MESSAGE TXQueue_4[J1939_TX_QUEUE_SIZE];
- struct Request_List REQUEST_LIST;
- #if J1939_TP_RX_TX
- // TP协议全局变量
- J1939_TP_Flags J1939_TP_Flags_t;
- J1939_TRANSPORT_RX_INFO TP_RX_MSG;
- J1939_TRANSPORT_TX_INFO TP_TX_MSG;
- #endif // J1939_TP_RX_TX
- static void J1939_ReceiveMessages(void);
- static j1939_uint8_t J1939_TransmitMessages(void);
- /**
- * @note 硬件滤波器2 或 软件滤波器 滤波配置(设置PS段)\n
- */
- void SetAddressFilter(j1939_uint8_t Address)
- {
- /*软件滤波*/
- #if J1939SoftwareFilterEn == J1939_TRUE
- switch (Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- NodeAddress_1 = Address;
- break;
- }
- case Select_CAN_NODE_2:
- {
- NodeAddress_2 = Address;
- break;
- }
- case Select_CAN_NODE_3:
- {
- NodeAddress_3 = Address;
- break;
- }
- case Select_CAN_NODE_4:
- {
- NodeAddress_4 = Address;
- break;
- }
- default:
- {
- break;
- }
- }
- #endif // J1939SoftwareFilterEn
- /*硬件滤波*/
- Port_SetAddressFilter(Address);
- }
- /**
- * @param[in] J1939_MESSAGE *
- * @note 发送*MsgPtr的信息,所有的数据字段(比如数据长度、优先级、和源地址)必须已经设置。\n
- */
- void SendOneMessage(J1939_MESSAGE *MsgPtr)
- {
- // 设置消息的最后部分,确保DataLength规范。(参考CAN B2.0)
- MsgPtr->Mxe.Res = 0; // 参考J1939的数据链路层(SAE J1939-21)
- MsgPtr->Mxe.RTR = 0;
- if (MsgPtr->Mxe.DataLength > 8)
- MsgPtr->Mxe.DataLength = 8;
- // 发送一帧消息,将 J1939_MESSAGE 中的所有消息加载道can模块自有的结构中
- Port_CAN_Transmit(MsgPtr);
- }
- /**
- * @param[in] MsgPtr 用户要出队的消息
- * @param[in] _Can_Node 要出队的CAN硬件编号
- * @return RC_SUCCESS 消息出队成功
- * @return RC_QUEUEEMPTY 没有消息返回
- * @note 从接受队列中读取一个信息到*MsgPtr。如果我们用的是中断,需要将中断失能,在获取接受队列数据时
- */
- j1939_uint8_t J1939_DequeueMessage(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
- {
- j1939_uint8_t _rc = RC_SUCCESS;
- //***************************关接受中断********************************
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_RXinterruptDisable();
- #endif
- switch (_Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- if (RXQueueCount_1 == 0)
- {
- _rc = RC_QUEUEEMPTY;
- }
- else
- {
- *MsgPtr = RXQueue_1[RXHead_1];
- RXHead_1++;
- if (RXHead_1 >= J1939_RX_QUEUE_SIZE)
- RXHead_1 = 0;
- RXQueueCount_1--;
- }
- break;
- }
- case Select_CAN_NODE_2:
- {
- if (RXQueueCount_2 == 0)
- {
- _rc = RC_QUEUEEMPTY;
- }
- else
- {
- *MsgPtr = RXQueue_2[RXHead_2];
- RXHead_2++;
- if (RXHead_2 >= J1939_RX_QUEUE_SIZE)
- RXHead_2 = 0;
- RXQueueCount_2--;
- }
- break;
- }
- case Select_CAN_NODE_3:
- {
- if (RXQueueCount_3 == 0)
- {
- _rc = RC_QUEUEEMPTY;
- }
- else
- {
- *MsgPtr = RXQueue_3[RXHead_3];
- RXHead_3++;
- if (RXHead_3 >= J1939_RX_QUEUE_SIZE)
- RXHead_3 = 0;
- RXQueueCount_3--;
- }
- break;
- }
- case Select_CAN_NODE_4:
- {
- if (RXQueueCount_4 == 0)
- {
- _rc = RC_QUEUEEMPTY;
- }
- else
- {
- *MsgPtr = RXQueue_4[RXHead_4];
- RXHead_4++;
- if (RXHead_4 >= J1939_RX_QUEUE_SIZE)
- RXHead_4 = 0;
- RXQueueCount_4--;
- }
- break;
- }
- default:
- {
- _rc = RC_CANNOTRECEIVE;
- break;
- }
- }
- //***************************开接受中断********************************
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_RXinterruptEnable();
- #endif
- return _rc;
- }
- /**
- * @param[in] MsgPtr 存储读取消息的缓存
- * @param[in] _Can_Node 读取消息的CAN硬件编号(从哪一路CAN读取数据)
- * @return RC_SUCCESS 读取消息成功,
- * @return RC_QUEUEEMPTY 读取消息不成功,没有消息。
- * @note 从接受队列中读取一个信息到*MsgPtr。
- */
- j1939_uint8_t J1939_Read_Message(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
- {
- return J1939_DequeueMessage(MsgPtr, _Can_Node);
- }
- /**
- * @param[in] MsgPtr 用户要入队的消息
- * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
- * @return RC_SUCCESS 消息入队成功
- * @return RC_QUEUEFULL 发送列队满,消息入队失败
- * @return RC_CANNOTTRANSMIT 系统目前不能发送消息
- * @note 这段程序,将*MsgPtr放入发送消息列队中\n
- 如果信息不能入队或者发送,将有一个相应的返回提示,\n
- 如果发送中断被设置(可用),当消息列队后,发送中断被使能
- */
- j1939_uint8_t J1939_EnqueueMessage(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
- {
- j1939_uint8_t _rc = RC_SUCCESS;
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptDisable();
- #endif
- if (0)
- _rc = RC_CANNOTTRANSMIT;
- else
- {
- switch (_Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
- (TXQueueCount_1 < J1939_TX_QUEUE_SIZE))
- {
- if (TXQueueCount_1 < J1939_TX_QUEUE_SIZE)
- {
- TXQueueCount_1++;
- TXTail_1++;
- if (TXTail_1 >= J1939_TX_QUEUE_SIZE)
- TXTail_1 = 0;
- }
- else
- {
- J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
- }
- TXQueue_1[TXTail_1] = *MsgPtr;
- }
- else
- _rc = RC_QUEUEFULL;
- break;
- }
- case Select_CAN_NODE_2:
- {
- if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
- (TXQueueCount_2 < J1939_TX_QUEUE_SIZE))
- {
- if (TXQueueCount_2 < J1939_TX_QUEUE_SIZE)
- {
- TXQueueCount_2++;
- TXTail_2++;
- if (TXTail_2 >= J1939_TX_QUEUE_SIZE)
- TXTail_2 = 0;
- }
- else
- {
- J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
- }
- TXQueue_2[TXTail_2] = *MsgPtr;
- }
- else
- _rc = RC_QUEUEFULL;
- break;
- }
- case Select_CAN_NODE_3:
- {
- if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
- (TXQueueCount_3 < J1939_TX_QUEUE_SIZE))
- {
- if (TXQueueCount_3 < J1939_TX_QUEUE_SIZE)
- {
- TXQueueCount_3++;
- TXTail_3++;
- if (TXTail_3 >= J1939_TX_QUEUE_SIZE)
- TXTail_3 = 0;
- }
- else
- {
- J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
- }
- TXQueue_3[TXTail_3] = *MsgPtr;
- }
- else
- _rc = RC_QUEUEFULL;
- break;
- }
- case Select_CAN_NODE_4:
- {
- if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
- (TXQueueCount_4 < J1939_TX_QUEUE_SIZE))
- {
- if (TXQueueCount_4 < J1939_TX_QUEUE_SIZE)
- {
- TXQueueCount_4++;
- TXTail_4++;
- if (TXTail_4 >= J1939_TX_QUEUE_SIZE)
- TXTail_4 = 0;
- }
- else
- {
- J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
- }
- TXQueue_4[TXTail_4] = *MsgPtr;
- }
- else
- _rc = RC_QUEUEFULL;
- break;
- }
- default:
- {
- break;
- }
- }
- }
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- // 触发发送中断
- Port_TXinterruptOk();
- #endif
- return _rc;
- }
- /**
- * @param[in] MsgPtr 存储发送消息的缓存
- * @param[in] _Can_Node 发送消息的CAN硬件编号(从哪一路CAN发送数据)
- * @return RC_SUCCESS 发送消息成功
- * @return RC_QUEUEFULL 发送消息不成功,发送列队满,消息入队失败
- * @return RC_CANNOTTRANSMIT 发送消息不成功,系统目前不能发送消息
- * @note 如果信息不能入队或者发送,将有一个相应的返回提示,\n
- */
- j1939_uint8_t J1939_Send_Message(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
- {
- return J1939_EnqueueMessage(MsgPtr, _Can_Node);
- }
- void j1939_msg_push_queue(p_pdu_tag rec_msg)
- {
- J1939_MESSAGE _msg;
- _msg.Mxe.DataPage = rec_msg->id.b.dp;
- _msg.Mxe.Priority = rec_msg->id.b.p;
- _msg.Mxe.PDUFormat = rec_msg->id.b.pf;
- _msg.Mxe.PDUSpecific = rec_msg->id.b.ps;
- _msg.Mxe.SourceAddress = rec_msg->id.b.sa;
- _msg.Mxe.DataLength = rec_msg->reg.dlc;
- _msg.Mxe.PGN = 0;
- for (uint8_t index = 0; index < rec_msg->reg.dlc; index++)
- {
- _msg.Mxe.Data[index] = rec_msg->data.u8_buf[index];
- }
- // en_queue(&j1939_rx_queue, _msg);
- }
- /**
- *
- * @note 这段代码在系统初始化中被调用,(放在CAN设备初始化之后)\n
- 初始化J1939全局变量\n
- */
- void J1939_Initialization()
- {
- /*初始化全局变量*/
- J1939_Flags.FlagVal = 0; // 没有声明地址,其他的标识位将被设置为0(复位)
- /*初始化接受和发送列队*/
- TXHead_1 = 0;
- TXHead_2 = 0;
- TXHead_3 = 0;
- TXHead_4 = 0;
- TXTail_1 = 0xFF;
- TXTail_2 = 0xFF;
- TXTail_3 = 0xFF;
- TXTail_4 = 0xFF;
- RXHead_1 = 0;
- RXHead_2 = 0;
- RXHead_3 = 0;
- RXHead_4 = 0;
- RXTail_1 = 0xFF;
- RXTail_2 = 0xFF;
- RXTail_3 = 0xFF;
- RXTail_4 = 0xFF;
- TXQueueCount_1 = 0;
- TXQueueCount_2 = 0;
- TXQueueCount_3 = 0;
- TXQueueCount_4 = 0;
- RXQueueCount_1 = 0;
- RXQueueCount_2 = 0;
- RXQueueCount_3 = 0;
- RXQueueCount_4 = 0;
- /*初始化节点地址*/
- NodeAddress_1 = J1939_STARTING_ADDRESS_1;
- NodeAddress_2 = J1939_STARTING_ADDRESS_2;
- NodeAddress_3 = J1939_STARTING_ADDRESS_3;
- NodeAddress_4 = J1939_STARTING_ADDRESS_4;
- /*初始化CAN节点的选择*/
- Can_Node = Select_CAN_NODE_1;
- /*初始化请求链表*/
- REQUEST_LIST.PGN = 0;
- REQUEST_LIST.data = J1939_NULL;
- REQUEST_LIST.update = J1939_NULL;
- REQUEST_LIST.lenght = 0;
- REQUEST_LIST.Can_Node = Select_CAN_NODE_Null;
- REQUEST_LIST.next = J1939_NULL;
- /*将TP协议置为空闲*/
- #if J1939_TP_RX_TX
- J1939_TP_Flags_t.state = J1939_TP_NULL;
- J1939_TP_Flags_t.TP_RX_CAN_NODE = Select_CAN_NODE_Null;
- J1939_TP_Flags_t.TP_TX_CAN_NODE = Select_CAN_NODE_Null;
- TP_TX_MSG.packets_request_num = 0;
- TP_TX_MSG.packets_total = 0;
- TP_TX_MSG.packet_offset_p = 0;
- TP_TX_MSG.time = 0;
- TP_TX_MSG.state = J1939_TP_TX_WAIT;
- TP_RX_MSG.packets_ok_num = 0;
- TP_RX_MSG.packets_total = 0;
- TP_RX_MSG.time = 0;
- TP_RX_MSG.state = J1939_TP_RX_WAIT;
- #endif
- }
- /**
- * @note 这个函数被调用,当设备产生CAN中断(可能是接受中断,也可能是发送中断)\n
- 首先我们要清除中断标识位\n
- 然后调用接受或者发送函数。
- */
- #if J1939_POLL_ECAN == J1939_FALSE
- void J1939_ISR(void)
- {
- // 判断相关标识位,是接受还是发送
- // 清除标识位
- Port_CAN_identifier_clc();
- // 调用相关的处理函数
- J1939_ReceiveMessages();
- J1939_TransmitMessages();
- #if J1939_TP_RX_TX
- J1939_TP_Poll();
- #endif // J1939_TP_RX_TX
- // 可能存在因为错误产生中断,直接清除相关的标识位
- }
- #endif
- /**
- * @param[in] ElapsedTime 一个大概的毫秒数,通常设置 5 或 3
- * @note 如果我们采用轮询的方式获取信息,这个函数每几个毫秒将被调用一次。\n
- 不断的接受消息和发送消息从消息队列中\n
- 此外,如果我们正在等待一个地址竞争反应。\n
- 如果超时,我们只接收特定的消息(目标地址 = J1939_Address)\n
- 如果设备使用中断,此函数被调用,在调用J1939_Initialization()函数后,因为\n
- J1939_Initialization()可能初始化WaitingForAddressClaimContention标识位为1.\n
- 如果接受到命令地址消息,这个函数也必须被调用,以防万一总线要求我们改变地址\n
- 如果使用中断模式,本程序将不会处理接受和发送消息,只处理地址竞争超时。\n
- */
- // 声明TP轮询函数
- void J1939_TP_Poll();
- void J1939_Poll()
- {
- // 我们必须调用J1939_ReceiveMessages接受函数,在时间被重置为0之前。
- #if J1939_POLL_ECAN == J1939_TRUE
- Can_Node = Select_CAN_NODE_1;
- J1939_Address = NodeAddress_1;
- J1939_ReceiveMessages();
- J1939_TransmitMessages();
- Can_Node = Select_CAN_NODE_2;
- J1939_Address = NodeAddress_2;
- J1939_ReceiveMessages();
- J1939_TransmitMessages();
- Can_Node = Select_CAN_NODE_3;
- J1939_Address = NodeAddress_3;
- J1939_ReceiveMessages();
- J1939_TransmitMessages();
- Can_Node = Select_CAN_NODE_4;
- J1939_Address = NodeAddress_4;
- J1939_ReceiveMessages();
- J1939_TransmitMessages();
- #if J1939_TP_RX_TX
- J1939_TP_Poll();
- #endif // J1939_TP_RX_TX
- #endif // J1939_POLL_ECAN == J1939_TRUE
- }
- void J1939_Response(const j1939_uint32_t PGN);
- #if J1939SoftwareFilterEn == J1939_TRUE
- /**
- * @return RC_SUCCESS 消息是可以接受
- * @return RC_CANNOTTRANSMIT 消息是不可以接受
- * @note 软件滤波器\n
- * @note 基于SAE J1939协议,我们需要CAN控制器提供至少3个滤波器给J1939协议代码。三个滤波器分别配置如下:
- 1. 设置滤波器0,只接受广播信息(PF = 240 -255)。
- 2. 设置设置滤波器1,2只接受全局地址(J1939_GLOBAL_ADDRESS)
- 3. 随着程序的运行,将改变滤波器2,来适应程序逻辑。
- */
- j1939_uint8_t J1939_Messages_Filter(J1939_MESSAGE *MsgPtr)
- {
- /*滤波器0*/
- if ((MsgPtr->Mxe.PDUFormat) >= 240)
- {
- return RC_SUCCESS;
- }
- /*滤波器1*/
- if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS))
- {
- return RC_SUCCESS;
- }
- /*滤波器2*/
- switch (Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_1))
- {
- return RC_SUCCESS;
- }
- break;
- }
- case Select_CAN_NODE_2:
- {
- if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_2))
- {
- return RC_SUCCESS;
- }
- break;
- }
- case Select_CAN_NODE_3:
- {
- if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_3))
- {
- return RC_SUCCESS;
- }
- break;
- }
- case Select_CAN_NODE_4:
- {
- if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_4))
- {
- return RC_SUCCESS;
- }
- break;
- }
- default:
- {
- break;
- }
- }
- return RC_CANNOTTRANSMIT;
- }
- #endif // J1939SoftwareFilterEn
- /**
- * @note 这段程序被调用,当CAN收发器接受数据(中断 或者 轮询)。\n
- 如果一个信息被接受, 它将被调用\n
- 如果信息是一个网络管理信息或长帧传输(TP),接受的信息将被加工处理,在这个函数中。\n
- 否则, 信息将放置在用户的接收队列。\n
- 注意:在这段程序运行期间中断是失能的。\n
- */
- void J1939_ReceiveMessages(void)
- {
- #if J1939_TP_RX_TX
- j1939_uint32_t _pgn = 0;
- #endif // J1939_TP_RX_TX
- /*从接收缓存中读取信息到OneMessage中,OneMessage是一个全局变量*/
- /*Port_CAN_Receive函数读取到数据返回1,没有数据则返回0*/
- if (Port_CAN_Receive(&OneMessage))
- {
- #if J1939SoftwareFilterEn == J1939_TRUE
- if (J1939_Messages_Filter(&OneMessage) != RC_SUCCESS)
- {
- return;
- }
- #endif // J1939SoftwareFilterEn
- switch (OneMessage.Mxe.PDUFormat)
- {
- #if J1939_TP_RX_TX
- case J1939_PF_TP_CM: // 参考J1939-21 TP多帧传输协议
- _pgn = (j1939_uint32_t)((OneMessage.Mxe.Data[7] << 16) & 0xFF0000) + (j1939_uint32_t)((OneMessage.Mxe.Data[6] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[5]) & 0xFF);
- if ((J1939_TP_Flags_t.state == J1939_TP_NULL) && (TP_RX_MSG.state == J1939_TP_RX_WAIT))
- {
- if (OneMessage.Mxe.Data[0] == 16)
- {
- J1939_TP_Flags_t.state = J1939_TP_RX;
- J1939_TP_Flags_t.TP_RX_CAN_NODE = Can_Node;
- TP_RX_MSG.tp_rx_msg.SA = OneMessage.Mxe.SourceAddress;
- TP_RX_MSG.tp_rx_msg.PGN = (j1939_uint32_t)((OneMessage.Mxe.Data[7] << 16) & 0xFF0000) + (j1939_uint32_t)((OneMessage.Mxe.Data[6] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[5]) & 0xFF);
- /*如果系统繁忙*/
- if (TP_RX_MSG.osbusy)
- {
- TP_RX_MSG.state = J1939_TP_RX_ERROR;
- break;
- }
- /*判断是否有足够的内存接收数据,如果没有直接,断开连接*/
- if (((j1939_uint32_t)((OneMessage.Mxe.Data[2] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[1]) & 0xFF)) > J1939_TP_MAX_MESSAGE_LENGTH)
- {
- TP_RX_MSG.state = J1939_TP_RX_ERROR;
- break;
- }
- TP_RX_MSG.tp_rx_msg.byte_count = ((j1939_uint32_t)((OneMessage.Mxe.Data[2] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[1]) & 0xFF));
- TP_RX_MSG.packets_total = OneMessage.Mxe.Data[3];
- TP_RX_MSG.time = J1939_TP_T2;
- TP_RX_MSG.state = J1939_TP_RX_READ_DATA;
- break;
- }
- goto PutInReceiveQueue;
- break;
- }
- if (J1939_TP_Flags_t.state == J1939_TP_TX)
- {
- /*校验PGN*/
- if (_pgn == TP_TX_MSG.tp_tx_msg.PGN)
- {
- switch (OneMessage.Mxe.Data[0])
- {
- case J1939_RTS_CONTROL_BYTE:
- /* 程序运行到这里,说明已经与网络中设备1建立虚拟链接(作为发送端),但是收到设备2的链接请求,并且同一个PGN消息请求*/
- /* 根据J1939-21数据链路层的规定,我们要保持原有的链接,不做任何事,设备2会应为超时自动放弃链接*/
- break;
- case J1939_CTS_CONTROL_BYTE:
- if ((J1939_TP_TX_CM_WAIT == TP_TX_MSG.state) || (J1939_TP_WAIT_ACK == TP_TX_MSG.state))
- {
- /* 发送等待保持 */
- if (0x00u == OneMessage.Mxe.Data[1])
- {
- /* 刷新等待计数器 */
- TP_TX_MSG.time = J1939_TP_T4;
- }
- else
- {
- if ((OneMessage.Mxe.Data[2] + OneMessage.Mxe.Data[1]) > (TP_TX_MSG.packets_total + 1))
- {
- /*请求超出数据包范围*/
- TP_TX_MSG.state = J1939_TP_TX_ERROR;
- }
- else
- { /* response parameter OK */
- TP_TX_MSG.packets_request_num = OneMessage.Mxe.Data[1];
- TP_TX_MSG.packet_offset_p = (j1939_uint8_t)(OneMessage.Mxe.Data[2] - 1);
- TP_TX_MSG.state = J1939_TP_TX_DT;
- }
- }
- }
- break;
- case J1939_EOMACK_CONTROL_BYTE:
- if (J1939_TP_WAIT_ACK == TP_TX_MSG.state)
- {
- TP_TX_MSG.state = J1939_TX_DONE;
- }
- // 这里可以增加一个对数据的校验
- break;
- case J1939_CONNABORT_CONTROL_BYTE:
- // 收到一个放弃连接,什么都不做,协议会在一段延时时间后主动放弃链接
- break;
- default:
- break;
- }
- }
- }
- goto PutInReceiveQueue;
- break;
- #endif // J1939_TP_RX_TX
- #if J1939_TP_RX_TX
- case J1939_PF_DT:
- if ((TP_RX_MSG.state == J1939_TP_RX_DATA_WAIT) && (TP_RX_MSG.tp_rx_msg.SA == OneMessage.Mxe.SourceAddress))
- {
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u] = OneMessage.Mxe.Data[1];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 1] = OneMessage.Mxe.Data[2];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 2] = OneMessage.Mxe.Data[3];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 3] = OneMessage.Mxe.Data[4];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 4] = OneMessage.Mxe.Data[5];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 5] = OneMessage.Mxe.Data[6];
- TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 6] = OneMessage.Mxe.Data[7];
- /*特殊处理重新接受已接受过的数据包*/
- if ((OneMessage.Mxe.Data[0]) > TP_RX_MSG.packets_ok_num)
- {
- TP_RX_MSG.packets_ok_num++;
- }
- TP_RX_MSG.time = J1939_TP_T1;
- /*判断是否收到偶数个数据包或者读取到最后一个数据包*/
- if ((TP_RX_MSG.packets_ok_num % 2 == 0) || (TP_RX_MSG.packets_ok_num == TP_RX_MSG.packets_total))
- {
- TP_RX_MSG.state = J1939_TP_RX_READ_DATA;
- break;
- }
- break;
- }
- // 程序不可能运行到这,但是我们不能放弃接受的数据包
- goto PutInReceiveQueue;
- #endif // J1939_TP_RX_TX
- case J1939_PF_REQUEST:
- /*用OneMessage.Mxe.PGN 来存下被请求的PGN*/
- if (OneMessage.Mxe.Data[1] < 240)
- {
- OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Mxe.Data[2] << 16) & 0x030000) + (j1939_uint32_t)((OneMessage.Mxe.Data[1] << 8) & 0xFF00) + 0x00;
- }
- else
- {
- OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Mxe.Data[2] << 16) & 0x030000) + (j1939_uint32_t)((OneMessage.Mxe.Data[1] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[0]) & 0xFF);
- }
- J1939_Response(OneMessage.Mxe.PGN);
- break;
- default:
- PutInReceiveQueue:
- {
- /*
- if(OneMessage.Mxe.PDUFormat < 240){
- OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Array[0]<<16)&0x030000)
- +(j1939_uint32_t)((OneMessage.Array[1]<<8)&0xFF00)
- +0x00;
- }else{
- OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Array[0]<<16)&0x030000)
- +(j1939_uint32_t)((OneMessage.Array[1]<<8)&0xFF00)
- +(j1939_uint32_t)((OneMessage.Array[2])&0xFF);
- }
- */
- if (OneMessage.Mxe.PDUFormat < 240)
- {
- OneMessage.Mxe.PGN = (OneMessage.Mxe.Res << 17) + (OneMessage.Mxe.DataPage << 16) + (OneMessage.Mxe.PDUFormat << 8);
- }
- else
- {
- OneMessage.Mxe.PGN = (OneMessage.Mxe.Res << 17) + (OneMessage.Mxe.DataPage << 16) + (OneMessage.Mxe.PDUFormat << 8) + OneMessage.Mxe.PDUSpecific;
- }
- switch (Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
- (RXQueueCount_1 < J1939_RX_QUEUE_SIZE))
- {
- if (RXQueueCount_1 < J1939_RX_QUEUE_SIZE)
- {
- RXQueueCount_1++;
- RXTail_1++;
- if (RXTail_1 >= J1939_RX_QUEUE_SIZE)
- RXTail_1 = 0;
- }
- else
- {
- J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
- J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_1;
- }
- RXQueue_1[RXTail_1] = OneMessage;
- }
- else
- J1939_Flags.ReceivedMessagesDropped = 1; // 产生数据溢出
- break;
- }
- case Select_CAN_NODE_2:
- {
- if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
- (RXQueueCount_2 < J1939_RX_QUEUE_SIZE))
- {
- if (RXQueueCount_2 < J1939_RX_QUEUE_SIZE)
- {
- RXQueueCount_2++;
- RXTail_2++;
- if (RXTail_2 >= J1939_RX_QUEUE_SIZE)
- RXTail_2 = 0;
- }
- else
- {
- J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
- J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_2;
- }
- RXQueue_2[RXTail_2] = OneMessage;
- }
- else
- J1939_Flags.ReceivedMessagesDropped = 1;
- break;
- }
- case Select_CAN_NODE_3:
- {
- if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
- (RXQueueCount_3 < J1939_RX_QUEUE_SIZE))
- {
- if (RXQueueCount_3 < J1939_RX_QUEUE_SIZE)
- {
- RXQueueCount_3++;
- RXTail_3++;
- if (RXTail_3 >= J1939_RX_QUEUE_SIZE)
- RXTail_3 = 0;
- }
- else
- {
- J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
- J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_3;
- }
- RXQueue_3[RXTail_3] = OneMessage;
- }
- else
- J1939_Flags.ReceivedMessagesDropped = 1;
- break;
- }
- case Select_CAN_NODE_4:
- {
- if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
- (RXQueueCount_4 < J1939_RX_QUEUE_SIZE))
- {
- if (RXQueueCount_4 < J1939_RX_QUEUE_SIZE)
- {
- RXQueueCount_4++;
- RXTail_4++;
- if (RXTail_4 >= J1939_RX_QUEUE_SIZE)
- RXTail_4 = 0;
- }
- else
- {
- J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
- J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_4;
- }
- RXQueue_4[RXTail_4] = OneMessage;
- }
- else
- J1939_Flags.ReceivedMessagesDropped = 1;
- break;
- }
- default:
- {
- break;
- }
- }
- }
- }
- }
- }
- /**
- * @return RC_SUCCESS 信息发送成功
- * @return RC_CANNOTTRANSMIT 系统没有发送消息,没有要发送的消息,或错误的CAN设备
- * @note 调用这个函数后,如果发送消息列队中有消息就位,则会发送消息 ,如果不能发送消息,相关的错误代码将返回。\n
- 程序运行期间,中断是被失能的。
- */
- static j1939_uint8_t J1939_TransmitMessages()
- {
- switch (Can_Node)
- {
- case Select_CAN_NODE_1:
- {
- if (TXQueueCount_1 == 0)
- {
- // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- return RC_CANNOTTRANSMIT;
- }
- else
- {
- while (TXQueueCount_1 > 0)
- {
- /*确保上次数据发送成功*/
- /**************可增加一个判断函数**************************/
- TXQueue_1[TXHead_1].Mxe.SourceAddress = NodeAddress_1;
- SendOneMessage((J1939_MESSAGE *)&(TXQueue_1[TXHead_1]));
- TXHead_1++;
- if (TXHead_1 >= J1939_TX_QUEUE_SIZE)
- TXHead_1 = 0;
- TXQueueCount_1--;
- }
- /*配置了一些标识位,使能中断*/
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- }
- break;
- }
- case Select_CAN_NODE_2:
- {
- if (TXQueueCount_2 == 0)
- {
- // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- return RC_CANNOTTRANSMIT;
- }
- else
- {
- while (TXQueueCount_2 > 0)
- {
- /*确保上次数据发送成功*/
- /**************可增加一个判断函数**************************/
- TXQueue_2[TXHead_2].Mxe.SourceAddress = NodeAddress_2;
- SendOneMessage((J1939_MESSAGE *)&(TXQueue_2[TXHead_2]));
- TXHead_2++;
- if (TXHead_2 >= J1939_TX_QUEUE_SIZE)
- TXHead_2 = 0;
- TXQueueCount_2--;
- }
- /*配置了一些标识位,使能中断*/
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- }
- break;
- }
- case Select_CAN_NODE_3:
- {
- if (TXQueueCount_3 == 0)
- {
- // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- return RC_CANNOTTRANSMIT;
- }
- else
- {
- while (TXQueueCount_3 > 0)
- {
- /*确保上次数据发送成功*/
- /**************可增加一个判断函数**************************/
- TXQueue_3[TXHead_3].Mxe.SourceAddress = NodeAddress_3;
- SendOneMessage((J1939_MESSAGE *)&(TXQueue_3[TXHead_3]));
- TXHead_3++;
- if (TXHead_3 >= J1939_TX_QUEUE_SIZE)
- TXHead_3 = 0;
- TXQueueCount_3--;
- }
- /*配置了一些标识位,使能中断*/
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- }
- break;
- }
- case Select_CAN_NODE_4:
- {
- if (TXQueueCount_4 == 0)
- {
- // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- return RC_CANNOTTRANSMIT;
- }
- else
- {
- while (TXQueueCount_4 > 0)
- {
- /*确保上次数据发送成功*/
- /**************可增加一个判断函数**************************/
- TXQueue_4[TXHead_4].Mxe.SourceAddress = NodeAddress_4;
- SendOneMessage((J1939_MESSAGE *)&(TXQueue_4[TXHead_4]));
- TXHead_4++;
- if (TXHead_4 >= J1939_TX_QUEUE_SIZE)
- TXHead_4 = 0;
- TXQueueCount_4--;
- }
- /*配置了一些标识位,使能中断*/
- #if J1939_POLL_ECAN == J1939_FALSE
- Port_TXinterruptEnable();
- #endif
- }
- break;
- }
- default:
- {
- return RC_CANNOTTRANSMIT;
- break;
- }
- }
- return RC_SUCCESS;
- }
- #if J1939_TP_RX_TX
- /**
- * @note 发送TP.DT,参考J1939-21
- */
- void J1939_TP_DT_Packet_send(void)
- {
- J1939_MESSAGE _msg;
- j1939_uint16_t _packet_offset_p;
- j1939_int32_t _i = 0;
- _msg.Mxe.Priority = J1939_TP_DT_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_DT;
- _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
- _msg.Mxe.DataLength = 8;
- /*获取请求发送的数据包数量*/
- if (TP_TX_MSG.packets_request_num > 0)
- {
- TP_TX_MSG.packets_request_num--;
- /*获取数据偏移指针*/
- _packet_offset_p = (j1939_uint16_t)(TP_TX_MSG.packet_offset_p * 7u);
- /*加载数据包编号*/
- _msg.Mxe.Data[0] = (j1939_uint8_t)(1u + TP_TX_MSG.packet_offset_p);
- for (_i = 0; _i < 7; _i++)
- {
- _msg.Mxe.Data[_i + 1] = TP_TX_MSG.tp_tx_msg.data[_packet_offset_p + _i];
- }
- /*是否是最后一包数据消息*/
- if (TP_TX_MSG.packet_offset_p == (TP_TX_MSG.packets_total - 1u))
- {
- /*参数群是否能被填满,是否需要填充,*/
- if (_packet_offset_p > TP_TX_MSG.tp_tx_msg.byte_count - 7)
- {
- /*计算需要填充的数据数*/
- _i = TP_TX_MSG.tp_tx_msg.byte_count - _packet_offset_p - 7;
- for (; _i < 0; _i++)
- {
- /*我们默认J1939的参数群大小为8*/
- _msg.Mxe.Data[_i + 8] = J1939_RESERVED_BYTE;
- }
- }
- TP_TX_MSG.packets_request_num = 0;
- TP_TX_MSG.packet_offset_p = 0;
- TP_TX_MSG.time = J1939_TP_T3;
- /* 跳转步骤,等待结束确认或则重新发送数据请求*/
- TP_TX_MSG.state = J1939_TP_WAIT_ACK;
- }
- else
- {
- /*为下一个数据发送做准备*/
- TP_TX_MSG.packet_offset_p++;
- TP_TX_MSG.state = J1939_TP_TX_DT;
- }
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- }
- else
- {
- TP_TX_MSG.packets_request_num = 0;
- TP_TX_MSG.packet_offset_p = 0;
- TP_TX_MSG.time = J1939_TP_T3;
- TP_TX_MSG.state = J1939_TP_WAIT_ACK;
- }
- }
- /**
- * @note 发送TP。CM-RTS,16,23,4,255,PGN消息,参考J1939-21,
- */
- void J1939_CM_Start(void)
- {
- j1939_uint32_t pgn_num;
- J1939_MESSAGE _msg;
- pgn_num = TP_TX_MSG.tp_tx_msg.PGN;
- _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
- _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.Data[0] = J1939_RTS_CONTROL_BYTE;
- _msg.Mxe.Data[1] = (j1939_uint8_t)TP_TX_MSG.tp_tx_msg.byte_count;
- _msg.Mxe.Data[2] = (j1939_uint8_t)((TP_TX_MSG.tp_tx_msg.byte_count) >> 8);
- _msg.Mxe.Data[3] = TP_TX_MSG.packets_total;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- /*刷新等待时间,触发下一个步骤()*/
- TP_TX_MSG.time = J1939_TP_T3;
- TP_TX_MSG.state = J1939_TP_TX_CM_WAIT;
- }
- /**
- * @note 中断TP链接
- */
- void J1939_TP_TX_Abort(void)
- {
- J1939_MESSAGE _msg;
- j1939_uint32_t pgn_num;
- pgn_num = TP_TX_MSG.tp_tx_msg.PGN;
- _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
- _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.Data[0] = J1939_CONNABORT_CONTROL_BYTE;
- _msg.Mxe.Data[1] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- /*结束发送*/
- TP_TX_MSG.state = J1939_TX_DONE;
- }
- /**
- * @note 中断TP链接
- */
- void J1939_TP_RX_Abort(void)
- {
- J1939_MESSAGE _msg;
- j1939_uint32_t pgn_num;
- pgn_num = TP_RX_MSG.tp_rx_msg.PGN;
- _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
- _msg.Mxe.DestinationAddress = TP_RX_MSG.tp_rx_msg.SA;
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.Data[0] = J1939_CONNABORT_CONTROL_BYTE;
- _msg.Mxe.Data[1] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- /*结束发送*/
- TP_RX_MSG.state = J1939_RX_DONE;
- }
- /**
- * @note TP的计时器
- */
- j1939_uint8_t J1939_TP_TX_RefreshCMTimer(j1939_uint16_t dt_ms)
- {
- if ((J1939_TP_TX_CM_WAIT == TP_TX_MSG.state) || (J1939_TP_WAIT_ACK == TP_TX_MSG.state))
- {
- if (TP_TX_MSG.time > dt_ms)
- {
- TP_TX_MSG.time = TP_TX_MSG.time - dt_ms;
- return J1939_TP_TIMEOUT_NORMAL;
- }
- else
- {
- /*超时 */
- TP_TX_MSG.time = 0u;
- return J1939_TP_TIMEOUT_ABNORMAL;
- }
- }
- else
- {
- return J1939_TP_TIMEOUT_NORMAL;
- }
- }
- /**
- * @note TP的计时器
- */
- j1939_uint8_t J1939_TP_RX_RefreshCMTimer(j1939_uint16_t dt_ms)
- {
- if ((J1939_TP_RX_DATA_WAIT == TP_RX_MSG.state))
- {
- if (TP_RX_MSG.time > dt_ms)
- {
- TP_RX_MSG.time = TP_RX_MSG.time - dt_ms;
- return J1939_TP_TIMEOUT_NORMAL;
- }
- else
- {
- /*超时 */
- TP_RX_MSG.time = 0u;
- return J1939_TP_TIMEOUT_ABNORMAL;
- }
- }
- else
- {
- return J1939_TP_TIMEOUT_NORMAL;
- }
- }
- /**
- * @note 发送读取数据 TP.CM_CTS 和 EndofMsgAck消息。
- */
- void J1939_read_DT_Packet()
- {
- J1939_MESSAGE _msg;
- j1939_uint32_t pgn_num;
- pgn_num = TP_RX_MSG.tp_rx_msg.PGN;
- _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
- _msg.Mxe.DestinationAddress = TP_RX_MSG.tp_rx_msg.SA;
- _msg.Mxe.DataLength = 8;
- /*如果系统繁忙,保持链接但是不传送消息*/
- if (TP_RX_MSG.osbusy)
- {
- _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
- _msg.Mxe.Data[1] = 0;
- _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- return;
- }
- if (TP_RX_MSG.packets_total > TP_RX_MSG.packets_ok_num)
- {
- /*最后一次响应,如果不足2包数据*/
- if ((TP_RX_MSG.packets_total - TP_RX_MSG.packets_ok_num) == 1)
- {
- _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
- _msg.Mxe.Data[1] = 1;
- _msg.Mxe.Data[2] = TP_RX_MSG.packets_total;
- _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- TP_RX_MSG.state = J1939_TP_RX_DATA_WAIT;
- return;
- }
- _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
- _msg.Mxe.Data[1] = 2;
- _msg.Mxe.Data[2] = (TP_RX_MSG.packets_ok_num + 1);
- _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- TP_RX_MSG.state = J1939_TP_RX_DATA_WAIT;
- return;
- }
- else
- {
- /*发送传输正常结束消息,EndofMsgAck*/
- _msg.Mxe.Data[0] = J1939_EOMACK_CONTROL_BYTE;
- _msg.Mxe.Data[1] = (TP_RX_MSG.tp_rx_msg.byte_count & 0x00ff);
- _msg.Mxe.Data[2] = ((TP_RX_MSG.tp_rx_msg.byte_count >> 8) & 0x00ff);
- _msg.Mxe.Data[3] = TP_RX_MSG.packets_total;
- _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
- _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
- _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
- _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
- /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
- J1939_EnqueueMessage(&_msg, Can_Node);
- TP_RX_MSG.state = J1939_RX_DONE;
- return;
- }
- }
- /**
- * @note TP协议的心跳,为了满足在总线的计时准确,10ms轮询一次 J1939_TP_TX_RefreshCMTimer(10)\n
- 如果想要更高的分辨率,1ms轮询一次,但是要改下面计时函数 J1939_TP_TX_RefreshCMTimer(1)
- */
- void J1939_TP_Poll()
- {
- if (J1939_TP_Flags_t.state == J1939_TP_NULL || J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
- {
- return;
- }
- if (J1939_TP_Flags_t.state == J1939_TP_RX)
- {
- Can_Node = J1939_TP_Flags_t.TP_RX_CAN_NODE;
- switch (TP_RX_MSG.state)
- {
- case J1939_TP_RX_WAIT:;
- break;
- case J1939_TP_RX_READ_DATA:
- /*发送读取数据 TP.CM_CTS 和 EndofMsgAck消息*/
- J1939_read_DT_Packet();
- break;
- case J1939_TP_RX_DATA_WAIT:
- /*等待TP.DT帧传输的消息*/
- if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_RX_RefreshCMTimer(10))
- {
- /* 等待超时,发生连接异常,跳转到异常步骤 */
- TP_RX_MSG.state = J1939_TP_RX_ERROR;
- }
- break;
- case J1939_TP_RX_ERROR:
- J1939_TP_RX_Abort();
- J1939_TP_Flags_t.TP_RX_CAN_NODE = Select_CAN_NODE_Null;
- break;
- case J1939_RX_DONE:
- TP_RX_MSG.packets_ok_num = 0;
- TP_RX_MSG.packets_total = 0;
- TP_RX_MSG.time = J1939_TP_T3;
- TP_RX_MSG.state = J1939_TP_RX_WAIT;
- J1939_TP_Flags_t.state = J1939_TP_NULL;
- break;
- default:
- break;
- }
- return;
- }
- if (J1939_TP_Flags_t.state == J1939_TP_TX)
- {
- Can_Node = J1939_TP_Flags_t.TP_TX_CAN_NODE;
- switch (TP_TX_MSG.state)
- {
- case J1939_TP_TX_WAIT:
- /*没有要发送的数据*/
- break;
- case J1939_TP_TX_CM_START:
- /*发送TP.CM_RTS帧传输的消息(参考j1939-21)*/
- J1939_CM_Start();
- break;
- case J1939_TP_TX_CM_WAIT:
- /*等待TP.CM_CTS帧传输的消息*/
- if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_TX_RefreshCMTimer(10))
- {
- /* 等待超时,发生连接异常,跳转到异常步骤 */
- TP_TX_MSG.state = J1939_TP_TX_ERROR;
- }
- break;
- case J1939_TP_TX_DT:
- J1939_TP_DT_Packet_send();
- break;
- case J1939_TP_WAIT_ACK:
- /*等待TP.EndofMsgACK帧传输的消息*/
- if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_TX_RefreshCMTimer(10))
- {
- /* 等待超时,发生连接异常,跳转到异常步骤 */
- TP_TX_MSG.state = J1939_TP_TX_ERROR;
- }
- break;
- case J1939_TP_TX_ERROR:
- J1939_TP_TX_Abort();
- break;
- case J1939_TX_DONE:
- TP_TX_MSG.packets_request_num = 0;
- TP_TX_MSG.packet_offset_p = 0;
- TP_TX_MSG.time = J1939_TP_T3;
- TP_TX_MSG.state = J1939_TP_TX_WAIT;
- J1939_TP_Flags_t.state = J1939_TP_NULL;
- break;
- default:
- // 程序不会运行到这里来,可以增加一个调试输出
- break;
- }
- return;
- }
- }
- /**这是一个非阻塞io接口
- *
- * @param[in] PGN TP会话的参数群编号
- * @param[in] SA TP会话的目标地址
- * @param[in] *data TP会话的数据缓存地址
- * @param[in] data_num TP会话的数据大小
- * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
- * @return RC_SUCCESS 成功打开TP链接,开始进入发送流程
- * @return RC_CANNOTTRANSMIT 不能发送,因为TP协议已经建立虚拟链接,并且未断开
- * @note TP协议的发送函数
- */
- j1939_int8_t J1939_TP_TX_Message(j1939_uint32_t PGN, j1939_uint8_t DA, j1939_uint8_t *data, j1939_uint16_t data_num, CAN_NODE _Can_Node)
- {
- j1939_uint16_t _byte_count = 0;
- /*取得发送权限*/
- if (J1939_TP_Flags_t.state == J1939_TP_NULL)
- {
- J1939_TP_Flags_t.state = J1939_TP_TX;
- J1939_TP_Flags_t.TP_TX_CAN_NODE = _Can_Node;
- }
- else
- {
- return RC_CANNOTTRANSMIT; // 不能发送,因为TP协议已经建立虚拟链接,并且未断开
- }
- TP_TX_MSG.tp_tx_msg.PGN = PGN;
- TP_TX_MSG.tp_tx_msg.SA = DA;
- TP_TX_MSG.tp_tx_msg.byte_count = data_num;
- for (_byte_count = 0; _byte_count < data_num; _byte_count++)
- {
- TP_TX_MSG.tp_tx_msg.data[_byte_count] = data[_byte_count];
- }
- TP_TX_MSG.packet_offset_p = 0;
- TP_TX_MSG.packets_request_num = 0;
- TP_TX_MSG.packets_total = data_num / 7;
- if ((data_num % 7) != 0)
- {
- TP_TX_MSG.packets_total++;
- }
- TP_TX_MSG.time = J1939_TP_T3;
- // 触发开始CM_START
- TP_TX_MSG.state = J1939_TP_TX_CM_START;
- return RC_SUCCESS;
- }
- /**
- * @param[in] msg.data 读取数据的缓存
- * @param[in] msg.data_num 读取数据的缓存大小
- * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
- * @param[out] msg.SA 数据源地址
- * @param[out] msg.byte_count 数据大小
- * @param[out] msg.PGN 数据参数群编号
- * @return RC_CANNOTRECEIVE 不能接受,TP协议正在接受数据中
- * @return RC_SUCCESS 读取数据成功
- * @note TP的接受函数 , 接受缓存的大小必须大于接受数据的大小,建议初始化缓存大小用 J1939_TP_MAX_MESSAGE_LENGTH\n
- 请正确带入 缓存区的大小,参数错误程序运行有风险
- */
- j1939_int8_t J1939_TP_RX_Message(TP_RX_MESSAGE *msg, CAN_NODE _Can_Node)
- {
- j1939_uint16_t _a = 0;
- /*判断是否能读取数据*/
- if (J1939_TP_Flags_t.state == J1939_TP_NULL && TP_RX_MSG.tp_rx_msg.PGN != 0)
- {
- J1939_TP_Flags_t.state = J1939_TP_OSBUSY;
- }
- else
- {
- return RC_CANNOTRECEIVE; // 不能接受,TP协议正在接受数据中,或没有数据
- }
- // 判断是不是要读取那一路CAN数据
- if (_Can_Node != J1939_TP_Flags_t.TP_RX_CAN_NODE)
- {
- /*释放TP接管权限*/
- if (J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
- {
- J1939_TP_Flags_t.state = J1939_TP_NULL;
- }
- return RC_CANNOTRECEIVE;
- }
- // 判断数据缓存够不够
- if ((msg->data_num) < TP_RX_MSG.tp_rx_msg.byte_count)
- {
- return RC_CANNOTRECEIVE; // 不能接受,缓存区太小
- }
- /*获取数据*/
- for (_a = 0; _a < msg->data_num; _a++)
- {
- msg->data[_a] = TP_RX_MSG.tp_rx_msg.data[_a];
- }
- /*获取数据 源地址*/
- msg->SA = TP_RX_MSG.tp_rx_msg.SA;
- /*获取数据的大小*/
- msg->byte_count = TP_RX_MSG.tp_rx_msg.byte_count;
- /*获取数据PGN*/
- msg->PGN = TP_RX_MSG.tp_rx_msg.PGN;
- /*丢弃读取过的数据*/
- TP_RX_MSG.tp_rx_msg.byte_count = 0u;
- TP_RX_MSG.tp_rx_msg.PGN = 0;
- /*释放TP接管权限*/
- if (J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
- {
- J1939_TP_Flags_t.state = J1939_TP_NULL;
- }
- return RC_SUCCESS;
- }
- /**
- * @param[in] pgn 被请求的参数群
- * @param[in] DA 目标地址(DestinationAddress) 当DA = 0xff表示是全局请求
- * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
- * @note 请求(从全局范围或则特定目的地的)参数群,请求规则J1939-21的16-17页,有明确的说明
- */
- void J1939_Request_PGN(j1939_uint32_t pgn, j1939_uint8_t DA, CAN_NODE _Can_Node)
- {
- J1939_MESSAGE _msg;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.Priority = J1939_REQUEST_PRIORITY;
- _msg.Mxe.DestinationAddress = DA;
- _msg.Mxe.DataLength = 3;
- _msg.Mxe.PDUFormat = J1939_PF_REQUEST;
- _msg.Mxe.Data[0] = (j1939_uint8_t)(pgn & 0x000000FF);
- _msg.Mxe.Data[1] = (j1939_uint8_t)((pgn & 0x0000FF00) >> 8);
- _msg.Mxe.Data[2] = (j1939_uint8_t)((pgn & 0x00FF0000) >> 16);
- while (J1939_EnqueueMessage(&_msg, _Can_Node) != RC_SUCCESS)
- ;
- }
- /**
- * @param[in] data 需要发送数据的缓存
- * @param[in] dataLenght 发送数据的缓存大小
- * @param[in] PGN 需要发送数据的PGN(参数群编号)
- * @param[in] void (*dataUPFun)() 用于更新缓存data 的函数地址指针
- * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
- * @note 创建一个PGN 的 请求 对应的 响应\n 如果收到改请求则先运行 REQUEST_LIST.dataUPFun(),在将数据REQUEST_LIST.data发送出去
- * @warning 本函数只能被串行调用,(多线程)并行调用请在函数外加互斥操作
- */
- void J1939_Create_Response(j1939_uint8_t data[], j1939_uint16_t dataLenght, j1939_uint32_t PGN, void (*dataUPFun)(), CAN_NODE _Can_Node)
- {
- /*查找可用的链表项*/
- struct Request_List *_requestList = &REQUEST_LIST;
- while (J1939_NULL != _requestList->next)
- {
- _requestList = _requestList->next;
- }
- _requestList->next = (struct Request_List *)malloc(sizeof(struct Request_List));
- _requestList = _requestList->next;
- /*对新的链表项赋值*/
- _requestList->data = data;
- _requestList->lenght = dataLenght;
- _requestList->PGN = PGN;
- _requestList->update = dataUPFun;
- _requestList->Can_Node = _Can_Node;
- _requestList->next = J1939_NULL;
- }
- /**
- * @note 当收到一个PGN请求后,如果有REQUEST_LIST中有相应的PGN,则会自动发送REQUEST_LIST中的PGN。\n
- 如果没有则会发送一个NACK; 本函数的响应逻辑,参考J1939-21 17页表4
- */
- void J1939_Response(const j1939_uint32_t PGN)
- {
- J1939_MESSAGE _msg;
- /*查找可用的链表项*/
- struct Request_List *_requestList = &REQUEST_LIST;
- while ((PGN != _requestList->PGN) || (Can_Node != _requestList->Can_Node))
- {
- if (_requestList->next == J1939_NULL)
- {
- /*原文档规定 全局请求不被支持时不能响应 NACK*/
- if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
- {
- return;
- }
- if ((PGN & 0xFF00) >= 0xF000)
- {
- return;
- }
- /*没有相应的PGN响应被创建,向总线发送一个NACK*/
- _msg.Mxe.Priority = J1939_ACK_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
- _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.SourceAddress = J1939_Address;
- _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] = (PGN & 0x0000FF);
- _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
- _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
- SendOneMessage((J1939_MESSAGE *)&_msg);
- return;
- }
- else
- {
- _requestList = _requestList->next;
- }
- }
- /*调用dataUPFun()函数,主要用于参数群数据更新*/
- if (J1939_NULL != _requestList->update)
- {
- _requestList->update();
- }
- /*响应请求*/
- if (_requestList->lenght > 8)
- {
- /*回一个确认响应多帧(非广播多帧)*/
- if (RC_SUCCESS != J1939_TP_TX_Message(_requestList->PGN, OneMessage.Mxe.SourceAddress, _requestList->data, _requestList->lenght, Can_Node))
- {
- /*原文档规定 全局请求不被支持时不能响应 NACK*/
- if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
- {
- return;
- }
- /*如果长帧发送不成功*/
- _msg.Mxe.Priority = J1939_ACK_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
- _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.SourceAddress = J1939_Address;
- _msg.Mxe.Data[0] = J1939_ACCESS_DENIED_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] = (PGN & 0x0000FF);
- _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
- _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
- SendOneMessage((J1939_MESSAGE *)&_msg);
- return;
- }
- /*回一个确认响应*/
- _msg.Mxe.Priority = J1939_ACK_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
- /*原文档规定 全局请求响应到全局*/
- if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
- {
- _msg.Mxe.DestinationAddress = 0XFF;
- }
- else
- {
- _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
- }
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.SourceAddress = J1939_Address;
- _msg.Mxe.Data[0] = J1939_ACK_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] = (PGN & 0x0000FF);
- _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
- _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
- SendOneMessage((J1939_MESSAGE *)&_msg);
- }
- else
- {
- /*回一个确认响应*/
- _msg.Mxe.Priority = J1939_ACK_PRIORITY;
- _msg.Mxe.DataPage = 0;
- _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
- _msg.Mxe.SourceAddress = J1939_Address;
- /*原文档规定 全局请求响应到全局*/
- if ((OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS) || ((PGN & 0xFF00) >= 0xF000))
- {
- _msg.Mxe.DestinationAddress = 0XFF;
- }
- else
- {
- _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
- }
- _msg.Mxe.DataLength = 8;
- _msg.Mxe.SourceAddress = J1939_Address;
- _msg.Mxe.Data[0] = J1939_ACK_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] = (PGN & 0x0000FF);
- _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
- _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
- SendOneMessage((J1939_MESSAGE *)&_msg);
- /*回一个确认响应单帧*/
- _msg.Mxe.Priority = J1939_ACK_PRIORITY;
- _msg.Mxe.DataPage = (((_requestList->PGN) >> 16) & 0x1);
- _msg.Mxe.PDUFormat = ((_requestList->PGN) >> 8) & 0xFF;
- _msg.Mxe.SourceAddress = J1939_Address;
- /*原文档规定 全局请求响应到全局*/
- if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
- {
- _msg.Mxe.DestinationAddress = 0XFF;
- }
- else
- {
- _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
- }
- _msg.Mxe.DataLength = _requestList->lenght;
- {
- j1939_uint8_t _i = 0;
- for (_i = 0; _i < (_requestList->lenght); _i++)
- {
- _msg.Mxe.Data[_i] = _requestList->data[_i];
- }
- for (; _i < 8; _i++)
- {
- _msg.Mxe.Data[_i] = 0xFF;
- }
- }
- SendOneMessage((J1939_MESSAGE *)&_msg);
- }
- }
- #endif
|