can_demo.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. #include <stdio.h>
  2. #include "amt630hv160_lib.h"
  3. #include "can_uds.h"
  4. #include "fs/ff.h"
  5. #include "fs/diskio.h"
  6. #include <string.h>
  7. #include "mailbox_message.h"
  8. #include "update.h"
  9. extern int UsbHostInit(void);
  10. extern void WDT_McuReboot(void);
  11. CanPort_t *ecu_cap = NULL;
  12. CanPort_t *host_cap = NULL;
  13. static u8 reboot_flg = 0;
  14. static void can_ecudemo_thread(void *pvParameters)
  15. {
  16. for (;;) {
  17. CanMsg rxmsg[8] = {0};
  18. int revlen;
  19. int i;
  20. if ((revlen = iCanRead(ecu_cap, rxmsg, 8, pdMS_TO_TICKS(10))) > 0) {
  21. for (i = 0; i < revlen; i++) {
  22. if (rxmsg[i].StdId == PHY_ADDR_ID) {
  23. CAN_UDS_Process(rxmsg[i].Data, rxmsg[i].DLC);
  24. }
  25. }
  26. }
  27. }
  28. }
  29. static void can_hostdemo_thread(FIL *fp,u32 filetype,u32 upfileSize)
  30. {
  31. uint8_t param[16];
  32. uint32_t plen;
  33. uint8_t *rspData;
  34. uint32_t rspLen;
  35. uint32_t packetSize;
  36. uint8_t *pPacketData = NULL;
  37. uint32_t leftsize;
  38. uint32_t sendsize;
  39. uint32_t bsc = 1;
  40. uint32_t checksum = 0xffffffff;
  41. UINT size;
  42. FRESULT fret;
  43. //0x10: 会话控制
  44. //0x03: 切换到扩展会话
  45. param[0] = 0x03;
  46. plen = 1;
  47. if (!CAN_UDS_RequestService(0x10, param, plen, &rspData, &rspLen))
  48. goto exit;
  49. //0x31: 例程控制
  50. //0x01: 启动例程
  51. //0x02 0x03: 例程RID:检查刷写条件
  52. param[0] = 0x01;
  53. param[1] = 0x02;
  54. param[2] = 0x03;
  55. plen = 3;
  56. if (!CAN_UDS_RequestService(0x31, param, plen, &rspData, &rspLen))
  57. goto exit;
  58. //0x85: 故障码控制设置
  59. //0x02: 停止故障码存储
  60. param[0] = 0x02;
  61. plen = 1;
  62. if (!CAN_UDS_RequestService(0x85, param, plen, &rspData, &rspLen))
  63. goto exit;
  64. //0x28: 通讯控制
  65. //0x03: 停止发送报文、接收报文
  66. //0x03: 应用与网络报文
  67. param[0] = 0x03;
  68. param[1] = 0x03;
  69. plen = 2;
  70. if (!CAN_UDS_RequestService(0x28, param, plen, &rspData, &rspLen))
  71. goto exit;
  72. //0x10: 会话控制
  73. //0x02: 切换到编程会话
  74. param[0] = 0x02;
  75. plen = 1;
  76. if (!CAN_UDS_RequestService(0x10, param, plen, &rspData, &rspLen))
  77. goto exit;
  78. //0x27: 安全访问
  79. //0x01: 请求种子
  80. param[0] = 0x01;
  81. plen = 1;
  82. if (!CAN_UDS_RequestService(0x27, param, plen, &rspData, &rspLen))
  83. goto exit;
  84. //0x27: 安全访问
  85. //0x02: 发送与验证key
  86. //4字节key由上面获取到的种子计算生成
  87. param[0] = 0x02;
  88. param[1] = ~rspData[2];
  89. param[2] = ~rspData[3];
  90. param[3] = ~rspData[4];
  91. param[4] = ~rspData[5];
  92. plen = 5;
  93. if (!CAN_UDS_RequestService(0x27, param, plen, &rspData, &rspLen))
  94. goto exit;
  95. //0x31: 例程控制
  96. //0x01: 启动例程
  97. //0xFF 0x00: 例程RID:擦除代码存储区数据
  98. param[0] = 0x01;
  99. param[1] = 0xFF;
  100. param[2] = 0x00;
  101. plen = 3;
  102. if (!CAN_UDS_RequestService(0x31, param, plen, &rspData, &rspLen))
  103. goto exit;
  104. //0x34: 请求下载
  105. //0x00: 不采用压缩算法和加密算法
  106. //0x04: 地址为0个字节,长度为4个字节
  107. //4个字节长度
  108. param[0] = 0x00;
  109. param[1] = 0x04;
  110. param[2] = (upfileSize >> 24) & 0xff;
  111. param[3] = (upfileSize >> 16) & 0xff;
  112. param[4] = (upfileSize >> 8) & 0xff;
  113. param[5] = upfileSize & 0xff;
  114. param[6] = filetype;
  115. plen = 7;
  116. if (!CAN_UDS_RequestService(0x34, param, plen, &rspData, &rspLen))
  117. goto exit;
  118. if ((rspData[1] >> 4) == 2 && rspLen >= 4)
  119. packetSize = (rspData[2] << 8) | rspData[3];
  120. else if ((rspData[1] >> 4) == 4 && rspLen >= 6)
  121. packetSize = (rspData[2] << 24) | (rspData[3] << 16)
  122. | (rspData[4] << 8) | rspData[5];
  123. printf("Respond packet_size is %d.\n", packetSize);
  124. pPacketData = pvPortMalloc(packetSize);
  125. if (!pPacketData) {
  126. printf("No enough memory to alloc for pPacketData.\n");
  127. goto exit;
  128. }
  129. //0x36: 传输数据
  130. //0xXX: 块序号
  131. //packetSize - 2字节的数据
  132. leftsize = upfileSize;
  133. packetSize -= 2; //除去SID,BSC和filetype
  134. while (leftsize) {
  135. sendsize = leftsize > packetSize ? packetSize : leftsize;
  136. pPacketData[0] = bsc++;
  137. fret = f_read(fp, &pPacketData[1], sendsize, &size);
  138. if(fret != FR_OK) {
  139. printf("Read file fail! fret=%d\n", fret);
  140. break;
  141. }
  142. printf("bsc=%d \n", bsc-1);
  143. checksum = xcrc32(&pPacketData[1], sendsize, checksum, HARD_CALC_CRC);
  144. //printf("bsc=%d,checksum = 0x%x \n", bsc-1, checksum);
  145. if(!CAN_UDS_RequestService(0x36, pPacketData, sendsize + 1, &rspData, &rspLen))
  146. break;
  147. leftsize -= sendsize;
  148. }
  149. //0x37: 请求传输退出
  150. if (!CAN_UDS_RequestService(0x37, param, 0, &rspData, &rspLen))
  151. goto exit;
  152. if (rspLen >= 1 && rspData[0]) {
  153. reboot_flg = 1;
  154. }
  155. //0x31: 例程控制
  156. //0x01: 启动例程
  157. //0x02 0x02: 例程RID: 检查APP存储区所有数据是否正确
  158. param[0] = 0x01;
  159. param[1] = 0x02;
  160. param[2] = 0x02;
  161. param[3] = (checksum >> 24) & 0xff;
  162. param[4] = (checksum >> 16) & 0xff;
  163. param[5] = (checksum >> 8) & 0xff;
  164. param[6] = checksum & 0xff;
  165. plen = 7;
  166. if (!CAN_UDS_RequestService(0x31, param, plen, &rspData, &rspLen))
  167. goto exit;
  168. if (filetype == UPFILE_TYPE_MCU_IMAGE || filetype == UPFILE_TYPE_MCU_FB) {
  169. if (rspLen >= 4 && !rspData[4]) {
  170. printf("Checksum ok\r\n");
  171. } else {
  172. printf("Checksum fail\r\n");
  173. goto exit;
  174. }
  175. }
  176. //0x31: 例程控制
  177. //0x01: 启动例程
  178. //0xFF 0x01: 例程RID: 检查编程依赖性
  179. param[0] = 0x01;
  180. param[1] = 0xFF;
  181. param[2] = 0x01;
  182. plen = 3;
  183. if (!CAN_UDS_RequestService(0x31, param, plen, &rspData, &rspLen))
  184. goto exit;
  185. if (filetype == UPFILE_TYPE_MCU_IMAGE || filetype == UPFILE_TYPE_MCU_FB) {
  186. if (rspLen >= 4 && rspData[4]) {
  187. reboot_flg = 1;
  188. printf("Check Programming Dependencies response ok\r\n");
  189. } else {
  190. printf("Check Programming Dependencies response fail\r\n");
  191. goto exit;
  192. }
  193. }
  194. //0x11: ECU复位
  195. //0x01: 硬件复位
  196. param[0] = 0x01;
  197. plen = 1;
  198. if (!CAN_UDS_RequestService(0x11, param, plen, &rspData, &rspLen))
  199. goto exit;
  200. vTaskDelay(pdMS_TO_TICKS(3000));
  201. //0x10: 会话控制
  202. //0x03: 扩展会话
  203. param[0] = 0x03;
  204. plen = 1;
  205. if (!CAN_UDS_RequestService(0x10, param, plen, &rspData, &rspLen))
  206. goto exit;
  207. //0x28: 通讯控制
  208. //0x00: 允许发送报文、接收报文
  209. //0x03: 应用与网络报文
  210. param[0] = 0x00;
  211. param[1] = 0x03;
  212. plen = 2;
  213. if (!CAN_UDS_RequestService(0x28, param, plen, &rspData, &rspLen))
  214. goto exit;
  215. //0x85: 故障码控制设置
  216. //0x01: 启用故障码存储
  217. param[0] = 0x01;
  218. plen = 1;
  219. if (!CAN_UDS_RequestService(0x85, param, plen, &rspData, &rspLen))
  220. goto exit;
  221. //0x10: 会话控制
  222. //0x01: 默认会话
  223. param[0] = 0x01;
  224. plen = 1;
  225. if (!CAN_UDS_RequestService(0x10, param, plen, &rspData, &rspLen))
  226. goto exit;
  227. exit:
  228. if (pPacketData)
  229. vPortFree(pPacketData);
  230. f_close(fp);
  231. }
  232. static void update_from_can(void *pvParameters)
  233. {
  234. FRESULT fret;
  235. FILINFO fileinfo = {0};
  236. FATFS fs;
  237. uint32_t upfileSize;
  238. FIL fp = {0};
  239. char filename[32];
  240. if (UsbHostInit() < 0) {
  241. printf("UsbHostInit fail\n");
  242. goto exit;
  243. }
  244. fret = f_mount(&fs, DRVPATH(DRV_USB), 0);
  245. if(fret == FR_OK) {
  246. printf("Mount file ok\n");
  247. } else {
  248. printf("Mount file fail\n");
  249. goto exit;
  250. }
  251. for(int i = UPFILE_TYPE_LDR; i < UPFILE_TYPE_NUM; i++){
  252. sprintf(filename, "%s%s", DRVPATH(DRV_USB), g_upfilename[i]);
  253. fret = f_open(&fp, filename, FA_OPEN_EXISTING | FA_READ);
  254. if(fret != FR_OK) {
  255. //printf("Open file fail %s\n", filename);
  256. continue;
  257. }
  258. fret = f_stat(filename, &fileinfo);
  259. if (fret != FR_OK) {
  260. printf("Get file info fail\n");
  261. goto exit;
  262. }
  263. upfileSize = fileinfo.fsize;
  264. can_hostdemo_thread(&fp,i,upfileSize);
  265. }
  266. if (reboot_flg)
  267. WDT_McuReboot();
  268. exit:
  269. printf("udate from can finish! \n");
  270. vTaskDelay(portMAX_DELAY);
  271. }
  272. int can_ecu_demo(void)
  273. {
  274. CanPort_t *cap = xCanOpen(CAN_ID0);
  275. CanTimInit_t CanTimInit;
  276. if (!cap) {
  277. printf("open can %d fail.\n", CAN_ID0);
  278. vTaskDelete(NULL);
  279. return -1;
  280. }
  281. CanTimInit.Bps = CANFD500kBaud;
  282. CanTimInit.DatBps = CANFD1MBaud;
  283. CanTimInit.tdc_en = 0;
  284. CanTimInit.sspoff = 0;
  285. vCanInit(cap, &CanTimInit, CAN_MODE_NORMAL);
  286. CAN_FilterInitTypeDef canfilter;
  287. canfilter.IDE_M = STD_OR_EXT;
  288. canfilter.ID = PHY_ADDR_ID;
  289. canfilter.IDMASK = 0x0;
  290. canfilter.FILTERx = 0;
  291. vCanSetFilter(cap, canfilter);
  292. ecu_cap = cap;
  293. /* 创建ECU工作线程 */
  294. if (xTaskCreate(can_ecudemo_thread, "canecu", 1024, NULL,
  295. (tskIDLE_PRIORITY + 1) | portPRIVILEGE_BIT, NULL) != pdPASS) {
  296. printf("create can hostdemo task fail.\n");
  297. return -1;
  298. }
  299. return 0;
  300. }
  301. int can_host_demo(void)
  302. {
  303. CanPort_t *cap = xCanOpen(CAN_ID1);
  304. CanTimInit_t CanTimInit;
  305. if (!cap) {
  306. printf("open can %d fail.\n", CAN_ID1);
  307. vTaskDelete(NULL);
  308. return -1;
  309. }
  310. CanTimInit.Bps = CANFD500kBaud;
  311. CanTimInit.DatBps = CANFD1MBaud;
  312. CanTimInit.tdc_en = 0;
  313. CanTimInit.sspoff = 0;
  314. vCanInit(cap, &CanTimInit, CAN_MODE_NORMAL);
  315. CAN_FilterInitTypeDef canfilter;
  316. canfilter.IDE_M = STD_OR_EXT;
  317. canfilter.ID = RSP_ADDR_ID;
  318. canfilter.IDMASK = 0x0;
  319. canfilter.FILTERx = 0;
  320. vCanSetFilter(cap, canfilter);
  321. host_cap = cap;
  322. //vTaskDelay(1000*20);
  323. /*创建上位机工作线程 */
  324. if (xTaskCreate(update_from_can, "canhost", 1024, NULL,
  325. (tskIDLE_PRIORITY + 1) | portPRIVILEGE_BIT, NULL) != pdPASS) {
  326. printf("create can hostdemo task fail.\n");
  327. return -1;
  328. }
  329. return 0;
  330. }