在stm32f7上使用带有freeRTOS的sprint / printf的问题

如何解决在stm32f7上使用带有freeRTOS的sprint / printf的问题

两天以来,我一直在尝试使printf \ sprintf在我的项目中运行... MCU:STM32F722RETx

我尝试使用newLib,heap3,heap4等,但没有任何效果。 HardFault_Handler在每个时间运行。 现在,我尝试使用来自this link的简单实现,仍然存在相同的问题。我想我的设备存在双精度数问题,因为程序在_ftoa函数中从此行if (value != value)运行HardFault_Handler。(这很奇怪,因为此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,_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_FOR_STACK_OVERFLOW设置为2,但从未调用钩子函数。我发现奇怪的想法:这种解决方案有效:

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

但此解决方案不是:

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

不知道为什么要通过副本传递变量,生成HardFault_Handler ...

解决方法

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

https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

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

,

当我的 SiFive HiFive Rev B 使用FreeRTOS时,printf也出错。

为解决此问题,我重写了_fstat_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;
}

并为 SiFive HiFive Rev B 硬件的UART0创建另一个uart_putc函数:

void uart_putc(int c)
{
#define uart0_txdata    (*(volatile uint32_t*)(0x10013000)) // uart0 txdata register
#define UART_TXFULL             (1 << 31)  // uart0 txdata flag
    while ((uart0_txdata & UART_TXFULL) != 0) { }
    uart0_txdata = c;
}
,

newlib C运行时库(在许多嵌入式工具链中使用)在内部使用它自己的malloc-family例程。 newlib维护一些内部缓冲区,并且需要对线程安全性的一些支持: http://www.nadler.com/embedded/newlibAndFreeRTOS.html

硬错误可能是由于未对齐的内存访问引起的: https://www.keil.com/support/docs/3777.htm

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?