工具/软件:
尊敬的 TI 专家:
在 MSPM0G3507上运行使用 GNU ARM 工具链构建的映像时、我会遇到奇怪的问题。 我已经 确定了 2个"硬故障"出现的地方 、但 只有在以下情况下才会出现:
1.运行"发行版构建",即使用编译 -Os。
2.未连接调试器。
这些情况使确定究竟是什么触发了这样一个 严重的错误有点困难,但我认为我能够做到这一点,其中一次这样的事件:
在使用 GNU ARM 工具链 arm-gnu-toolchurs-14.2.rel1-MinGW-w64-i686-arm-none-eabi 进行的发布构建中、 当 DL_SYSCTL_configSYSPLL() TI SDK 版本2_03_00_07的例程写入 SYSCTL->SOCLOCK.SYSPLLPARAM0以下内容时、似乎会发生硬故障:
void DL_SYSCTL_configSYSPLL(DL_SYSCTL_SYSPLLConfig *config)
{
/* PLL configurations are retained in lower reset levels. Set default
* behavior of disabling the PLL to keep a consistent behavior regardless
* of reset level. */
DL_SYSCTL_disableSYSPLL();
/* Check that SYSPLL is disabled before configuration */
while ((DL_SYSCTL_getClockStatus() & (DL_SYSCTL_CLK_STATUS_SYSPLL_OFF)) !=
(DL_SYSCTL_CLK_STATUS_SYSPLL_OFF)) {
;
}
// set SYSPLL reference clock
DL_Common_updateReg(&SYSCTL->SOCLOCK.SYSPLLCFG0,
((uint32_t) config->sysPLLRef), SYSCTL_SYSPLLCFG0_SYSPLLREF_MASK);
// set predivider PDIV (divides reference clock)
DL_Common_updateReg(&SYSCTL->SOCLOCK.SYSPLLCFG1, ((uint32_t) config->pDiv),
SYSCTL_SYSPLLCFG1_PDIV_MASK);
// save CPUSS CTL state and disable the cache
uint32_t ctlTemp = DL_CORE_getInstructionConfig();
DL_CORE_configInstruction(DL_CORE_PREFETCH_ENABLED, DL_CORE_CACHE_DISABLED,
DL_CORE_LITERAL_CACHE_ENABLED);
// populate SYSPLLPARAM0/1 tuning registers from flash, based on input freq
SYSCTL->SOCLOCK.SYSPLLPARAM0 =
*(volatile uint32_t *) ((uint32_t) config->inputFreq); <-- Hard Fault occurs here
SYSCTL->SOCLOCK.SYSPLLPARAM1 =
*(volatile uint32_t *) ((uint32_t) config->inputFreq + (uint32_t) 0x4);
// restore CPUSS CTL state
CPUSS->CTL = ctlTemp;
// set feedback divider QDIV (multiplies to give output frequency)
DL_Common_updateReg(&SYSCTL->SOCLOCK.SYSPLLCFG1,
((config->qDiv << SYSCTL_SYSPLLCFG1_QDIV_OFS) &
SYSCTL_SYSPLLCFG1_QDIV_MASK),
SYSCTL_SYSPLLCFG1_QDIV_MASK);
// write clock output dividers, enable outputs, and MCLK source to SYSPLLCFG0
DL_Common_updateReg(&SYSCTL->SOCLOCK.SYSPLLCFG0,
(((config->rDivClk2x << SYSCTL_SYSPLLCFG0_RDIVCLK2X_OFS) &
SYSCTL_SYSPLLCFG0_RDIVCLK2X_MASK) |
((config->rDivClk1 << SYSCTL_SYSPLLCFG0_RDIVCLK1_OFS) &
SYSCTL_SYSPLLCFG0_RDIVCLK1_MASK) |
((config->rDivClk0 << SYSCTL_SYSPLLCFG0_RDIVCLK0_OFS) &
SYSCTL_SYSPLLCFG0_RDIVCLK0_MASK) |
config->enableCLK2x | config->enableCLK1 | config->enableCLK0 |
(uint32_t) config->sysPLLMCLK),
(SYSCTL_SYSPLLCFG0_RDIVCLK2X_MASK | SYSCTL_SYSPLLCFG0_RDIVCLK1_MASK |
SYSCTL_SYSPLLCFG0_RDIVCLK0_MASK |
SYSCTL_SYSPLLCFG0_ENABLECLK2X_MASK |
SYSCTL_SYSPLLCFG0_ENABLECLK1_MASK |
SYSCTL_SYSPLLCFG0_ENABLECLK0_MASK |
SYSCTL_SYSPLLCFG0_MCLK2XVCO_MASK));
// enable SYSPLL
SYSCTL->SOCLOCK.HSCLKEN |= SYSCTL_HSCLKEN_SYSPLLEN_ENABLE;
// wait until SYSPLL startup is stabilized
while ((DL_SYSCTL_getClockStatus() & SYSCTL_CLKSTATUS_SYSPLLGOOD_MASK) !=
DL_SYSCTL_CLK_STATUS_SYSPLL_GOOD) {
;
}
}
重复:
硬故障 不会 在以下情况下发生:
1.代码是用编译的 -O0。 这 在我 只编译时也是如此 这个特定的例程 使用 -O0 (使用 __attribute__((optimize("O0"))))。
2.我在连接调试器的情况下运行代码。
因此、从我的角度来看、任何编程问题(即参数配置保存一些错误数据)都可以排除。
另一种情况似乎 仅出现在 GNU ARM 工具链 v9.2.1中、发生在 中的 FreeRTOS 例程中 vPortSuppressTicksAndSleep() (这需要 #define configUSE_TICKLESS_IDLE 1)。 我不确定在此例程中硬故障发生的确切位置。
为什么这种 情况 甚至令人担忧的是、当我向代码 中添加任意中断处理程序而不是让 Default_Handler 管理它时、它会消失...即使固件中既未使用也未启用此中断!
听起来很疯狂、对吧? 不过:
我可以始终如一地重现此行为。 同样、 当我应用 上述任何"变通办法"时、我可以始终如一地消除这些问题。
您对此 行为有何解释?
谢谢、
Chris。



