NXP MCU 技术论坛
直播中

熊本熊

8年用户 1372经验值
擅长:处理器/DSP
私信 关注
[问答]

S32K118优化代码使SDK FLASH_DRV_EraseSector()返回STATUS_ERROR是怎么回事?

我正在为带有 S32K118 处理器的定制 PCB 开发引导加载程序。在这里,我通过 CAN 通信传输 hex 文件的所有数据,并将每个闪存扇区写入以下地址并向上:0x20000。此引导加载程序成功地将通信数据闪存到 MCU 的闪存。如果我跳转到闪烁的应用程序,它似乎工作正常。
但是,当我在构建设置中将引导加载程序代码的优化级别从无更改为例如 -O3 时,如下所示:

我的方法中发生了一些奇怪的事情:
[size=1 2 3 4 5 6 7]status_t abs_Flash_Write_Sector(uint32_t 地址, uint32_t 大小, uint8_t* sourceBuffer, uint32_t bufferSize)
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]status_t ret = STATUS_SUCCESS;
[size=1 2 3 4 5 6 7]uint32_t failAddress = 0;
[size=1 2 3 4 5 6 7]INT_SYS_DisableIRQGlobal();
[size=1 2 3 4 5 6 7]/* 在长时间耗时的闪存操作之前设置回调函数
[size=1 2 3 4 5 6 7]*(例如:擦除)让应用程序代码在闪存操作时执行其他任务
[size=1 2 3 4 5 6 7]* 在操作中。
[size=1 2 3 4 5 6 7]在这种情况下,我们使用它为* 闪存命令完成事件 */
[size=1 2 3 4 5 6 7]flash_callback_t pCallBack = (flash_callback_t)CCIF_Callback[size=1 2 3 4 5 6 7]启用中断;
[size=1 2 3 4 5 6 7]flashSSDConfig.CallBack = pCallBack;
[size=1 2 3 4 5 6 7]/* 擦除特定的 PFlash 扇区 */
[size=1 2 3 4 5 6 7]/* 配置地址、大小以擦除扇区功能。例如在 S32K144 */
[size=1 2 3 4 5 6 7]size = FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
[size=1 2 3 4 5 6 7]ret = FLASH_DRV_EraseSector(&flashSSDConfig, 地址, 大小); <------------ 这里是我的代码崩溃(更多信息见下文)
[size=1 2 3 4 5 6 7]DEV_ASSERT(STATUS_SUCCESS == ret);
[size=1 2 3 4 5 6 7]/* 禁用回调 */
[size=1 2 3 4 5 6 7]flashSSDConfig.CallBack = NULL_CALLBACK;
[size=1 2 3 4 5 6 7]/* 在边缘级别值为 1 时验证擦除操作,用户读取 */
[size=1 2 3 4 5 6 7]ret = FLASH_DRV_VerifySection(&flashSSDConfig, address, size / FTFx_DPHRASE_SIZE, 1u);
[size=1 2 3 4 5 6 7]DEV_ASSERT(STATUS_SUCCESS == ret);
[size=1 2 3 4 5 6 7]/* 将一些数据写入已擦除的 PFlash 扇区 */
[size=1 2 3 4 5 6 7]ret = FLASH_DRV_Program(&flashSSDConfig, address, bufferSize, sourceBuffer);
[size=1 2 3 4 5 6 7]DEV_ASSERT(STATUS_SUCCESS == ret);
[size=1 2 3 4 5 6 7]/* 在 margin level 值 1,user margin 验证程序操作 */
[size=1 2 3 4 5 6 7]ret = FLASH_DRV_ProgramCheck(&flashSSDConfig, address, bufferSize, sourceBuffer, &failAddress, 1u);
[size=1 2 3 4 5 6 7]DEV_ASSERT(STATUS_SUCCESS == ret);
[size=1 2 3 4 5 6 7]INT_SYS_EnableIRQGlobal();
[size=1 2 3 4 5 6 7]返还;
[size=1 2 3 4 5 6 7]}
当调用此方法并且我使用我的通用多链路调试探针运行调试时,它显示崩溃并转到默认 ISR。当我放置一个断点时,FLASH_DRV_EraseSector() 返回一个 STATUS_ERROR。

当我拔下调试探针时,重新启动 pcb 并在不调试的情况下运行我的代码。当我开始将 hex 文件闪存到设备时,似乎会发生同样的错误。因为可以看到它在同一个地方停止工作。
我不确定为什么会这样。我读过未初始化的变量会导致这种行为,但我确保我能想到的一切都已初始化。
有没有人知道这可能是什么原因?非常感谢任何帮助。

在我的引导加载程序链接器文件下面:
[size=1 2 3 4 5 6 7]/* 入口点 */
[size=1 2 3 4 5 6 7]ENTRY(Reset_Handler)
[size=1 2 3 4 5 6 7]HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000200;
[size=1 2 3 4 5 6 7]堆栈大小 = 定义(__堆栈大小__)?__堆栈大小__:0x00000200;
[size=1 2 3 4 5 6 7]/* 如果在链接时定义了符号 __flash_vector_table__=1
[size=1 2 3 4 5 6 7]* 中断向量将不会被复制到 RAM。
[size=1 2 3 4 5 6 7]* 警告:使用来自闪存的中断向量将不允许
[size=1 2 3 4 5 6 7]* INT_SYS_InstallHandler 因为该部分是只读的。
[size=1 2 3 4 5 6 7]*/
[size=1 2 3 4 5 6 7]M_VECTOR_RAM_SIZE = DEFINED(__flash_vector_table__) ? 0x0:0x00C0;
[size=1 2 3 4 5 6 7]/* 指定内存区域 */
[size=1 2 3 4 5 6 7]MEMORY
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]/* Flash */
[size=1 2 3 4 5 6 7]m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0
[size=1 2 3 4 5 6 7]m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
[size=1 2 3 4 5 6 7]m_text (RX) : ORIGIN = 0x00000041 0x0001FFFF - 0x00000410 /* 16KB - 0x10*/

[size=1 2 3 4 5 6 7]/* SRAM_L */
[size=1 2 3 4 5 6 7]m_custom (RW) : ORIGIN = 0x1FFFFC00, LENGTH = 0x00000400

[size=1 2 3 4 5 6 7]/* SRAM_U */
[size=1 2 3 4 5 6 7]m_data (RW) : ORIGIN = 0x20000000, OR LENGTH = 0x00R m0030 数据 0x1FFFFC00, LENGTH =
[size=1 2 3 4 5 6 7]0x00000400 = 0x200030C0, 长度 = 0x00002740

[size=1 2 3 4 5 6 7]m_exchange_info (RW) : ORIGIN = 0x20005800, 长度 = 0x00000010
[size=1 2 3 4 5 6 7]}
[size=1 2 3 4 5 6 7]/* 定义输出部分 */
[size=1 2 3 4 5 6 7]SECTIONS
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]/* 启动代码首先进入内部闪存 */
[size=1 2 3 4 5 6 7].interrupts :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]__VECTOR_TABLE = .;
[size=1 2 3 4 5 6 7]__interrupts_start__ = .;
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]KEEP(*(.isr_vector)) /* 启动代码 */
[size=1 2 3 4 5 6 7]__interrupts_end__ = .;
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]} > m_interrupts
[size=1 2 3 4 5 6 7].flash_config :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]KEEP(*(.FlashConfig)) /* 闪存配置字段 (FCF) */
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]} > m_flash_config


[size=1 2 3 4 5 6 7]/* 程序代码和其他数据进入内部闪存 */
[size=1 2 3 4 5 6 7].text :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]*(.text) /* .text 部分(代码)*/
[size=1 2 3 4 5 6 7]*(.text*) /* .text* 部分(代码)*/
[size=1 2 3 4 5 6 7]*(.rodata) /* .rodata 部分(常量、字符串等) */
[size=1 2 3 4 5 6 7]*(.rodata*) /* .rodata* 节(常量、字符串等)*/
[size=1 2 3 4 5 6 7]*(.init) /* crti.o 文件中使用的节 */
[size=1 2 3 4 5 6 7]*(.fini) /* crti.o 文件中使用的节crti.o 文件 */
[size=1 2 3 4 5 6 7]*(.eh_frame) /* crtbegin.o 文件中使用的部分 */
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]} > m_text

[size=1 2 3 4 5 6 7]/* fvp4 的 libgcc.a 库使用的部分 */
[size=1 2 3 4 5 6 7].ARM :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]__exidx_start = .;
[size=1 2 3 4 5 6 7]*(.ARM.exidx*)
[size=1 2 3 4 5 6 7]__exidx_end = .;
[size=1 2 3 4 5 6 7]} > m_text
[size=1 2 3 4 5 6 7]__etext = .; /* 在代码末尾定义一个全局符号。*/
[size=1 2 3 4 5 6 7]__DATA_ROM = .; /* Symbol 被启动用于数据初始化。*/
[size=1 2 3 4 5 6 7].interrupts_ram :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__VECTOR_RAM__ = .;
[size=1 2 3 4 5 6 7]__RAM_START = .;
[size=1 2 3 4 5 6 7]__interrupts_ram_start__ = .; /* 在数据开始处创建一个全局符号。*/
[size=1 2 3 4 5 6 7]*(.m_interrupts_ram) /* 这是一个用户定义的部分。*/
[size=1 2 3 4 5 6 7]。+= M_VECTOR_RAM_SIZE;
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__interrupts_ram_end__ = .; /* 在数据末尾定义一个全局符号。*/
[size=1 2 3 4 5 6 7]} > m_data
[size=1 2 3 4 5 6 7]__VECTOR_RAM = DEFINED(__flash_vector_table__) ? 起源(m_interrupts):__VECTOR_RAM__;
[size=1 2 3 4 5 6 7]__RAM_VECTOR_TABLE_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : (__interrupts_ram_end__ - __interrupts_ram_start__) ;
[size=1 2 3 4 5 6 7].data : AT(__DATA_ROM)
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__DATA_RAM = .;
[size=1 2 3 4 5 6 7]__data_start__ = .; /* 在数据开始处创建一个全局符号。*/
[size=1 2 3 4 5 6 7]*(.data) /* .data 部分 */
[size=1 2 3 4 5 6 7]*(.data*) /* .data* 部分 */
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__data_end__ = .; /* 在数据末尾定义一个全局符号。*/
[size=1 2 3 4 5 6 7]} > m_data
[size=1 2 3 4 5 6 7]__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
[size=1 2 3 4 5 6 7]__CODE_ROM = __DATA_END; /* 代码初始化使用符号。*/
[size=1 2 3 4 5 6 7].code : AT(__CODE_ROM)
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__CODE_RAM = .;
[size=1 2 3 4 5 6 7]__code_start__ = .; /* 在代码开始处创建一个全局符号。*/
[size=1 2 3 4 5 6 7]__code_ram_start__ = .;
[size=1 2 3 4 5 6 7]*(.code_ram) /* 用于在 RAM 中存储代码的自定义部分 */
[size=1 2 3 4 5 6 7]. =对齐(4);
[size=1 2 3 4 5 6 7]__code_end__ = .; /* 在代码末尾定义一个全局符号。*/
[size=1 2 3 4 5 6 7]__code_ram_end__ = .;
[size=1 2 3 4 5 6 7]} > m_data
[size=1 2 3 4 5 6 7]__CODE_END = __CODE_ROM + (__code_end__ - __code_start__);
[size=1 2 3 4 5 6 7]__CUSTOM_ROM = __CODE_END;
[size=1 2 3 4 5 6 7]/* 可用于将数据放置在绝对地址的自定义节块。*/
[size=1 2 3 4 5 6 7]/* 使用 __attribute__((section (".customSection"))) 在这里放置数据。*/
[size=1 2 3 4 5 6 7]/* 仅在未使用 MTB(Micro Trace Buffer)时使用此部分,因为 MTB 使用相同的 RAM 区域,如 S32K 参考手册中所述。*/
[size=1 2 3 4 5 6 7].customSectionBlock ORIGIN(m_custom) : AT(__CUSTOM_ROM)
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]__customSectionStart = .;
[size=1 2 3 4 5 6 7]__customSection_start__ = .;
[size=1 2 3 4 5 6 7]KEEP(*(.customSection)) /* 即使没有被引用也保留部分。*/
[size=1 2 3 4 5 6 7]__customSection_end__ = .;
[size=1 2 3 4 5 6 7]} > m_custom
[size=1 2 3 4 5 6 7]__CUSTOM_END = __CUSTOM_ROM + (__customSection_end__ - __customSection_start__);
[size=1 2 3 4 5 6 7]__rom_end = __CUSTOM_END;
[size=1 2 3 4 5 6 7]/* 未初始化的数据部分。*/
[size=1 2 3 4 5 6 7].bss :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]/* 启动时使用它来初始化 .bss 部分。*/
[size=1 2 3 4 5 6 7]。=对齐(4);
[size=1 2 3 4 5 6 7]__BSS_START = .;
[size=1 2 3 4 5 6 7]__bss_start__ = .;
[size=1 2 3 4 5 6 7]*(.bss)
[size=1 2 3 4 5 6 7]*(.bss*)
[size=1 2 3 4 5 6 7]*(普通)
[size=1 2 3 4 5 6 7]。=对齐(4);
[size=1 2 3 4 5 6 7]__bss_end__ = .;
[size=1 2 3 4 5 6 7]__BSS_END = .;
[size=1 2 3 4 5 6 7]} > m_data_2
[size=1 2 3 4 5 6 7]/* 将堆部分放在程序数据之后 */
[size=1 2 3 4 5 6 7].heap :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(8);
[size=1 2 3 4 5 6 7]__end__ = .;
[size=1 2 3 4 5 6 7]__heap_start__ = .;
[size=1 2 3 4 5 6 7]提供(结束=。);
[size=1 2 3 4 5 6 7]提供(_end = .);
[size=1 2 3 4 5 6 7]提供(__end = .);
[size=1 2 3 4 5 6 7]__HeapBase = .;
[size=1 2 3 4 5 6 7]. += 堆大小;
[size=1 2 3 4 5 6 7]__HeapLimit = .;
[size=1 2 3 4 5 6 7]__heap_limit = .;
[size=1 2 3 4 5 6 7]__heap_end__ = .;
[size=1 2 3 4 5 6 7]} > m_data_2
[size=1 2 3 4 5 6 7]/* 在块的末尾初始化堆栈 */
[size=1 2 3 4 5 6 7]__StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2);
[size=1 2 3 4 5 6 7]__StackLimit = __StackTop - STACK_SIZE;
[size=1 2 3 4 5 6 7]提供(__stack = __StackTop);
[size=1 2 3 4 5 6 7]__RAM_END = __StackTop;
[size=1 2 3 4 5 6 7].stack __StackLimit :
[size=1 2 3 4 5 6 7]{
[size=1 2 3 4 5 6 7]. =对齐(8);
[size=1 2 3 4 5 6 7]__stack_start__ = .;
[size=1 2 3 4 5 6 7]. += 堆栈大小;
[size=1 2 3 4 5 6 7]__stack_end__ = .;
[size=1 2 3 4 5 6 7]} > m_data_2
[size=1 2 3 4 5 6 7].ARM.attributes 0 : { *(.ARM.attributes) }

[size=1 2 3 4 5 6 7]/* 内存验证 */
[size=1 2 3 4 5 6 7]ASSERT(__rom_end <= (ORIGIN(m_text) + LENGTH(m_text)), "Region m_text overflowed!")
[size=1 2 3 4 5 6 7]断言(__StackLimit >= __HeapLimit,“区域 m_data_2 溢出堆栈和堆”)
[size=1 2 3 4 5 6 7]}

更多回帖

发帖
×
20
完善资料,
赚取积分