Embedded stm32f7上带freeRTOS的sprint/printf出现问题

Embedded stm32f7上带freeRTOS的sprint/printf出现问题,embedded,printf,stm32,freertos,stm32f7,Embedded,Printf,Stm32,Freertos,Stm32f7,两天以来,我一直试图让printf\sprintf在我的项目中工作。。。 MCU:STM32F722RETx 我试着使用newLib、heap3、heap4等等,但没有任何效果。HardFault_处理程序每运行一次。 现在,我试图使用简单的实现,但仍然是相同的问题。我想我的设备在双数方面有一些问题,因为程序在ftoa函数中从这一行if(value!=value)(奇怪的是,这个stm32支持FPU) 你们知道吗?(现在我正在使用heap_4.c) 我的编译器选项: target_compile

两天以来,我一直试图让printf\sprintf在我的项目中工作。。。 MCU:STM32F722RETx

我试着使用newLib、heap3、heap4等等,但没有任何效果。HardFault_处理程序每运行一次。 现在,我试图使用简单的实现,但仍然是相同的问题。我想我的设备在双数方面有一些问题,因为程序在ftoa函数中从这一行
if(value!=value)
(奇怪的是,这个stm32支持FPU) 你们知道吗?(现在我正在使用heap_4.c) 我的编译器选项:

target_compile_options(${PROJ_NAME} PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:
    -std=c++14
>
-mcpu=cortex-m7
-mthumb
-mfpu=fpv5-d16
-mfloat-abi=hard
-Wall
-ffunction-sections
-fdata-sections
-O1 -g
-DLV_CONF_INCLUDE_SIMPLE
 )
target_link_options(${PROJ_NAME} PUBLIC
${LINKER_OPTION} ${LINKER_SCRIPT}
-mcpu=cortex-m7
-mthumb
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
-specs=nosys.specs
-specs=nano.specs
# -Wl,--wrap,malloc
# -Wl,--wrap,_malloc_r
-u_printf_float
-u_sprintf_float
 )
链接器脚本:

/* Highest address of the user mode stack */
_estack = 0x20040000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
   RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 256K
  FLASH (rx)    : ORIGIN = 0x08000000, LENGTH = 512K
}
更新: 我不认为这是堆栈问题,我已将configCHECK\u FOR\u stack\u OVERFLOW设置为2,但从未调用hook函数。我发现奇怪的想法:这种溶液有效:

float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f", 23.5f);
但这一解决方案并非:

float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f",d);

不知道为什么要按副本传递变量,生成硬故障处理程序…

您可以实现一个硬故障处理程序,该处理程序至少会为您提供发生问题的SP位置。这将提供更多的洞察力


它应该让您知道问题是否是由于MCU内的浮点错误造成的,或者是由于可能由某些链接问题引起的分支错误造成的。

您可以实现一个硬故障处理程序,该处理程序至少会向您提供发生问题的SP位置。这将提供更多的洞察力


它应该让您知道您的问题是由于MCU内的浮点错误还是由于可能由某些链接问题引起的分支错误造成的

在我的SiFive HiFive Rev B中使用FreeRTOS时,我也遇到了printf的错误

为了解决这个问题,我重写了
\u fstat
\u write
函数来更改
printf的输出函数

/*
 * Retarget functions for printf()
 */
#include <errno.h>
#include <sys/stat.h>

int _fstat (int file, struct stat * st) {
    errno = -ENOSYS;
    return -1;
}

int _write (int file, char * ptr, int len) {
    extern int uart_putc(int c);
    int i;

    /* Turn character to capital letter and output to UART port */
    for (i = 0; i < len; i++) uart_putc((int)*ptr++);
    return 0;
}

在将FreeRTOS用于我的SiFive HiFive Rev B时,我还出现了
printf
错误

为了解决这个问题,我重写了
\u fstat
\u write
函数来更改
printf的输出函数

/*
 * Retarget functions for printf()
 */
#include <errno.h>
#include <sys/stat.h>

int _fstat (int file, struct stat * st) {
    errno = -ENOSYS;
    return -1;
}

int _write (int file, char * ptr, int len) {
    extern int uart_putc(int c);
    int i;

    /* Turn character to capital letter and output to UART port */
    for (i = 0; i < len; i++) uart_putc((int)*ptr++);
    return 0;
}

newlib C-runtime库(在许多嵌入式工具链中使用)在内部使用自己的malloc系列例程。newlib维护一些内部缓冲区,并需要一些线程安全支持:

硬故障可能由未对齐的内存访问引起:

newlib C-runtime库(用于许多嵌入式工具链)在内部使用自己的malloc系列例程。newlib维护一些内部缓冲区,并需要一些线程安全支持:

硬故障可能由未对齐的内存访问引起:

检查堆栈指针是否在导致硬故障的任何点溢出堆栈。我相信STM32F722具有单精度FPU,这意味着软件库将用于任何双重操作。我不知道这是否重要,但你提到了双倍,所以我想我会提到它。如果你可以复制的话,可以尝试用CubeMX生成一个简单的项目,并使用STM32CubeIDE的“硬故障分析器”。如果可以的话“我怀疑编译器或链接器选项有问题。请检查堆栈指针是否在导致硬故障的任何点溢出堆栈。我相信STM32F722具有单精度FPU,这意味着软件库将用于任何双精度操作。我不知道这是否重要,但你提到了双倍,所以我想我会提到它。如果你可以复制的话,可以尝试用CubeMX生成一个简单的项目,并使用STM32CubeIDE的“硬故障分析器”。如果不能,我将怀疑编译器或链接器选项有问题。寄存器:r0:536871872\r1:1\r2:1\r3:1102839808\r12:2779096485\lr:134320687\pc:134314822\psr:553648128\n我已将断点设置为“pc”“地址,但它设置为sprintf函数:<现在我使用heap_4.c和标准stdio函数。你知道吗?这些寄存器对我来说是神奇的数字^^我还注意到S31寄存器有值:-nan(0x7fffff)寄存器:r0:536871872\r1:1\r2:1\r3:1102839808\r12:2779096485\lr:134320687\pc:134314822\psr:553648128\n我已将断点设置为“pc”地址,但它设置为sprintf函数:<现在我使用heap_4.c和标准stdio函数。你知道吗?这些寄存器对我来说是神奇的数字^^我还注意到S31寄存器的值为:-nan(0x7fffff)