完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1. 案例概述
在制作在线升级软件的CAN通信协议时,为了能够对多个MCU进行同时升级,并且可靠地获取每个MCU的升级状态,需要对MCU的CAN节点进行编址。 假如我们只想实现每次仅仅升级一个MCU,那就没必要对其进行编址了。 假如我们想要每次升级多个MCU,并且采用对正确结果不回复、只对错误结果回复的方式,也不必编址。只有升级失败的MCU回复失败标志,但这样统计的结果却是不可靠的。 2. 问题原因分析 在过去,曾经使用拨码开关,对电池均衡装置的24个模块手工编址。但是拨码开关并不是标准配置,退一步说,作为通用Boot loader当然也不应该依赖拨码开关,所以要考虑一种不需要拨码开关的自动编址方法。我们使用的STM系列芯片,每个芯片有一个全球唯一的“设备唯一标识符”(Unique Device ID),简称UDID。这是能够可靠地区分各个芯片的数据。 接下来考虑CAN通信的特点。CAN通信是一种不分主机从机的通信,所有节点都可以主动发送报文,这是其他通信方式,比如以485为例的串口等,所不具备的。为了防止多个节点同时发送不同报文产生的错误,CAN通信采用仲裁机制对报文的ID进行仲裁。因为CAN通信的仲裁机制不对DLC和DATA进行仲裁,所以我们不可以通过DATA传递UDID信息的。上位机要想获取所有MCU的UDID信息,MCU就必须将UDID信息放置在CAN报文的ID中。 3. 解决方案 我们分析一下STM系列芯片的UDID的特点,以及CAN报文ID的特点。UDID是96位的整数,而CAN报文ID分两种情况,标准帧有11位,扩展帧有29位。为了每条报文能够容纳尽可能多的信息,我们采用扩展帧格式。将96位的UDID分成若干组,分别放置在CAN报文ID中,只要简单的算术就能算出,至少要拆成4组,每组24位。这样,ID剩余了5位,这5位能够表达32种命令,对一个简单的Boot loader来说,已经足够了。 我们通过4条不同的召唤报文,将4组UDID片段分别召唤上来。上位机要做的事情,当然就是压缩了,将每个24位的片段压缩成n位,然后将压缩前的片段和压缩后的片段,它们的对应关系广播给全体MCU。MCU收到所有的对应关系,对照自身的UDID,算出属于自己的4组压缩后的片段。MCU将4组压缩后的片段,再次拼接起来,得到4n位的压缩UDID,作为自己的地址,传送给上位机。上位机收到地址,便可知道对应MCU的存在。 首先考虑压缩的办法,这里使用最单纯的占座法。将收到的片段,按照时间顺序,从1开始对号入座。 接下来考虑n的取值,要想将4n位全部放置在CAN的29位ID中,n能取到的最大值是7,这样理论上可以区分128个不同的MCU。但这样会对CAN报文的ID空间造成很大破坏。退而求其次,n取值为6,这样理论上可以区分64个不同的MCU,4组压缩后的地址片段共占用24位,这和压缩前的每个地址片段的位数恰好是一样的,也便于制作协议。考虑到地址中不宜出现全0和全1,以及保留一些情况以备扩展,我们编号时,从1到60进行编号,这样就避开了全0的0号和全1的63号,同时保留了61号和62号备用。目前我们的产品,同时连接60个已经足够了。 上位机收到24位的压缩UDID后,将其拆成4组,每组6位,并各自解压缩,便可还原出真实的UDID。 这里其实涉及一个说法问题。两片MCU的UDID一定不同,但是其分成4份之后,1片MCU的某1份很可能和其他MCU的对应位置的1份相同。考虑最极端的情况,我们连接了60 × 60 × 60 × 60个MCU(暂不考虑CAN网络本身容纳节点的能力),而它们的UDID在压缩后,每个UDID片段,在去除重复后都只剩60个不同的。这样的结果,使得所有MCU都正常识别了。但我们不能因此而宣称我们支持60 × 60 × 60 × 60个MCU的同时升级,我们只能宣称我们支持60个MCU可以同时升级。为了避免多于60个的MCU的成功编址,上位机要最后加一个确认报文,认可60个以内的MCU的地址,否决第60个以后的MCU的地址。 4. 实践情况 定义上位机与MCU的通信协议。上位机不必给自己编址,只要注意避免发生ID冲突即可。下面是协议中有关编址的部分。 4.1. 请求UDID 上位机向MCU请求各自的UDID。每次召唤其中的1组。 表 4-1 由PC发给MCU的UDID请求
表 4-2 请求UDID的组号与片段的关系
表 4-3 由MCU发给PC的UDID回应
4.2. 分配地址 上位机通过收集UDID的报文,统计每个UDID片段并各自独立编号: 1°统计UDID[95:72]的数据,去掉重复数据后,以报文中的时间标识为准,取不超过60个数据,从1开始分配编号,这个编号记做ADDR_I; 2°统计UDID[71:48]的数据,去掉重复数据后,以报文中的时间标识为准,取不超过60个数据,从1开始分配编号,这个编号记做ADDR_J; 3°统计UDID[47:24]的数据,去掉重复数据后,以报文中的时间标识为准,取不超过60个数据,从1开始分配编号,这个编号记做ADDR_K; 4°统计UDID[23:0]的数据,去掉重复数据后,以报文中的时间标识为准,取不超过60个数据,从1开始分配编号,这个编号记做ADDR_L。 表 4-4 由PC发给MCU的分配ADDR_I报文
表 4-5 由PC发给MCU的分配ADDR_J报文
表 4-6 由PC发给MCU的分配ADDR_K报文
表 4-7 由PC发给MCU的分配ADDR_L报文
地址片段与地址的拼接关系如下表: 表 4-8 地址片段与地址的拼接关系
MCU得到完整的装置地址后,将自身的内置Flash容量回复给上位机。 表 4-9 由MCU发给PC的设备信息
上位机据此报文,按照时间顺序取60个有效地址,发送允许升级报文。 表 4-10 由PC发给MCU的允许升级报文
UP_ALLOW是升级允许标志,0x55表示允许升级,0xAA表示禁止升级。 5. 效果评价 效果和我们预期的一致。 拿12个MCU进行测试,截取上位机记录的编址部分的报文如下: TX: 13000013 14 RX: 14431337 00 RX: 14431337 00 RX: 14431339 00 RX: 14431556 00 RX: 14431557 00 RX: 14431757 00 RX: 14432042 00 TX: 13000013 15 RX: 15253232 00 RX: 15343135 00 RX: 15403135 00 RX: 15413135 00 RX: 15433135 00 RX: 15483135 00 RX: 15503135 00 RX: 15513135 00 RX: 15523135 00 RX: 15533135 00 RX: 15593135 00 RX: 15613135 00 TX: 13000013 16 RX: 164E3405 00 RX: 16524105 00 TX: 13000013 17 RX: 17D2FF32 00 RX: 17D5FF32 00 RX: 17D6FF32 00 RX: 17D6FF34 00 RX: 17D7FF32 00 RX: 17DAFF32 00 TX: 13000014 43 13 37 01 TX: 13000014 43 13 39 02 TX: 13000014 43 15 56 03 TX: 13000014 43 15 57 04 TX: 13000014 43 17 57 05 TX: 13000014 43 20 42 06 TX: 13000015 25 32 32 01 TX: 13000015 34 31 35 02 TX: 13000015 40 31 35 03 TX: 13000015 41 31 35 04 TX: 13000015 43 31 35 05 TX: 13000015 48 31 35 06 TX: 13000015 50 31 35 07 TX: 13000015 51 31 35 08 TX: 13000015 52 31 35 09 TX: 13000015 53 31 35 0A TX: 13000015 59 31 35 0B TX: 13000015 61 31 35 0C TX: 13000016 4E 34 05 01 TX: 13000016 52 41 05 02 TX: 13000017 D2 FF 32 01 RX: 0C045081 01 00 F1 07 TX: 13000017 D5 FF 32 02 RX: 0C046082 01 00 F1 07 RX: 0C048082 01 00 F1 07 RX: 0C049082 01 00 F1 07 RX: 0C0CB082 01 00 F1 07 RX: 0C10C082 01 00 F1 07 TX: 13000017 D6 FF 32 03 RX: 0C043083 01 00 F1 07 RX: 0C14A083 01 00 F1 07 TX: 13000017 D6 FF 34 04 RX: 0C181044 01 00 F1 07 TX: 13000017 D7 FF 32 05 RX: 0C082085 01 00 F1 07 RX: 0C047085 01 00 F1 07 TX: 13000017 DA FF 32 06 RX: 0C044086 01 00 F1 07 TX: 1300000C 04 50 81 55 TX: 1300000C 04 60 82 55 TX: 1300000C 04 80 82 55 TX: 1300000C 04 90 82 55 TX: 1300000C 0C B0 82 55 TX: 1300000C 10 C0 82 55 TX: 1300000C 04 30 83 55 TX: 1300000C 14 A0 83 55 TX: 1300000C 18 10 44 55 TX: 1300000C 08 20 85 55 TX: 1300000C 04 70 85 55 TX: 1300000C 04 40 86 55 上位机成功整理出这12片MCU的UDID,如下(分4组以十六进制显示): 431337.433135.524105.D2FF32 431337.483135.524105.D5FF32 431337.513135.524105.D5FF32 431337.523135.524105.D5FF32 431556.593135.524105.D5FF32 431557.613135.524105.D5FF32 431337.403135.524105.D6FF32 431757.533135.524105.D6FF32 432042.253232.4E3405.D6FF34 431339.343135.524105.D7FF32 431337.503135.524105.D7FF32 431337.413135.524105.DAFF32 我们看一看上位机发出的第一条报文,即TX: 13000013 14。 理论上应该收到12条报文回复,但实际上只收到了7条,可以看出,其中有很多条,由于报文内容完全一致,在报文仲裁时同时通过仲裁,使得上位机只收到了1条。但也并非所有的相同报文都这样合并了,实际上我们收到了两条RX: 14431337 00。 经过多次调整和测试,为了能够可靠认出全部的MCU,我们需要将报文的等待时间放得很长。采用1000kbps的比特率,每条召唤报文需要等200毫秒。 6. 推广建议 这种自动编址方案,对于自动升级这类一次性使用的场合,非常合适。 但是,对于需要长久运行的场合,这种自动编址方案并不适合。首先这需要一个扮演上位机的节点,进行地址分配;这个地址分配会很耗时;由于所有地址都是临时地址,所以任何一个节点,一旦因为任何原因而丢失地址,就必须令整个网络重新进行地址分配,否则这个节点便再也无法回到网络中。 要想将这种自动编址方案应用到产品中,还需要改良。 |
||||
|
||||
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1251 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1265 浏览 1 评论
666 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
495 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1250 浏览 2 评论
1699浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
388浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
359浏览 3评论
346浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
324浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-11 17:17 , Processed in 1.023318 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191