打印

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

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

  USART_SendData(USART2, (INT8U) ch);
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) != SET);
       
  err = OSSemPost(SharedUSARTSem);
       
  return (ch);
}

相关帖子

沙发
仙帝将王|  楼主 | 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 编辑

效果一样的,都会卡,区别是一个卡在里面,一个卡在外面;相同点:都卡,没有必要搞可重入

使用特权

评论回复
5
仙帝将王|  楼主 | 2014-6-13 07:43 | 只看该作者
bob.xue 发表于 2014-6-11 13:26
效果一样的,都会卡,区别是一个卡在里面,一个卡在外面;相同点:都卡,没有必要搞可重入 ...

对不起,没有完全理解你的意思。请问会卡在哪里?我测试了下是可以的,还没有发现问题

使用特权

评论回复
6
仙帝将王|  楼主 | 2014-6-13 07:44 | 只看该作者
dwh000 发表于 2014-6-11 07:52
你做三个任务都是打印任务,延时设定的都不一样,你试下!

测试没有问题:)

使用特权

评论回复
7
hgjinwei| | 2014-6-14 20:16 | 只看该作者
printf 要看库的支持,有些库会动用到堆的空间(貌似使用malloc分配空间),如果是这样,这里也是需要互斥的。

使用特权

评论回复
8
原野之狼| | 2014-6-14 20:54 | 只看该作者
我认为楼主的方法可行。

使用特权

评论回复
9
仙帝将王|  楼主 | 2014-6-15 22:44 | 只看该作者
hgjinwei 发表于 2014-6-14 20:16
printf 要看库的支持,有些库会动用到堆的空间(貌似使用malloc分配空间),如果是这样,这里也是需要互斥的 ...

您好,我平时主要针对硬件编程,上层软件不是很懂。我所用的printf是在Keil MDK for ARM平台下的,用的是里面的Micro Lib,不知道这里的printf是不是有堆的操作。楼主熟悉MDK编译器吗,请教下。

使用特权

评论回复
10
仙帝将王|  楼主 | 2014-6-15 22:45 | 只看该作者
原野之狼 发表于 2014-6-14 20:54
我认为楼主的方法可行。

我觉得也可行,至今没有任何问题

使用特权

评论回复
11
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 深刻!
12
仙帝将王|  楼主 | 2014-7-29 09:33 | 只看该作者
john_lee 发表于 2014-6-20 00:45
MDK的MicroLib里的stdio函数都是非线程安全的。
但MDK的标准库里的stdio函数则是线程安全的。


对,按照库规定在多线程下是不安全的。但是我的困惑是,我的修改是不是有作用?是否起到了保护资源竞争的作用?

使用特权

评论回复
13
zhanglinsen| | 2015-10-10 10:30 | 只看该作者
我也是刚接触ucos系统 想问您下 您那段程序中的sharedusartsem是什么意思啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

25

帖子

1

粉丝