国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee

 找回密碼
 注冊
搜索

CAN Bootloader協議介紹與C++源碼

[復制鏈接]
樓主
coolice 發表于 2020-4-30 00:07:54 | 只看該作者 |倒序瀏覽 |閱讀模式
CAN Bootloader命令列表
命令名稱    命令值(Hex)    說明
GET_ADDR(1)    000    向主機請求本機地址
ERASE(2)    XX1    擦除應用程序
WRITE(3)    XX2    將程序寫入Flash
READ(4)    XX3    將程序從Flash中讀出
GO(5)    XX4    執行應用程序
SET_WRITE_ADDR    XX5    設置寫數據起始地址
WRITE_CONTINUOUS    XX6    連續寫數據,寫數據地址自動遞增
SET_READ_ADDR    XX7    設置讀數據起始地址
READ_CONTINUOUS    XX8    連續讀數據,讀數據起始地址遞增
GET_VERSION    XX9    獲取Bootloader固件版本
ADDR_OK    XXC    請求地址可用
ADDR_ERROR    XXD    請求地址不可用
CMD_OK    XXE    命令執行成功
CMD_ERROR    XXF    命令執行失敗
1、本機地址為7bit,所以在CAN總線上最多只能連接128個節點,本命令由從機發出,主機會給從機分配一個臨時地址并回復CMD_OK,如果主機地址使用完畢則回復CMD_ERROR,從機可以根據接收到的主機反饋判斷本機地址設置是否成功;
2、擦除應用程序命令會帶擦除起始地址和擦除結束地址;
3、寫數據命令帶4字節寫數據地址參數和4字節的數據;
4、讀數據命令會攜帶4字節地址,從機返回4字節數據;
5、執行應用程序;

命令詳解
GET_ADDR:
該命令由從機發送給主機,主機接收到該命令后會分配一個地址給從機,如果主機無法分配地址則發送ADDR_ERROR回復從機,此時從機應進入無法獲取地址的錯誤處理程序中。主機和從機在發送命令的時候必須攜帶8字節物理地址,也就是說DLC為8。從機如果正確獲取到地址后可以設置過濾器為只接收和自己地址匹配的數據,這樣可以減少CPU的負擔。
ERASE:
擦除應用程序儲存地址區域的數據,該命令由主機發送給從機,命令攜帶8字節數據,前4字節數據為擦出起始地址,后4字節為擦出結束地址,從機接收到該命令后可回復CMD_OK或CMD_ERROR給主機。
WRITE:
將一個字(4Byte)的數據寫入指定的Flash地址,該命令由主機發送給從機,命令攜帶8字節數據,前4字節為數據寫入地址,后4字節為準備寫入的數據。
READ:
從指定的Flash地址讀取4字節的數據,該命令由主機發送給從機或者從機發送給主機,主機發送給從機的時候攜帶4字節地址參數,從機發送給主機的時候攜帶4字節的數據。
GO:
執行應用程序,該命令由主機發送給從機,命令攜帶4字節的地址參數,從機接收到該命令后從指定的地址開始執行程序。
SET_WRITE_ADDR:
設置連續寫數據的起始地址,該命令由主機發送給從機,命令攜帶4字節的地址參數。
WRITE_CONTINUOUS:
連續寫數據到Flash中,該命令由主機發送給從機,從機根據SET_WRITE_ADDR命令設置的起始地址將程序數據寫入Flash中,該命令攜帶最多8字節的程序數據。
SET_READ_ADDR:
設置連續讀數據起始地址,該命令由主機發送給從機,命令攜帶4字節的地址參數。
READ_CONTINUOUS:
連續讀數據,該命令由主機發送給從機或者由從機發送給主機,由主機發送給從機時DLC為0,從機接收到這個命令后將該命令攜帶最多8字節數據返回給主機。
GET_VERSION:
獲取Bootloader固件版本號,版本號由兩字節組成,第一字節為主版本號,第二字節為從版本號。
ADDR_OK:
返回合法的從機地址。
ADDR_ERROR:
不能正常分配從機地址。
CMD_OK:
命令支持成功。
CMD_ERROR:
命令執行失敗。
CAN Bootloader.rar (440.04 KB, 售價: 1 E幣)
部分源程序如下:
  1.     QCoreApplication::processEvents(QEventLoop::AllEvents);
  2.     //檢測在線狀態
  3.     for(i=0;i<model->rowCount();i++){
  4.         uint32_t local_addr,retry=0;
  5.         if(!model->item(i,0)->text().isEmpty()){
  6.             //清除之前接收的數據
  7.             VCI_ClearBuffer(VCI_USBCAN2,
  8.                             ui->deviceIndexComboBox->currentIndex(),
  9.                             ui->channelIndexComboBox->currentIndex());
  10.             local_addr = model->item(i,0)->text().toInt(NULL,0);
  11.             //發送在線檢測命令
  12.             CAN_SendData.DataLen = 0;
  13.             CAN_SendData.ExternFlag = 0;
  14.             CAN_SendData.RemoteFlag = 0;
  15.             CAN_SendData.SendType = 0;
  16.             CAN_SendData.ID = (local_addr<<4)|ONLINE_CHECK;
  17.             ret = VCI_Transmit(VCI_USBCAN2,
  18.                                ui->deviceIndexComboBox->currentIndex(),
  19.                                ui->channelIndexComboBox->currentIndex(),
  20.                                &CAN_SendData,
  21.                                1);
  22.             if(ret!=1){
  23.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  24.             }
  25.             retry = 0;
  26.             while(1){
  27.                 ret = VCI_Receive(VCI_USBCAN2,
  28.                                   ui->deviceIndexComboBox->currentIndex(),
  29.                                   ui->channelIndexComboBox->currentIndex(),
  30.                                   &CAN_ReadData[0],
  31.                                   1);
  32.                 if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==CMD_OK)){
  33.                     mac_str.sprintf("%02X%02X%02X%02X%02X%02X%02X%02X",
  34.                                     CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1],
  35.                                     CAN_ReadData[0].Data[2],CAN_ReadData[0].Data[3],
  36.                                     CAN_ReadData[0].Data[4],CAN_ReadData[0].Data[5],
  37.                                     CAN_ReadData[0].Data[6],CAN_ReadData[0].Data[7]);
  38.                     model->item(i,1)->setText(mac_str);
  39.                     break;
  40.                 }else{
  41.                     if(retry<10){
  42.                         Sleep(10);
  43.                         retry++;
  44.                     }else{
  45.                         for(int c=0;c<model->columnCount();c++){
  46.                             model->item(i,c)->setText("");
  47.                         }
  48.                         can_addr.local_addr[i+1]=0;
  49.                         break;
  50.                     }
  51.                 }
  52.             }
  53.         }
  54.     }
  55.     QCoreApplication::processEvents(QEventLoop::AllEvents);
  56.     //獲取版本信息
  57.     for(i=0;i<model->rowCount();i++){
  58.         uint32_t local_addr,retry=0;
  59.         if(!model->item(i,0)->text().isEmpty()){
  60.             //清除之前接收的數據
  61.             VCI_ClearBuffer(VCI_USBCAN2,
  62.                             ui->deviceIndexComboBox->currentIndex(),
  63.                             ui->channelIndexComboBox->currentIndex());
  64.             local_addr = model->item(i,0)->text().toInt(NULL,0);
  65.             //發送在線檢測命令
  66.             CAN_SendData.DataLen = 0;
  67.             CAN_SendData.ExternFlag = 0;
  68.             CAN_SendData.RemoteFlag = 0;
  69.             CAN_SendData.SendType = 0;
  70.             CAN_SendData.ID = (local_addr<<4)|GET_VERSION;
  71.             ret = VCI_Transmit(VCI_USBCAN2,
  72.                                ui->deviceIndexComboBox->currentIndex(),
  73.                                ui->channelIndexComboBox->currentIndex(),
  74.                                &CAN_SendData,
  75.                                1);
  76.             if(ret!=1){
  77.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  78.             }
  79.             retry = 0;
  80.             while(1){
  81.                 ret = VCI_Receive(VCI_USBCAN2,
  82.                                   ui->deviceIndexComboBox->currentIndex(),
  83.                                   ui->channelIndexComboBox->currentIndex(),
  84.                                   &CAN_ReadData[0],
  85.                                   1);
  86.                 if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==GET_VERSION)){
  87.                     str.sprintf("V%d.%d",CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1]);
  88.                     model->item(local_addr-1,2)->setText(str);
  89.                     break;
  90.                 }else{
  91.                     if(retry<10){
  92.                         Sleep(10);
  93.                         retry++;
  94.                     }else{
  95.                         break;
  96.                     }
  97.                 }
  98.             }
  99.         }
  100.     }
  101. }

  102. void MainWindow::on_openFilePushButton_clicked()
  103. {
  104.     QString fileName;
  105.     fileName=QFileDialog::getOpenFileName(this,
  106.                                           tr("Open files"),
  107.                                           "",
  108. ……………………

  109. …………限于本文篇幅 余下代碼請下載附件…………
復制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規則

手機版|小黑屋|ELEOK |網站地圖

GMT+8, 2026-5-26 02:48

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回復 返回頂部 返回列表