嵌入式技术论坛
直播中

张波

7年用户 1402经验值
私信 关注
[问答]

用sprintf把浮点数打印出来就出现hard faul怎么办

大家好,刚接触RTT,第一感觉shell做的很好,调试起来很方便,所以开始在这个平台上做一些东西。

现在我遇到一个问题:

我想用sprintf把浮点数打印出来的时候就出现hard fault。

代码如下:
void ds18b20_thread_entry(void * parameter)
{
  char __string[10];
  float __T;
  ds18b20_init();
  while(ds18b20_check() == 0)
  {
    lcd_showString(30,110,"DS18B20 detecting..");
    rt_thread_delay(100);
  }
  lcd_showString(30,110,"DS18B20 detected   ");
  lcd_showString(30,130,"Temperate:");
  while(1)
  {
    __T = ds18b20_getTemp();
    sprintf(__string, "%f", __T);
    lcd_showString(110,130,(const char*)__string);
    rt_thread_delay(200);
  }
}

编译器:Sourcery G++ Lite 2009q3-68
注:线程创建时使用动态内存方式。
使用sprintf打印浮点编译时提示缺少函数_***rk。于是从网上找了一下这个函数。加进去重新编译通过,但运行完sprintf(),再接着跑rt_thread_delay()的时候就出现hard fault了。

#include
extern int  __HEAP_START;
caddr_t _***rk ( int incr )
{
  static unsigned char *heap = NULL;
  unsigned char *prev_heap;
  if (heap == NULL)
  {
    heap = (unsigned char *)&__HEAP_START;
  }
  prev_heap = heap;
  /* check removed to show basic approach */
  heap += incr;
  return (caddr_t) prev_heap;
}
__HEAP_START在linkerscript里面定义的
......
        /* This is used by the startup in order to initialize the .bss secion */
        _ebss = . ;
        _estack = .;
        *(.bss.init)
    } > DATA
    __bss_end = .;
    _end = .;
    PROVIDE(__HEAP_START = _end );
    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
......
不知道是不是_***rk ()定义的heap跟系统用的heap重叠了,请问问题主要出在哪里,还有其他方法打印浮点数吗?
谢谢



回帖(7)

百灵千岛酱

2022-4-8 10:35:17
你用的是哪个分支?_***rk是不能这么用的,这样使用系统会出现错误(因为动态堆内存管理已经被RT-Thread接管了)。
举报

张波

2022-4-8 10:35:34
我现在用的是
URL :
Revision: 1364

我尝试过rt_sprintf,但发现rt_sprintf不支持%f。请问现在打印浮点数是怎样处理的呢?是不是只能把浮点数转换成整数(循环乘以10,取整数部分)再打印出来呢?
举报

百灵千岛酱

2022-4-8 10:36:05
硬件平台是什么?

newlib的sprintf可能与_***rk有关系;另外,ARM平台在MDK中,浮点数需要线程栈向8对齐,但对于newlib, gcc还不知道是否也相类似。你先需要把你的硬件平台说说
举报

张波

2022-4-8 10:36:37
我的开发平台:
eclipse+ CDT + GNU ARM Eclipse Plug-in
编译器:
arm-none-eabi-gcc(Sourcery G++ Lite 2009q3-68)
硬件:
ALIENTEK的板子,MCU是STM32F103RBT6的

现在我只拷贝了kernel以及finsh的代码来用,其他部分没加进来。
据我了解,amr-none-eabi-的编译器不像amr-elf-的,它没有包含完整的nwelib部分,所以用到库函数时,经常会提示某些函数没主体,主体还需要自己实现。
我想如果用MDK不会出现这样的问题,因为armcc已经把newlib做好了。
举报

百灵千岛酱

2022-4-8 10:37:13
所以说,下次有问题一定需要讲清楚硬件平台,当然还有编译器,配置情况等。

你这个问题是,你的newlib根本没做移植,所以肯定出问题!既然你是用arm-none-eabi-,那么你就把RT-Thread中的RT_USING_NEWLIB打开吧,并编译libc/newlib下的代码。

arm-none-eabi-是包含newlib的,没包含的话,你的sprintf就无法链接成功了。
举报

张波

2022-4-8 10:37:51
我把RT_USING_NEWLIB给define了,然后再把componentslibc

ewlib下的代码加入,重新编译。得到很多implicit declaration of function 的警告以及以下的错误:

undefined reference to `mkdir'  syscalls.c  /STM32_test/program/os/components/libc/newlib  line 0  C/C++ Problem

undefined reference to `rt_console_init'  libc.c  /STM32_test/program/os/components/libc/newlib  line 0  C/C++ Problem

下面是rtconfig.h的内容

/* RT-Thread config file */

#ifndef __RTTHREAD_CFG_H__

#define __RTTHREAD_CFG_H__

/* RT_NAME_MAX*/

#define RT_NAME_MAX  10

/* RT_ALIGN_SIZE*/

#define RT_ALIGN_SIZE  4

/* PRIORITY_MAX */

#define RT_THREAD_PRIORITY_MAX  32

/* Tick per Second */

#define RT_TICK_PER_SECOND  100

/* SECTION: RT_DEBUG */

/* Thread Debug */

#define RT_DEBUG

#define RT_THREAD_DEBUG

#define RT_USING_OVERFLOW_CHECK

/* Using Hook */

//#define RT_USING_HOOK

/* Using Software Timer */

/* #define RT_USING_TIMER_SOFT */

#define RT_TIMER_THREAD_PRIO    4

#define RT_TIMER_THREAD_STACK_SIZE  512

#define RT_TIMER_TICK_PER_SECOND  10

/* SECTION: IPC */

/* Using Semaphore*/

#define RT_USING_SEMAPHORE

/* Using Mutex */

#define RT_USING_MUTEX

/* Using Event */

#define RT_USING_EVENT

/* Using MailBox */

#define RT_USING_MAILBOX

/* Using Message Queue */

#define RT_USING_MESSAGEQUEUE

/* SECTION: Memory Management */

/* Using Memory Pool Management*/

#define RT_USING_MEMPOOL

/* Using Dynamic Heap Management */

#define RT_USING_HEAP

/* Using Small MM */

#define RT_USING_SMALL_MEM

/* SECTION: Device System */

/* Using Device System */

#define RT_USING_DEVICE

#define RT_USING_UART1

/* SECTION: Console options */

#define RT_USING_CONSOLE

/* the buffer size of console*/

#define RT_CONSOLEBUF_SIZE  128

/* SECTION: finsh, a C-Express shell */

#define RT_USING_FINSH

/* Using symbol table */

#define FINSH_USING_SYMTAB

#define FINSH_USING_DESCRIPTION

/* SECTION: the runtime libc library */

/* the runtime libc library */

#define RT_USING_NEWLIB

#define RT_USING_DFS_DEVFS

/* SECTION: device filesystem */

//#define RT_USING_DFS

//#define RT_USING_DFS_ELMFAT

/* the max number of mounted filesystem */

//#define DFS_FILESYSTEMS_MAX      2

/* the max number of opened files     */

//#define DFS_FD_MAX          4

/* the max number of cached sector     */

//#define DFS_CACHE_MAX_NUM       4

/* SECTION: lwip, a lighwight TCP/IP protocol stack */

//#define RT_USING_LWIP

/* LwIP uses RT-Thread Memory Management */

//#define RT_LWIP_USING_RT_MEM

/* Enable ICMP protocol*/

//#define RT_LWIP_ICMP

/* Enable UDP protocol*/

//#define RT_LWIP_UDP

/* Enable TCP protocol*/

//#define RT_LWIP_TCP

/* Enable DNS */

//#define RT_LWIP_DNS

/* the number of simulatenously active TCP connections*/

//#define RT_LWIP_TCP_PCB_NUM  5

/* ip address of target*/

//#define RT_LWIP_IPADDR0  192

//#define RT_LWIP_IPADDR1  168

//#define RT_LWIP_IPADDR2  1

//#define RT_LWIP_IPADDR3  30

/* gateway address of target*/

//#define RT_LWIP_GWADDR0  192

//#define RT_LWIP_GWADDR1  168

//#define RT_LWIP_GWADDR2  1

//#define RT_LWIP_GWADDR3  1

/* mask address of target*/

//#define RT_LWIP_MSKADDR0  255

//#define RT_LWIP_MSKADDR1  255

//#define RT_LWIP_MSKADDR2  255

//#define RT_LWIP_MSKADDR3  0

/* tcp thread options */

//#define RT_LWIP_TCPTHREAD_PRIORITY    12

//#define RT_LWIP_TCPTHREAD_MBOX_SIZE    4

//#define RT_LWIP_TCPTHREAD_STACKSIZE    1024

/* ethernet if thread options */

//#define RT_LWIP_ETHTHREAD_PRIORITY    15

//#define RT_LWIP_ETHTHREAD_MBOX_SIZE    4

//#define RT_LWIP_ETHTHREAD_STACKSIZE    512

#endif

我现在只加了kernel,finsh,和newlib的代码到里面
举报

李玉兰

2022-4-8 10:38:14
这个问题现在还存在?直接取git的代码,用scons编译bsp/stm32f40x的工程,
下载到Stm32F4Discovery上,串口用sprintf打印的浮点数,直接就是%f字符串,没有解析出来。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分