This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSPM0G3107:归零结构时出现硬故障异常。

Guru**** 2396165 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1419708/mspm0g3107-hard-fault-exception-when-zeroing-structs

器件型号:MSPM0G3107

工具与软件:

你(们)好

我将一些软件移植到该 MCU、并且在我将结构清零时 MCU 抛出硬故障异常存在问题。

我在尝试找出导致问题的原因后有点迷路。 但我怀疑问题可能出在链接器文件中。

我使用 IAR 9.50和 Ozone 作为 调试器、这是例外情况

链接脚本如下:

/************** MEMORY MAP ******************************************/
/* _________________________________________________________________*/
/*| Non Main BSL                       |0x41C0 017F           (128B)*/
/*|____________________________________|0x41C0 0100_________________*/
/*:                                    :                            */
/*| Non Main BCR                       |0x41C0 007F                 */
/*|____________________________________|0x41C0 0000_________________*/
/*:                                    :                            */
/*:____________________________________:           _________________*/
/*| Stack, Heap, Static data           |0x2020 7FFF  RAM (32K)      */
/*|                                    |                            */
/*|____________________________________|0x2020 1650_________________*/
/*| Class B (size 0xe00)               |                            */
/*|____________________________________|0x2020 0850_________________*/
/*| RUNTIME_CHK_BUF (0x20)             |                            */
/*|____________________________________|0x2020 0830_________________*/
/*| CSTACK (0x800 + 0x10)              |                            */
/*|____________________________________|0x2020 0020_________________*/
/*| Common RAM (0x20)                  |                            */
/*|____________________________________|0x2020 0000_________________*/
/*:                                    :                            */
/*:____________________________________:           _________________*/
/*| HwInfo                             |0x0001 FFFF           (1K)  */
/*|____________________________________|0x0001 FC00_________________*/
/*| Settings                           |0x0001 FBFF           (2K)  */
/*|                                    |                            */
/*|____________________________________|0x0001 F400_________________*/
/*| Boot Config                        |0x0001 F3FF           (85K) */
/*| (256B)                             |                    :       */
/*|____________________________________|0x0001 F300         :       */
/*| Application code                   |                    :       */
/*|____________________________________|                    :       */
/*| Common const for Applic            |                    :       */
/*| (version info) (568B)              |                    :       */
/*|____________________________________|0x0000 A300         :       */
/*| Int vectors for Applic             |                            */
/*|____________________________________|0x0000 A000_________________*/
/*| Boot code                          |0x0000 9FFF           (40K) */
/*|____________________________________|                            */
/*| Common const for Boot              |                            */
/*| (version info) (568B)              |                            */
/*|____________________________________|0x0000 0300                 */
/*| Int vectors for Boot               |                            */
/*|____________________________________|0x0000 0000_________________*/

/*--- Specials ---*/
/* Offset to start of code for application */
define symbol __application_displacement__      = 0x0a000;

/* Offset to start of const data area for application (available also from boot) */
define symbol __common_const_displacement__     = 0x00300;

/* Size of common Ram area for boot and application */
define symbol __size_common_ram__               = 0x00020;

/* size_classBdata_ram */
define symbol __size_classBdata_ram__           = 0x00e00;

/* Absolute address for start of interrupt vector table */
define symbol __intvec_start__                  = 0x0a000;

/* Absolute address to area with constants for boot for access from both appl and boot */
define symbol __common_const_appl_start__       = 0x0a300;

/* Size of boot configuration area located at end of a App address space */
define symbol __size_bootconfig__               = 0x00100;

/*-Sizes-*/
define symbol __size_proc_stack__               = 0x0000;
define symbol __size_cstack__                   = 0x400;
define symbol __size_heap__                     = 0x800;
define symbol __size_stack_bottom__             = 0x10;

/*-Memory Regions-*/
define symbol __region_ROM_start__              = 0x00000000;
define symbol __region_ROM_end__                = 0x0001FFFF;
define symbol __region_RAM_start__              = 0x20200000;
define symbol __region_RAM_end__                = 0x20207FFF;
define symbol __region_RAM_stack_start__        = __region_RAM_start__ + __size_common_ram__;
define symbol __region_RAM_stack_end__          = __region_RAM_stack_start__ + __size_cstack__ + __size_stack_bottom__ - 1;
define symbol __region_RUN_TIME_CHK_BUF_start__ = __region_RAM_stack_end__ + 1;
define symbol __region_RUN_TIME_CHK_BUF_end__   = __region_RUN_TIME_CHK_BUF_start__ + 32 - 1;   // Size (6+2)*4 bytes
define symbol __region_CLASSB_start__           = __region_RUN_TIME_CHK_BUF_end__ + 4 + 1;      // 4 bytes because RAM check operates 4 bytes before CLASSB RAM area.
define symbol __region_CLASSB_end__             = __region_CLASSB_start__ + __size_classBdata_ram__ - 1;


define symbol __region_NON_MAIN_BCR_start__     = 0x41C00000;
define symbol __region_NON_MAIN_BCR_end__       = 0x41C0007F;
define symbol __region_NON_MAIN_BSL_start__     = 0x41C00100;
define symbol __region_NON_MAIN_BSL_end__       = 0x41C0017F;




define symbol __region_application_end__        = __region_ROM_end__ - __size_bootconfig__;
define symbol __region_BootConf_start__         = __region_application_end__ + 1; // Start on the first address after application end

/* Reserved space in iar.dynexit for calls at exit */
define symbol __iar_maximum_atexit_calls        = 3;

export symbol __region_ROM_start__;
export symbol __region_ROM_end__;
export symbol __region_RAM_start__;
export symbol __region_RAM_end__;
export symbol __region_CLASSB_start__;
export symbol __region_CLASSB_end__;
export symbol __region_BootConf_start__;

define memory mem with size = 4G;

define region ROM_region                = mem:[from __region_ROM_start__ to __region_ROM_end__];
define region BOOT_CONFIG_region        = mem:[from __region_BootConf_start__ to __region_ROM_end__ ];   // Boot config region/area
define region RAM_stack_region          = mem:[from __region_RAM_stack_start__ to __region_RAM_stack_end__];
define region RUN_TIME_CHK_BUF_region   = mem:[from __region_RUN_TIME_CHK_BUF_start__ to __region_RUN_TIME_CHK_BUF_end__];
define region CLASS_B_RAM_region        = mem:[from __region_CLASSB_start__ to __region_CLASSB_end__];
define region RAM_region                = mem:[from __region_RAM_start__ to __region_RAM_end__];

define region NON_MAIN_BCR_region       = mem:[from __region_NON_MAIN_BCR_start__ to __region_NON_MAIN_BCR_end__];
define region NON_MAIN_BSL_region       = mem:[from __region_NON_MAIN_BSL_start__ to __region_NON_MAIN_BSL_end__];

initialize by copy { readwrite };
do not initialize  { section .noinit, section STACK_BOTTOM, section RUN_TIME_RAM_BUF, section CLASS_B_RAM};

// placements #############################
place at address mem:__intvec_start__ { readonly section .intvec };
place at address mem:__common_const_appl_start__ { readonly section .CommonConst };

// Create an 8-byte end-aligned block and put all read-only sections in it
define block ALIGNED_ROM with end alignment = 8 { readonly };
place in ROM_region  { block ALIGNED_ROM };

define block CSTACK     with alignment = 8, size = __size_cstack__     { };
define block PROC_STACK with alignment = 8, size = __size_proc_stack__ { };
define block HEAP       with alignment = 8, size = __size_heap__       { };
place in RAM_region  { readwrite, block PROC_STACK, block HEAP };

define block STACK_BOTTOM_B  with alignment = 8, size = __size_stack_bottom__  { section STACK_BOTTOM };
define block stack_order with fixed order { block STACK_BOTTOM_B, block CSTACK };
place in RAM_stack_region { block stack_order };

place in CLASS_B_RAM_region { readwrite data section CLASS_B_RAM, section CLASS_B_RAM_REV  };
place in RUN_TIME_CHK_BUF_region { readwrite data section RUN_TIME_RAM_BUF  };

place in NON_MAIN_BCR_region  { section .BCRConfig };
place in NON_MAIN_BSL_region  { section .BSLConfig };

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我首先要查看的是.map 文件、用于查看0x108A0处的内容。 这至少应该为您提供一个要使用的函数名称。

    如果你认为你正在把记忆归零,我的第一个猜测是,大小计算是错误的。 (也许它以前是偶然工作的?)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这段代码是从 STM32平台移植的、因此我认为移植过程中经常遇到问题、因为导致此问题的代码没有变化。

    在检查映射文件后、我可以确认存储器地址是 memset 出现的位置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否知道哪个(memset)调用正在执行此操作? 单步执行调用函数应该会知道一些信息。 你也可以通过追踪堆栈找到点,尽管这需要一些耐心。

    移植结构中的常见潜在问题是位域和打包。

    Cortex-M0不能使用未对齐的存储器引用、而 Cortex-M4/M7允许使用它们。 (虽然 memset 应该不受对齐危险的影响。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这也是我的怀疑。
    但这显然是一个红色的鲱鱼。 出于某种原因、我的调试器在错误的位置执行了操作并出现了硬故障。

    这是因为将阵列归零后、代码将继续检查某些闪存区域、一次检查一个字节、几次读取后将继续进行硬故障检查。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否知道哪个代码行(更好的是:哪个指令)出现故障? 堆栈布局(在** SP 处)与相关 Thread 中的布局相同。

    如果它不在 memset ()中,(重新)就会引入对齐的可能性。 您要从哪个 STM32移植?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    高 Isac、

    您的器件是否在完全相同的存储器读取中出现了硬故障? 这是硬故障还是达到 NMI?

    在开始的内存映射注释中、您位于内存的 ECC 区域。 您需要确保同时设置了 ECC 位并正确等待。 如果你的结构在闪存中、使用 SRAM、那么如果你因数组边界以及数组放置位置而遇到内存访问故障、我更感兴趣。

    此致、
    Luke

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它从闪存读取是、并且在读取的同一存储器上出现故障、至少会根据我是否更改了优化、对代码库进行更大的更改等而发生变化、但它位于同一个常规区域。 但如果我不做任何更改、它会在完全相同的位置发生故障。

    就我所能看到的而言、硬故障。 检查 NMI 时、似乎未检测到闪存 DED。
    但我发现 DEDERRADDR 包含一个地址。 这是否意味着 DEDERRADDR 中的地址有问题?

    编辑:好的,我开始怀疑这是一个问题的组合。 SRAM 中的闪存访问和归零/填充结构都会导致崩溃。 但写入 RAM 似乎也会导致崩溃。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    高 Isac、

    闪存读取将检测/触发 FLASHDED 错误。

    • 您是一次写入一个闪存字、还是正在执行较小的代码集?
      • 较小的写入将要求用户以特定方式处理 ECC 段。 TRM 中的第6.3.3.2节 提供了详细信息。  
    • DEDERRADDR 包含 导致 ECC 错误的地址。 我建议的是处理 FLASHDED NMI 并使用该地址对扇区进行重新编程。 除非错误地处理写入、否则不应定期出现 ECC 错误、这可能会导致错误  
    • 您是否能够检查在遇到此故障时正在访问哪个 SRAM 地址?
      • 除非您的边界将跨越 SRAM 区域、否则我不希望 SRAM 访问出现任何硬故障。 (可能由指针访问然后对地址进行添加而引起)

    而且、您没有尝试在闪存上使用 memset、对吧? 不应在闪存区域上使用 Memset。

    此致、
    Luke  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我仅对 RAM 中的对象使用 memset。

    但我想我发现了问题。 这是其中一个驱动程序中的一个实现方案、在闪存中进行了越界读取、并结合了一些对象来填充 RAM。
    这是一个棘手的问题、因为闪存读取过早失败、而不是超出范围。

    因此、我的解决方案是调整边界并修复驱动程序(而不是 DL 驱动程序)中的错误、然后调整一些结构大小、这样它现在就可以正常工作了。

    感谢您的帮助!