前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Component之kprintf

Component之kprintf

作者头像
Taishan3721
发布2019-11-14 14:48:19
1.1K0
发布2019-11-14 14:48:19
举报
文章被收录于专栏:这里只有VxWorks

调试程序时,最常用的一个手段是打印一些调试语句,而最常用的打印函数应该就是printf()了。printf()的作用是向标准输出设备输出格式化的调试语句。这个标准输出设备默认是PC Console或串口

也可以修改,例如改为文件或管道

不过printf()这种IO操作默认是阻塞模式的,因此不能在ISR中使用。那调试中断的时候,可以使用logMsg()来打印调试语句

logMsg()在ISR中执行时,通过底层的msgQSend(logMsgQId, msg, sizeof(msg), NO_WAIT,MSG_PRI_NORMAL)将调试语句发送给优先级为0的任务tLogTask

不过要想使用logMsg(),需要在usrRoot()调用logInit()之后;使用printf(),需要在usrRoot()调用usrSerialInit()或usrPcConsoleInit()之后。

那在这些初始化之前如何打印调试语句呢?

vx6新加了一个组件(好像是从vx67开始的):Kernel Write

这个组件只是给开发人员提供了两个函数kputs()和kprintf()。这两个函数的声明分别类似于ANSI定义的puts和printf(),其作用也差不多,它俩就是打印语句,用来调试的。

那么,区别呢?kputs/kprintf()默认只能输出到串口,而且使用的是串口的轮询模式。这样做的好处是:在中断使能和IO系统初始化之前的内核启动阶段就可以使用它了!

可以看到,在usrInit()阶段的sysHwInit()之后、usrCacheEnable()之前,就可以使用kprintf()了,这可比printf()/logMsg()的可用时机提前了很多。

另外,logMsg()在调用msgQSend()时用的NO_WAIT方式,因此有可能会丢弃部分消息

kput()/kprintf()就不存在这个问题了,它们既不会阻塞,也不会丢弃消息

如果Target的串口不能用,这个Kernel Write组件还可以通过自定义函数DEBUG_KWRITE_USR_RTN来输出调试语句。它可以将语句直接输出到RAM区域,或者Flash等NVRam里

来看一个输出到RAM保留区的例子

再次调用kprintf()后,调试语句就是记录到这个User Reserved Memory里了

最后,对比一下它们仨

printf()

  • 最常用
  • 阻塞模式,不丢消息
  • 不能用于中断
  • 在usrRoot()初始化IO系统后才能调用

logMsg()

  • 可用于中断
  • 可能丢消息
  • 在初始化IO系统和logging机制后才能调用

kprintf()

  • 在usrInit()调用sysHwInit()之后即可调用
  • 可用于中断
  • 可输出到串口或Memory设备
  • 不丢消息

这正是:

系统在启动,IO未使能。

如何来调试?kprintf可使用。

我是泰山,专注VX 15年!

欢迎关注VxWorks567,

一起学习,共同进步!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 这里只有VxWorks 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档