J1939.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783
  1. /*********************************************************************
  2. *
  3. * J1939 Main Source Code
  4. *
  5. *********************************************************************
  6. *
  7. * 本程序是由XieTongXueFlyMe对现有的J1939协议文档分析,和对前辈的贡献总结,
  8. * 写出的一套开源的J1939驱动。
  9. * 本协议特点:
  10. * 1.易移植(不针对特定的CAN硬件,只要满足CAN2.0B即可)
  11. * 2.轻量级(可适应低端的MCU)
  12. * 3.支持多任务调用接口(可用于嵌入式系统)
  13. * 4.双模式(轮询或者中断,逻辑更加简单明了)
  14. * 5.不掉帧(数据采用收发列队缓存)
  15. *
  16. * 源代码下载:
  17. * https://github.com/XeiTongXueFlyMe/J1939
  18. * 源代码临时手册Web站点:
  19. * https://xeitongxueflyme.github.io/j1939doc.github.io/
  20. *
  21. * Version Date Description
  22. * -------------------------------------------------------------------
  23. * v1.0.0 2017/06/04 首个版本 Version 1 测试版发布
  24. * v1.0.1 2017/08/04 完善功能
  25. * v1.1.0 2017/11/22 Version 1 稳定发布版
  26. * v2.0.1 2017/11/24 Version 2 测试版发布
  27. * v2.0.2 2018/01/03 解决V2.0.1 遗留问题
  28. * v2.1.0 2018/01/20 Version 2 稳定发布版
  29. * Author Date changes
  30. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  31. *XeiTongXueFlyMe 7/06/04 首个版本
  32. *XeiTongXueFlyMe 7/08/04 增加对TP的支持
  33. *XeiTongXueFlyMe 7/11/24 增加对多路CAN硬件的收发,和报文处理
  34. *XeiTongXueFlyMe 7/11/29 增加请求和响应API
  35. *XeiTongXueFlyMe 7/12/07 重做TP接受API函数
  36. *XeiTongXueFlyMe 7/12/08 增加软件滤波器
  37. *XeiTongXueFlyMe 8/01/03 重做接受发送API,简化协议栈初始化调用逻辑
  38. **********************************************************************/
  39. #ifndef __J1939_SOURCE
  40. #define __J1939_SOURCE
  41. #include "queue.h"
  42. #include <stdint.h>
  43. #endif
  44. #include "J1939.H"
  45. #include "J1939_config.H"
  46. #define J1939_TRUE 1 /**< 代表函数正确返回*/
  47. #define J1939_FALSE 0 /**< 代表函数错误返回*/
  48. #define ADDRESS_CLAIM_TX 1 /**< 进入地址竞争发送处理模式*/
  49. #define ADDRESS_CLAIM_RX 2 /**< 进入地址竞争接受处理模式*/
  50. // 全局变量。
  51. /** 设备的标称符
  52. *
  53. * 我们需要在"J1939_config.H"中配置
  54. * @note 在初始化中赋值,赋值参考参考1939-81文档
  55. */
  56. j1939_uint8_t CA_Name[J1939_DATA_LENGTH];
  57. j1939_uint8_t CommandedAddress;
  58. j1939_uint8_t J1939_Address;
  59. J1939_FLAG J1939_Flags;
  60. J1939_MESSAGE OneMessage;
  61. CAN_NODE Can_Node;
  62. // 节点地址
  63. j1939_uint8_t NodeAddress_1;
  64. j1939_uint8_t NodeAddress_2;
  65. j1939_uint8_t NodeAddress_3;
  66. j1939_uint8_t NodeAddress_4;
  67. // 接受列队全局变量(CAN_NODE_1)
  68. j1939_uint8_t RXHead_1;
  69. j1939_uint8_t RXTail_1;
  70. j1939_uint8_t RXQueueCount_1;
  71. J1939_MESSAGE RXQueue_1[J1939_RX_QUEUE_SIZE];
  72. // 发送列队全局变量 (CAN_NODE_1)
  73. j1939_uint8_t TXHead_1;
  74. j1939_uint8_t TXTail_1;
  75. j1939_uint8_t TXQueueCount_1;
  76. J1939_MESSAGE TXQueue_1[J1939_TX_QUEUE_SIZE];
  77. // 接受列队全局变量(CAN_NODE_2)
  78. j1939_uint8_t RXHead_2;
  79. j1939_uint8_t RXTail_2;
  80. j1939_uint8_t RXQueueCount_2;
  81. J1939_MESSAGE RXQueue_2[J1939_RX_QUEUE_SIZE];
  82. // 发送列队全局变量 (CAN_NODE_2)
  83. j1939_uint8_t TXHead_2;
  84. j1939_uint8_t TXTail_2;
  85. j1939_uint8_t TXQueueCount_2;
  86. J1939_MESSAGE TXQueue_2[J1939_TX_QUEUE_SIZE];
  87. // 接受列队全局变量(CAN_NODE_3)
  88. j1939_uint8_t RXHead_3;
  89. j1939_uint8_t RXTail_3;
  90. j1939_uint8_t RXQueueCount_3;
  91. J1939_MESSAGE RXQueue_3[J1939_RX_QUEUE_SIZE];
  92. // 发送列队全局变量 (CAN_NODE_3)
  93. j1939_uint8_t TXHead_3;
  94. j1939_uint8_t TXTail_3;
  95. j1939_uint8_t TXQueueCount_3;
  96. J1939_MESSAGE TXQueue_3[J1939_TX_QUEUE_SIZE];
  97. // 接受列队全局变量(CAN_NODE_4)
  98. j1939_uint8_t RXHead_4;
  99. j1939_uint8_t RXTail_4;
  100. j1939_uint8_t RXQueueCount_4;
  101. J1939_MESSAGE RXQueue_4[J1939_RX_QUEUE_SIZE];
  102. // 发送列队全局变量 (CAN_NODE_4)
  103. j1939_uint8_t TXHead_4;
  104. j1939_uint8_t TXTail_4;
  105. j1939_uint8_t TXQueueCount_4;
  106. J1939_MESSAGE TXQueue_4[J1939_TX_QUEUE_SIZE];
  107. struct Request_List REQUEST_LIST;
  108. #if J1939_TP_RX_TX
  109. // TP协议全局变量
  110. J1939_TP_Flags J1939_TP_Flags_t;
  111. J1939_TRANSPORT_RX_INFO TP_RX_MSG;
  112. J1939_TRANSPORT_TX_INFO TP_TX_MSG;
  113. #endif // J1939_TP_RX_TX
  114. static void J1939_ReceiveMessages(void);
  115. static j1939_uint8_t J1939_TransmitMessages(void);
  116. /**
  117. * @note 硬件滤波器2 或 软件滤波器 滤波配置(设置PS段)\n
  118. */
  119. void SetAddressFilter(j1939_uint8_t Address)
  120. {
  121. /*软件滤波*/
  122. #if J1939SoftwareFilterEn == J1939_TRUE
  123. switch (Can_Node)
  124. {
  125. case Select_CAN_NODE_1:
  126. {
  127. NodeAddress_1 = Address;
  128. break;
  129. }
  130. case Select_CAN_NODE_2:
  131. {
  132. NodeAddress_2 = Address;
  133. break;
  134. }
  135. case Select_CAN_NODE_3:
  136. {
  137. NodeAddress_3 = Address;
  138. break;
  139. }
  140. case Select_CAN_NODE_4:
  141. {
  142. NodeAddress_4 = Address;
  143. break;
  144. }
  145. default:
  146. {
  147. break;
  148. }
  149. }
  150. #endif // J1939SoftwareFilterEn
  151. /*硬件滤波*/
  152. Port_SetAddressFilter(Address);
  153. }
  154. /**
  155. * @param[in] J1939_MESSAGE *
  156. * @note 发送*MsgPtr的信息,所有的数据字段(比如数据长度、优先级、和源地址)必须已经设置。\n
  157. */
  158. void SendOneMessage(J1939_MESSAGE *MsgPtr)
  159. {
  160. // 设置消息的最后部分,确保DataLength规范。(参考CAN B2.0)
  161. MsgPtr->Mxe.Res = 0; // 参考J1939的数据链路层(SAE J1939-21)
  162. MsgPtr->Mxe.RTR = 0;
  163. if (MsgPtr->Mxe.DataLength > 8)
  164. MsgPtr->Mxe.DataLength = 8;
  165. // 发送一帧消息,将 J1939_MESSAGE 中的所有消息加载道can模块自有的结构中
  166. Port_CAN_Transmit(MsgPtr);
  167. }
  168. /**
  169. * @param[in] MsgPtr 用户要出队的消息
  170. * @param[in] _Can_Node 要出队的CAN硬件编号
  171. * @return RC_SUCCESS 消息出队成功
  172. * @return RC_QUEUEEMPTY 没有消息返回
  173. * @note 从接受队列中读取一个信息到*MsgPtr。如果我们用的是中断,需要将中断失能,在获取接受队列数据时
  174. */
  175. j1939_uint8_t J1939_DequeueMessage(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
  176. {
  177. j1939_uint8_t _rc = RC_SUCCESS;
  178. //***************************关接受中断********************************
  179. #if J1939_POLL_ECAN == J1939_FALSE
  180. Port_RXinterruptDisable();
  181. #endif
  182. switch (_Can_Node)
  183. {
  184. case Select_CAN_NODE_1:
  185. {
  186. if (RXQueueCount_1 == 0)
  187. {
  188. _rc = RC_QUEUEEMPTY;
  189. }
  190. else
  191. {
  192. *MsgPtr = RXQueue_1[RXHead_1];
  193. RXHead_1++;
  194. if (RXHead_1 >= J1939_RX_QUEUE_SIZE)
  195. RXHead_1 = 0;
  196. RXQueueCount_1--;
  197. }
  198. break;
  199. }
  200. case Select_CAN_NODE_2:
  201. {
  202. if (RXQueueCount_2 == 0)
  203. {
  204. _rc = RC_QUEUEEMPTY;
  205. }
  206. else
  207. {
  208. *MsgPtr = RXQueue_2[RXHead_2];
  209. RXHead_2++;
  210. if (RXHead_2 >= J1939_RX_QUEUE_SIZE)
  211. RXHead_2 = 0;
  212. RXQueueCount_2--;
  213. }
  214. break;
  215. }
  216. case Select_CAN_NODE_3:
  217. {
  218. if (RXQueueCount_3 == 0)
  219. {
  220. _rc = RC_QUEUEEMPTY;
  221. }
  222. else
  223. {
  224. *MsgPtr = RXQueue_3[RXHead_3];
  225. RXHead_3++;
  226. if (RXHead_3 >= J1939_RX_QUEUE_SIZE)
  227. RXHead_3 = 0;
  228. RXQueueCount_3--;
  229. }
  230. break;
  231. }
  232. case Select_CAN_NODE_4:
  233. {
  234. if (RXQueueCount_4 == 0)
  235. {
  236. _rc = RC_QUEUEEMPTY;
  237. }
  238. else
  239. {
  240. *MsgPtr = RXQueue_4[RXHead_4];
  241. RXHead_4++;
  242. if (RXHead_4 >= J1939_RX_QUEUE_SIZE)
  243. RXHead_4 = 0;
  244. RXQueueCount_4--;
  245. }
  246. break;
  247. }
  248. default:
  249. {
  250. _rc = RC_CANNOTRECEIVE;
  251. break;
  252. }
  253. }
  254. //***************************开接受中断********************************
  255. #if J1939_POLL_ECAN == J1939_FALSE
  256. Port_RXinterruptEnable();
  257. #endif
  258. return _rc;
  259. }
  260. /**
  261. * @param[in] MsgPtr 存储读取消息的缓存
  262. * @param[in] _Can_Node 读取消息的CAN硬件编号(从哪一路CAN读取数据)
  263. * @return RC_SUCCESS 读取消息成功,
  264. * @return RC_QUEUEEMPTY 读取消息不成功,没有消息。
  265. * @note 从接受队列中读取一个信息到*MsgPtr。
  266. */
  267. j1939_uint8_t J1939_Read_Message(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
  268. {
  269. return J1939_DequeueMessage(MsgPtr, _Can_Node);
  270. }
  271. /**
  272. * @param[in] MsgPtr 用户要入队的消息
  273. * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
  274. * @return RC_SUCCESS 消息入队成功
  275. * @return RC_QUEUEFULL 发送列队满,消息入队失败
  276. * @return RC_CANNOTTRANSMIT 系统目前不能发送消息
  277. * @note 这段程序,将*MsgPtr放入发送消息列队中\n
  278. 如果信息不能入队或者发送,将有一个相应的返回提示,\n
  279. 如果发送中断被设置(可用),当消息列队后,发送中断被使能
  280. */
  281. j1939_uint8_t J1939_EnqueueMessage(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
  282. {
  283. j1939_uint8_t _rc = RC_SUCCESS;
  284. #if J1939_POLL_ECAN == J1939_FALSE
  285. Port_TXinterruptDisable();
  286. #endif
  287. if (0)
  288. _rc = RC_CANNOTTRANSMIT;
  289. else
  290. {
  291. switch (_Can_Node)
  292. {
  293. case Select_CAN_NODE_1:
  294. {
  295. if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
  296. (TXQueueCount_1 < J1939_TX_QUEUE_SIZE))
  297. {
  298. if (TXQueueCount_1 < J1939_TX_QUEUE_SIZE)
  299. {
  300. TXQueueCount_1++;
  301. TXTail_1++;
  302. if (TXTail_1 >= J1939_TX_QUEUE_SIZE)
  303. TXTail_1 = 0;
  304. }
  305. else
  306. {
  307. J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
  308. }
  309. TXQueue_1[TXTail_1] = *MsgPtr;
  310. }
  311. else
  312. _rc = RC_QUEUEFULL;
  313. break;
  314. }
  315. case Select_CAN_NODE_2:
  316. {
  317. if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
  318. (TXQueueCount_2 < J1939_TX_QUEUE_SIZE))
  319. {
  320. if (TXQueueCount_2 < J1939_TX_QUEUE_SIZE)
  321. {
  322. TXQueueCount_2++;
  323. TXTail_2++;
  324. if (TXTail_2 >= J1939_TX_QUEUE_SIZE)
  325. TXTail_2 = 0;
  326. }
  327. else
  328. {
  329. J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
  330. }
  331. TXQueue_2[TXTail_2] = *MsgPtr;
  332. }
  333. else
  334. _rc = RC_QUEUEFULL;
  335. break;
  336. }
  337. case Select_CAN_NODE_3:
  338. {
  339. if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
  340. (TXQueueCount_3 < J1939_TX_QUEUE_SIZE))
  341. {
  342. if (TXQueueCount_3 < J1939_TX_QUEUE_SIZE)
  343. {
  344. TXQueueCount_3++;
  345. TXTail_3++;
  346. if (TXTail_3 >= J1939_TX_QUEUE_SIZE)
  347. TXTail_3 = 0;
  348. }
  349. else
  350. {
  351. J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
  352. }
  353. TXQueue_3[TXTail_3] = *MsgPtr;
  354. }
  355. else
  356. _rc = RC_QUEUEFULL;
  357. break;
  358. }
  359. case Select_CAN_NODE_4:
  360. {
  361. if ((J1939_OVERWRITE_TX_QUEUE == J1939_TRUE) ||
  362. (TXQueueCount_4 < J1939_TX_QUEUE_SIZE))
  363. {
  364. if (TXQueueCount_4 < J1939_TX_QUEUE_SIZE)
  365. {
  366. TXQueueCount_4++;
  367. TXTail_4++;
  368. if (TXTail_4 >= J1939_TX_QUEUE_SIZE)
  369. TXTail_4 = 0;
  370. }
  371. else
  372. {
  373. J1939_Flags.TransmitMessagesdCover = 1; // 发送数据被覆盖,上一帧数据被覆盖
  374. }
  375. TXQueue_4[TXTail_4] = *MsgPtr;
  376. }
  377. else
  378. _rc = RC_QUEUEFULL;
  379. break;
  380. }
  381. default:
  382. {
  383. break;
  384. }
  385. }
  386. }
  387. #if J1939_POLL_ECAN == J1939_FALSE
  388. Port_TXinterruptEnable();
  389. // 触发发送中断
  390. Port_TXinterruptOk();
  391. #endif
  392. return _rc;
  393. }
  394. /**
  395. * @param[in] MsgPtr 存储发送消息的缓存
  396. * @param[in] _Can_Node 发送消息的CAN硬件编号(从哪一路CAN发送数据)
  397. * @return RC_SUCCESS 发送消息成功
  398. * @return RC_QUEUEFULL 发送消息不成功,发送列队满,消息入队失败
  399. * @return RC_CANNOTTRANSMIT 发送消息不成功,系统目前不能发送消息
  400. * @note 如果信息不能入队或者发送,将有一个相应的返回提示,\n
  401. */
  402. j1939_uint8_t J1939_Send_Message(J1939_MESSAGE *MsgPtr, CAN_NODE _Can_Node)
  403. {
  404. return J1939_EnqueueMessage(MsgPtr, _Can_Node);
  405. }
  406. void j1939_msg_push_queue(p_pdu_tag rec_msg)
  407. {
  408. J1939_MESSAGE _msg;
  409. _msg.Mxe.DataPage = rec_msg->id.b.dp;
  410. _msg.Mxe.Priority = rec_msg->id.b.p;
  411. _msg.Mxe.PDUFormat = rec_msg->id.b.pf;
  412. _msg.Mxe.PDUSpecific = rec_msg->id.b.ps;
  413. _msg.Mxe.SourceAddress = rec_msg->id.b.sa;
  414. _msg.Mxe.DataLength = rec_msg->reg.dlc;
  415. _msg.Mxe.PGN = 0;
  416. for (uint8_t index = 0; index < rec_msg->reg.dlc; index++)
  417. {
  418. _msg.Mxe.Data[index] = rec_msg->data.u8_buf[index];
  419. }
  420. // en_queue(&j1939_rx_queue, _msg);
  421. }
  422. /**
  423. *
  424. * @note 这段代码在系统初始化中被调用,(放在CAN设备初始化之后)\n
  425. 初始化J1939全局变量\n
  426. */
  427. void J1939_Initialization()
  428. {
  429. /*初始化全局变量*/
  430. J1939_Flags.FlagVal = 0; // 没有声明地址,其他的标识位将被设置为0(复位)
  431. /*初始化接受和发送列队*/
  432. TXHead_1 = 0;
  433. TXHead_2 = 0;
  434. TXHead_3 = 0;
  435. TXHead_4 = 0;
  436. TXTail_1 = 0xFF;
  437. TXTail_2 = 0xFF;
  438. TXTail_3 = 0xFF;
  439. TXTail_4 = 0xFF;
  440. RXHead_1 = 0;
  441. RXHead_2 = 0;
  442. RXHead_3 = 0;
  443. RXHead_4 = 0;
  444. RXTail_1 = 0xFF;
  445. RXTail_2 = 0xFF;
  446. RXTail_3 = 0xFF;
  447. RXTail_4 = 0xFF;
  448. TXQueueCount_1 = 0;
  449. TXQueueCount_2 = 0;
  450. TXQueueCount_3 = 0;
  451. TXQueueCount_4 = 0;
  452. RXQueueCount_1 = 0;
  453. RXQueueCount_2 = 0;
  454. RXQueueCount_3 = 0;
  455. RXQueueCount_4 = 0;
  456. /*初始化节点地址*/
  457. NodeAddress_1 = J1939_STARTING_ADDRESS_1;
  458. NodeAddress_2 = J1939_STARTING_ADDRESS_2;
  459. NodeAddress_3 = J1939_STARTING_ADDRESS_3;
  460. NodeAddress_4 = J1939_STARTING_ADDRESS_4;
  461. /*初始化CAN节点的选择*/
  462. Can_Node = Select_CAN_NODE_1;
  463. /*初始化请求链表*/
  464. REQUEST_LIST.PGN = 0;
  465. REQUEST_LIST.data = J1939_NULL;
  466. REQUEST_LIST.update = J1939_NULL;
  467. REQUEST_LIST.lenght = 0;
  468. REQUEST_LIST.Can_Node = Select_CAN_NODE_Null;
  469. REQUEST_LIST.next = J1939_NULL;
  470. /*将TP协议置为空闲*/
  471. #if J1939_TP_RX_TX
  472. J1939_TP_Flags_t.state = J1939_TP_NULL;
  473. J1939_TP_Flags_t.TP_RX_CAN_NODE = Select_CAN_NODE_Null;
  474. J1939_TP_Flags_t.TP_TX_CAN_NODE = Select_CAN_NODE_Null;
  475. TP_TX_MSG.packets_request_num = 0;
  476. TP_TX_MSG.packets_total = 0;
  477. TP_TX_MSG.packet_offset_p = 0;
  478. TP_TX_MSG.time = 0;
  479. TP_TX_MSG.state = J1939_TP_TX_WAIT;
  480. TP_RX_MSG.packets_ok_num = 0;
  481. TP_RX_MSG.packets_total = 0;
  482. TP_RX_MSG.time = 0;
  483. TP_RX_MSG.state = J1939_TP_RX_WAIT;
  484. #endif
  485. }
  486. /**
  487. * @note 这个函数被调用,当设备产生CAN中断(可能是接受中断,也可能是发送中断)\n
  488. 首先我们要清除中断标识位\n
  489. 然后调用接受或者发送函数。
  490. */
  491. #if J1939_POLL_ECAN == J1939_FALSE
  492. void J1939_ISR(void)
  493. {
  494. // 判断相关标识位,是接受还是发送
  495. // 清除标识位
  496. Port_CAN_identifier_clc();
  497. // 调用相关的处理函数
  498. J1939_ReceiveMessages();
  499. J1939_TransmitMessages();
  500. #if J1939_TP_RX_TX
  501. J1939_TP_Poll();
  502. #endif // J1939_TP_RX_TX
  503. // 可能存在因为错误产生中断,直接清除相关的标识位
  504. }
  505. #endif
  506. /**
  507. * @param[in] ElapsedTime 一个大概的毫秒数,通常设置 5 或 3
  508. * @note 如果我们采用轮询的方式获取信息,这个函数每几个毫秒将被调用一次。\n
  509. 不断的接受消息和发送消息从消息队列中\n
  510. 此外,如果我们正在等待一个地址竞争反应。\n
  511. 如果超时,我们只接收特定的消息(目标地址 = J1939_Address)\n
  512. 如果设备使用中断,此函数被调用,在调用J1939_Initialization()函数后,因为\n
  513. J1939_Initialization()可能初始化WaitingForAddressClaimContention标识位为1.\n
  514. 如果接受到命令地址消息,这个函数也必须被调用,以防万一总线要求我们改变地址\n
  515. 如果使用中断模式,本程序将不会处理接受和发送消息,只处理地址竞争超时。\n
  516. */
  517. // 声明TP轮询函数
  518. void J1939_TP_Poll();
  519. void J1939_Poll()
  520. {
  521. // 我们必须调用J1939_ReceiveMessages接受函数,在时间被重置为0之前。
  522. #if J1939_POLL_ECAN == J1939_TRUE
  523. Can_Node = Select_CAN_NODE_1;
  524. J1939_Address = NodeAddress_1;
  525. J1939_ReceiveMessages();
  526. J1939_TransmitMessages();
  527. Can_Node = Select_CAN_NODE_2;
  528. J1939_Address = NodeAddress_2;
  529. J1939_ReceiveMessages();
  530. J1939_TransmitMessages();
  531. Can_Node = Select_CAN_NODE_3;
  532. J1939_Address = NodeAddress_3;
  533. J1939_ReceiveMessages();
  534. J1939_TransmitMessages();
  535. Can_Node = Select_CAN_NODE_4;
  536. J1939_Address = NodeAddress_4;
  537. J1939_ReceiveMessages();
  538. J1939_TransmitMessages();
  539. #if J1939_TP_RX_TX
  540. J1939_TP_Poll();
  541. #endif // J1939_TP_RX_TX
  542. #endif // J1939_POLL_ECAN == J1939_TRUE
  543. }
  544. void J1939_Response(const j1939_uint32_t PGN);
  545. #if J1939SoftwareFilterEn == J1939_TRUE
  546. /**
  547. * @return RC_SUCCESS 消息是可以接受
  548. * @return RC_CANNOTTRANSMIT 消息是不可以接受
  549. * @note 软件滤波器\n
  550. * @note 基于SAE J1939协议,我们需要CAN控制器提供至少3个滤波器给J1939协议代码。三个滤波器分别配置如下:
  551. 1. 设置滤波器0,只接受广播信息(PF = 240 -255)。
  552. 2. 设置设置滤波器1,2只接受全局地址(J1939_GLOBAL_ADDRESS)
  553. 3. 随着程序的运行,将改变滤波器2,来适应程序逻辑。
  554. */
  555. j1939_uint8_t J1939_Messages_Filter(J1939_MESSAGE *MsgPtr)
  556. {
  557. /*滤波器0*/
  558. if ((MsgPtr->Mxe.PDUFormat) >= 240)
  559. {
  560. return RC_SUCCESS;
  561. }
  562. /*滤波器1*/
  563. if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS))
  564. {
  565. return RC_SUCCESS;
  566. }
  567. /*滤波器2*/
  568. switch (Can_Node)
  569. {
  570. case Select_CAN_NODE_1:
  571. {
  572. if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_1))
  573. {
  574. return RC_SUCCESS;
  575. }
  576. break;
  577. }
  578. case Select_CAN_NODE_2:
  579. {
  580. if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_2))
  581. {
  582. return RC_SUCCESS;
  583. }
  584. break;
  585. }
  586. case Select_CAN_NODE_3:
  587. {
  588. if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_3))
  589. {
  590. return RC_SUCCESS;
  591. }
  592. break;
  593. }
  594. case Select_CAN_NODE_4:
  595. {
  596. if (((MsgPtr->Mxe.PDUFormat) < 240) && (MsgPtr->Mxe.PDUSpecific == NodeAddress_4))
  597. {
  598. return RC_SUCCESS;
  599. }
  600. break;
  601. }
  602. default:
  603. {
  604. break;
  605. }
  606. }
  607. return RC_CANNOTTRANSMIT;
  608. }
  609. #endif // J1939SoftwareFilterEn
  610. /**
  611. * @note 这段程序被调用,当CAN收发器接受数据(中断 或者 轮询)。\n
  612. 如果一个信息被接受, 它将被调用\n
  613. 如果信息是一个网络管理信息或长帧传输(TP),接受的信息将被加工处理,在这个函数中。\n
  614. 否则, 信息将放置在用户的接收队列。\n
  615. 注意:在这段程序运行期间中断是失能的。\n
  616. */
  617. void J1939_ReceiveMessages(void)
  618. {
  619. #if J1939_TP_RX_TX
  620. j1939_uint32_t _pgn = 0;
  621. #endif // J1939_TP_RX_TX
  622. /*从接收缓存中读取信息到OneMessage中,OneMessage是一个全局变量*/
  623. /*Port_CAN_Receive函数读取到数据返回1,没有数据则返回0*/
  624. if (Port_CAN_Receive(&OneMessage))
  625. {
  626. #if J1939SoftwareFilterEn == J1939_TRUE
  627. if (J1939_Messages_Filter(&OneMessage) != RC_SUCCESS)
  628. {
  629. return;
  630. }
  631. #endif // J1939SoftwareFilterEn
  632. switch (OneMessage.Mxe.PDUFormat)
  633. {
  634. #if J1939_TP_RX_TX
  635. case J1939_PF_TP_CM: // 参考J1939-21 TP多帧传输协议
  636. _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);
  637. if ((J1939_TP_Flags_t.state == J1939_TP_NULL) && (TP_RX_MSG.state == J1939_TP_RX_WAIT))
  638. {
  639. if (OneMessage.Mxe.Data[0] == 16)
  640. {
  641. J1939_TP_Flags_t.state = J1939_TP_RX;
  642. J1939_TP_Flags_t.TP_RX_CAN_NODE = Can_Node;
  643. TP_RX_MSG.tp_rx_msg.SA = OneMessage.Mxe.SourceAddress;
  644. 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);
  645. /*如果系统繁忙*/
  646. if (TP_RX_MSG.osbusy)
  647. {
  648. TP_RX_MSG.state = J1939_TP_RX_ERROR;
  649. break;
  650. }
  651. /*判断是否有足够的内存接收数据,如果没有直接,断开连接*/
  652. if (((j1939_uint32_t)((OneMessage.Mxe.Data[2] << 8) & 0xFF00) + (j1939_uint32_t)((OneMessage.Mxe.Data[1]) & 0xFF)) > J1939_TP_MAX_MESSAGE_LENGTH)
  653. {
  654. TP_RX_MSG.state = J1939_TP_RX_ERROR;
  655. break;
  656. }
  657. 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));
  658. TP_RX_MSG.packets_total = OneMessage.Mxe.Data[3];
  659. TP_RX_MSG.time = J1939_TP_T2;
  660. TP_RX_MSG.state = J1939_TP_RX_READ_DATA;
  661. break;
  662. }
  663. goto PutInReceiveQueue;
  664. break;
  665. }
  666. if (J1939_TP_Flags_t.state == J1939_TP_TX)
  667. {
  668. /*校验PGN*/
  669. if (_pgn == TP_TX_MSG.tp_tx_msg.PGN)
  670. {
  671. switch (OneMessage.Mxe.Data[0])
  672. {
  673. case J1939_RTS_CONTROL_BYTE:
  674. /* 程序运行到这里,说明已经与网络中设备1建立虚拟链接(作为发送端),但是收到设备2的链接请求,并且同一个PGN消息请求*/
  675. /* 根据J1939-21数据链路层的规定,我们要保持原有的链接,不做任何事,设备2会应为超时自动放弃链接*/
  676. break;
  677. case J1939_CTS_CONTROL_BYTE:
  678. if ((J1939_TP_TX_CM_WAIT == TP_TX_MSG.state) || (J1939_TP_WAIT_ACK == TP_TX_MSG.state))
  679. {
  680. /* 发送等待保持 */
  681. if (0x00u == OneMessage.Mxe.Data[1])
  682. {
  683. /* 刷新等待计数器 */
  684. TP_TX_MSG.time = J1939_TP_T4;
  685. }
  686. else
  687. {
  688. if ((OneMessage.Mxe.Data[2] + OneMessage.Mxe.Data[1]) > (TP_TX_MSG.packets_total + 1))
  689. {
  690. /*请求超出数据包范围*/
  691. TP_TX_MSG.state = J1939_TP_TX_ERROR;
  692. }
  693. else
  694. { /* response parameter OK */
  695. TP_TX_MSG.packets_request_num = OneMessage.Mxe.Data[1];
  696. TP_TX_MSG.packet_offset_p = (j1939_uint8_t)(OneMessage.Mxe.Data[2] - 1);
  697. TP_TX_MSG.state = J1939_TP_TX_DT;
  698. }
  699. }
  700. }
  701. break;
  702. case J1939_EOMACK_CONTROL_BYTE:
  703. if (J1939_TP_WAIT_ACK == TP_TX_MSG.state)
  704. {
  705. TP_TX_MSG.state = J1939_TX_DONE;
  706. }
  707. // 这里可以增加一个对数据的校验
  708. break;
  709. case J1939_CONNABORT_CONTROL_BYTE:
  710. // 收到一个放弃连接,什么都不做,协议会在一段延时时间后主动放弃链接
  711. break;
  712. default:
  713. break;
  714. }
  715. }
  716. }
  717. goto PutInReceiveQueue;
  718. break;
  719. #endif // J1939_TP_RX_TX
  720. #if J1939_TP_RX_TX
  721. case J1939_PF_DT:
  722. if ((TP_RX_MSG.state == J1939_TP_RX_DATA_WAIT) && (TP_RX_MSG.tp_rx_msg.SA == OneMessage.Mxe.SourceAddress))
  723. {
  724. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u] = OneMessage.Mxe.Data[1];
  725. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 1] = OneMessage.Mxe.Data[2];
  726. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 2] = OneMessage.Mxe.Data[3];
  727. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 3] = OneMessage.Mxe.Data[4];
  728. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 4] = OneMessage.Mxe.Data[5];
  729. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 5] = OneMessage.Mxe.Data[6];
  730. TP_RX_MSG.tp_rx_msg.data[(OneMessage.Mxe.Data[0] - 1) * 7u + 6] = OneMessage.Mxe.Data[7];
  731. /*特殊处理重新接受已接受过的数据包*/
  732. if ((OneMessage.Mxe.Data[0]) > TP_RX_MSG.packets_ok_num)
  733. {
  734. TP_RX_MSG.packets_ok_num++;
  735. }
  736. TP_RX_MSG.time = J1939_TP_T1;
  737. /*判断是否收到偶数个数据包或者读取到最后一个数据包*/
  738. if ((TP_RX_MSG.packets_ok_num % 2 == 0) || (TP_RX_MSG.packets_ok_num == TP_RX_MSG.packets_total))
  739. {
  740. TP_RX_MSG.state = J1939_TP_RX_READ_DATA;
  741. break;
  742. }
  743. break;
  744. }
  745. // 程序不可能运行到这,但是我们不能放弃接受的数据包
  746. goto PutInReceiveQueue;
  747. #endif // J1939_TP_RX_TX
  748. case J1939_PF_REQUEST:
  749. /*用OneMessage.Mxe.PGN 来存下被请求的PGN*/
  750. if (OneMessage.Mxe.Data[1] < 240)
  751. {
  752. OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Mxe.Data[2] << 16) & 0x030000) + (j1939_uint32_t)((OneMessage.Mxe.Data[1] << 8) & 0xFF00) + 0x00;
  753. }
  754. else
  755. {
  756. 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);
  757. }
  758. J1939_Response(OneMessage.Mxe.PGN);
  759. break;
  760. default:
  761. PutInReceiveQueue:
  762. {
  763. /*
  764. if(OneMessage.Mxe.PDUFormat < 240){
  765. OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Array[0]<<16)&0x030000)
  766. +(j1939_uint32_t)((OneMessage.Array[1]<<8)&0xFF00)
  767. +0x00;
  768. }else{
  769. OneMessage.Mxe.PGN = (j1939_uint32_t)((OneMessage.Array[0]<<16)&0x030000)
  770. +(j1939_uint32_t)((OneMessage.Array[1]<<8)&0xFF00)
  771. +(j1939_uint32_t)((OneMessage.Array[2])&0xFF);
  772. }
  773. */
  774. if (OneMessage.Mxe.PDUFormat < 240)
  775. {
  776. OneMessage.Mxe.PGN = (OneMessage.Mxe.Res << 17) + (OneMessage.Mxe.DataPage << 16) + (OneMessage.Mxe.PDUFormat << 8);
  777. }
  778. else
  779. {
  780. OneMessage.Mxe.PGN = (OneMessage.Mxe.Res << 17) + (OneMessage.Mxe.DataPage << 16) + (OneMessage.Mxe.PDUFormat << 8) + OneMessage.Mxe.PDUSpecific;
  781. }
  782. switch (Can_Node)
  783. {
  784. case Select_CAN_NODE_1:
  785. {
  786. if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
  787. (RXQueueCount_1 < J1939_RX_QUEUE_SIZE))
  788. {
  789. if (RXQueueCount_1 < J1939_RX_QUEUE_SIZE)
  790. {
  791. RXQueueCount_1++;
  792. RXTail_1++;
  793. if (RXTail_1 >= J1939_RX_QUEUE_SIZE)
  794. RXTail_1 = 0;
  795. }
  796. else
  797. {
  798. J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
  799. J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_1;
  800. }
  801. RXQueue_1[RXTail_1] = OneMessage;
  802. }
  803. else
  804. J1939_Flags.ReceivedMessagesDropped = 1; // 产生数据溢出
  805. break;
  806. }
  807. case Select_CAN_NODE_2:
  808. {
  809. if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
  810. (RXQueueCount_2 < J1939_RX_QUEUE_SIZE))
  811. {
  812. if (RXQueueCount_2 < J1939_RX_QUEUE_SIZE)
  813. {
  814. RXQueueCount_2++;
  815. RXTail_2++;
  816. if (RXTail_2 >= J1939_RX_QUEUE_SIZE)
  817. RXTail_2 = 0;
  818. }
  819. else
  820. {
  821. J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
  822. J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_2;
  823. }
  824. RXQueue_2[RXTail_2] = OneMessage;
  825. }
  826. else
  827. J1939_Flags.ReceivedMessagesDropped = 1;
  828. break;
  829. }
  830. case Select_CAN_NODE_3:
  831. {
  832. if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
  833. (RXQueueCount_3 < J1939_RX_QUEUE_SIZE))
  834. {
  835. if (RXQueueCount_3 < J1939_RX_QUEUE_SIZE)
  836. {
  837. RXQueueCount_3++;
  838. RXTail_3++;
  839. if (RXTail_3 >= J1939_RX_QUEUE_SIZE)
  840. RXTail_3 = 0;
  841. }
  842. else
  843. {
  844. J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
  845. J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_3;
  846. }
  847. RXQueue_3[RXTail_3] = OneMessage;
  848. }
  849. else
  850. J1939_Flags.ReceivedMessagesDropped = 1;
  851. break;
  852. }
  853. case Select_CAN_NODE_4:
  854. {
  855. if ((J1939_OVERWRITE_RX_QUEUE == J1939_TRUE) ||
  856. (RXQueueCount_4 < J1939_RX_QUEUE_SIZE))
  857. {
  858. if (RXQueueCount_4 < J1939_RX_QUEUE_SIZE)
  859. {
  860. RXQueueCount_4++;
  861. RXTail_4++;
  862. if (RXTail_4 >= J1939_RX_QUEUE_SIZE)
  863. RXTail_4 = 0;
  864. }
  865. else
  866. {
  867. J1939_Flags.ReceivedMessagesdCover = 1; // 产生数据覆盖
  868. J1939_Flags.ReceivedMessagesdCoverOrDroppedNode = Select_CAN_NODE_4;
  869. }
  870. RXQueue_4[RXTail_4] = OneMessage;
  871. }
  872. else
  873. J1939_Flags.ReceivedMessagesDropped = 1;
  874. break;
  875. }
  876. default:
  877. {
  878. break;
  879. }
  880. }
  881. }
  882. }
  883. }
  884. }
  885. /**
  886. * @return RC_SUCCESS 信息发送成功
  887. * @return RC_CANNOTTRANSMIT 系统没有发送消息,没有要发送的消息,或错误的CAN设备
  888. * @note 调用这个函数后,如果发送消息列队中有消息就位,则会发送消息 ,如果不能发送消息,相关的错误代码将返回。\n
  889. 程序运行期间,中断是被失能的。
  890. */
  891. static j1939_uint8_t J1939_TransmitMessages()
  892. {
  893. switch (Can_Node)
  894. {
  895. case Select_CAN_NODE_1:
  896. {
  897. if (TXQueueCount_1 == 0)
  898. {
  899. // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
  900. #if J1939_POLL_ECAN == J1939_FALSE
  901. Port_TXinterruptEnable();
  902. #endif
  903. return RC_CANNOTTRANSMIT;
  904. }
  905. else
  906. {
  907. while (TXQueueCount_1 > 0)
  908. {
  909. /*确保上次数据发送成功*/
  910. /**************可增加一个判断函数**************************/
  911. TXQueue_1[TXHead_1].Mxe.SourceAddress = NodeAddress_1;
  912. SendOneMessage((J1939_MESSAGE *)&(TXQueue_1[TXHead_1]));
  913. TXHead_1++;
  914. if (TXHead_1 >= J1939_TX_QUEUE_SIZE)
  915. TXHead_1 = 0;
  916. TXQueueCount_1--;
  917. }
  918. /*配置了一些标识位,使能中断*/
  919. #if J1939_POLL_ECAN == J1939_FALSE
  920. Port_TXinterruptEnable();
  921. #endif
  922. }
  923. break;
  924. }
  925. case Select_CAN_NODE_2:
  926. {
  927. if (TXQueueCount_2 == 0)
  928. {
  929. // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
  930. #if J1939_POLL_ECAN == J1939_FALSE
  931. Port_TXinterruptEnable();
  932. #endif
  933. return RC_CANNOTTRANSMIT;
  934. }
  935. else
  936. {
  937. while (TXQueueCount_2 > 0)
  938. {
  939. /*确保上次数据发送成功*/
  940. /**************可增加一个判断函数**************************/
  941. TXQueue_2[TXHead_2].Mxe.SourceAddress = NodeAddress_2;
  942. SendOneMessage((J1939_MESSAGE *)&(TXQueue_2[TXHead_2]));
  943. TXHead_2++;
  944. if (TXHead_2 >= J1939_TX_QUEUE_SIZE)
  945. TXHead_2 = 0;
  946. TXQueueCount_2--;
  947. }
  948. /*配置了一些标识位,使能中断*/
  949. #if J1939_POLL_ECAN == J1939_FALSE
  950. Port_TXinterruptEnable();
  951. #endif
  952. }
  953. break;
  954. }
  955. case Select_CAN_NODE_3:
  956. {
  957. if (TXQueueCount_3 == 0)
  958. {
  959. // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
  960. #if J1939_POLL_ECAN == J1939_FALSE
  961. Port_TXinterruptEnable();
  962. #endif
  963. return RC_CANNOTTRANSMIT;
  964. }
  965. else
  966. {
  967. while (TXQueueCount_3 > 0)
  968. {
  969. /*确保上次数据发送成功*/
  970. /**************可增加一个判断函数**************************/
  971. TXQueue_3[TXHead_3].Mxe.SourceAddress = NodeAddress_3;
  972. SendOneMessage((J1939_MESSAGE *)&(TXQueue_3[TXHead_3]));
  973. TXHead_3++;
  974. if (TXHead_3 >= J1939_TX_QUEUE_SIZE)
  975. TXHead_3 = 0;
  976. TXQueueCount_3--;
  977. }
  978. /*配置了一些标识位,使能中断*/
  979. #if J1939_POLL_ECAN == J1939_FALSE
  980. Port_TXinterruptEnable();
  981. #endif
  982. }
  983. break;
  984. }
  985. case Select_CAN_NODE_4:
  986. {
  987. if (TXQueueCount_4 == 0)
  988. {
  989. // 如果没有要发送的消息从发送消息列队中,恢复中断(清空发送标识位)
  990. #if J1939_POLL_ECAN == J1939_FALSE
  991. Port_TXinterruptEnable();
  992. #endif
  993. return RC_CANNOTTRANSMIT;
  994. }
  995. else
  996. {
  997. while (TXQueueCount_4 > 0)
  998. {
  999. /*确保上次数据发送成功*/
  1000. /**************可增加一个判断函数**************************/
  1001. TXQueue_4[TXHead_4].Mxe.SourceAddress = NodeAddress_4;
  1002. SendOneMessage((J1939_MESSAGE *)&(TXQueue_4[TXHead_4]));
  1003. TXHead_4++;
  1004. if (TXHead_4 >= J1939_TX_QUEUE_SIZE)
  1005. TXHead_4 = 0;
  1006. TXQueueCount_4--;
  1007. }
  1008. /*配置了一些标识位,使能中断*/
  1009. #if J1939_POLL_ECAN == J1939_FALSE
  1010. Port_TXinterruptEnable();
  1011. #endif
  1012. }
  1013. break;
  1014. }
  1015. default:
  1016. {
  1017. return RC_CANNOTTRANSMIT;
  1018. break;
  1019. }
  1020. }
  1021. return RC_SUCCESS;
  1022. }
  1023. #if J1939_TP_RX_TX
  1024. /**
  1025. * @note 发送TP.DT,参考J1939-21
  1026. */
  1027. void J1939_TP_DT_Packet_send(void)
  1028. {
  1029. J1939_MESSAGE _msg;
  1030. j1939_uint16_t _packet_offset_p;
  1031. j1939_int32_t _i = 0;
  1032. _msg.Mxe.Priority = J1939_TP_DT_PRIORITY;
  1033. _msg.Mxe.DataPage = 0;
  1034. _msg.Mxe.PDUFormat = J1939_PF_DT;
  1035. _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
  1036. _msg.Mxe.DataLength = 8;
  1037. /*获取请求发送的数据包数量*/
  1038. if (TP_TX_MSG.packets_request_num > 0)
  1039. {
  1040. TP_TX_MSG.packets_request_num--;
  1041. /*获取数据偏移指针*/
  1042. _packet_offset_p = (j1939_uint16_t)(TP_TX_MSG.packet_offset_p * 7u);
  1043. /*加载数据包编号*/
  1044. _msg.Mxe.Data[0] = (j1939_uint8_t)(1u + TP_TX_MSG.packet_offset_p);
  1045. for (_i = 0; _i < 7; _i++)
  1046. {
  1047. _msg.Mxe.Data[_i + 1] = TP_TX_MSG.tp_tx_msg.data[_packet_offset_p + _i];
  1048. }
  1049. /*是否是最后一包数据消息*/
  1050. if (TP_TX_MSG.packet_offset_p == (TP_TX_MSG.packets_total - 1u))
  1051. {
  1052. /*参数群是否能被填满,是否需要填充,*/
  1053. if (_packet_offset_p > TP_TX_MSG.tp_tx_msg.byte_count - 7)
  1054. {
  1055. /*计算需要填充的数据数*/
  1056. _i = TP_TX_MSG.tp_tx_msg.byte_count - _packet_offset_p - 7;
  1057. for (; _i < 0; _i++)
  1058. {
  1059. /*我们默认J1939的参数群大小为8*/
  1060. _msg.Mxe.Data[_i + 8] = J1939_RESERVED_BYTE;
  1061. }
  1062. }
  1063. TP_TX_MSG.packets_request_num = 0;
  1064. TP_TX_MSG.packet_offset_p = 0;
  1065. TP_TX_MSG.time = J1939_TP_T3;
  1066. /* 跳转步骤,等待结束确认或则重新发送数据请求*/
  1067. TP_TX_MSG.state = J1939_TP_WAIT_ACK;
  1068. }
  1069. else
  1070. {
  1071. /*为下一个数据发送做准备*/
  1072. TP_TX_MSG.packet_offset_p++;
  1073. TP_TX_MSG.state = J1939_TP_TX_DT;
  1074. }
  1075. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1076. J1939_EnqueueMessage(&_msg, Can_Node);
  1077. }
  1078. else
  1079. {
  1080. TP_TX_MSG.packets_request_num = 0;
  1081. TP_TX_MSG.packet_offset_p = 0;
  1082. TP_TX_MSG.time = J1939_TP_T3;
  1083. TP_TX_MSG.state = J1939_TP_WAIT_ACK;
  1084. }
  1085. }
  1086. /**
  1087. * @note 发送TP。CM-RTS,16,23,4,255,PGN消息,参考J1939-21,
  1088. */
  1089. void J1939_CM_Start(void)
  1090. {
  1091. j1939_uint32_t pgn_num;
  1092. J1939_MESSAGE _msg;
  1093. pgn_num = TP_TX_MSG.tp_tx_msg.PGN;
  1094. _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
  1095. _msg.Mxe.DataPage = 0;
  1096. _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
  1097. _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
  1098. _msg.Mxe.DataLength = 8;
  1099. _msg.Mxe.Data[0] = J1939_RTS_CONTROL_BYTE;
  1100. _msg.Mxe.Data[1] = (j1939_uint8_t)TP_TX_MSG.tp_tx_msg.byte_count;
  1101. _msg.Mxe.Data[2] = (j1939_uint8_t)((TP_TX_MSG.tp_tx_msg.byte_count) >> 8);
  1102. _msg.Mxe.Data[3] = TP_TX_MSG.packets_total;
  1103. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1104. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1105. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1106. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1107. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1108. J1939_EnqueueMessage(&_msg, Can_Node);
  1109. /*刷新等待时间,触发下一个步骤()*/
  1110. TP_TX_MSG.time = J1939_TP_T3;
  1111. TP_TX_MSG.state = J1939_TP_TX_CM_WAIT;
  1112. }
  1113. /**
  1114. * @note 中断TP链接
  1115. */
  1116. void J1939_TP_TX_Abort(void)
  1117. {
  1118. J1939_MESSAGE _msg;
  1119. j1939_uint32_t pgn_num;
  1120. pgn_num = TP_TX_MSG.tp_tx_msg.PGN;
  1121. _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
  1122. _msg.Mxe.DataPage = 0;
  1123. _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
  1124. _msg.Mxe.DestinationAddress = TP_TX_MSG.tp_tx_msg.SA;
  1125. _msg.Mxe.DataLength = 8;
  1126. _msg.Mxe.Data[0] = J1939_CONNABORT_CONTROL_BYTE;
  1127. _msg.Mxe.Data[1] = J1939_RESERVED_BYTE;
  1128. _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
  1129. _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
  1130. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1131. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1132. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1133. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1134. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1135. J1939_EnqueueMessage(&_msg, Can_Node);
  1136. /*结束发送*/
  1137. TP_TX_MSG.state = J1939_TX_DONE;
  1138. }
  1139. /**
  1140. * @note 中断TP链接
  1141. */
  1142. void J1939_TP_RX_Abort(void)
  1143. {
  1144. J1939_MESSAGE _msg;
  1145. j1939_uint32_t pgn_num;
  1146. pgn_num = TP_RX_MSG.tp_rx_msg.PGN;
  1147. _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
  1148. _msg.Mxe.DataPage = 0;
  1149. _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
  1150. _msg.Mxe.DestinationAddress = TP_RX_MSG.tp_rx_msg.SA;
  1151. _msg.Mxe.DataLength = 8;
  1152. _msg.Mxe.Data[0] = J1939_CONNABORT_CONTROL_BYTE;
  1153. _msg.Mxe.Data[1] = J1939_RESERVED_BYTE;
  1154. _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
  1155. _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
  1156. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1157. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1158. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1159. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1160. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1161. J1939_EnqueueMessage(&_msg, Can_Node);
  1162. /*结束发送*/
  1163. TP_RX_MSG.state = J1939_RX_DONE;
  1164. }
  1165. /**
  1166. * @note TP的计时器
  1167. */
  1168. j1939_uint8_t J1939_TP_TX_RefreshCMTimer(j1939_uint16_t dt_ms)
  1169. {
  1170. if ((J1939_TP_TX_CM_WAIT == TP_TX_MSG.state) || (J1939_TP_WAIT_ACK == TP_TX_MSG.state))
  1171. {
  1172. if (TP_TX_MSG.time > dt_ms)
  1173. {
  1174. TP_TX_MSG.time = TP_TX_MSG.time - dt_ms;
  1175. return J1939_TP_TIMEOUT_NORMAL;
  1176. }
  1177. else
  1178. {
  1179. /*超时 */
  1180. TP_TX_MSG.time = 0u;
  1181. return J1939_TP_TIMEOUT_ABNORMAL;
  1182. }
  1183. }
  1184. else
  1185. {
  1186. return J1939_TP_TIMEOUT_NORMAL;
  1187. }
  1188. }
  1189. /**
  1190. * @note TP的计时器
  1191. */
  1192. j1939_uint8_t J1939_TP_RX_RefreshCMTimer(j1939_uint16_t dt_ms)
  1193. {
  1194. if ((J1939_TP_RX_DATA_WAIT == TP_RX_MSG.state))
  1195. {
  1196. if (TP_RX_MSG.time > dt_ms)
  1197. {
  1198. TP_RX_MSG.time = TP_RX_MSG.time - dt_ms;
  1199. return J1939_TP_TIMEOUT_NORMAL;
  1200. }
  1201. else
  1202. {
  1203. /*超时 */
  1204. TP_RX_MSG.time = 0u;
  1205. return J1939_TP_TIMEOUT_ABNORMAL;
  1206. }
  1207. }
  1208. else
  1209. {
  1210. return J1939_TP_TIMEOUT_NORMAL;
  1211. }
  1212. }
  1213. /**
  1214. * @note 发送读取数据 TP.CM_CTS 和 EndofMsgAck消息。
  1215. */
  1216. void J1939_read_DT_Packet()
  1217. {
  1218. J1939_MESSAGE _msg;
  1219. j1939_uint32_t pgn_num;
  1220. pgn_num = TP_RX_MSG.tp_rx_msg.PGN;
  1221. _msg.Mxe.Priority = J1939_TP_CM_PRIORITY;
  1222. _msg.Mxe.DataPage = 0;
  1223. _msg.Mxe.PDUFormat = J1939_PF_TP_CM;
  1224. _msg.Mxe.DestinationAddress = TP_RX_MSG.tp_rx_msg.SA;
  1225. _msg.Mxe.DataLength = 8;
  1226. /*如果系统繁忙,保持链接但是不传送消息*/
  1227. if (TP_RX_MSG.osbusy)
  1228. {
  1229. _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
  1230. _msg.Mxe.Data[1] = 0;
  1231. _msg.Mxe.Data[2] = J1939_RESERVED_BYTE;
  1232. _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
  1233. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1234. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1235. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1236. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1237. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1238. J1939_EnqueueMessage(&_msg, Can_Node);
  1239. return;
  1240. }
  1241. if (TP_RX_MSG.packets_total > TP_RX_MSG.packets_ok_num)
  1242. {
  1243. /*最后一次响应,如果不足2包数据*/
  1244. if ((TP_RX_MSG.packets_total - TP_RX_MSG.packets_ok_num) == 1)
  1245. {
  1246. _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
  1247. _msg.Mxe.Data[1] = 1;
  1248. _msg.Mxe.Data[2] = TP_RX_MSG.packets_total;
  1249. _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
  1250. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1251. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1252. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1253. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1254. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1255. J1939_EnqueueMessage(&_msg, Can_Node);
  1256. TP_RX_MSG.state = J1939_TP_RX_DATA_WAIT;
  1257. return;
  1258. }
  1259. _msg.Mxe.Data[0] = J1939_CTS_CONTROL_BYTE;
  1260. _msg.Mxe.Data[1] = 2;
  1261. _msg.Mxe.Data[2] = (TP_RX_MSG.packets_ok_num + 1);
  1262. _msg.Mxe.Data[3] = J1939_RESERVED_BYTE;
  1263. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1264. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1265. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1266. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1267. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1268. J1939_EnqueueMessage(&_msg, Can_Node);
  1269. TP_RX_MSG.state = J1939_TP_RX_DATA_WAIT;
  1270. return;
  1271. }
  1272. else
  1273. {
  1274. /*发送传输正常结束消息,EndofMsgAck*/
  1275. _msg.Mxe.Data[0] = J1939_EOMACK_CONTROL_BYTE;
  1276. _msg.Mxe.Data[1] = (TP_RX_MSG.tp_rx_msg.byte_count & 0x00ff);
  1277. _msg.Mxe.Data[2] = ((TP_RX_MSG.tp_rx_msg.byte_count >> 8) & 0x00ff);
  1278. _msg.Mxe.Data[3] = TP_RX_MSG.packets_total;
  1279. _msg.Mxe.Data[4] = J1939_RESERVED_BYTE;
  1280. _msg.Mxe.Data[7] = (j1939_uint8_t)((pgn_num >> 16) & 0xff);
  1281. _msg.Mxe.Data[6] = (j1939_uint8_t)(pgn_num >> 8 & 0xff);
  1282. _msg.Mxe.Data[5] = (j1939_uint8_t)(pgn_num & 0xff);
  1283. /*可能队列已满,发不出去,但是这里不能靠返回值进行无限的死等*/
  1284. J1939_EnqueueMessage(&_msg, Can_Node);
  1285. TP_RX_MSG.state = J1939_RX_DONE;
  1286. return;
  1287. }
  1288. }
  1289. /**
  1290. * @note TP协议的心跳,为了满足在总线的计时准确,10ms轮询一次 J1939_TP_TX_RefreshCMTimer(10)\n
  1291. 如果想要更高的分辨率,1ms轮询一次,但是要改下面计时函数 J1939_TP_TX_RefreshCMTimer(1)
  1292. */
  1293. void J1939_TP_Poll()
  1294. {
  1295. if (J1939_TP_Flags_t.state == J1939_TP_NULL || J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
  1296. {
  1297. return;
  1298. }
  1299. if (J1939_TP_Flags_t.state == J1939_TP_RX)
  1300. {
  1301. Can_Node = J1939_TP_Flags_t.TP_RX_CAN_NODE;
  1302. switch (TP_RX_MSG.state)
  1303. {
  1304. case J1939_TP_RX_WAIT:;
  1305. break;
  1306. case J1939_TP_RX_READ_DATA:
  1307. /*发送读取数据 TP.CM_CTS 和 EndofMsgAck消息*/
  1308. J1939_read_DT_Packet();
  1309. break;
  1310. case J1939_TP_RX_DATA_WAIT:
  1311. /*等待TP.DT帧传输的消息*/
  1312. if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_RX_RefreshCMTimer(10))
  1313. {
  1314. /* 等待超时,发生连接异常,跳转到异常步骤 */
  1315. TP_RX_MSG.state = J1939_TP_RX_ERROR;
  1316. }
  1317. break;
  1318. case J1939_TP_RX_ERROR:
  1319. J1939_TP_RX_Abort();
  1320. J1939_TP_Flags_t.TP_RX_CAN_NODE = Select_CAN_NODE_Null;
  1321. break;
  1322. case J1939_RX_DONE:
  1323. TP_RX_MSG.packets_ok_num = 0;
  1324. TP_RX_MSG.packets_total = 0;
  1325. TP_RX_MSG.time = J1939_TP_T3;
  1326. TP_RX_MSG.state = J1939_TP_RX_WAIT;
  1327. J1939_TP_Flags_t.state = J1939_TP_NULL;
  1328. break;
  1329. default:
  1330. break;
  1331. }
  1332. return;
  1333. }
  1334. if (J1939_TP_Flags_t.state == J1939_TP_TX)
  1335. {
  1336. Can_Node = J1939_TP_Flags_t.TP_TX_CAN_NODE;
  1337. switch (TP_TX_MSG.state)
  1338. {
  1339. case J1939_TP_TX_WAIT:
  1340. /*没有要发送的数据*/
  1341. break;
  1342. case J1939_TP_TX_CM_START:
  1343. /*发送TP.CM_RTS帧传输的消息(参考j1939-21)*/
  1344. J1939_CM_Start();
  1345. break;
  1346. case J1939_TP_TX_CM_WAIT:
  1347. /*等待TP.CM_CTS帧传输的消息*/
  1348. if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_TX_RefreshCMTimer(10))
  1349. {
  1350. /* 等待超时,发生连接异常,跳转到异常步骤 */
  1351. TP_TX_MSG.state = J1939_TP_TX_ERROR;
  1352. }
  1353. break;
  1354. case J1939_TP_TX_DT:
  1355. J1939_TP_DT_Packet_send();
  1356. break;
  1357. case J1939_TP_WAIT_ACK:
  1358. /*等待TP.EndofMsgACK帧传输的消息*/
  1359. if (J1939_TP_TIMEOUT_ABNORMAL == J1939_TP_TX_RefreshCMTimer(10))
  1360. {
  1361. /* 等待超时,发生连接异常,跳转到异常步骤 */
  1362. TP_TX_MSG.state = J1939_TP_TX_ERROR;
  1363. }
  1364. break;
  1365. case J1939_TP_TX_ERROR:
  1366. J1939_TP_TX_Abort();
  1367. break;
  1368. case J1939_TX_DONE:
  1369. TP_TX_MSG.packets_request_num = 0;
  1370. TP_TX_MSG.packet_offset_p = 0;
  1371. TP_TX_MSG.time = J1939_TP_T3;
  1372. TP_TX_MSG.state = J1939_TP_TX_WAIT;
  1373. J1939_TP_Flags_t.state = J1939_TP_NULL;
  1374. break;
  1375. default:
  1376. // 程序不会运行到这里来,可以增加一个调试输出
  1377. break;
  1378. }
  1379. return;
  1380. }
  1381. }
  1382. /**这是一个非阻塞io接口
  1383. *
  1384. * @param[in] PGN TP会话的参数群编号
  1385. * @param[in] SA TP会话的目标地址
  1386. * @param[in] *data TP会话的数据缓存地址
  1387. * @param[in] data_num TP会话的数据大小
  1388. * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
  1389. * @return RC_SUCCESS 成功打开TP链接,开始进入发送流程
  1390. * @return RC_CANNOTTRANSMIT 不能发送,因为TP协议已经建立虚拟链接,并且未断开
  1391. * @note TP协议的发送函数
  1392. */
  1393. 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)
  1394. {
  1395. j1939_uint16_t _byte_count = 0;
  1396. /*取得发送权限*/
  1397. if (J1939_TP_Flags_t.state == J1939_TP_NULL)
  1398. {
  1399. J1939_TP_Flags_t.state = J1939_TP_TX;
  1400. J1939_TP_Flags_t.TP_TX_CAN_NODE = _Can_Node;
  1401. }
  1402. else
  1403. {
  1404. return RC_CANNOTTRANSMIT; // 不能发送,因为TP协议已经建立虚拟链接,并且未断开
  1405. }
  1406. TP_TX_MSG.tp_tx_msg.PGN = PGN;
  1407. TP_TX_MSG.tp_tx_msg.SA = DA;
  1408. TP_TX_MSG.tp_tx_msg.byte_count = data_num;
  1409. for (_byte_count = 0; _byte_count < data_num; _byte_count++)
  1410. {
  1411. TP_TX_MSG.tp_tx_msg.data[_byte_count] = data[_byte_count];
  1412. }
  1413. TP_TX_MSG.packet_offset_p = 0;
  1414. TP_TX_MSG.packets_request_num = 0;
  1415. TP_TX_MSG.packets_total = data_num / 7;
  1416. if ((data_num % 7) != 0)
  1417. {
  1418. TP_TX_MSG.packets_total++;
  1419. }
  1420. TP_TX_MSG.time = J1939_TP_T3;
  1421. // 触发开始CM_START
  1422. TP_TX_MSG.state = J1939_TP_TX_CM_START;
  1423. return RC_SUCCESS;
  1424. }
  1425. /**
  1426. * @param[in] msg.data 读取数据的缓存
  1427. * @param[in] msg.data_num 读取数据的缓存大小
  1428. * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
  1429. * @param[out] msg.SA 数据源地址
  1430. * @param[out] msg.byte_count 数据大小
  1431. * @param[out] msg.PGN 数据参数群编号
  1432. * @return RC_CANNOTRECEIVE 不能接受,TP协议正在接受数据中
  1433. * @return RC_SUCCESS 读取数据成功
  1434. * @note TP的接受函数 , 接受缓存的大小必须大于接受数据的大小,建议初始化缓存大小用 J1939_TP_MAX_MESSAGE_LENGTH\n
  1435. 请正确带入 缓存区的大小,参数错误程序运行有风险
  1436. */
  1437. j1939_int8_t J1939_TP_RX_Message(TP_RX_MESSAGE *msg, CAN_NODE _Can_Node)
  1438. {
  1439. j1939_uint16_t _a = 0;
  1440. /*判断是否能读取数据*/
  1441. if (J1939_TP_Flags_t.state == J1939_TP_NULL && TP_RX_MSG.tp_rx_msg.PGN != 0)
  1442. {
  1443. J1939_TP_Flags_t.state = J1939_TP_OSBUSY;
  1444. }
  1445. else
  1446. {
  1447. return RC_CANNOTRECEIVE; // 不能接受,TP协议正在接受数据中,或没有数据
  1448. }
  1449. // 判断是不是要读取那一路CAN数据
  1450. if (_Can_Node != J1939_TP_Flags_t.TP_RX_CAN_NODE)
  1451. {
  1452. /*释放TP接管权限*/
  1453. if (J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
  1454. {
  1455. J1939_TP_Flags_t.state = J1939_TP_NULL;
  1456. }
  1457. return RC_CANNOTRECEIVE;
  1458. }
  1459. // 判断数据缓存够不够
  1460. if ((msg->data_num) < TP_RX_MSG.tp_rx_msg.byte_count)
  1461. {
  1462. return RC_CANNOTRECEIVE; // 不能接受,缓存区太小
  1463. }
  1464. /*获取数据*/
  1465. for (_a = 0; _a < msg->data_num; _a++)
  1466. {
  1467. msg->data[_a] = TP_RX_MSG.tp_rx_msg.data[_a];
  1468. }
  1469. /*获取数据 源地址*/
  1470. msg->SA = TP_RX_MSG.tp_rx_msg.SA;
  1471. /*获取数据的大小*/
  1472. msg->byte_count = TP_RX_MSG.tp_rx_msg.byte_count;
  1473. /*获取数据PGN*/
  1474. msg->PGN = TP_RX_MSG.tp_rx_msg.PGN;
  1475. /*丢弃读取过的数据*/
  1476. TP_RX_MSG.tp_rx_msg.byte_count = 0u;
  1477. TP_RX_MSG.tp_rx_msg.PGN = 0;
  1478. /*释放TP接管权限*/
  1479. if (J1939_TP_Flags_t.state == J1939_TP_OSBUSY)
  1480. {
  1481. J1939_TP_Flags_t.state = J1939_TP_NULL;
  1482. }
  1483. return RC_SUCCESS;
  1484. }
  1485. /**
  1486. * @param[in] pgn 被请求的参数群
  1487. * @param[in] DA 目标地址(DestinationAddress) 当DA = 0xff表示是全局请求
  1488. * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
  1489. * @note 请求(从全局范围或则特定目的地的)参数群,请求规则J1939-21的16-17页,有明确的说明
  1490. */
  1491. void J1939_Request_PGN(j1939_uint32_t pgn, j1939_uint8_t DA, CAN_NODE _Can_Node)
  1492. {
  1493. J1939_MESSAGE _msg;
  1494. _msg.Mxe.DataPage = 0;
  1495. _msg.Mxe.Priority = J1939_REQUEST_PRIORITY;
  1496. _msg.Mxe.DestinationAddress = DA;
  1497. _msg.Mxe.DataLength = 3;
  1498. _msg.Mxe.PDUFormat = J1939_PF_REQUEST;
  1499. _msg.Mxe.Data[0] = (j1939_uint8_t)(pgn & 0x000000FF);
  1500. _msg.Mxe.Data[1] = (j1939_uint8_t)((pgn & 0x0000FF00) >> 8);
  1501. _msg.Mxe.Data[2] = (j1939_uint8_t)((pgn & 0x00FF0000) >> 16);
  1502. while (J1939_EnqueueMessage(&_msg, _Can_Node) != RC_SUCCESS)
  1503. ;
  1504. }
  1505. /**
  1506. * @param[in] data 需要发送数据的缓存
  1507. * @param[in] dataLenght 发送数据的缓存大小
  1508. * @param[in] PGN 需要发送数据的PGN(参数群编号)
  1509. * @param[in] void (*dataUPFun)() 用于更新缓存data 的函数地址指针
  1510. * @param[in] _Can_Node 要入队的CAN硬件编号(要选择的使用的CAN硬件编号)
  1511. * @note 创建一个PGN 的 请求 对应的 响应\n 如果收到改请求则先运行 REQUEST_LIST.dataUPFun(),在将数据REQUEST_LIST.data发送出去
  1512. * @warning 本函数只能被串行调用,(多线程)并行调用请在函数外加互斥操作
  1513. */
  1514. void J1939_Create_Response(j1939_uint8_t data[], j1939_uint16_t dataLenght, j1939_uint32_t PGN, void (*dataUPFun)(), CAN_NODE _Can_Node)
  1515. {
  1516. /*查找可用的链表项*/
  1517. struct Request_List *_requestList = &REQUEST_LIST;
  1518. while (J1939_NULL != _requestList->next)
  1519. {
  1520. _requestList = _requestList->next;
  1521. }
  1522. _requestList->next = (struct Request_List *)malloc(sizeof(struct Request_List));
  1523. _requestList = _requestList->next;
  1524. /*对新的链表项赋值*/
  1525. _requestList->data = data;
  1526. _requestList->lenght = dataLenght;
  1527. _requestList->PGN = PGN;
  1528. _requestList->update = dataUPFun;
  1529. _requestList->Can_Node = _Can_Node;
  1530. _requestList->next = J1939_NULL;
  1531. }
  1532. /**
  1533. * @note 当收到一个PGN请求后,如果有REQUEST_LIST中有相应的PGN,则会自动发送REQUEST_LIST中的PGN。\n
  1534. 如果没有则会发送一个NACK; 本函数的响应逻辑,参考J1939-21 17页表4
  1535. */
  1536. void J1939_Response(const j1939_uint32_t PGN)
  1537. {
  1538. J1939_MESSAGE _msg;
  1539. /*查找可用的链表项*/
  1540. struct Request_List *_requestList = &REQUEST_LIST;
  1541. while ((PGN != _requestList->PGN) || (Can_Node != _requestList->Can_Node))
  1542. {
  1543. if (_requestList->next == J1939_NULL)
  1544. {
  1545. /*原文档规定 全局请求不被支持时不能响应 NACK*/
  1546. if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
  1547. {
  1548. return;
  1549. }
  1550. if ((PGN & 0xFF00) >= 0xF000)
  1551. {
  1552. return;
  1553. }
  1554. /*没有相应的PGN响应被创建,向总线发送一个NACK*/
  1555. _msg.Mxe.Priority = J1939_ACK_PRIORITY;
  1556. _msg.Mxe.DataPage = 0;
  1557. _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
  1558. _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
  1559. _msg.Mxe.DataLength = 8;
  1560. _msg.Mxe.SourceAddress = J1939_Address;
  1561. _msg.Mxe.Data[0] = J1939_NACK_CONTROL_BYTE;
  1562. _msg.Mxe.Data[1] = 0xFF;
  1563. _msg.Mxe.Data[2] = 0xFF;
  1564. _msg.Mxe.Data[3] = 0xFF;
  1565. _msg.Mxe.Data[4] = 0xFF;
  1566. _msg.Mxe.Data[5] = (PGN & 0x0000FF);
  1567. _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
  1568. _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
  1569. SendOneMessage((J1939_MESSAGE *)&_msg);
  1570. return;
  1571. }
  1572. else
  1573. {
  1574. _requestList = _requestList->next;
  1575. }
  1576. }
  1577. /*调用dataUPFun()函数,主要用于参数群数据更新*/
  1578. if (J1939_NULL != _requestList->update)
  1579. {
  1580. _requestList->update();
  1581. }
  1582. /*响应请求*/
  1583. if (_requestList->lenght > 8)
  1584. {
  1585. /*回一个确认响应多帧(非广播多帧)*/
  1586. if (RC_SUCCESS != J1939_TP_TX_Message(_requestList->PGN, OneMessage.Mxe.SourceAddress, _requestList->data, _requestList->lenght, Can_Node))
  1587. {
  1588. /*原文档规定 全局请求不被支持时不能响应 NACK*/
  1589. if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
  1590. {
  1591. return;
  1592. }
  1593. /*如果长帧发送不成功*/
  1594. _msg.Mxe.Priority = J1939_ACK_PRIORITY;
  1595. _msg.Mxe.DataPage = 0;
  1596. _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
  1597. _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
  1598. _msg.Mxe.DataLength = 8;
  1599. _msg.Mxe.SourceAddress = J1939_Address;
  1600. _msg.Mxe.Data[0] = J1939_ACCESS_DENIED_CONTROL_BYTE;
  1601. _msg.Mxe.Data[1] = 0xFF;
  1602. _msg.Mxe.Data[2] = 0xFF;
  1603. _msg.Mxe.Data[3] = 0xFF;
  1604. _msg.Mxe.Data[4] = 0xFF;
  1605. _msg.Mxe.Data[5] = (PGN & 0x0000FF);
  1606. _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
  1607. _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
  1608. SendOneMessage((J1939_MESSAGE *)&_msg);
  1609. return;
  1610. }
  1611. /*回一个确认响应*/
  1612. _msg.Mxe.Priority = J1939_ACK_PRIORITY;
  1613. _msg.Mxe.DataPage = 0;
  1614. _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
  1615. /*原文档规定 全局请求响应到全局*/
  1616. if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
  1617. {
  1618. _msg.Mxe.DestinationAddress = 0XFF;
  1619. }
  1620. else
  1621. {
  1622. _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
  1623. }
  1624. _msg.Mxe.DataLength = 8;
  1625. _msg.Mxe.SourceAddress = J1939_Address;
  1626. _msg.Mxe.Data[0] = J1939_ACK_CONTROL_BYTE;
  1627. _msg.Mxe.Data[1] = 0xFF;
  1628. _msg.Mxe.Data[2] = 0xFF;
  1629. _msg.Mxe.Data[3] = 0xFF;
  1630. _msg.Mxe.Data[4] = 0xFF;
  1631. _msg.Mxe.Data[5] = (PGN & 0x0000FF);
  1632. _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
  1633. _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
  1634. SendOneMessage((J1939_MESSAGE *)&_msg);
  1635. }
  1636. else
  1637. {
  1638. /*回一个确认响应*/
  1639. _msg.Mxe.Priority = J1939_ACK_PRIORITY;
  1640. _msg.Mxe.DataPage = 0;
  1641. _msg.Mxe.PDUFormat = J1939_PF_ACKNOWLEDGMENT;
  1642. _msg.Mxe.SourceAddress = J1939_Address;
  1643. /*原文档规定 全局请求响应到全局*/
  1644. if ((OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS) || ((PGN & 0xFF00) >= 0xF000))
  1645. {
  1646. _msg.Mxe.DestinationAddress = 0XFF;
  1647. }
  1648. else
  1649. {
  1650. _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
  1651. }
  1652. _msg.Mxe.DataLength = 8;
  1653. _msg.Mxe.SourceAddress = J1939_Address;
  1654. _msg.Mxe.Data[0] = J1939_ACK_CONTROL_BYTE;
  1655. _msg.Mxe.Data[1] = 0xFF;
  1656. _msg.Mxe.Data[2] = 0xFF;
  1657. _msg.Mxe.Data[3] = 0xFF;
  1658. _msg.Mxe.Data[4] = 0xFF;
  1659. _msg.Mxe.Data[5] = (PGN & 0x0000FF);
  1660. _msg.Mxe.Data[6] = ((PGN >> 8) & 0x0000FF);
  1661. _msg.Mxe.Data[7] = ((PGN >> 16) & 0x0000FF);
  1662. SendOneMessage((J1939_MESSAGE *)&_msg);
  1663. /*回一个确认响应单帧*/
  1664. _msg.Mxe.Priority = J1939_ACK_PRIORITY;
  1665. _msg.Mxe.DataPage = (((_requestList->PGN) >> 16) & 0x1);
  1666. _msg.Mxe.PDUFormat = ((_requestList->PGN) >> 8) & 0xFF;
  1667. _msg.Mxe.SourceAddress = J1939_Address;
  1668. /*原文档规定 全局请求响应到全局*/
  1669. if (OneMessage.Mxe.PDUSpecific == J1939_GLOBAL_ADDRESS)
  1670. {
  1671. _msg.Mxe.DestinationAddress = 0XFF;
  1672. }
  1673. else
  1674. {
  1675. _msg.Mxe.DestinationAddress = OneMessage.Mxe.SourceAddress;
  1676. }
  1677. _msg.Mxe.DataLength = _requestList->lenght;
  1678. {
  1679. j1939_uint8_t _i = 0;
  1680. for (_i = 0; _i < (_requestList->lenght); _i++)
  1681. {
  1682. _msg.Mxe.Data[_i] = _requestList->data[_i];
  1683. }
  1684. for (; _i < 8; _i++)
  1685. {
  1686. _msg.Mxe.Data[_i] = 0xFF;
  1687. }
  1688. }
  1689. SendOneMessage((J1939_MESSAGE *)&_msg);
  1690. }
  1691. }
  1692. #endif