J1939.c 63 KB

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