6/27/2011 4:55:57 PM


6/27/2011 4:55:57 PM

不本地显示 无法出图像
busybox的kill命令
杀pm的时机有问题?
问题非必现
进入屏保

Management of user modes and system states is divided to two separate entities;

Mode Control Entity (MCE) and Device State Management Entity (DSME).

With this differentiation it is possible to maintain and develop user context and system context control scheme without complex overlaps.

模式控制实体和设备状态实体

音视频同步

pm起作用的时候usb也关掉了 串口也无法输入

现在pm的起停没有什么问题

现在分析为什么注册失败会导致采集失败?

为什么enqueue失败?
pxa_camera_zl

传进来的v4l2_buffer 肯定没有问题

request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd)

33 号中断是camera的中断

选的sensor id

SET_OV2655_SENSOR(cam_ctx)  初试化了cam_ctx 结构体

现在是dequeue 消息

如果p_report_head 为null,就失败

poll就是判断的这个

上下 左右  地远离断脚

-1 表示返回失败

在看一下 errno

现在返回的是9

Bad file number 

线程安全的

头文件errno.h定义了一个全局的宏errno,它被展开为一个int类型的“左值”,这意味着宏errno不一定是个对象的标识符,也可以展开为一个由函数返回的可以修改的“左值”,比如int *errno(),这个后面会讲,你可以暂且把它理解为一个全局的int型变量(虽然这样理解是错的,不过方便理解)。

 

简单来说,errno.h只是为了提供了一种错误报告机制。比如,一个函数调用fopen()发生了错误,它可能就会去修改errno的值,这样外部的代码可以通过判断errno的值来区分fopen()内部执行时是否发生错误,并根据errno值的不同来确定具体的错误类型。
先来看一段代码,Demo1:

view sourceprint?01 #include    <stdio.h> 

02 #include    <errno.h>  

03   

04 int main ( int argc, char *argv[] ) 

05 { 

06     //try to open file "whatever.txt". when you run this demo,make sure the file is NOT existed..。 

07     FILE *fp = fopen("whatever.txt","r"); 

08   

09     if(fp ==NULL) 

10     { 

11         printf("Can not open file/n"); 

12   

13         printf("errno value: %d, it means: %s",errno, strerror(errno)); 

14     } 

15   

16     return 0; 

17 }

程序会输出:

view sourceprint?1 Can not open file

2 errno value: 2, it means: No such file or directory

strerror是标准库stdio.h定义的一个函数,它用来返回错误代码所代表的含义。如Demo1所示,我们用fopen(也在stdio.h中定义)打开一个并不存在的文件,因此返回的fp是一个空指针。而在fopen尝试打开文件失败时会修改errno的值,Demo1里fopen失败原因是文件不存在,因此fopen将会把errno指向的值修改为2,通过stderror可以看到错误代码2的意思是“No such file or directory”。

帅气,看起来用errno来报告错误,既方便,也很简单,但实际应用时远没Demo1那么简单,试下Demo2:

view sourceprint?01 #include    <stdio.h> 

02 #include    <errno.h> 

03 #include    <math.h>   

04   

05 int main ( int argc, char *argv[] ) 

06 { 

07     /*try to open file "whatever.txt". when you run this demo,make sure the file is NOT existed...*/

08     FILE *fp = fopen("whatever.txt","r"); 

09   

10     if(fp ==NULL) 

11     { 

12         printf("Can not open file/n"); 

13   

14         int root = sqrt(123568 -123668 ); 

15   

16         printf("errno value: %d, it means: %s",errno, strerror(errno)); 

17     } 

18   

19     return 0; 

20 }

程序会输出:

view sourceprint?1 Can not open file

2 errno value: 33, it means: Numerical argument out of domain

这跟我们期望的错误信息完全不一样,因为sqrt函数在得到一个非法的参数时,它把errno的值修改成了33,覆盖了fopen设置的错误代码。所以,使用errno一个比较安全的编码方式是,在下个库函数调用之前就查看它的值,千万不要因为某个库函数看似很简单就假设它不会修改errno的值,那样会死的很惨……如果必须在查看errno之前调用别的库函数,一种安全的方式是先把errno的值保存到一个临时变量里,然后调用那个“必须”调用的库函数,处理完毕后再把errno恢复到之前的值。如Demo3:

view sourceprint?01 #include    <stdio.h> 

02 #include    <errno.h> 

03 #include    <math.h>   

04   

05 double getSqrt(double value) 

06 { 

07     //1、save last errno to a temp variable 

08     int tmpErrno = errno; 

09     //2、set errno to 0 

10     errno = 0; 

11   

12     double root = sqrt(123568 -123668 ); 

13   

14     printf("I changed errno to '%d' sliently...but it's safe /n",errno); 

15   

16     //3.restore errno 

17     errno = tmpErrno; 

18   

19     return root; 

20 } 

21   

22 int main ( int argc, char *argv[] ) 

23 { 

24     FILE *fp = fopen("whatever.txt","r"); 

25   

26     if(fp ==NULL) 

27     { 

28         printf("Can not open file/n"); 

29   

30         getSqrt(-1); 

31   

32         printf("errno value: %d, it means: %s",errno, strerror(errno)); 

33     } 

34   

35     return 0; 

36 }

程序会输出:

view sourceprint?1 Can not open file

2 I changed errno to '33' sliently...but it's safe 

3 errno value: 2, it means: No such file or directory

现在,就像期望的那样输出了。
但是……
这样真的安全么?!想像一下,如果errno是个全局变量,那多线程环境下岂不完蛋了?!本来线程A把errno设置成2,还没执行到查看错误的语句时,线程B就把errno设置成了33,然后线程A才开始查看errno并输出错误信息,而这时输出的错误就很让人抓狂了!神呀,这破东西多线程没法儿用哇!
但是……
你多虑了……文章开始说过,宏errno可以被展开为一个“左值”,比如int* getYourErrno(),所以你可以在getYourErrno()里返回一个线程内的局部变量,这样不管哪个线程修改errno都修改的它自己的局部变量,所以我们担心的问题是不存在的。看下errno.h的源码就明白了

view sourceprint?01 /* Get the error number constants from the system-specific file. 

02    This file will test __need_Emath and _ERRNO_H.  */

03 #include <bits/errno.h> 

04 #undef  __need_Emath 

05   

06 #ifdef  _ERRNO_H 

07   

08 /* Declare the `errno' variable, unless it's defined as a macro by 

09    bits/errno.h.  This is the case in GNU, where it is a per-thread 

10    variable.  This redeclaration using the macro still works, but it 

11    will be a function declaration without a prototype and may trigger 

12    a -Wstrict-prototypes warning.  */

13 #ifndef errno 

14 extern int errno; 

15 #endif

上面的注释说了,如果errno没有定义过就把errno定义为“extern int errno;”,如果这样多线程时是会发生悲剧的,先不着急哭,我们去前面看看它是否被定义过,前面的代码include了一个叫bits/errno.h的头文件,看名字就很“险恶”,进去看看:

view sourceprint?1 # ifndef __ASSEMBLER__ 

2 /* Function to get address of global `errno' variable.  */

3 extern int *__errno_location (void) __THROW __attribute__ ((__const__)); 

4   

5 #  if !defined _LIBC || defined _LIBC_REENTRANT 

6 /* When using threads, errno is a per-thread value.  */

7 #   define errno (*__errno_location ()) 

8 #  endif 

9 # endif /* !__ASSEMBLER__ */

果然来者不善……如果没定义宏__ASSEMBLER__,就会执行中间的代码,里面的代码又说了,如果你没定义_LIBC或者定义了_LIBC_REENTRANT他们就会把errno定义为__errno_location,一看到宏_LIBC_REENTRANT里面有“reentrant(重入)”就知道它不是个好东西……不是,是看到它的名字就知道它是跟多线程有关的,所以如果要在多线程环境下正确的使用errno,你需要确保__ASSEMBLER__没有被定义,而且_LIBC没被定义或者定义了_LIBC_REENTRANT。
可以写个程序看下自己开发环境里这几个宏的设置:

view sourceprint?01 #include <stdio.h> 

02 #include <errno.h> 

03   

04 int main( void ) 

05 { 

06 #ifndef __ASSEMBLER__ 

07         printf( "__ASSEMBLER__ is NOT defined!/n" ); 

08 #else 

09         printf( "__ASSEMBLER__ is defined!/n" ); 

10 #endif 

11   

12 #ifndef __LIBC 

13         printf( "__LIBC is NOT defined/n" ); 

14 #else 

15         printf( "__LIBC is defined!/n" ); 

16 #endif 

17   

18 #ifndef _LIBC_REENTRANT 

19         printf( "_LIBC_REENTRANT is NOT defined/n" ); 

20 #else 

21         printf( "_LIBC_REENTRANT is defined!/n" ); 

22 #endif 

23   

24         return 0; 

25 }

我的输出:

view sourceprint?1 _ASSEMBLER__ is NOT defined! 

2 __LIBC is NOT defined! 

3 _LIBC_REENTRANT is NOT defined!

哈!看来我可以在多线程下安全的使用errno,如果你的默认环境不可以就在makefile里定义上_LIBC_REENTRANT吧

{"categories":"['2023/6/9 1:30:00','2023/6/9 1:35:00','2023/6/9 1:40:00','2023/6/9 1:45:00','2023/6/9 1:50:00','2023/6/9 1:55:00','2023/6/9 2:00:00']","series":"[ { "name": "O3", "type": "line", "data": [ 51.0, 53.0, 51.0, 47.0, 45.0, 46.0, 45.0 ], "yAxisIndex": 0, "smooth": true, "itemStyle": {normal: {color: '',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }, { "name": "PM10", "type": "line", "data": [ 65.0, 65.0, 65.0, 65.0, 65.0, 83.0, 83.0 ], "yAxisIndex": 0, "smooth": true, "itemStyle": {normal: {color: '#33B1FF',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }, { "name": "PM2.5", "type": "line", "data": [ 24.0, 24.0, 24.0, 24.0, 24.0, 24.0, 22.0 ], "yAxisIndex": 0, "smooth": true, "itemStyle": {normal: {color: '#FF9900',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }, { "name": "SO2", "type": "line", "data": [ 7.0, 7.0, 7.0, 7.0, 6.0, 6.0, 6.0 ], "yAxisIndex": 0, "smooth": true, "itemStyle": {normal: {color: '#F366BD',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }, { "name": "NO2", "type": "line", "data": [ 10.0, 10.0, 9.0, 10.0, 12.0, 13.0, 12.0 ], "yAxisIndex": 0, "smooth": true, "itemStyle": {normal: {color: '#1F9804',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }, { "name": "CO", "type": "line", "data": [ null, null, null, null, null, null, null ], "yAxisIndex": 1, "smooth": true, "itemStyle": {normal: {color: '#0055CC',lineStyle: { width: 2,type: 'solid'}}}, "showAllSymbol": "true" }]"}转json格式
06-10
{"categories":"['2023/6/9 1:30:00','2023/6/9 1:35:00','2023/6/9 1:40:00','2023/6/9 1:45:00','2023/6/9 1:50:00','2023/6/9 1:55:00','2023/6/9 2:00:00']","series":"[ { \"name\": \"O3\", \"type\": \"line\", \"data\": [ 51.0, 53.0, 51.0, 47.0, 45.0, 46.0, 45.0 ], \"yAxisIndex\": 0, \"smooth\": true, \"itemStyle\": {normal: {color: '',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }, { \"name\": \"PM10\", \"type\": \"line\", \"data\": [ 65.0, 65.0, 65.0, 65.0, 65.0, 83.0, 83.0 ], \"yAxisIndex\": 0, \"smooth\": true, \"itemStyle\": {normal: {color: '#33B1FF',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }, { \"name\": \"PM2.5\", \"type\": \"line\", \"data\": [ 24.0, 24.0, 24.0, 24.0, 24.0, 24.0, 22.0 ], \"yAxisIndex\": 0, \"smooth\": true, \"itemStyle\": {normal: {color: '#FF9900',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }, { \"name\": \"SO2\", \"type\": \"line\", \"data\": [ 7.0, 7.0, 7.0, 7.0, 6.0, 6.0, 6.0 ], \"yAxisIndex\": 0, \"smooth\": true, \"itemStyle\": {normal: {color: '#F366BD',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }, { \"name\": \"NO2\", \"type\": \"line\", \"data\": [ 10.0, 10.0, 9.0, 10.0, 12.0, 13.0, 12.0 ], \"yAxisIndex\": 0, \"smooth\": true, \"itemStyle\": {normal: {color: '#1F9804',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }, { \"name\": \"CO\", \"type\": \"line\", \"data\": [ null, null, null, null, null, null, null ], \"yAxisIndex\": 1, \"smooth\": true, \"itemStyle\": {normal: {color: '#0055CC',lineStyle: { width: 2,type: 'solid'}}}, \"showAllSymbol\": \"true\" }]"}转json格式
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值