硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1159|回复: 6
收起左侧

[ThreadX全家桶] ThreadX的安全printf打印一种错误情况分享

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107598
QQ
发表于 2023-2-1 01:21:06 | 显示全部楼层 |阅读模式
1、测试条件

网友发的一个问题。
[C] 纯文本查看 复制代码
const uint8_t InnerSwVersion[20] = "SF11_V01.01_20230116";
const uint8_t OldSwVersion[11] = {
    0x46, 0x31, 0x30, 0x33, 0x44, 0x49, 0x41, 0x47, 0x53, 0x30, 0x32
};

加入了互斥处理的printf
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*        函 数 名: App_Printf
*        功能说明: 线程安全的printf方式                                            
*        形    参: 同printf的参数。
*             在C中,当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表
*        返 回 值: 无
*********************************************************************************************************
*/
static  void  App_Printf(const char *fmt, ...)
{
    char  buf_str[200 + 1]; /* 特别注意,如果printf的变量较多,注意此局部变量的大小是否够用 */
    va_list   v_args;


    va_start(v_args, fmt);
   (void)vsnprintf((char       *)&buf_str[0],
                   (size_t      ) sizeof(buf_str),
                   (char const *) fmt,
                                  v_args);
    va_end(v_args);

        /* 互斥操作 */
    tx_mutex_get(&AppPrintfSemp, TX_WAIT_FOREVER);

    printf("%s", buf_str);

   /tx_mutex_put(&AppPrintfSemp);                                         
}


实际打印函数:
[C] 纯文本查看 复制代码
extern const uint8_t InnerSwVersion[20];
extern const uint8_t OldSwVersion[11];
static void AppTaskUserIF(ULONG thread_input)
{
        uint8_t ucKeyCode;        /* 按键代码 */

        (void)thread_input;
                  
        while(1)
        {        
                ucKeyCode = bsp_GetKey();
                
                if (ucKeyCode != KEY_NONE)
                {
                        switch (ucKeyCode)
                        {
                                case KEY_DOWN_K1:                          /* K1键按打印任务执行情况 */
                    App_Printf("1: %s\r\n", InnerSwVersion);
                    App_Printf("2: %s\r\n", OldSwVersion);
                                        break;
                                

                                default:                     /* 其他的键值不处理 */
                                        break;
                        }
                }

        tx_thread_sleep(20);
        }
}


2、错误现象

image.png

3、问题解决

变量定义的空间小了const uint8_t InnerSwVersion[20] = "SF11_V01.01_20230116"

这个实际上是21个字符,字符常量末尾还有个结束符,简单些,修改为21,或者置空均可

image.png






回复

使用道具 举报

74

主题

1225

回帖

1447

积分

至尊会员

积分
1447
发表于 2023-2-1 09:47:08 | 显示全部楼层
那明显就是不懂的字符串的概念啊,不是bug,是他自己不会用了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107598
QQ
 楼主| 发表于 2023-2-1 09:55:02 | 显示全部楼层
wdliming 发表于 2023-2-1 09:47
那明显就是不懂的字符串的概念啊,不是bug,是他自己不会用了

防不胜防,没留心这个问题。
回复

使用道具 举报

23

主题

1407

回帖

1476

积分

至尊会员

积分
1476
发表于 2023-2-1 10:33:34 | 显示全部楼层
这种的,编译器自动提示更合理。
代码不规范,亲人两行泪!
回复

使用道具 举报

18

主题

288

回帖

342

积分

高级会员

积分
342
发表于 2023-2-1 10:46:28 | 显示全部楼层
字符串数组中的括号中一般不写具体的值,最后用strlen获得即可
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2023-2-2 14:24:25 | 显示全部楼层
第二个数组也要 +1,现在是后面没数据,默认为 0。如果后面有数据,照样会出来一截多余的内容。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107598
QQ
 楼主| 发表于 2023-2-3 09:48:24 | 显示全部楼层
ihavedone 发表于 2023-2-2 14:24
第二个数组也要 +1,现在是后面没数据,默认为 0。如果后面有数据,照样会出来一截多余的内容。

emWin的各种图片转换最喜欢在数组后面搞这种操作了,转换都是N+1,末尾补0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-7 11:41 , Processed in 0.381675 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表