UCOS-II调用printf()可重入问题

[复制链接]
8121|12
 楼主| 仙帝将王 发表于 2014-6-9 18:13 | 显示全部楼层 |阅读模式
大家好,为了方便向串口打印各种数据类型,本人对printf()函数所调用的fput()进行了重定向。本人程序是基于UCOS-II的,考虑到不同任务需要向串口打印数据,就想到了可重入问题。所以我在对fputc()重定向时在函数入口和出口时使用了信号量对串口资源进行保护。本人对printf()的原理不是了解特别清楚,因为在标准C语言中printf中的stdout是不可重入的。和大家一起探讨下,我的做法是否解决了当前应用程序多任务下的可重入问题。欢迎各位进来讨论,发表意见,多多指导,共同学习。谢谢!
  1. int fputc(int ch, FILE *f)
  2. {
  3.   INT8U err;
  4.        
  5.   OSSemPend(SharedUSARTSem, 0, &err);

  6.   USART_SendData(USART2, (INT8U) ch);
  7.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) != SET);
  8.        
  9.   err = OSSemPost(SharedUSARTSem);
  10.        
  11.   return (ch);
  12. }
 楼主| 仙帝将王 发表于 2014-6-10 20:02 | 显示全部楼层
dwh000 发表于 2014-6-10 08:47
这种做法仍然没有办法保证一个任务使用串口这个共享资源.
比如说有两个任务
task 1 这个优先级高

非常感谢楼主的分析。由于我对printf不是了解的特别清楚,请问printf里面还有哪些共享资源需要保护?如果只有串口的话我觉得可行。
 楼主| 仙帝将王 发表于 2014-6-10 23:24 | 显示全部楼层
我发现我在多任务下调用printf,程序到现在为止没有发现过什么问题。但是不知道有没有什么潜在的隐患,请大家帮忙分析下, 谢谢!
bob.xue 发表于 2014-6-11 13:26 | 显示全部楼层
本帖最后由 bob.xue 于 2014-6-11 13:28 编辑

效果一样的,都会卡,区别是一个卡在里面,一个卡在外面;相同点:都卡,没有必要搞可重入
 楼主| 仙帝将王 发表于 2014-6-13 07:43 | 显示全部楼层
bob.xue 发表于 2014-6-11 13:26
效果一样的,都会卡,区别是一个卡在里面,一个卡在外面;相同点:都卡,没有必要搞可重入 ...

对不起,没有完全理解你的意思。请问会卡在哪里?我测试了下是可以的,还没有发现问题
 楼主| 仙帝将王 发表于 2014-6-13 07:44 | 显示全部楼层
dwh000 发表于 2014-6-11 07:52
你做三个任务都是打印任务,延时设定的都不一样,你试下!

测试没有问题:)
hgjinwei 发表于 2014-6-14 20:16 | 显示全部楼层
printf 要看库的支持,有些库会动用到堆的空间(貌似使用malloc分配空间),如果是这样,这里也是需要互斥的。
原野之狼 发表于 2014-6-14 20:54 | 显示全部楼层
我认为楼主的方法可行。
 楼主| 仙帝将王 发表于 2014-6-15 22:44 | 显示全部楼层
hgjinwei 发表于 2014-6-14 20:16
printf 要看库的支持,有些库会动用到堆的空间(貌似使用malloc分配空间),如果是这样,这里也是需要互斥的 ...

您好,我平时主要针对硬件编程,上层软件不是很懂。我所用的printf是在Keil MDK for ARM平台下的,用的是里面的Micro Lib,不知道这里的printf是不是有堆的操作。楼主熟悉MDK编译器吗,请教下。
 楼主| 仙帝将王 发表于 2014-6-15 22:45 | 显示全部楼层
原野之狼 发表于 2014-6-14 20:54
我认为楼主的方法可行。

我觉得也可行,至今没有任何问题
john_lee 发表于 2014-6-20 00:45 | 显示全部楼层
仙帝将王 发表于 2014-6-15 22:44
您好,我平时主要针对硬件编程,上层软件不是很懂。我所用的printf是在Keil MDK for ARM平台下的,用的是 ...

MDK的MicroLib里的stdio函数都是非线程安全的。
但MDK的标准库里的stdio函数则是线程安全的。

参见MDK库参考。

评分

参与人数 1威望 +10 收起 理由
dwh000 + 10 深刻!

查看全部评分

 楼主| 仙帝将王 发表于 2014-7-29 09:33 来自手机 | 显示全部楼层
john_lee 发表于 2014-6-20 00:45
MDK的MicroLib里的stdio函数都是非线程安全的。
但MDK的标准库里的stdio函数则是线程安全的。


对,按照库规定在多线程下是不安全的。但是我的困惑是,我的修改是不是有作用?是否起到了保护资源竞争的作用?
zhanglinsen 发表于 2015-10-10 10:30 | 显示全部楼层
我也是刚接触ucos系统 想问您下 您那段程序中的sharedusartsem是什么意思啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

25

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部