bootloader和app之间的注意问题以及调试技巧【基于s32ds】

汽车ECU常见的数据总线有CAN和LIN,因此通常汽车ECU的bootloader都是通过CAN或者LIN下载数据的。当然也可以基于其他总线,比如基于SPI总线或者I2C总线(典型如一些带有安全监测的功能安全ECU,通过主MCU对功能安全监测MCU的程序进行升级)以及以太网(基于Enternet通信的中控或者全液晶仪表的ECU以及下一代高速网关和ADAS
ECU)。

@TOC - 通信协议

为了保证通信的可靠性,必须开发一个基于通信总线完善的通信协议,应用程序下载端和bootloader之间需要建立请求命令(request
command)、确认(acknowledge)、等待(block wait)、错误重传(errorre-send)等机制----bootloader根据不同的请求命令完成不同的任务并确认操作是否完成(ACK)以及数据是否正被确完整的传输,若出现数据错误(通过校验和或者ECC实现),需要进行自动重传

为了实现数据的可靠传输,一般在总线通信协议中添加信源编码,即在发送是对有效数据进行校验和或者ECC计算并将结果在通信数据帧中和有效数据一起发送,bootloader接收端,接收到数据帧后对有效数据域进行发送端同样的校验和或者ECC计算,得出结果与接收到的校验和或者ECC计算结果值进行比较从而判断数据的完整性。应用程序编程文件(S19/HEX/BIN)都具有相应的校验和机制,所以可以采取直接传送程序编程文件行的方式;否则,用户需要在上位机软件中首先解析编程文件,再将其中的地址和数据及代码封装打包成某种定制的通信协议,在bootloader中还得对其进行解包,这样一来,略显麻烦,但有些主机厂(Car OEM)为了知识产权保护,有自己的bootloader协议,这种情况下,bootloader开发者就必须按照主机厂的要求来开发;

一些正规的大主机厂要求其ECU供应商开发放入ECU bootloader必须基于UDS等总线诊断协议,在UDS中规定了相应的CAN
ID给bootloader使用,那么久必须在该类ECU中的bootloader工程中加入相应的UDS协议栈;

@TOC - 嵌入式C语言应用工程中堆栈的定义和作用

堆(heap)是用于动态分配内存的RAM区域,heap的空间是用户手动申请和释放的:C语言中的malloc(size), calloc(num, size)函数分配heap,释放使用free(*heap)函数;
.bss:未初始化段,MCU启动 (boot/startup)过程中会将该RAM区初始化为0;

.data:数据段,该RAM区存放初始化值不为0的全局变量,其初始化值放置在编译结果的.copy(Flash/EEPROM)数据区,每次MCU启动(boot/startup)时,会将其初始值取出对.data区进行初始化;

.stack:栈段,该地址空间的大小在C工程的链接文件中给出,CPU会自动保留该区域,不对其进行任何初始化,但在进入C语言main ()函数之前必须将.stack的起始地址 (stack的最小地址或者最高地址,也称为栈顶—stacktop,具体取决于该CPU架构的栈生长方式) 赋值给CPU的栈指针寄存器SP (stack pointer) ,该过程也被称为堆栈初始化;
.heap:堆段,该地址空间的大小在C工程的链接文件中给出,CPU会自动保留该区域,并初始化用于堆管理的指针链表;因为嵌入式MCU的片上RAM资源都非常小,是十分宝贵的资源,而使用heap对RAM空间进行动态管理效率极低,所以在嵌入式编程中极少使用heap,默认的嵌入式MCUC语言应用工程中是没有.heap段的;
.text: 代码段,用于存放C应用工程中所有C函数代码的编译结果,比如启动函数startup,main函数等;
.copy:拷贝段,用于存放.data段的初始化值;
.const:常量段,用于存放工程中使用const修饰定义或者#define定义的常量;
interrupt vector table:中断向量表,用于存放包含默认复位向量在内的内核CPU异常和外设中断向量表,其为内核CPU异常或者外设中断的中断服务函数ISR地址数组;

KEIL 编译结果示例:
Code(CODE DATA):代码的大小 ,存储在ROM中,掉电保存
RO(read only data)	:常量所占空间 ,只读,存储在ROM中
RW(已初始化可读可写数据段RW DATA)	:程序中已经初始化的变量所占空间 ,可读可写变量,既在ROM中,又在RAM中存储
ZI	:未初始化的static变量和全局变量以及堆栈所占的空间 ,初始化为0的变量,存储在RAM中

计算公式:
RAM = RW  +  ZI;
ROM = code  +  RW  +  RO;

-@TOC堆栈大小确定

嵌入式MCU软件开发集成环境(IDE)中的链接器(linker)会根据工程的链接文件(linkerfile)分配stack的大小的地址范围,在工程编译生成的map(内存映射)文件中能够看到stack占用具体RAM地址范围;当然在map文件中一般也可以看到工程中各函数的调用关系,从而可以分析出工程的最大函数调用层级;然后debug工程,在该最大调用函数中设置一个断点,观察CPU的SP寄存器值,用该值与栈顶相减即可得到该工程函数调用所需的最大stack空间;在该值的基础上考虑中断嵌套,再增加相应的中断嵌套所需的stack消耗,即可估计出整个工程运行时所需的stack大小。当然如果某个函数中使用了大量的局部变量,那可能包含该函数的调用嵌套才是整个工程的“关键路径”,而非真实调用层级最多但不包含该函数的”关键路径”。一般建议再增加一定字节的stack作为系统裕量。
目前有专门的付费代码分析工具可以帮助客户分析工程的stack消耗,发现潜在的堆栈溢出问题。比如IAR的C-STAT C运行时代码分析(C-RUNRuntime analysis)工具ThreadX C-SPY debuggerplugin stack调试工具,当然其作为一个plugin插件只能配合IAR工作,对IAR的嵌入式C工程进行堆栈调试。

  • @TOC防止堆栈溢出的几个编程建议

  • @TOC在工程的调试配置选项中配置使能Attach调试功能

  • 更换下载执行文件

由于我们是调试其他应用工程,不需要对其进行编译链接,所以可以选择Disable auto build,否则每次选择Attach还会编译这个测试工程,浪费时间。

  • 使能Attach调试:

在Startup窗口,使能Attach调试:去掉运行时选项(Runtime Options)默认的Run on reset和Set breakpoint at:main,勾选Attach to Running Target

  • 添加调试工程目录

添加工程目录:在Source栏下的源文件查找路径(Source Lookup Path),通过添加文件系统路径方式将要调试的应用工程根目录添加到该调试配置

  • 开始调试

刚进入调试界面时,MCU处于运行状态,需要点击暂停才能查看寄存器和变量以及进行其他的调试功能。

  • @TOC使用PEMicro保护某些程序下载地址

使用PEMicro调试器是可以设置程序下载是对目标MCU片上NVM的保护,具体方法如下:
在工程的Debug Configuration中,选择GDB PEMicro Interface Debugging的调试目标,在Debugger窗口,点击高级选项(Advanced Option),在高级选项窗口中,勾选Preserver this range(Memory Rang 0…2,最多可以保护三段存储器空间),并输入需要保护的存储器起始地址即可。

  • @TOC关于几种执行文件格式解析

S19文件:https://en.wikipedia.org/wiki/SREC_(file_format)
HEX文件:https://en.wikipedia.org/wiki/Intel_HEX
BIN文件:https://en.wikipedia.org/wiki/Binary_file

接另我另外两篇:巧用断点设置查找bug【debug:链接
S32DS平台上使用DWT模块进行代码时间计算和利用脚本文件进行问题定位:链接
未完待更新。。。

s32k144是一款微控制器,bootloader是在该微控制器上运行的一段特殊程序,用于加载和启动应用程序。s32k144bootloader跳转指的是当bootloader执行完其任务后,将控制权交给应用程序的过程。 s32k144bootloader跳转的实现方法有多种,具体取决于设计者的要求和需求。以下是其中一种常见的实现方法: 1. 在bootloader中,定义一个函数,该函数的功能是跳转到应用程序的入口点。这个入口点地址需要在编译应用程序时预先确定并保存在某个特定位置,供bootloader跳转使用。 2. 应用程序在编译时,将入口点地址写入一个特定的内存位置,例如特殊的区域或一个预留的变量中。 3. 在bootloader中,通过读取这个特定的内存位置,获取应用程序的入口点地址。 4. 当bootloader的任务完成时,即完成了一些必要的操作,例如固件更新或配置加载等,bootloader将调用这个特定的函数,跳转到应用程序的入口点。 5. 跳转到应用程序后,控制权交给应用程序,应用程序将开始执行。 这种方法的好处是灵活性和可靠性。通过将入口点地址保存在特定的内存位置,bootloader可以在不同的应用程序之间跳转,从而实现多个应用程序共存的功能。另外,此方法也确保了bootloader和应用程序之间的隔离,增强了系统的安全性和可靠性。 总之,s32k144bootloader跳转是将控制权从bootloader转移到应用程序的过程,它可以通过在编译应用程序时预先确定和保存入口点地址的方法来实现。这种方法在实现多个应用程序共存并增加系统的安全性和可靠性方面具有优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值