OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6380|回复: 9

【求助】多任务环境下串口输出debug信息的方法

[复制链接]

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2016-10-21 15:26:37 | 显示全部楼层 |阅读模式
20金钱
楼主的程序是基于freeRTOS的,划分成了几个任务。为了方便调试,在一些地方增加了一些从串口输出debug信息的代码,同时为了方便在编译时去掉这些代码,我是用宏定义的方法在头文件里面使用串口输出函数:
[mw_shl_code=c,true]#ifdef USER_DEBUG   
#define UserDebug(message) do{\
                               UARTprintf(message);\
                                                                                                                 }while(0)     
#else      
#define UserDebug(message)[/mw_shl_code]

UARTprint函数就大概相当于printf()

这么干在裸跑的非抢占式的程序里面不会出现什么问题,不过在抢占式内核里面,偶尔会出现一条以上的debug信息交错到一起的现象。


于是我又添加了另一种输出的方式:
为debug输出额外创建一个进程专用于输出,并创建一个与之相关的消息队列。如果需要串口打印一个字符串,就把字符串的指发送到队列里面。这样确实可以完全消除输出时的冲突,不过这么用就只能输出字符串,而不能像printf函数那样把多个参数也放进去用了。

有没有前辈指点一下,像这种把数目不定的参数(例如printf里的参数)用队列怎么发送出去?


最佳答案

查看完整内容[请看2#楼]

像printf这种公共资源一般都用一个互斥锁来互斥访问的,没必要用队列,也不建议关中断,毕竟如果printf的数据比较多的话会很耗CPU时间的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
11922
金钱
11922
注册时间
2015-11-5
在线时间
2086 小时
发表于 2016-10-21 15:26:38 | 显示全部楼层
像printf这种公共资源一般都用一个互斥锁来互斥访问的,没必要用队列,也不建议关中断,毕竟如果printf的数据比较多的话会很耗CPU时间的
回复

使用道具 举报

19

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
308
金钱
308
注册时间
2014-10-19
在线时间
42 小时
发表于 2016-10-21 16:38:28 | 显示全部楼层
帮顶  之前也想弄 不过看了一些试了一些 没成功 我现在一般是在打印的前后上锁   防止打印出错
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
 楼主| 发表于 2016-10-21 16:54:51 | 显示全部楼层
漂泊的雨林 发表于 2016-10-21 16:38
帮顶  之前也想弄 不过看了一些试了一些 没成功 我现在一般是在打印的前后上锁   防止打印出错

请问下 直接关中断,或者挂起调度器,或者加信号量保护,哪个方法对串口打印更恰当一些?我是freeRTOS新手,对资源保护理解不是很深,不过希望串口打印的代码对程序本身的影响尽量的小
回复

使用道具 举报

19

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
308
金钱
308
注册时间
2014-10-19
在线时间
42 小时
发表于 2016-10-21 17:22:04 | 显示全部楼层
我也不是很懂  我是用UCOS  没用FREERTOS
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6661
金钱
6661
注册时间
2016-5-29
在线时间
909 小时
发表于 2016-10-25 16:18:34 | 显示全部楼层
使用 sprintf  可以顺利解决这个问题.. 先使用sprintf 把要打印的内容放到一个指针或者数组里,再把他的内容填充到打印列队.
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
 楼主| 发表于 2016-10-26 10:24:58 | 显示全部楼层
操作系统 发表于 2016-10-25 16:18
使用 sprintf  可以顺利解决这个问题.. 先使用sprintf 把要打印的内容放到一个指针或者数组里,再把他的内容 ...

在子函数里面,把字符串常量的指针送到队列里是没问题的,也可以把栈区的变量送到队列里,但是不能栈区的变量的指针送到队列里面。经过sprintf处理过的变量变成了栈区的字符串,直接把指针入队肯定是不行的。如果去动态分配内存,总有free的时候,那也是不行的。
也许我这种需求本身就有问题吧。
暂时用的是加信号量的方法。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6661
金钱
6661
注册时间
2016-5-29
在线时间
909 小时
发表于 2016-10-26 13:49:18 | 显示全部楼层
你的想法是正确的. 只是不用把指针加到列队,而是把指针指向的内容复制到列队.  列队本身有独立的缓冲区.
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
 楼主| 发表于 2016-10-27 11:33:44 | 显示全部楼层
操作系统 发表于 2016-10-26 13:49
你的想法是正确的. 只是不用把指针加到列队,而是把指针指向的内容复制到列队.  列队本身有独立的缓冲区.

我明白你说的入队的输入参数格式。但是我说的是另外的问题。

我想送入队列的内容就是指针啊。而函数的输入参数是个二级指针。
比如说你想打印一些dubug信息。
“negative parameter”
“divide zero”
“interlock”
对这些长度未知的常量字符串,当然是应该把指针而不是字符串本体入队啊,而入队时的输入参数应该是个指向字符串指针的二级指针。 否则你建立队列的时候用多大的宽度呢?

但是对于附带额外的未知个数的参数的debug信息,就没什么好办法了。
比如printf(“channel %d value overflow”,ch);
在使用之前,既不知道有几个参数,也不知道它们是什么类型的,创建队列的时候就没法确定队列的宽度。

至于你说的用sprintf处理。1.处理过的字符串仍然在栈区(如果真放到堆区就没法再多任务环境用了),不能直接传递指针 。2.长度未知,队列宽度不明。不过就算字符串长度能确定,太长的字符串也没有直接拷贝的道理。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6661
金钱
6661
注册时间
2016-5-29
在线时间
909 小时
发表于 2016-10-27 11:51:40 | 显示全部楼层
呵呵,,自己再想一下办法吧.
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 22:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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