如何用linux printk level在linux中写日志

printk如何定向输出到UART的?_Linux编程_Linux公社-Linux系统门户网站
你好,游客
printk如何定向输出到UART的?
来源:Linux社区&
作者:skywalkzf
我们通常在config里面配置这么一句“CONFIG_CMDLINE="console=tty0 console=ttyMT3, root=/dev/ram"”,然后修改console的赋值就可以改变输出的位置,代码中如何实现的呢?这里紧接着上文中的printk.c文件中,有这么一个函数先看一下:/*&* Set up a list of consoles. &Called from init/main.c&*/拉风的注释直接告诉了我们这个函数被init/main.c文件中某个函数调用。
static&int&__init&console_setup(char&*str)&&
&&&&char&buf[sizeof(console_cmdline[0].name)&+&4];&&&
&&&&char&*s,&*options,&*brl_options&=&NULL;&&
&&&&int&&&
#ifdef&CONFIG_A11Y_BRAILLE_CONSOLE &&
&&&&if&(!memcmp(str,&"brl,",&4))&{&&
&&&&&&&&brl_options&=&"";&&
&&&&&&&&str&+=&4;&&
&&&&}&else&if&(!memcmp(str,&"brl=",&4))&{&&
&&&&&&&&brl_options&=&str&+&4;&&
&&&&&&&&str&=&strchr(brl_options,&',');&&
&&&&&&&&if&(!str)&{&&
&&&&&&&&&&&&printk(KERN_ERR&"need&port&name&after&brl=\n");&&
&&&&&&&&&&&&return&1;&&
&&&&&&&&}&&
&&&&&&&&*(str++)&=&0;&&
&&&&if&(str[0]&&=&'0'&&&&str[0]&&=&'9')&{&&
&&&&&&&&strcpy(buf,&"ttyS");&&
&&&&&&&&strncpy(buf&+&4,&str,&sizeof(buf)&-&5);&&
&&&&}&else&{&&
&&&&&&&&strncpy(buf,&str,&sizeof(buf)&-&1);&&
&&&&buf[sizeof(buf)&-&1]&=&0;&&
&&&&if&((options&=&strchr(str,&','))&!=&NULL)&&
&&&&&&&&*(options++)&=&0;&&
#ifdef&__sparc__ &&
&&&&if&(!strcmp(str,&"ttya"))&&
&&&&&&&&strcpy(buf,&"ttyS0");&&
&&&&if&(!strcmp(str,&"ttyb"))&&
&&&&&&&&strcpy(buf,&"ttyS1");&&
&&&&for&(s&=&&*s;&s++)&&
&&&&&&&&if&((*s&&=&'0'&&&&*s&&=&'9')&||&*s&==&',')&&
&&&&&&&&&&&&break;&&
&&&&idx&=&simple_strtoul(s,&NULL,&10);&&
&&&&*s&=&0;&&
&&&&__add_preferred_console(buf,&idx,&options,&brl_options);&&
&&&&console_set_on_cmdline&=&1;&&
&&&&return&1;&&
}&&可以看到这里面有对字符串的解析,获得tty的name,index,options。加入链表是由下面的宏来做的。
__setup("console=",&console_setup);&&好像是不是缺少了点东东,在main.c中调用的的链表呢?在这里register_console()。
void&register_console(struct&console&*newcon)&&
&&&&............................&&
&&&&for&(i&=&0;&i&&&MAX_CMDLINECONSOLES&&&&console_cmdline[i].name[0];&&
&&&&&&&&&&&&i++)&{&&
&&&&&&&&if&(strcmp(console_cmdline[i].name,&newcon-&name)&!=&0)&&
&&&&&&&&&&&&continue;&&
&&&&&&&&if&(newcon-&index&&=&0&&&&&
&&&&&&&&&&&&newcon-&index&!=&console_cmdline[i].index)&&
&&&&&&&&&&&&continue;&&
&&&&&&&&if&(newcon-&index&&&0)&&
&&&&&&&&&&&&newcon-&index&=&console_cmdline[i].&&
#ifdef&CONFIG_A11Y_BRAILLE_CONSOLE &&
&&&&&&&&if&(console_cmdline[i].brl_options)&{&&
&&&&&&&&&&&&newcon-&flags&|=&CON_BRL;&&
&&&&&&&&&&&&braille_register_console(newcon,&&
&&&&&&&&&&&&&&&&&&&&console_cmdline[i].index,&&
&&&&&&&&&&&&&&&&&&&&console_cmdline[i].options,&&
&&&&&&&&&&&&&&&&&&&&console_cmdline[i].brl_options);&&
&&&&&&&&&&&&return;&&
&&&&&&&&}&&
&&&&&&&&if&(newcon-&setup&&&&&
&&&&&&&&&&&&newcon-&setup(newcon,&console_cmdline[i].options)&!=&0)&&
&&&&&&&&&&&&break;&&
&&&&&&&&newcon-&flags&|=&CON_ENABLED;&&
&&&&&&&&newcon-&index&=&console_cmdline[i].&&
&&&&&&&&if&(i&==&selected_console)&{&&
&&&&&&&&&&&&newcon-&flags&|=&CON_CONSDEV;&&
&&&&&&&&&&&&preferred_console&=&selected_&&
&&&&&&&&}&&
&&&&&&&&break;&&
&&&&if&(!(newcon-&flags&&&CON_ENABLED))&&
&&&&&&&&return;&&
........................................&&
}&&当然了,上面的函数在源码中的注释很是详细,如果需要看的,读源码是最佳的选择。到了这里,so command line的tty端口的指定就到了这里了。
相关资讯 & & &
& (01月14日)
& (01月10日)
& (01月15日)
& (01月14日)
& (10/12/:53)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款博客访问: 564295
博文数量: 115
博客积分: 1919
博客等级: 上尉
技术积分: 1877
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
要将linux内核的带级别控制的printk内容打印出来,在命令行输入 dmesg -n 8 就将所有级别的信息都打印出来。
Linux命令:dmesg  功能说明:显示开机信息。
  语 法:dmesg [-cn][-s ]
  补充说明:kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文件里。
  参 数:
  -c 显示信息后,清除ring buffer中的内容。
  -s 预设置为8196,刚好等于ring buffer的大小。
  -n 设置记录信息的层级。
printk() 使用说明
内核通过 printk() 输出的信息具有日志级别,日志级别是通过在 printk() 输出的字符串前加一个带尖括号的整数来控制的,如 printk("Hello, world! ");。内核中共提供了八种不同的日志级别,在 linux/kernel.h 中有相应的宏对应。
#define KERN_EMERG&&&&& ""&&& /* system is unusable */&
#define KERN_ALERT&&&&& ""&&& /* action must be taken immediately */&
#define KERN_CRIT&&&&&& ""&&& /* critical conditions */&
#define KERN_ERR&&&&&&& ""&&& /* error conditions */&
#define KERN_WARNING&&& ""&&& /* warning conditions */&
#define KERN_NOTICE&&&& ""&&& /* normal but significant */&
#define KERN_INFO&&&&&& ""&&& /* informational */&
#define KERN_DEBUG&&&&& ""&&& /* debug-level messages */
#define KERN_EMERG&&&&& ""&&& /* system is unusable */
#define KERN_ALERT&&&&& ""&&& /* action must be taken immediately */
#define KERN_CRIT&&&&&& ""&&& /* critical conditions */
#define KERN_ERR&&&&&&& ""&&& /* error conditions */
#define KERN_WARNING&&& ""&&& /* warning conditions */
#define KERN_NOTICE&&&& ""&&& /* normal but significant */
#define KERN_INFO&&&&&& ""&&& /* informational */
#define KERN_DEBUG&&&&& ""&&& /* debug-level messages */
所以 printk() 可以这样用:printk(KERN_INFO "Hello, world! ");。
未指定日志级别的 printk() 采用的默认级别是 DEFAULT_MESSAGE_LOGLEVEL,这个宏在 kernel/printk.c 中被定义为整数 4,即对应KERN_WARNING。
在 /proc/sys/kernel/printk 会显示4个数值(可由 echo 修改),分别表示当前控制台日志级别、未明确指定日志级别的默认消息日志级别、最小(最高)允许设置的控制台日志级别、引导时默认的日志级别。当 printk() 中的消息日志级别小于当前控制台日志级别时,printk 的信息(要有符)就会在控制台上显示。但无论当前控制台日志级别是何值,通过 /proc/kmsg (或使用dmesg)总能查看。另外如果配置好并运行了 syslogd 或 klogd,没有在控制台上显示的 printk 的信息也会追加到 /var/log/messages.log 中。
通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
#cat /proc/sys/kernel/printk
6&& 4& 1&& 7
上面显示的4个数据分别对应控制台日志级别、默认的消息日志级别、最低的控制台日志级别和默认的控制台日志级别。
可用下面的命令设置当前日志级别:
# echo 8 > /proc/sys/kernel/printk
分析与总结:
&&&&&&& Printf在终端显示,printk()函数为内核空间里边的信息打印函数,就像c编程时用的printf()函数一样,专供内核中的信息展示用,他没有调用printf()的原因是在编译内核时还没有c的库函数可以供调用。
在linux中,可以像使用printf()一样使用printk(),也可以加上优先级使用,比如如下:
&&&printk(KERN_ALERT "LCD light exit.\n");
printk()函数有八个优先级定义,如下:
#define&&&& KERN_EMERG&&&& ""&&&&&&& /* system is unusable*/
#define&&&& KERN_ALERT&&&& ""&&&&&&& /* action must be taken immediately*/
#define&&&& KERN_CRIT&&&&& ""&&&&&&& /* critical conditions*/
#define&&&& KERN_ERR&&&&&& ""&&&&&&& /* error conditions&*/
#define&&&& KERN_WARNING&&&""&&&&&&& /* warning conditions&*/
#define&&&& KERN_NOTICE&&&&""&&&&&&& /* normal but significant condition*/
#define&&&& KERN_INFO&&&&& ""&&&&&&& /* informational&*/
#define&&&& KERN_DEBUG&&&& ""&&&&&&& /* debug-level messages&*/
&& 当printk()优先级低于int console_loglevel,信息将直接打印在你的终端上(x 环境下好像不行)。如果同时 syslogd和klogd都在运行,信息也同时添加在文件 /var/log/messages,而不管是否显示在控制台上与否。我们使用像 KERN_ALERT这样的高优先级,来确保printk()将信息输出到控制台而不是只是添加到日志文件中。当你编写真正的实用的模块时,你应该针对可能遇到的情况使用合适的优先级。
/var/log/messages里的信息可以使用 cat& /var/log/messages 进行查看。
控制台的日志级别可以使用&&& cat /peoc/sys/kernel/printk 查看。
控制台的日志级别可以用&&& echo 3 > /peoc/sys/kernel/printk& 改变(3为要写入的值,可改变)。
阅读(5258) | 评论(0) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。14811人阅读
P.OS-操作系统 & 内核(89)
L.Linux 开发(182)
&&&& 函数printk的使用方法和printf相似,用于内核打印消息。printk根据日志级别(loglevel)对消息进行分类。日志级别用宏定义,日志级别宏展开为一个字符串,在编译时由预处理器将它和消息文本拼接成一个字符串,因此printk 函数中日志级别宏和格式字符串间不能有逗号。
&& 下面是两个printk的例子,一个用于打印调试信息,另一个用于打印临界条件信息。
printk(KERN_DEBUG "Here I am: %s:%i/n", _ _FILE_ _, _ _LINE_ _); printk(KERN_CRIT "I' giving up on %p/n", ptr);
&& printk的日志级别定义如下(在linux26/includelinux/kernel.h中):
#defineKERN_EMERG"&0&"#defineKERN_ALERT"&1&"#defineKERN_CRIT"&2&"#defineKERN_ERR"&3&"#defineKERN_WARNING"&4&"#defineKERN_NOTICE"&5&"#defineKERN_INFO"&6&"#defineKERN_DEBUG"&7&" extern int console_printk[]; #define console_loglevel  (console_printk[0])#define default_message_loglevel  (console_printk[1])#define minimum_console_loglevel  (console_printk[2])#define default_console_loglevel  (console_printk[3])
日志级别的范围是0~7,没有指定日志级别的printk语句默认采用的级别是 DEFAULT_ MESSAGE_LOGLEVEL,其定义列出如下(在linux26/kernel/printk.c中):
#define DEFAULT_MESSAGE_LOGLEVEL 4
内核可把消息打印到当前控制台上,可以指定控制台为字符模式的终端或打印机等。默认情况下,&控制台&就是当前的虚拟终端。
为了更好地控制不同级别的信息显示在控制台上,内核设置了控制台的日志级别console_loglevel。printk日志级别的作用是打印一定级别的消息,与之类似,控制台只显示一定级别的消息。
当日志级别小于console_loglevel时,消息才能显示出来。控制台相应的日志级别定义如下:
#define MINIMUM_CONSOLE_LOGLEVEL  1   #define DEFAULT_CONSOLE_LOGLEVEL  7
int console_printk[4] = {DEFAULT_CONSOLE_LOGLEVEL, DEFAULT_MESSAGE_LOGLEVEL, MINIMUM_CONSOLE_LOGLEVEL,DEFAULT_CONSOLE_LOGLEVEL,};
如果系统运行了klogd和syslogd,则无论console_loglevel为何值,内核消息都将追加到/var/log/messages中。如果klogd没有运行,消息不会传递到用户空间,只能查看/proc/kmsg。
变量console_loglevel的初始值是DEFAULT_CONSOLE_LOGLEVEL,可以通过sys_syslog系统调用进行修改。调用klogd时可以指定-c开关选项来修改这个变量。如果要修改它的当前值,必须先杀掉klogd,再加-c选项重新启动它。
注:#ps -e 查看所有进程PID,然后KILL。通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
#cat /proc/sys/kernel/printk6 4 1 7
上面显示的4个数据分别对应控制台日志级别、默认的消息日志级别、最低的控制台日志级别和默认的控制台日志级别。
可用下面的命令设置当前日志级别:
# echo 8 & /proc/sys/kernel/printk
printk打印消息机制
在内核中,函数printk将消息打印到环形缓冲区__log_buf中,并将消息传给控制台进行显示。控制台驱动程序根据控制台的日志级别显示日志消息。
应用程序通过系统调用sys_syslog管理环形缓冲区__log_buf,它可以读取数据、清除缓冲区、设置日志级别、开/关控制台等。
当系统调用sys_syslog从环形缓冲区__log_buf读取数据时,如果缓冲区没有数据,系统调用sys_syslog所在进程将被加入到等待队列log_wait中进行等待。当printk将数据打印到缓冲区后,将唤醒系统调用sys_syslog所在进程从缓冲区中读取数据。等待队列 log_wait定义如下:
DECLARE_WAIT_QUEUE_HEAD(log_wait);//等待队列log_wait
环形缓冲区__log_buf在使用之前就是已定义好的全局变量,缓冲区的长度为1 && CONFIG_LOG_ BUF_SHIFT。变量CONFIG_LOG_BUF_SHIFT在内核编译时由配置文件定义,对于i386平台,其值定义如下(在 linux26/arch/i386/defconfig中):
CONFIG_LOG_BUF_SHIFT=18
在内核编译时,编译器根据配置文件的设置,产生如下的宏定义:
#define CONFIG_LOG_BUF_SHIFT 18
环形缓冲区__log_buf定义如下(在linux26/kernel/printk.c中):
#define __LOG_BUF_LEN(1 && CONFIG_LOG_BUF_SHIFT) //定义环形缓冲区的长度,i386平台为 static char __log_buf[__LOG_BUF_LEN]; //printk的环形缓冲区static char *log_buf = __log_static int log_buf_len = __LOG_BUF_LEN; static DEFINE_SPINLOCK(logbuf_lock);
通过宏定义LOG_BUF,缓冲区__log_buf具备了环形缓冲区的操作行为。宏定义LOG_BUF得到缓冲区指定位置序号的字符,位置序号超过缓冲区长度时,通过与长度掩码LOG_BUF_MASK进行逻辑与操作,位置序号循环回到环形缓冲区中的位置。
宏定义LOG_BUF及位置序号掩码LOG_BUF_MASK的定义列出如下:
#define LOG_BUF_MASK (log_buf_len-1)#define LOG_BUF(idx)  (log_buf[(idx) & LOG_BUF_MASK])
为了指明环形缓冲区__log_buf字符读取位置,定义了下面的位置变量:
static unsigned long log_static unsigned long con_static unsigned long log_static unsigned long logged_
任何地方的内核调用都可以调用函数printk打印调试、安全、提示和错误消息。函数printk尝试得到控制台信号量(console_sem),如果得到,就将信息输出到环形缓冲区__log_buf中,然后函数release_console_sem()在释放信号量之前把环形缓冲区中的消息送到控制台,调用控制台驱动程序显示打印的信息。如果没得到信号量,就只将信息输出到环形缓冲区后返回。函数printk的调用层次如图1所示。
图1 函数printk的调用层次图
函数printk列出如下(在linux26/kernel/printk.c中):
asmlinkage int printk(const char *fmt, ...){va_ va_start(args, fmt);r = vprintk(fmt, args);va_end(args); } asmlinkage int vprintk(const char *fmt, va_list args){int printed_char *p;static char printk_buf[1024];static int log_level_unknown = 1; preempt_disable(); //关闭内核抢占if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id()) zap_locks(); local_irq_save(flags); //存储本地中断标识lockdep_off();spin_lock(&logbuf_lock);printk_cpu = smp_processor_id(); 
printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
for (p = printk_ *p; p++) {if (log_level_unknown) { if (printk_time) {int loglev_char tbuf[50], *unsigned long nanosec_
if (p[0] == '&' && p[1] &='0' &&p[1] &= '7' && p[2] == '&') {loglev_char = p[1]; //获取日志级别字符p += 3;printed_len -= 3;} else {loglev_char = default_message_loglevel+ '0';}t = printk_clock();//返回当前时钟,以ns为单位nanosec_rem = do_div(t, );tlen = sprintf(tbuf,"&%c&[%5lu.%06lu] ",loglev_char,(unsigned long)t,nanosec_rem/1000);//写入格式化后的日志级别和时间 for (tp = tp & tbuf + tp++) emit_log_char(*tp);  //将日志级别和时间字符输出到循环缓冲区printed_len +=} else {if (p[0] != '&' || p[1] & '0' ||p[1] & '7' || p[2] != '&') {emit_log_char('&');emit_log_char(default_message_loglevel+ '0');  //输出字符到循环缓冲区emit_log_char('&');printed_len += 3;}}log_level_unknown = 0;if (!*p)}emit_log_char(*p);//将其他printk_buf数据输出到循环缓冲区if (*p == '/n')log_level_unknown = 1;} if (!down_trylock(&console_sem)) { console_locked = 1;printk_cpu = UINT_MAX;spin_unlock(&logbuf_lock);
if (cpu_online(smp_processor_id()) || have_callable_console()) {console_may_schedule = 0;release_console_sem();} else { console_locked = 0;up(&console_sem);}lockdep_on();local_irq_restore(flags); //恢复本地中断标识} else { printk_cpu = UINT_MAX;spin_unlock(&logbuf_lock);lockdep_on();local_irq_restore(flags); //恢复本地中断标识} preempt_enable(); //开启抢占机制return printed_}
函数release_console_sem()给控制台系统开锁,释放控制台系统及驱动程序调用者持有的信号量。持有信号量时,表示printk 已在缓冲区存有数据。函数release_console_sem()在释放信号量之前将这些数据送给控制台显示。如果后台进程klogd在等待环形缓冲区装上数据,它唤醒klogd进程。
函数release_console_sem列出如下(在linux26/kernel/printk.c中):
void release_console_sem(void){unsigned long _con_start, _log_unsigned long wake_klogd = 0; for ( ; ; ) {spin_lock_irqsave(&logbuf_lock, flags);wake_klogd |= log_start - log_if (con_start == log_end)_con_start = con__log_end = log_con_start = log_spin_unlock_irqrestore(&logbuf_lock, flags);//调用控制台driver的write函数写入到控制台call_console_drivers(_con_start, _log_end);}console_locked = 0;console_may_schedule = 0;up(&console_sem);spin_unlock_irqrestore(&logbuf_lock, flags);if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))wake_up_interruptible(&log_wait);//唤醒在等待队列上的进程}
函数_call_console_drivers将缓冲区中从start到end - 1的数据输出到控制台进行显示。在输出数据到控制台之前,它检查消息的日志级别。只有日志级别小于控制台日志级别console_loglevel的消息,才能交给控制台驱动程序进行显示。
函数_call_console_drivers列出如下:
static void _call_console_drivers(unsigned long start,unsigned long end, int msg_log_level){//日志级别小于控制台日志级别的消息才能输出到控制台if ((msg_log_level & console_loglevel || ignore_loglevel) &&console_drivers && start != end) {if ((start & LOG_BUF_MASK) & (end & LOG_BUF_MASK)) { __call_console_drivers(start & LOG_BUF_MASK, log_buf_len);__call_console_drivers(0, end & LOG_BUF_MASK);} else {__call_console_drivers(start, end);}}}
函数__call_console_drivers调用控制台驱动程序的写操作函数显示消息。其列出如下:
static void __call_console_drivers(unsigned long start, unsigned long end){struct console * for (con = console_ con = con-&next) {if ((con-&flags & CON_ENABLED) && con-&write &&(cpu_online(smp_processor_id()) ||(con-&flags & CON_ANYTIME)))con-&write(con, &LOG_BUF(start), end - start); //调用驱动程序的写操作函数}}
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
Linux系统与内核群:
WP建站技术群:
访问:1958035次
积分:19942
积分:19942
排名:第311名
原创:339篇
转载:213篇
评论:227条
(1)(1)(2)(1)(2)(1)(2)(3)(2)(2)(1)(7)(4)(4)(2)(4)(1)(4)(1)(2)(5)(3)(8)(5)(5)(9)(4)(1)(1)(1)(1)(1)(4)(1)(1)(2)(1)(2)(9)(16)(1)(41)(68)(53)(4)(40)(53)(24)(28)(83)(7)(1)(12)(15)2800人阅读
我们在底层驱动或者中调用的函数其作用是将的内容输出到控制台,但实质是将需要输出的内容写入底层环形输出数据缓冲区,根据控制将数据输出到控制台;
基于此,我们可以在系统下手动关闭的信息输出到控制台(目的是即需要输出信息,但又不想通过频繁的串口输出中断输出到控制台,频繁串口中断将影响其他驱动实时性要求),此时使用来关闭信息输出至控制台(但信息任然将保存在缓冲区中);
表示所有信息均输出;
表示仅输出系统严重错误信息;故可频闭默认数据级别以及警告信息输出等而达到关闭绝大部分输出信息的目的。
查看输出所在环行缓冲区信息方法:
使用查看是否有进程,如果有,则进程会将输出信息从环形缓冲区中抓取保存在文件中,使用即可查看所有输出信息;此方法仍然是将信息通过串口输出到控制台,只是可以滞后输出,避免影像实时性强的驱动,但无法实时查看输出;
通过网络实时查看输出信息,此方法先使用来关闭信息输出至控制台,然后通过登陆到终端,此时需要先杀死方法中的进程(因为会先将输出缓冲区数据拿走导致其他进程无法取到输出缓冲区数据):
然后使用来阻塞获取实时的输出至缓冲区信息并显示即可;
进程是用于获取系统运行时各进程输出信息的后台进程,其会在下创建文件并记录日志信息,当文件不断增大时会对系统造成威胁,到空间占用为时则使其他进程对文件夹的读写失败从而导致其他进程执行失败!目前出现的为进程拨号至次必然失败,原因是文件系统被文件写满而导致的拨号脚本无法再写入中而导致拨号失败!
NFC内核信息查看方法:
输出信息可通过网络输出这样可无影响时序
在通过可看见哪些输出关闭,使用31 /proc/nfc来开放对应输出信息必须切换到可操作;
执行来获取
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:27819次
排名:千里之外
原创:28篇
转载:15篇
(1)(1)(1)(1)(1)(1)(1)(2)(1)(2)(1)(1)(1)(3)(2)(7)(20)主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
傻丫头和高科技产物小心翼翼的初恋
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:
CSDN &《程序员》编辑/记者,投稿&纠错等事宜请致邮
Linux驱动开发和应用开发常用的调试手段,找BUG的最佳选择

我要回帖

更多关于 printk.c linux 的文章

 

随机推荐