本帖最后由 小恩GG 于 2020-6-17 14:49 编辑
【经验分享】RT1020 BEE下APP进fault问题分析与解决 一 文档描述
最近遇到关于RT1020 BEE加密APP在某种配置下进入fault的案例。具体情况如下:
芯片 :MIMXRT1021带外部QSPI flash
问题描述:在做BEE加密之后,代码使用ldm指令访问到具体flash地址的时候,有时候会进入到hardfault,然而同样的代码,下载到非加密的RT芯片中,则运行正常。如果使能了Dcache,则BEE加密模式下也不会出现问题,禁止Dcache则出现问题。
问题复现:首先保证BEE加密过程都能正常工作,然后准备一个很简单的app,比如SDK里的ledblinky, 在启动代码startup_mimxrt1021.c中,添加如下代码在ResetISR()开始的地方:
- typedef struct
- {
- uint32_t uiWord_0;
- uint32_t uiWord_1;
- uint32_t uiWord_2;
- } SomeStruct_t;
- typedef struct
- {
- SomeStruct_t sStruct_A;
- SomeStruct_t sStruct_B;
- SomeStruct_t sStruct_C;
- } ASetOfStructs_t;
- static const ASetOfStructs_t FlashStruct;
- __attribute__ ((section(".after_vectors.reset")))
- void ResetISR(void) {
- // Disable interrupts
- __asm volatile ("cpsid i");
- static SomeStruct_t RAMStruct_A;
- static SomeStruct_t RAMStruct_B;
- static SomeStruct_t RAMStruct_C;
- RAMStruct_A = FlashStruct.sStruct_A;
- RAMStruct_B = FlashStruct.sStruct_B;
- RAMStruct_C = FlashStruct.sStruct_C;
- #if defined (__USE_CMSIS)
- // If __USE_CMSIS defined, then call CMSIS SystemInit code
- SystemInit();
- #else……….
复制代码或者将上述结构体定义与调用的代码,放到SystemInit之后,但是在SystemInit中,屏蔽掉代码SCB_EnableDCache();编译好app.19之后,RT芯片进入到serialdownload模式,通过MCUBootUtility的BEEEncrypted Image Boot下载进去,就会复现问题。 二,问题分析与测试
发现有这样的描述: The known hardware limitations of the BEE module are as follows: • Only supports 128 bits data width AXI interconnection • Only supports 16-byte burst access size. For single transaction, theminimum supported access size is limited to 4-byte. • Granularity of the address bias is 128 KB per step • Maximumsupported burst length is limited to 4. 经过和专家的确认,也得到了这样回复: BEE onlysupports 16-byte burst access size. This rule may be violated if master sendsunaligned burst because bus fabric may convert unaligned burst into non-16-byteaccess and cause BEE to send a bus error. To avoid this issue the general rulefor the master is to set start address to BEE 16-byte aligned, and total datanumber a multiple of 16-byte, so that the bus fabric can always feed BEE with16-byte access. 所以说,如果要想解决这个问题,需要保证访问入口地址16字节对齐,而且访问的数据总数也是16字节的整数倍。 然后,这边对原始的代码在非加密的MIMXRT1020-EVK板上做了debug,查看添加结构体的地址情况,具体如下:
可以看到对应结构体的变量地址,并不是16字节对齐的。 为了实现字节对齐,并且变量的长度也是16字节的整数倍,这里修改代码如下: - typedef struct
- {
- uint32_t uiWord_0;
- uint32_t uiWord_1;
- uint32_t uiWord_2;
- uint32_t dummy;
- } SomeStruct_t;
- typedef struct
- {
- SomeStruct_t sStruct_A;
- SomeStruct_t sStruct_B;
- SomeStruct_t sStruct_C;
- } ASetOfStructs_t;
- static const ASetOfStructs_t FlashStruct __attribute__ ((aligned (16)));
- // Disable interrupts
- __asm volatile ("cpsid i");
- static SomeStruct_t RAMStruct_A __attribute__ ((aligned (16)));
- static SomeStruct_t RAMStruct_B __attribute__ ((aligned (16)));
- static SomeStruct_t RAMStruct_C __attribute__ ((aligned (16)));
- RAMStruct_A = FlashStruct.sStruct_A;
- RAMStruct_B = FlashStruct.sStruct_B;
- RAMStruct_C = FlashStruct.sStruct_C;
复制代码添加__attribute__((aligned (16))),保证变量为16字节对齐,添加uint32_t dummy;为了凑够16字节的整数倍。 经过上述修改之后,再次在非BEE的MIMXRT1020-EVK板子上的debug,查看变量地址情况:
Debug结果可以发现,结构体的入口地址已经是16字节对齐了,而且每个结构体也是16字节的整数倍。这时候,生成.s19文件,再次烧录到已经做过BEE加密的MIMXT1020-EVK开发板中,烧录完成后,转为internal boot模式,再次上电,可以发现led灯已经成功闪烁,说明16字节对齐确实对BEE加密结果有修正效果,再次印证了SRM和专家的说法。三 总结 在使用BEE加密的时候,APP最好添加cache,因为cache在遇到不是16字节对齐的地址的时候,会自动分为两个burst,并且对齐地址,这也是为什么客户在添加了cache使能之后,不会出现问题。如果禁止了cache,那么必须要保证BEE访问的入口地址为16字节对齐,而且数据块字节总数是16字节的整数倍。希望该经验能够给大家带去帮助。
【经验分享】RT1020 BEE下APP进fault问题分析与解决.pdf
(494.47 KB, 下载次数: 8)
|