我正在使用 Tiva C EK-TM4C123GXL 开发板(MCU -> TM4C123GH6P)。对于这个特定的微控制器,我使用 Keil uVision 5、ARM 编译器 6.12 和 CMSIS 包。 我的代码如下:
#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;
}
}
构建后,我收到以下警告,但我能够加载代码:
.\RTE\Device\ARMCM0\ARMCM0_ac6.sct(19): warning: L6314W: No section matches pattern *(.bss.noinit).
调试会话从输入 Reset_Handler(在启动文件内)开始:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
函数
SystemInit
执行没有任何问题,但是当执行__main
时,程序跳转到HardFault_Handler
并保持永远循环。
到目前为止,我尝试修改堆栈大小,但没有结果。同样,我修改了堆大小,但问题仍然存在。我尝试使用 IAR,但问题变得更严重。
在网上搜索了一下,发现很多人在相同的DevBoard上都遇到了类似的问题,但我仍然找不到解决方案。
很可能您的项目设置不正确,并且您没有针对正确的 MCU 进行编译:
.\RTE\Device\ARMCM0\ARMCM0_ac6.sct(19):
您的 MCU 是 M4
,此消息表明您使用了一些 M0
分散文件。
测试
LDR R0, =__main
是否使用已设置LSB的地址加载R0(以指示拇指模式)。如果不是,那么您就不会在拇指模式下编译。
检查 HF 的原因(将
printf
替换为任何可用的内容) - 甚至只是放置断点并查看执行了什么
// Base address for System Control Space (SCB)
#define SCB_BASE 0xE000ED00
// Registers for fault status
#define SCB_HFSR (*(volatile uint32_t *)(SCB_BASE + 0x02C)) // Hard Fault Status Register
#define SCB_CFSR (*(volatile uint32_t *)(SCB_BASE + 0x028)) // Configurable Fault Status Register
#define SCB_MMAR (*(volatile uint32_t *)(SCB_BASE + 0x034)) // Memory Management Fault Address Register
#define SCB_BFAR (*(volatile uint32_t *)(SCB_BASE + 0x038)) // Bus Fault Address Register
#define SCB_AIRCR (*(volatile uint32_t *)(SCB_BASE + 0x00C)) // Application Interrupt and Reset Control Register
void displayHardwareFaultReason()
{
// Read the Hard Fault Status Register (HFSR)
uint32_t hfsr = SCB_HFSR;
if (hfsr & (1 << 30))
{
printf("FORCED: A configurable fault (such as usage, bus, or memory fault) escalated to hard fault.\n");
// Read the Configurable Fault Status Register (CFSR)
uint32_t cfsr = SCB_CFSR;
// Check memory management faults
if (cfsr & 0xFF) // MMFSR: Bits [7:0]
{
printf("Memory Management Fault Detected:\n");
if (cfsr & (1 << 0)) printf(" IACCVIOL: Instruction access violation.\n");
if (cfsr & (1 << 1)) printf(" DACCVIOL: Data access violation.\n");
if (cfsr & (1 << 3)) printf(" MUNSTKERR: Unstacking error during exception return.\n");
if (cfsr & (1 << 4)) printf(" MSTKERR: Stacking error during exception entry.\n");
if (cfsr & (1 << 7))
{
printf(" MMARVALID: MMAR contains the address of the faulting access: 0x%08X\n", SCB_MMAR);
}
}
// Check bus faults
if (cfsr & 0xFF00) // BFSR: Bits [15:8]
{
printf("Bus Fault Detected:\n");
if (cfsr & (1 << 8)) printf(" IBUSERR: Instruction bus error.\n");
if (cfsr & (1 << 9)) printf(" PRECISERR: Precise data bus error.\n");
if (cfsr & (1 << 10)) printf(" IMPRECISERR: Imprecise data bus error.\n");
if (cfsr & (1 << 11)) printf(" UNSTKERR: Unstacking error during exception return.\n");
if (cfsr & (1 << 12)) printf(" STKERR: Stacking error during exception entry.\n");
if (cfsr & (1 << 15))
{
printf(" BFARVALID: BFAR contains the address of the faulting access: 0x%08X\n", SCB_BFAR);
}
}
// Check usage faults
if (cfsr & 0xFFFF0000) // UFSR: Bits [31:16]
{
printf("Usage Fault Detected:\n");
if (cfsr & (1 << 16)) printf(" UNDEFINSTR: Undefined instruction.\n");
if (cfsr & (1 << 17)) printf(" INVSTATE: Invalid state.\n");
if (cfsr & (1 << 18)) printf(" INVPC: Invalid program counter.\n");
if (cfsr & (1 << 19)) printf(" NOCP: No coprocessor available.\n");
if (cfsr & (1 << 24)) printf(" UNALIGNED: Unaligned memory access.\n");
if (cfsr & (1 << 25)) printf(" DIVBYZERO: Division by zero.\n");
}
}
else if (hfsr & (1 << 1))
{
printf("VECTBL: Bus fault on vector table read during exception processing.\n");
}
else
{
printf("No forced faults detected.\n");
}
}