硬汉嵌入式论坛

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

[有问必答] 请教eric2013,V4例程中:线程安全的printf方式例程相关问题求助

[复制链接]

20

主题

249

回帖

309

积分

高级会员

积分
309
发表于 2016-1-1 21:31:29 | 显示全部楼层 |阅读模式
硬汉哥,请教V4板子例程:线程安全的printf方式 ,有几个问题求助

1、能否提供st官方的STM32F10x_StdPeriph_Driver 3.6.1的固件库下载地址呢,我在官网怎么也没找到。【好奇你是在哪里找到的呢】
2、CMSIS的库在哪里下载呢?
3、App_Printf 函数既然是线程安全的,很好用,你怎么没有在其他例程中使用这个函数呢?而是直接使用了printf,这样会不会不安全?
4、下面的函数中,OSSemPend为什么没有放到va_start前面呢?而是放到了va_end后。这样会不会造成任务2正在发数据,但是任务2大端1,
       他也发数据,他把数据也放到了buf_str中,把数据放完后发现得不到信号量,故任务2继续发数据,此时buf_str中的数据已经改变了,这样是不是数据就乱了呢?
如果把OSSemPend放到va_start就没有我说的那个情况了,你说呢?
  1. static void  App_Printf (CPU_CHAR *format, ...)
  2. {
  3.     CPU_CHAR  buf_str[80 + 1];
  4.     va_list   v_args;
  5.     CPU_INT08U  os_err;
  6.     va_start(v_args, format);
  7.    (void)vsnprintf((char       *)&buf_str[0],
  8.                    (size_t      ) sizeof(buf_str),
  9.                    (char const *) format,
  10.                                   v_args);
  11.     va_end(v_args);
  12.     OSSemPend((OS_EVENT  *)AppPrintfSemp,
  13.               (INT32U     )0,
  14.               (INT8U     *)&os_err);
  15.     printf("%s", buf_str);
  16.     os_err = OSSemPost((OS_EVENT *)AppPrintfSemp);
  17. }
复制代码

谢谢啦
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-1-2 15:57:03 | 显示全部楼层
不好意思啊,楼主,今天才回复。
1. 这个版本可以在这里下载,有详细说明:http://www.armbbs.cn/forum.php?mod=viewthread&tid=11940
2. 最新的CMSIS是4.5版本了,可以在ARM官网下载,官方的固件库里面是自带的,就是版本低些。
3. 例子都是循序渐进的。
4. 这几个函数应该是线程安全的吧,printf主要是调用到了串口,串口就一个,要互斥。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-2 19:33:17 | 显示全部楼层
谢谢硬汉回复

4、看来是我理解错了。我再仔细想想啊。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-2 19:38:47 | 显示全部楼层
我下下CMSIS的4.5库看看啊,到时传到这里
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-2 20:43:25 | 显示全部楼层
传不了啊

大小限制,我也无法发连接,等我够权限了再传吧
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-1-2 20:44:16 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:传不了啊

大小限制,我也无法发连接,等我够权限了再传吧 (2016-01-02 20:43) 
没事的,谢谢你[s:142][s:142]
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-1-2 20:48:28 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:谢谢硬汉回复

4、看来是我理解错了。我再仔细想想啊。 (2016-01-02 19:33) 
确切的说是每个调用这个函数的任务,进入到这个函数里面,都会从各自的任务栈空间申请新的
CPU_CHAR  buf_str[80 + 1];
va_list   v_args; 空间

这样调用函数va_start ,vsnprintf和va_end就不会存在冲突问题,出现线程安全问题主要是全局变量造成的,而这里都是使用的自己的栈空间。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-2 21:03:00 | 显示全部楼层

回 eric2013 的帖子

eric2013:确切的说是每个调用这个函数的任务,进入到这个函数里面,都会从各自的任务栈空间申请新的
CPU_CHAR  buf_str[80 + 1];
va_list   v_args; 空间

....... (2016-01-02 20:48) 
谢谢啦

大侠能否解压下pack文件,我下载了,无法打开,看资料说要keil加载后才可以打开

我没有装keil,能否把源文件给分享出来呢
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-2 21:15:02 | 显示全部楼层

回 eric2013 的帖子

eric2013:

确切的说是每个调用这个函数的任务,进入到这个函数里面,都会从各自的任务栈空间申请新的
CPU_CHAR  buf_str[80 + 1];
va_list   v_args; 空间

.......
CMSIS 4.5 下载地址:
http://www.keil.com/dd2/pack/#/eula-container
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-1-3 09:53:32 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:

CMSIS 4.5 下载地址:
http://www.keil.com/dd2/pack/#/eula-container

  
你下载的是用MDK的,从arm官网下载,这个是压缩包,解压下即可:
http://www.arm.com/zh/products/p ... erface-standard.php

不过需要你在ARM官网注册一个账号,简单注册一个即可。
=================================================================
15.png
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-3 11:24:27 | 显示全部楼层

回 eric2013 的帖子

eric2013:你下载的是用MDK的,从arm官网下载,这个是压缩包,解压下即可:
http://www.arm.com/zh/products/p ... erface-standard.php

不过需要你在ARM官网注册一个账号,简单注册一个即可。
....... (2016-01-03 09:53) 
哦,我也点到这里了。但是需要注册,后来找到了那个不用注册的就下载了,下下来还解不开。

再次感谢
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-3 12:47:30 | 显示全部楼层

回 eric2013 的帖子

eric2013:

你下载的是用MDK的,从arm官网下载,这个是压缩包,解压下即可:
http://www.arm.com/zh/products/p ... erface-standard.php

不过需要你在ARM官网注册一个账号,简单注册一个即可。
.......
eric2013:

你下载的是用MDK的,从arm官网下载,这个是压缩包,解压下即可:
http://www.arm.com/zh/products/p ... erface-standard.php

不过需要你在ARM官网注册一个账号,简单注册一个即可。
.......
再请教一个问题:刚才我注册下载了CMSIS-SP-00300-r4p5-00rel0.zip,解压后看版本是4.30的,应该是4.50才对呢?这是则么回事,我没下载对?
1.png


解压后看文件是4.30的
2.png


我下载的就是4.5版本呢
CMSIS版本.png


由于文件多大,97M,我这里无法上传,有谁需要的话自己下载。需要用公司的邮箱注册,注册很简单,一会完成就就可以下载了,500K的速度,一会就下完了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-1-6 00:33:26 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:再请教一个问题:刚才我注册下载了CMSIS-SP-00300-r4p5-00rel0.zip,解压后看版本是4.30的,应该是4.50才对呢?这是则么回事,我没下载对?



....... (2016-01-03 12:47) 
估计是官网没有更新好,压缩的4.3版本就上传了,按说不应该啊。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2016-1-21 21:57:43 | 显示全部楼层

回 eric2013 的帖子

eric2013:估计是官网没有更新好,压缩的4.3版本就上传了,按说不应该啊。 (2016-01-06 00:33) 
是啊,arm不会犯这么低级的错误吧。。。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-5-31 17:06:18 | 显示全部楼层

回 eric2013 的帖子

eric2013:

确切的说是每个调用这个函数的任务,进入到这个函数里面,都会从各自的任务栈空间申请新的
CPU_CHAR  buf_str[80 + 1];
va_list   v_args; 空间

.......

硬汉哥,今天测试发现这个线程安全的App_Printf 似乎并不安全啊[s:152]
下面是我的测试情况:
系统有4个任务,uCOS-II 2.92
任务1:优先级1,任务中使用App_Printf 输出类似:M1,000.4,m,105的数据
任务2:优先级2,任务中使用App_Printf输出类似:M2,000.4,m,105的数据
任务3:优先级3,任务中使用App_Printf输出类似:M3,000.4,m,105的数据
任务4:优先级4,任务中使用App_Printf输出当前时间:T2017-05-31_16-28-30

测试结果为:当输出时间的任务4正在输出时间时,任务1或2或3打断任务4输出了其他任务的信息,后才输出任务4的信息,即App_Printf并不是安全的,是可以被打断的。
测试截图如下:
2017-05-31_164823.png
2017-05-31_165158.png


试探解决:我把App_Printf函数中的信号量改为了互斥信号量或者把OSSemPend放到va_start前面,问题依然没有解决,还是有被插入现象。
分析:信号量或互斥信号量放到函数中,该函数在被低优先级的任务调用并使用时高优先级的任务依然可以打断该任务且抢占使用该函数,这样的话才可以解析我的试验现象。这么理解对吗?
解决方法?:把互斥信号量从App_Printf函数中拿出,任务中调用时写成如下的形式应该就可以了。

OSMutexPend((OS_EVENT  *)AppPrintfSemp,
              (INT32U     )0,
              (INT8U     *)&os_err);
App_Printf (........);

os_err = OSMutexPost((OS_EVENT *)AppPrintfSemp);


硬汉哥我理解的对不?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2017-5-31 17:34:24 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:硬汉哥,今天测试发现这个线程安全的App_Printf 似乎并不安全啊[s:152]
下面是我的测试情况:
系统有4个任务,uCOS-II 2.92
....... (2017-05-31 17:06) 
不好用就在程序里面单独做互斥吧。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-5-31 22:10:18 | 显示全部楼层

回 eric2013 的帖子

eric2013:

不好用就在程序里面单独做互斥吧。
嗯,这是最后的解决方法了。

程序中使用了许多这个函数,每次用都加那两句话有点麻烦,这种函数中加的方式为什么不能用呢?还有其他解决方法吗?

谢谢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2017-6-1 00:53:19 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:嗯,这是最后的解决方法了。

程序中使用了许多这个函数,每次用都加那两句话有点麻烦,这种函数中加的方式为什么不能用呢?还有其他解决方法吗?

....... (2017-05-31 22:10) 
那就重新封装个吧,里面直接调用printf和互斥,不加额外的东西了,你试试。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-6-2 10:51:23 | 显示全部楼层

回 eric2013 的帖子

eric2013:那就重新封装个吧,里面直接调用printf和互斥,不加额外的东西了,你试试。 (2017-06-01 00:53) 
刚才试了下,,还是不行,和以前效果相同。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2017-6-2 10:56:00 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:刚才试了下,,还是不行,和以前效果相同。 (2017-06-02 10:51) 
你的互斥是不是用的可能有问题,uCOS-II使用互斥,在创建的时候要设置一个高优先级,是不是问题出在这个地方了。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-6-2 11:24:39 | 显示全部楼层

回 eric2013 的帖子

eric2013:你的互斥是不是用的可能有问题,uCOS-II使用互斥,在创建的时候要设置一个高优先级,是不是问题出在这个地方了。 (2017-06-02 10:56)
互斥没有问题吧,相关信息如下。系统优先级如下:

#define TASK_START_PRIO     0u
#define TASK_FPGA_PRIO      1u
#define TASK_M1_PRIO           2u
#define TASK_M2_PRIO           3u
#define TASK_M3_PRIO           4u
#define TASK_Time_PRIO      15u

//定义
static OS_EVENT *Sem_printf_security;//全局变量
//创建
Sem_printf_security=OSMutexCreate(0, &err);
//使用
OSMutexPend(Sem_printf_security,0,&err);
OSMutexPost(Sem_printf_security);
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2017-6-2 11:50:50 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:互斥没有问题吧,相关信息如下。系统优先级如下:

#define TASK_START_PRIO     0u
#define TASK_FPGA_PRIO      1u
....... (2017-06-02 11:24) 
OSMutexCreate(0, &err); 设置为0是个错误。

这样你的启动任务优先级跟这个优先级翻转都设置为0了。uCOS-II是不支持同优先级的,特别注意。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-6-2 12:45:21 | 显示全部楼层

回 eric2013 的帖子

eric2013:OSMutexCreate(0, &err); 设置为0是个错误。

这样你的启动任务优先级跟这个优先级翻转都设置为0了。uCOS-II是不支持同优先级的,特别注意。 (2017-06-02 11:50) 
嗯,,但是启动任务启动后,我就挂起它了,没有人和它抢了呢?

这个优先级我设置为多少好呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2017-6-2 12:55:38 | 显示全部楼层

回 小狐狸 的帖子

小狐狸:嗯,,但是启动任务启动后,我就挂起它了,没有人和它抢了呢?

这个优先级我设置为多少好呢? (2017-06-02 12:45) 
比所有使用此互斥信号量的任务优先级都高。这个优先级一定要是没有被占用的。
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-6-2 13:08:26 | 显示全部楼层

回 eric2013 的帖子

eric2013:比所有使用此互斥信号量的任务优先级都高。这个优先级一定要是没有被占用的。 (2017-06-02 12:55) 
好的,我试下
回复

使用道具 举报

20

主题

249

回帖

309

积分

高级会员

积分
309
 楼主| 发表于 2017-6-2 13:35:58 | 显示全部楼层

回 eric2013 的帖子

eric2013:比所有使用此互斥信号量的任务优先级都高。这个优先级一定要是没有被占用的。 (2017-06-02 12:55) 
额,刚试了下,我把互斥信号量的优先级分配到了没有任务使用的优先级上,测试效果比以前好很多,但是偶尔还会出现一次串口数据被其他任务插入的情况。

串口互斥后的优先级改为了0,任务的优先级从5开始分配的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-3 04:14 , Processed in 0.256816 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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