完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我正在为带有 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]} |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1883个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36261 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4343 浏览 0 评论
5998 浏览 1 评论
6721 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4170 浏览 0 评论
585浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
579浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
568浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
655浏览 2评论
726浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-10-20 04:49 , Processed in 1.089658 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号