Giter Site home page Giter Site logo

usbxyz / can-bootloader Goto Github PK

View Code? Open in Web Editor NEW
327.0 38.0 229.0 5.02 MB

使用USB2XXX实现的CAN Bootloader功能,实现CAN节点固件远程升级

License: GNU General Public License v3.0

C 88.39% Assembly 9.61% HTML 1.43% C++ 0.09% QMake 0.01% C# 0.17% Java 0.12% Batchfile 0.18% LabVIEW 0.01%

can-bootloader's Introduction

CAN-Bootloader

使用USB2XXX实现的CAN Bootloader功能,实现CAN节点固件远程升级

基于大家的需求,我们重新推出了基于CAN UDS协议的Bootloader/固件升级,程序通用性更强,也更加实用,代码下载链接:https://gitee.com/toomoss_admin/can_uds_bootloader

功能简介

  • 利用CAN总线实现对有CAN总线接口的设备进行固件升级;
  • 升级采用一键升级方式,傻瓜式操作,方便使用;
  • 用户可以自己修改上位机源码和下位机源码,实现固件的加密传输;
  • 目前此项目包含了STM32F1,STM32F2,STM32F4系列单片机示例源码,后面会增加其他单片机源码;
  • 上位机界面程序目前是用Qt(C++)实现,同时也有C#,Labview及安卓版本代码;

使用步骤

1,将USB2XXX(USB2CAN适配器)通过一个CAN收发器模块(如:TJA1050)连接到CAN总线上,同时将要实现升级功能的板子也连接到CAN总线上。
2,找到和你所使用的单片机对应的源码,比如为STM32F103芯片,用keil 5打开bootloader/RVMDK目录下的工程,检查下你的CAN总线引脚配置是否跟我代码里面的一样,若是一样的,则可以直接编译下载,若不一样,则需要更改CAN总线引脚配置部分代码;
3,和bootloader同目录下有个app目录,同样打开app/RVMDK目录下的工程文件,并编译工程,若一切正常的,那么在app/RVMDK/Output目录下应该会生成一个.bin文件,这个就是我们后面用来升级的固件;
4,使用Qt5打开software/CANBootloader-Qt/project目录下的CAN_Bootloader.pro文件,点击“构建”->“运行”即可编译运行此程序(若没有Qt开发环境,可以直接下载我打包好的程序,安装后即可运行,百度网盘下载地址:http://pan.baidu.com/s/1hsFjZMk ,在“软件”->“CANBootloader”目录)。
5,运行CANBootloader上位机软件后,点击“操作”->“扫描节点”,此时软件会弹出节点地址范围设置对话框,设置好扫描的节点返回,点击“确定”之后软件就开始扫描节点,同时将扫描到的节点显示在节点列表里面,选择列表里面的节点,然后再点击界面上的“打开文件”按钮,在弹出的文件浏览对话框中找到第3步编译出来的.bin文件,然后再点击“更新固件”按钮,此时就会开始固件更新,固件更新成功后,节点列表里面的节点固件类型会由原来的“BOOT”变成“APP”,到此固件更新完毕。
6,若当前固件是“APP”的情况下,一样是可以进行固件更新的,只是在更新固件之前程序会有一个固件跳转的操作,具体流程可以参考源码。

参考资料

好消息!!!

很高兴这个项目得到大家的认可,也有很多人将代码拿到自己的工程中使用,基于大家的反馈,也发现了当前版本的一些不足,所以我又花了些时间,重新制定了一套协议,重新实现了CAN Bootloader代码。 目前协议文档已经写好,上位机软件也修改完成,单片机代码目前只实现了STM32F4的代码,后续会逐步完善,等我把这些资料和代码整理下之后再发布出来,若急需的用户可以通过上面的联系方式联系我获取代码和资料。 目前新版本的协议和代码改进点如下:

  • 之前数据传输会用到多个ID,而且节点地址也定义在ID中,实际使用中发现这样做非常不合理,因为CAN的ID对于一个CAN网络来说非常宝贵,特别是在汽车CAN网络中,这样传输协议会浪费大量的帧ID,而且很多时候也是不允许这样做的,所以新版本的协议数据传输可以用一个ID实现,最多2个ID(可以自己配置)。
  • 新版本的协议在进行多个节点同时更新时,稳定性和可靠性更高,之前的版本无法获取每个节点的更新状态,所以在更新的时候若某个节点更新出错是无法知道的,而新版本的协议弥补了这个不足。
  • 之前版本的协议在数据传输出错后没法知道数据是传输出错还是写入芯片出错,新版本的协议弥补了这个不足,若发现数据传输出错,可以对数据进行重新传输。
  • 新版本的协议在对数据进行块传输时增加了每一帧的数据包序号,如此可以更加可靠的传输数据,从节点接收到数据后也更容易对数据进行重新组包。
  • 新版本协议在制定的时候考虑到了使用其他总线进行更新,比如UART,SPI,IIC,LIN等,所以通用性更强,同样的代码更容易移植到使用其他总线进行更新。

can-bootloader's People

Contributors

usbxyz avatar wdluo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

can-bootloader's Issues

本人学习STM32_CAN通信协议,参考博主代码,提几个疑问!

本人使用STM32F103ZET6型号单片机,CAN1的TX RX引脚复用到GPIOD_0和GPIOD_1上面。
image
在参考了博主的资料后以下是本人的GPIO初始化代码,如有问题还请帮忙指正!

static void CANPort_GPIO_Config(void)
{	
	/*-----------------1.使能GPIO_D并重映射为CAN1---------------------*/
	/*-----------------1.1使能GPIO_D1 CAN TX引脚---------------------*/
	 GPIO_InitTypeDef  GPIO_InitStructure;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); 		//使能GPIOD的时钟                                                                
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);    //使能CAN1时钟
	 
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;			//CAN TX发送引脚
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	/*-----------------1.2使能GPIO_D0 CAN RX引脚---------------------*/
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入
	 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
	 GPIO_Init(GPIOD,&GPIO_InitStructure);			//初始化TX引脚

	 
	 GPIO_PinRemapConfig(GPIO_Remap2_CAN1,  ENABLE);
	
	

}

static void CAN_Mod_Config(void)
{		
	/*--------CAN配置结构体---------------*/
		CAN_InitTypeDef CAN_InitStructure;
		CAN_FilterInitTypeDef   CAN_FilterInitStructure;
		CAN_DeInit(CAN1);											//CAN结构体复位
		CAN_StructInit(&CAN_InitStructure);		//CAN结构体初始化
#if CAN_INT_ENABLE
    NVIC_InitTypeDef        NVIC_InitStructure;	 
#endif
//	  CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能
//		CAN_InitStructure.CAN_ABOM=ENABLE; //MCR-ABOM 使能自动离线管理
//		CAN_InitStructure.CAN_AWUM=ENABLE; //MCR-AWUM 使用自动唤醒模式
//		CAN_InitStructure.CAN_NART=DISABLE; //MCR-NART 禁止报文自动重传
//		CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收 FIFO 不锁定
	/*------------------设置CAN的工作模式-------------------------*/
		CAN_InitStructure.CAN_TTCM=DISABLE;         //非时间触发通信模式  
		CAN_InitStructure.CAN_ABOM=DISABLE;         //软件自动离线管理   
		CAN_InitStructure.CAN_AWUM=DISABLE;         //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
		CAN_InitStructure.CAN_NART=ENABLE;          //禁止报文自动传送 
		CAN_InitStructure.CAN_RFLM=DISABLE;         //报文不锁定,新的覆盖旧的  
		CAN_InitStructure.CAN_TXFP=DISABLE;         //优先级由报文标识符决定 
		CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;  //模式设置:CAN_Mode_Normal 普通模式,CAN_Mode_LoopBack 回环模式;
		
	/*--------------------设置CAN的通信速率----------------------------*/
	//CANbps= Fpclk/((BRP+1)*((Tseg1+1)+(Tseg2+1)+1)
	//例如CANbps=APB1总线频率30000000/4/(8+6+1))=500k bps
	//总体配置方向: Tseg1>=Tseg2  Tseg2>=tq; Tseg2>=2TSJW 
			CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;  //设置项目(1~4)
			CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //设置项目(1~16)
			CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //设置项目(1~8)
			CAN_InitStructure.CAN_Prescaler=10;			//设置项目(1~1024)
		
			CAN_Init(CAN1,&CAN_InitStructure);
		/*---------------设置过滤器------------------------*/
		CAN_FilterInitStructure.CAN_FilterNumber = 0;
		CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;   //屏蔽位模式
    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;  //32位宽 
    CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;    //32位ID
    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0
    CAN_FilterInit(&CAN_FilterInitStructure);           //滤波器初始化
		
#if CAN_INT_ENABLE 	//以下是用于CAN中断方式接收的设置
    CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);              //FIFO0消息挂号中断允许.            
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
#endif
}

关于通讯协议文档的疑问

也就是当命令地址为0的时候,每个节点收到命令之后都应该执行该命令,但是由于同一时刻,CAN总线上不能传输多个节点的数据,所以这些从节点再执行0地址命令的时候可以不用返回状态

不能同时传输,但可以依次传输啊,为何不能返回状态呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.