Tiva C EK-TM4C123GXL开发板MCU无法进入main函数求助
Tiva C TM4C123GH6P执行__main触发HardFault问题排查与解决
环境与问题概述
使用Tiva C EK-TM4C123GXL开发板(MCU型号TM4C123GH6P),开发环境为Keil uVision 5 + ARM编译器6.12 + 对应CMSIS包。编译代码时出现链接警告:
.\RTE\Device\ARMCM0\ARMCM0_ac6.sct(19): warning: L6314W: No section matches pattern *(.bss.noinit).
调试时,Reset_Handler中SystemInit可正常执行,但调用__main时直接跳转到HardFault_Handler进入死循环。修改栈/堆大小、更换IAR环境均未解决问题。
用户代码如下:
#include "TM4C123GH6PM.h" // CMSIS-compatible interface #include <stdint.h> // C99 standard integers #define LED_RED (1U << 1) #define LED_BLUE (1U << 2) #define LED_GREEN (1U << 3) void delay(int volatile iter); int main(void) { SYSCTL->RCGCGPIO |= (1U << 5); /* enable AHB for GPIOF */ SYSCTL->GPIOHBCTL |= (1U << 5); /* enable clock for GPIOF */ /* configure LEDs (digital output) */ GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); /* turn all LEDs off */ GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; GPIOF_AHB->DATA_Bits[LED_BLUE] = LED_BLUE; while (1) { GPIOF_AHB->DATA_Bits[LED_RED] = LED_RED; delay(500000); GPIOF_AHB->DATA_Bits[LED_RED] = 0; delay(250000); } return 0; // unreachable code } void delay(int volatile iter) { while (iter > 0) { // delay loop --iter; } }
问题根源与解决步骤
1. 解决链接警告(L6314W)
该警告是因为分散加载文件ARMCM0_ac6.sct中引用了.bss.noinit段,但代码未使用该段。直接修改该文件:
- 找到
*(.bss.noinit)所在行,添加注释符;注释掉该行,或直接删除该行即可消除警告。
2. 核心问题:错误的设备配置与启动/分散加载文件
TM4C123GH6P是Cortex-M4F内核,但当前工程使用了Cortex-M0的分散加载文件(ARMCM0_ac6.sct)和启动文件,这会导致内存布局、栈/堆配置与实际MCU不匹配,触发HardFault。
修正步骤:
- 打开Keil工程,进入
Options for Target→Device,确认选中Texas Instruments → TM4C123GH6PM,而非其他Cortex-M0/M3设备。 - 切换到
Linker选项卡:- 取消勾选
Use Scatter File,让Keil自动生成匹配TM4C123的内存布局; - 若手动指定分散加载文件,需选择
TM4C123GH6PM_ac6.sct(位于RTE/Device/TM4C123GH6PM目录下)。
- 取消勾选
- 切换到
Asm选项卡,确认启动文件为startup_TM4C123GH6PM.s,而非Cortex-M0的启动文件。
3. 定位HardFault具体原因(调试辅助)
在HardFault_Handler中添加寄存器读取代码,可精准定位错误类型:
#include "TM4C123GH6PM.h" void HardFault_Handler(void) { uint32_t cfsr = SCB->CFSR; uint32_t hfsr = SCB->HFSR; // 调试时查看这两个变量的值: // - CFSR的IBUSERR位=1:指令总线错误,多为Flash地址配置错误 // - CFSR的DACCVIOL位=1:数据访问违例,多为栈/全局变量地址非法 while(1); }
4. 代码优化(潜在问题规避)
将delay函数的参数类型从int改为uint32_t,避免符号扩展导致的异常:
void delay(uint32_t volatile iter) { while (iter > 0) { --iter; } }
内容的提问来源于stack exchange,提问作者Nemanja
相关产品推荐
相关产品推荐

