Linux系统下通过CAN总线更新程序

2019-05-22 09:27杨超胡旭
无线互联科技 2019年4期
关键词:CAN总线

杨超 胡旭

摘 要:在嵌入式设备研发过程中,程序的更新是不可避免的问题。如果嵌入式设备数量众多或者已经封闭安装,使用连线下载方式重新将全部设备更新程序,将是一项困难的工作。所以使用远程方式进行程序的更新是嵌入式设备必不可少的一项功能。无操作系统嵌入式设备一般在用户程序段之前加入一段IAP程序段,在开机之后先运行IAP程序,如果需要升级程序进入接收状态,最后将接收到的程序覆盖用户程序段完成升级。而内嵌操作系统的嵌入式设备就更容易一些,只需要增加一个接收升级指令的线程,将更新后的程序替换原有文件就完成了升级。这两种处理方式大多数都是通过以太网接收升级包,而文章讨论的嵌入式设备底层不具备以太网接口,而是使用CAN总线完成整个升级过程。

关键词:CAN总线;远程更新;Linux系统

中国飞机强度研究所自主研发设计生产的数据采集系统,结构如图1所示。

客户端使用以太网与通讯控制器相连接,而每一个通讯控制底下连接了数个采集模块,每一个采集模块都内嵌Linux操作系统。通讯控制器负责接收客户端发送的各种命令,将命令解析后,按需要将解析后的命令通过控制器局域网络(Controller Area Network,CAN)总线发送给相应对的采集模块,采集模块在收到命令后完成相应的任務并通过CAN总线将数据结果返回通讯控制器。通讯控制器将数个采集模块返回的数据包整合,按照一定的格式打包返回给客户端,这样就完成了整个命令下发和数据返回的过程。在实际使用中,如果每一次更新都需要把采集模块从机箱中拆出,更新后在安装,这样的工作量是非常巨大的。所以在本系统中使用远程更新是非常必需的。由于采集模块与通讯控制器之间只有CAN总线连接,而没有以太网接口,如果需要完成远程升级的任务,就无法按照以往的以太网方式进行[1]。本文详细介绍如何使用CAN总线来完成整个升级的过程。

1 软件设计说明

采集模块的程序远程更新的过程涉及两部分的软件设计:通讯控制器与采集模块。通讯控制器负责接收升级命令和升级数据包并下发,这部分的远程升级使用IAP方式,由于此方式使用较为广泛,例程较多,比较简单不再过多阐述。采集模块使用Freescale 的i.MX6Q处理器,内嵌Linux操作系统[2]。程序流程如图2所示。

在采集模块中,处理正常工作所需要的执行文件之外,增加了update可执行文件,负责完成升级工作。在程序主线程运行过程中,如果收到上层发来升级的命令,主线程首先关闭与AD转换相关的副线程,关闭主线程,然后开启软件升级线程。在软件升级线程中,主要工作有:判断升级类型、建立备份升级文件、接收升级数据、写入备份文件、校验文件、替换原有执行文件。在完成了升级线程所有步骤之后,将升级结果发送主机,然后板卡自动重启执行更新后的程序。

在整个升级过程中需要注意以下两个地方:(1)在开始执行升级前需要关闭正在运行的线程,因为升级的程序有可能就是正在执行的程序,如果边执行边进行文件替换有可能造成文件写入错误。(2)需要建立备份文件,将所有更新的程序写入,最后进行更新数据的校验,如果校验通过则开始替换原文件。

由于是使用CAN总线进行数据接收,每一个CAN数据包可接收8字节数据,除去命令头、控制字节、计数字节,每一个CAN数据包只能发送4个字节的升级数据。并且系统在正常的升级过程中一次性会同时升级多个机箱,所以本系统在升级过程中充分利用了双层通讯结构,在同时升级多个机箱的情况下,首先将需要升级的可执行文件使用以太网分别下发给各个通讯控制器,通讯控制器将数据暂存在本地。接下来通讯控制器将升级数据分解成多个4字节的CAN数据包依次下发给每一个采集模块。本系统中CAN总线速度设置为750 kb/s,在同时升级8个板卡并且合理协调时间间隔后,在升级文件为2 M左右大小时,实测整个升级过程需要几分钟[3]。

2 程序说明

在升级线程启动之后,首先进行外部资源的初始化,关闭相关的线程,然后进入命令接受状态,根据命令种类不同进入不同的处理流程,随后进入升级开始函数,首先打开备份文件,将收到的升级数据写入备份文件,进行数据校验,并记录数据总数:

Data_Update_Start()

{

unsigned char write_buff[4],i;

if(first_open == 0)

{

first_open = 1;

txt_fd = open(“test_copy”, O_RDWR); //打开升级备份文件

if (-1 == txt_fd)

{

printf(“open error\n”);

}

else

{

printf(“open success,txt_fd = %d\n”, txt_fd);

}

}

for(i=0;i<4;i++)

write_buff[i] = recievedata[i+4];

ret = write(txt_fd, write_buff, recievedata[1]);

if (ret < 0)

{

printf(“write error.\n”);

update_count = -1;

}

CRC_check(); //数据校验 如未通过校验,客户端会重新发送这一段数据

update_count = update_count + recievedata[1]; //升级数据计数

}

Data_Update_Finish()

{

unsigned char i,size;

unsigned long long_size;

close(txt_fd);

first_open = 0;

for(i=0;i<8;i++)

frame.data[i] = 0;

frame.data[0] = 0xF2;

frame.data[1] = DAU_number;

long_size = update_count& 0x000000ff;

size = (char) long_size;

frame.data[7] = size;

long_size = update_count& 0x0000ff00;

long_size = long_size >> 8;

size = (char) long_size;

frame.data[6] = size;

long_size = update_count& 0x00ff0000;

long_size = long_size >> 16;

size = (char) long_size;

frame.data[5] = size;

long_size = update_count& 0xff000000;

long_size = long_size >> 24;

size = (char) long_size;

frame.data[4] = size;

frame.can_dlc = 8;

nbytes = sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr));

}

最后的升級完成函数中首先判断升级上位机发送的升级指令中,指明的需要升级的可执行文件。然后将已经更新完成的备份文件替换掉原可执行文件。最后向上位机发送升级成功报告并重新启动采集板卡,完成整个升级过程。此部分软件考虑到篇幅限制不在此列出。

3 结语

按照以上的远程升级软件设计,理论课可同时进行255台采集机箱的升级工作。由于CAN总线通讯升级部分各个机箱是并行运行,多台升级与单台采集机箱升级消耗时间几乎相同。实际测试同时升级8台机箱,更新AD采样计算部分程序时,该部分可执行文件大小为2.2 M,共用时5分28秒。虽然从文件传输角度考虑速度比较慢,但是考虑到系统升级对于时间要求不高且此方法的远程升级大大减少了现场拆装工作量,节省了数十倍的时间,本文讨论的测量系统的远程升级功能已经圆满完成了任务。

[参考文献]

[1]宋宝华. Linux设备驱动开发详解[M].2版.北京:人民邮电出版社,2008.

[2]MATTHEW N,STON R.Linux程序设计[M].4版.北京:人民邮电出版社,2007.

[3]斯洛斯.ARM嵌入式系统开发:软件设计与优化[M].北京:北京航空航天大学出版社,2005.

猜你喜欢
CAN总线
基于嵌入式的汽车辅助制动系统研究