Arm 4 微控制器上的硬故障错误
Hard Fault Error on Arm 4 microcontroller
我的 Tiva C 控制器有一个非常奇怪的问题,我需要一些帮助,基本上它在 sprintf
行崩溃,没有明显的原因。我的应用程序只是一个智能玩具,可以通过蓝牙以各种模式进行控制。对于这些模式,我们使用有限状态机代码并读取玩具的当前加速度,仅用于监控,并且每隔一段时间使用周期性定时器发送一次,该定时器每隔几秒产生一个周期性中断以更新值加速度
现在加速的读取是通过一个简单的函数完成的,读取正常,直到试图将该读数存储在一个字符串中并且程序只是抛出一个硬错误。这个函数(读取加速度)在玩具车的所有其他模式下工作正常,除了这个新模式它总是崩溃并抛出硬故障错误。我目前的想法是,这可能是由于函数调用过多导致堆栈已满,但我怎么知道堆栈是否已满?
这是它崩溃的行:
sprintf(acceleration,"x%.2f y%.2f z%.2f", X_Axis1, Y_Axis1, Z_Axis1);
这是一个简单的 sprintf
,它存储从加速度轴 x
、y
和 z
读取的值,然后将发生这种情况的原因存储在加速度变量中?
这也是定时器处理程序中 keil 的故障报告,我曾经调用一个 ReadAccel()
函数,该函数在所有模式下都有效,除了最近的一个,所以我想我会把代码移到里面计时器处理程序中的函数从堆栈中保存一点,但它仍然给出了一个硬错误
如果有人可以将我重定向到如何确定这是否是堆栈已满错误,我将非常感激,因为我认为这就是错误。
void TIMER2A_Handler(void)
{
char acceleration[22];
RawX_Axis1=ReadAccelX();
X_Axis1 = RawX_Axis1 * 0.00390625+0.35;
RawY_Axis1=ReadAccelY();
Y_Axis1 = RawY_Axis1 * 0.00390625+0.08;
RawZ_Axis1=ReadAccelZ();
Z_Axis1 = (RawY_Axis1 * 0.00390625)+1.08;
sprintf(acceleration,"x%.2f y%.2f z%.2f",X_Axis1,Y_Axis1,Z_Axis1);
UARTSend(UART3_BASE,acceleration);
UARTCharPut(UART3_BASE,'\n');
TIMER2_RIS_R = 0xFFFFFFFF;
TIMER2_ICR_R = 0xFFFFFFFF;
}
首先尝试不调用 sprintf,只需在 UARTSend
中发送一个硬编码字符串。如果这停止了崩溃,那么您需要找出 sprintf
导致崩溃的原因。我看到两个问题:
- 有可能stack overflow(哈哈)
- 缓冲区溢出的可能性。
您为 sprintf 分配了一个 22 字节的缓冲区,这可能太小了,因为它只允许每个加速度使用六个字符(包括可能的减号和小数点)。尝试格式化并单独发送每个加速度。它还可以减轻 sprintf 中潜在的堆栈溢出。
此外,请尝试使用简化的内联字符串转换。例如在将每个数字乘以 100 后将其转换为 int(给你一个 2 dp 定点数)并使用简单的除法和 mod 除以 10 并添加到 0x30 (ASCII 0
) 来创建字符串。
我的 Tiva C 控制器有一个非常奇怪的问题,我需要一些帮助,基本上它在 sprintf
行崩溃,没有明显的原因。我的应用程序只是一个智能玩具,可以通过蓝牙以各种模式进行控制。对于这些模式,我们使用有限状态机代码并读取玩具的当前加速度,仅用于监控,并且每隔一段时间使用周期性定时器发送一次,该定时器每隔几秒产生一个周期性中断以更新值加速度
现在加速的读取是通过一个简单的函数完成的,读取正常,直到试图将该读数存储在一个字符串中并且程序只是抛出一个硬错误。这个函数(读取加速度)在玩具车的所有其他模式下工作正常,除了这个新模式它总是崩溃并抛出硬故障错误。我目前的想法是,这可能是由于函数调用过多导致堆栈已满,但我怎么知道堆栈是否已满?
这是它崩溃的行:
sprintf(acceleration,"x%.2f y%.2f z%.2f", X_Axis1, Y_Axis1, Z_Axis1);
这是一个简单的 sprintf
,它存储从加速度轴 x
、y
和 z
读取的值,然后将发生这种情况的原因存储在加速度变量中?
这也是定时器处理程序中 keil 的故障报告,我曾经调用一个 ReadAccel()
函数,该函数在所有模式下都有效,除了最近的一个,所以我想我会把代码移到里面计时器处理程序中的函数从堆栈中保存一点,但它仍然给出了一个硬错误
如果有人可以将我重定向到如何确定这是否是堆栈已满错误,我将非常感激,因为我认为这就是错误。
void TIMER2A_Handler(void)
{
char acceleration[22];
RawX_Axis1=ReadAccelX();
X_Axis1 = RawX_Axis1 * 0.00390625+0.35;
RawY_Axis1=ReadAccelY();
Y_Axis1 = RawY_Axis1 * 0.00390625+0.08;
RawZ_Axis1=ReadAccelZ();
Z_Axis1 = (RawY_Axis1 * 0.00390625)+1.08;
sprintf(acceleration,"x%.2f y%.2f z%.2f",X_Axis1,Y_Axis1,Z_Axis1);
UARTSend(UART3_BASE,acceleration);
UARTCharPut(UART3_BASE,'\n');
TIMER2_RIS_R = 0xFFFFFFFF;
TIMER2_ICR_R = 0xFFFFFFFF;
}
首先尝试不调用 sprintf,只需在 UARTSend
中发送一个硬编码字符串。如果这停止了崩溃,那么您需要找出 sprintf
导致崩溃的原因。我看到两个问题:
- 有可能stack overflow(哈哈)
- 缓冲区溢出的可能性。
您为 sprintf 分配了一个 22 字节的缓冲区,这可能太小了,因为它只允许每个加速度使用六个字符(包括可能的减号和小数点)。尝试格式化并单独发送每个加速度。它还可以减轻 sprintf 中潜在的堆栈溢出。
此外,请尝试使用简化的内联字符串转换。例如在将每个数字乘以 100 后将其转换为 int(给你一个 2 dp 定点数)并使用简单的除法和 mod 除以 10 并添加到 0x30 (ASCII 0
) 来创建字符串。