You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:50:21