This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294KCPDT:sprintf 时的浮点问题

Guru**** 2553450 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf

器件型号:TM4C1294KCPDT

您好、

我需要将字符串数据发送到以太网、我在转换浮点值时遇到 sprintf 函数问题、如下所示。

float rffth =12.523;

char thbuffer[10];

sprintf (thbuffer、"%0.2f"、rffth);

sprintf 崩溃应用程序。 我还交叉检查了 include 库要求。 它可以使用整数或字符串。

我使用的是 CCS v9.1 和 TI RTOS v:- 2.16.1.14

请帮助

此致

Khodidas Domadiya

嵌入式工程师

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="289369" URL"~/support/microcontrollers/other-microcontrollers-group/other/f/other-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf ]sprintf 崩溃应用程序。 我还交叉检查了 include 库要求。

    与格式化整数值或字符串值相比、格式化浮点值可能需要更多的堆栈空间。

    是从 TI-RTOS 任务还是从 main()发出有问题的 sprintf 调用?

    使用的堆栈大小是多少?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    奇怪的是,本周通过中断矢量也出现了同样的问题(%u)非操作系统 fprint()。 但是、打印十进制值似乎是有效的。  您可以在 CCS 调试中看到浮点十进制等效。 正在尝试打印小数点%c'。' 崩溃。 对%i 或%d 进行了一些奇数浮点字符转换。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     切斯特是否解决了您的问题? 您是否增加了堆栈? 分配足够的堆栈(例如1536)后,sprintf 没有问题。 注意:我通过粘贴您的代码来创建一个简单的程序。 看到存储在该缓冲区中的值。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    %符号后的 printf()格式字符是什么? 海报代码没有在%符号后面添加格式参数、而是在末尾添加 此外、假设 C++ printf()从 RTOS System_printf()和 UARTprintf()中退出。 奇怪的 sprintf()没有包含在我的 C++编码文档中。 我一直在使用 UARTprintf(),因此这可能是它对使用各种格式字符(单精度浮点数)的 NMI 进行硬故障的原因。 我不相信 FPU IEEE 支持双精度(f)、也不支持项目运行时(rtsv7M4_T_le_v4SPD16_eabi.lib)  

    3.1.5浮点单元(FPU)
    本节介绍了浮点单元(FPU)及其使用的寄存器。 FPU 提供:
    适用于单精度(C float)数据处理操作的■32位指令

    表7-1. 基本 printf 转换

    f double;[-1M.DDDD、其中 d 的数量由精度给出(默认值6)。


    e、E double;[-1m.ddddde±xx 或[-1m.dddddE±XX、其中 d 的 Number 由精度给出(默认值6)。


    G、G double;如果指数小于-4或大于或等于精度、则使用%e 或%E;否则使用%f 不打印尾随零和尾随小数点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    sprintf()等各种标准函数被编译到名为 libc.a.的库中

    如果您四处搜索、您会发现库的源位于目录中、如 C:\ti\ccs1030\ccs\tools\compiler\ti-cgt-arm_20.2.5.LTS lib\src。

    如果您进一步挖掘、您将看到 sprintf()调用 printf(),该函数最终在_printfi.c 文件中实现

    在该文件中,您会发现函数 fcvt()用于浮点转换。

    该函数(以及其他函数)通过 NOFLOAT 和 Minimal 等宏打开和关闭。 如果这两个宏都未定义、则浮点转换的处理内置到库中。 如果定义了浮点支持、则会省略浮点支持。

    您使用的 libc.a 的特定版本似乎没有启用浮点支持,因此 sprintf()中的崩溃。

    这是10亿美元的问题:谁应该知道这个库中内置了什么支持呢? Makefile 和所有内容都是完全不可理解的。

    至少 TivaWare 库 ustdlib.c 中 usprintf ()的简单实现已清楚地记录并明确说明了支持的格式说明符:扰流器:而不是浮点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="40553" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf/3769591 #3769591"]如果您四处搜索,您会发现库的源位于目录中,如 C:\ti\ccs1030\ccs\tools\compiler\ti-cgt-arm_20.2.5.spl\lib\src。

    通常不会将该路径添加到我们的 CCS 工程中。 然而、项目常规选项卡自动添加了~18.12.4.LTS/include/libcxx、这省略了 sprintf ()和 printf ()。 将{${CG_TOOL_ROOT}/lib/libc.a}添加到 C++常规库选项卡中、代码检查不会扫描 lib.ca 函数的索引、因此不支持指令 sprintf ()、printf ()函数。   

    重点是这些较旧的 C++打印功能可能会由于合理的原因而发生冲突。 IEEE 754标准似乎早于 C99附录、其中后缀(f)表示单精度 FPU 运算。 然而、编译器将 (后缀(f))的双精度 FPU 操作置为有效、从而将 FPSCR 标志设置为 true 并且立即触发 NMI 硬故障异常。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    BTW: 添加#include 不为 spfintf()配置 UART 外设 ,并且 CCS 控制台被 CDT 构建占用。 我们必须使用 UARTprintf()或其他一些函数,这些函数具有用于缓冲连接的 UART 输出或用于虚拟 COM 的 UART 驱动程序。  sprintf()和 printf()数据流似乎已移植到 Visual Studio IDE 控制台的 SDIO.dll 驱动程序和 MSBasic 调试运行时间。 我已经在 Windows 调试基本版中运行了十年、几乎忘记了如何从 cmd 提示符进入该程序

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="40553" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf/3769591 #3769591"]这是一个十亿美元的问题:谁应该知道这个库中内置了什么支持呢? Makefile 和所有内容都是完全不可理解的。

    根据 ARM 优化 C/C++编译器 v20.2.0.LTS 用户指南 :

    即、库应使用所有选项进行构建、-printf_support 选项会告知链接器选择适当的支持。

    [引用 userid="40553" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf/3769591 #3769591"]您使用的特定版本 libc.a 没有启用浮点支持,因此 sprintf()中的崩溃。

    对于 ti-cgt-arm_20.2.0.LTS、使用了以下代码:

    #include <stdio.h>
    
    /**
     * main.c
     */
    int main(void)
    {
        float rffth =12.523;
    
        char thbuffer[10];
    
        sprintf(thbuffer,"%0.2f",rffth);
    
    	return 0;
    }

    在 CCS Build -> ARM Compiler -> Advanced Options -> Language Options 下的 CCS 项目选项中、将"level of printf/scanf support required (-printf_support)"设置为 nofloat。

    导致编译错误:

    Building file: "../main.c"
    Invoking: ARM Compiler
    "/home/mr_halfword/ti/ccs1000/ccs/tools/compiler/ti-cgt-arm_20.2.0.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="/home/mr_halfword/workspace_v10/TM4C1294KCPDT_float_printf" --include_path="/home/mr_halfword/ti/ccs1000/ccs/tools/compiler/ti-cgt-arm_20.2.0.LTS/include" --define=ccs="ccs" --define=PART_TM4C1294KCPDT -g --gcc --printf_support=nofloat --diag_warning=225 --diag_wrap=off --display_error_number --verbose_diagnostics --abi=eabi --preproc_with_compile --preproc_dependency="main.d_raw"  "../main.c"
     
    >> Compilation failure
    subdir_rules.mk:7: recipe for target 'main.obj' failed
    "../main.c", line 14: error #2632: Conversion f not allowed in printf_support=nofloat mode
          sprintf(thbuffer,"%0.2f",rffth);
                                        ^
     
    1 error detected in the compilation of "../main.c".
    即、如果您使用常量格式字符串、编译器应陷阱使用不受支持的选项。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="91588" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf/3771096 #3771096"]并在 CCS Build -> ARM 编译器->高级选项->语言选项中将"所需的 printf/scanf 支持级别(-printf_support)"设置为 nofloat。[/quot]

    啊哈! 谢谢你。 我们对此表示非常赞赏。

    我刚刚检查了一个最近完成的项目。 两件事。

    第一、libc.a 作为库包含在链接器设置中

    第二、在语言选项中、"所需的 printf/scanf 支持级别(--printf_support)"设置为"完全"。

    项目是从其中一个模板创建的、因此这些设置是从示例继承的。

    事情是,我使用的是 TivaWare ustdlib.c 库中提供的 usprintf(),该函数不支持浮点运算。 我这样做是因为所有示例都使用了 usprintf()来支持 sprintf()。 该项目使用 Kentec 图形 LCD 来显示来自其中一个传感器板的温度和湿度读数。 这些读数是浮点值(缩放后),由于 usprintf()不支持浮点,因此我最后编写了一个小函数,将浮点值"破裂"到其整数和小数部分,每个部分都由 uint32_t 表示

    更新该项目并摆脱 usprintf()并只使用 sprintf()的时间! 我今天学到了一些东西!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    如果需要任何其他选项或其他操作来执行 sprintf、则基于 TI -RTOS 的应用程序中不会有此项目选项、因为我需要它作为字符串格式发送到以太网。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     下面是一个小型程序、用于使用 sprintf 将浮点值存储到字符串中、然后使用 UARTprintf 和 printf 进行打印。

    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "drivers/pinout.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    // Configure the UART and its pins.  This must be called before UARTprintf().
    //
    //*****************************************************************************
    void
    ConfigureUART(void)
    {
        //
        // Enable the GPIO Peripheral used by the UART.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Enable UART0
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Configure GPIO Pins for UART mode.
        //
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000); // Default 16Mhz SYSCLK using PIOSC
    }
    
    
    //*****************************************************************************
    //
    // Print "Hello World!" to the UART on the Intelligent UART Module.
    //
    //*****************************************************************************
    int
    main(void)
    {
    	float rffth =12.523;
    	int abc = 123;
    
    	char thbuffer[10];
    
    	sprintf(thbuffer,"%0.2f",rffth);
    
        ConfigureUART();
    
        UARTprintf("Using UARTprintf\n");
        UARTprintf("rffth is %s\n", thbuffer);
    
        printf("Using printf\n");
        printf("rffth is %s\n", thbuffer);
    
    
    	while (1);
    
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="48581" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019510/tm4c1294kcpdt-floating-point-issue-when-sprintf/3769575 #3769575"] RTOS System_printf ()
    Unknown 说:
    因为我需要它作为字符串格式发送到以太网。  [/报价]

    您可能需要添加#include 要将 printf()字符串路由到以太网 TXD 传输的环形缓冲器中? printf()如何使用 streams.h 来知道控制台端口是如何使用 CCS IDE? 我几年前尝试让 printf()正常工作,即使在 CCS 论坛上也无法做到。 当我调用时,RTOS System_print()输出到 Debug 消息控制台。

    BTW:这用于模拟浮点值的小数点、UARTLprintf ("MyPointer->0.%i\n"、VarOutput)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将很快进行测试和恢复