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币)
部分源程序如下:
- QCoreApplication::processEvents(QEventLoop::AllEvents);
- //检测在线状态
- for(i=0;i<model->rowCount();i++){
- uint32_t local_addr,retry=0;
- if(!model->item(i,0)->text().isEmpty()){
- //清除之前接收的数据
- VCI_ClearBuffer(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex());
- local_addr = model->item(i,0)->text().toInt(NULL,0);
- //发送在线检测命令
- CAN_SendData.DataLen = 0;
- CAN_SendData.ExternFlag = 0;
- CAN_SendData.RemoteFlag = 0;
- CAN_SendData.SendType = 0;
- CAN_SendData.ID = (local_addr<<4)|ONLINE_CHECK;
- ret = VCI_Transmit(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex(),
- &CAN_SendData,
- 1);
- if(ret!=1){
- QMessageBox::warning(this,"Warning","Send Data Error!");
- }
- retry = 0;
- while(1){
- ret = VCI_Receive(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex(),
- &CAN_ReadData[0],
- 1);
- if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==CMD_OK)){
- mac_str.sprintf("%02X%02X%02X%02X%02X%02X%02X%02X",
- CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1],
- CAN_ReadData[0].Data[2],CAN_ReadData[0].Data[3],
- CAN_ReadData[0].Data[4],CAN_ReadData[0].Data[5],
- CAN_ReadData[0].Data[6],CAN_ReadData[0].Data[7]);
- model->item(i,1)->setText(mac_str);
- break;
- }else{
- if(retry<10){
- Sleep(10);
- retry++;
- }else{
- for(int c=0;c<model->columnCount();c++){
- model->item(i,c)->setText("");
- }
- can_addr.local_addr[i+1]=0;
- break;
- }
- }
- }
- }
- }
- QCoreApplication::processEvents(QEventLoop::AllEvents);
- //获取版本信息
- for(i=0;i<model->rowCount();i++){
- uint32_t local_addr,retry=0;
- if(!model->item(i,0)->text().isEmpty()){
- //清除之前接收的数据
- VCI_ClearBuffer(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex());
- local_addr = model->item(i,0)->text().toInt(NULL,0);
- //发送在线检测命令
- CAN_SendData.DataLen = 0;
- CAN_SendData.ExternFlag = 0;
- CAN_SendData.RemoteFlag = 0;
- CAN_SendData.SendType = 0;
- CAN_SendData.ID = (local_addr<<4)|GET_VERSION;
- ret = VCI_Transmit(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex(),
- &CAN_SendData,
- 1);
- if(ret!=1){
- QMessageBox::warning(this,"Warning","Send Data Error!");
- }
- retry = 0;
- while(1){
- ret = VCI_Receive(VCI_USBCAN2,
- ui->deviceIndexComboBox->currentIndex(),
- ui->channelIndexComboBox->currentIndex(),
- &CAN_ReadData[0],
- 1);
- if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==GET_VERSION)){
- str.sprintf("V%d.%d",CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1]);
- model->item(local_addr-1,2)->setText(str);
- break;
- }else{
- if(retry<10){
- Sleep(10);
- retry++;
- }else{
- break;
- }
- }
- }
- }
- }
- }
- void MainWindow::on_openFilePushButton_clicked()
- {
- QString fileName;
- fileName=QFileDialog::getOpenFileName(this,
- tr("Open files"),
- "",
- ……………………
- …………限于本文篇幅 余下代码请下载附件…………
复制代码
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|
|