在Host/Kernel Shell里,用的最多的命令应该就是i了。
它可以看到每个Task的基本信息,其中有一列叫做ERRNO。
很多人在看到某个Task的ERRNO不为0时,会担心哪里出了问题。其实单独的ERRNO并没什么事儿,一般都不用管它。好了,可以拉到最后点赞了。
如果非要深究的话,咱们打开源码
可以看到,VxWorks定义了一个全局变量errno,用来记录中断里的error状态
另外,每个Task也可以通过宏errno来访问自己TCB里的一个成员errorStatus
那这个errno有什么用呢?
Kernel里有些函数的返回值是个整型数,执行失败时,就可以表示多种错误情况;但是有些函数的返回值是个指针,那出现错误时,只能返回NULL。这个时候,就可以使用errno来表示不同的错误分支了。当然了,返回值是整型数的函数,也可以操作这个errno,毕竟每个Task都有自己的TCB。
因此,我们可以通过errno的值,来查看Task/Interrupt最后的一次错误情况。不过Kernel函数已经对errno做了处理(但很可能不清除它),只要Task的状态没有问题,我们App就不用额外担心它们了。
那怎么查看errno呢?不建议直接访问变量errno或TCB成员errorStatus。而是调用函数errnoGet()
或者包含组件INCLUDE_STAT_SYM_TBL
然后在Shell里调用printErrno()
它可以打印errno代表的含义
接下来看看errno值的组成:errno是一个32bits的数,高16位表示module,低16位表示该module内的错误编号。module 0预留给了Unix errno。VxWorks使用module 1-500。因此用户可以从501开始定义自己的errno,例如
所以刚刚的0x3d0001(0x3d==61)表示module M_objLib里的第一种错误
而0x0001就表示S_objLib_OBJ_ID_ERROR了
tNet0这是个系统任务,不方便调试。咱们自己写个例子,让它出现errno不为0的情况
创建个任务来调用这个test()函数
任务出错了,用tt命令看看哪里出的错
执行到semTake()时,第一个参数为0,加个printf()看看
果然是信号量ID为NULL
这时候就可以用errno了
也可以在代码中就把errno打印出来
然后看一下semOpen()的函数定义
原来这个errno是因为mode设置的不对,加上它吧
这次正常了
Task成功阻塞到二进制信号量上了
这正是:
函数返回值有限,Error NO.来扩展。
错误不能单一看,任务状态更关键。