RT-Thread使用sscanf %X时,需要启用libc

目标将字符串char str[]="12345678"转成数组array,使得array[0]=0x12;array[1]=0x34;array[2]=0x56;array[3]=0x78。
因为将代码下载到单片机中太费时间,就使用了RT-Thread的QEMU在线仿真进行。

C:\RT-ThreadStudio\workspace\pdulib_test>C:/RT-ThreadStudio/repo/Extract/Debugger_Support_Packages/RealThread/QEMU/4.2.0/qemu-system-arm.exe -M stm32f407-atk-explorer --kernel Debug/rtthread.elf -nographic -show-cursor-S -s

代码如下:

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-06     SummerGift   first version
 * 2018-11-19     flybreak     add stm32f407-atk-explorer bsp
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/**
 * 将2byte的16进制字符串转为uint8_t类型
 * @param addr
 * @param value
 * @return
 */
static int hexstr2uint8_t(char *addr, uint8_t *value)
{
    
    
    uint8_t ret = RT_EOK;
    char *temp = RT_NULL;
    temp = rt_calloc(1, 3);
    if (temp == RT_NULL)
    {
    
    
        LOG_E("no memery for hexstring to uint8_t");
        ret = -RT_ENOMEM;
        goto __exit;
    }
    strncpy(temp, addr, 2);
    LOG_D("temp=>%s",temp);
    sscanf(temp, "%X", value);
    LOG_D("value=>%d",*value);
    ret = RT_EOK;

    __exit:
    //
    rt_free(temp);
    return ret;
}

static rt_err_t get_info(char *data)
{
    
    
    int len = strlen(data);
    char *hexstr = RT_NULL;    //先把ascii格式的data转成hex
    hexstr = rt_malloc(len + 1);
    hexstr[strlen(data)] = '\0';
    LOG_D("input_str=>%s",data);LOG_D("strlen=>%d\n",len);
    for (int i = 0; i < len / 2; i++)
    {
    
    
        LOG_D("ptr[%d]=>%s",i,data);
        hexstr2uint8_t(data, hexstr + i);
        data += 2;
        LOG_D("hexstr[%d]=>0x%x\n",i,hexstr[i]);
    }
    //
    LOG_HEX("hexstr", 16, hexstr, 4);
    rt_free(hexstr);
    return 0;
}

char ss1[100] = "54C854C8";
int main(void)
{
    
    
    get_info(ss1);

    while (1)
    {
    
    
        rt_thread_mdelay(500);
    }

    return RT_EOK;
}

显示效果如下:

 \ | /
- RT -     Thread Operating System
 / | \     4.0.2 build Sep  6 2020
 2006 - 2019 Copyright by rt-thread team
[3] D/main: input_str=>54C854C8
[9] D/main: strlen=>8

[11] D/main: ptr[0]=>54C854C8
[14] D/main: temp=>54
[15] D/main: value=>84
[16] D/main: hexstr[0]=>0x54

[17] D/main: ptr[1]=>C854C8
[17] D/main: temp=>C8
[18] D/main: value=>0
[20] D/main: hexstr[1]=>0x0

[20] D/main: ptr[2]=>54C8
[21] D/main: temp=>54
[22] D/main: value=>84
[24] D/main: hexstr[2]=>0x54

[25] D/main: ptr[3]=>C8
[28] D/main: temp=>C8
[29] D/main: value=>0
[30] D/main: hexstr[3]=>0x0

D/HEX hexstr: 0000-000F: 54 00 54 00                                         T.T.
msh >

就很神奇,C8使用sscanf读出来是0。
多次测试发现,只要十六进制数高位位字母,就没有办法读出来。
在这里插入图片描述
为了确认这个观察,排除是我代码的问题,写一个最简单的sscanf加%X的代码,读出来是0。

在这里插入图片描述
用菜鸟在线c编译,同样的代码能识别出来值为208。
在这里插入图片描述
那就说明是仿真的问题了?毕竟用的都是标准库。
等等, 此时突然想起了Keil勾选的MicroLib,RT-Thread之前编译AT指令集的时候遇到神奇问题需要勾选libc,是不是这个东西在作怪?

在这里插入图片描述
勾选上libc,一切ok!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_27508477/article/details/108432258