时间:2016-12-25来源:本站原创作者:佚名

linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KERN_DEBUG)来输出打印信息。要打开这个开关需要下面两步。

1.打开调试开关:你调试的文件中必然包含了linux/device.h,或者linux/paltforam_device.h,后者包含了前者,在包含此头文件之前,使用#defineDEBUG1来打开调试开关:例如#includelinux/kernel.h#includelinux/init.h#includelinux/clk.h#includelinux/module.h#defineDEBUG1/*添加在驱动的程序中,而非头文件*/#includelinux/platform_device.h在linux/device.h文件中:#definedev_printk(level,dev,format,arg...)\printk(level%s%s:format,dev_driver_string(dev),(dev)-bus_id,##arg)#ifdefDEBUG#definedev_dbg(dev,format,arg...)\dev_printk(KERN_DEBUG,dev,format,##arg)#elsestaticinlineint__attribute__((format(printf,2,3)))dev_dbg(structdevice*dev,constchar*fmt,...){return0;}#endif但是这个打开了之后,也不能顺利的输出信息,原因是printk有默认的信息级别。

linux/kernel文件中#defineKERN_EMERG0/*systemisunusable*/#defineKERN_ALERT1/*actionmustbetakenimmediately*/#defineKERN_CRIT2/*criticalconditions*/#defineKERN_ERR3/*errorconditions*/#defineKERN_WARNING4/*warningconditions*/#defineKERN_NOTICE5/*normalbutsignificantcondition*/#defineKERN_INFO6/*informational*/#defineKERN_DEBUG7/*debug-levelmessages*/可以看到KERN_DEBUG是级别最低的。2、修改文件kernel/printk文件/*printkswithoutaloglevelusethis..*/#defineDEFAULT_MESSAGE_LOGLEVEL4/*KERN_WARNING*//*WeshoweverythingthatisMOREimportantthanthis..*/#defineMINIMUM_CONSOLE_LOGLEVEL1/*Minimumloglevelweletpeopleuse*/#defineDEFAULT_CONSOLE_LOGLEVEL8/*anythingMOREseriousthanKERN_DEBUG*/其中DEFAULT_CONSOLE_LOGLEVEL为终端console输出的最低级别,比这严重的都将输出。原来该值为7,则调试信息无法输出,修改为8则全部有输出。3,用echo命令#echo8/proc/sys/kernel/printk#cat/proc/sys/kernel/printk四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。

测试程序如下:

/*i2c_test.c*/#includestdio.h#includelinux/types.h#includestdlib.h#includefcntl.h#includeunistd.h#includesys/types.h#includesys/ioctl.h#includeerrno.h

#defineI2C_RETRIES0x#defineI2C_TIMEOUT0x#defineI2C_RDWR0x/*********定义structi2c_rdwr_ioctl_data和structi2c_msg,要和内核一致*******/structi2c_msg{unsignedshortaddr;unsignedshortflags;#defineI2C_M_TEN0x#defineI2C_M_RD0xunsignedshortlen;unsignedchar*buf;};structi2c_rdwr_ioctl_data{structi2c_msg*msgs;intnmsgs;/*nmsgs这个数量决定了有多少开始信号,对于“单开始时序”,取1*/};intmain(){intfd,ret;structi2c_rdwr_ioctl_datae2prom_data;

fd=open(/dev/i2c-0,O_RDWR);/*dev/i2c-0是在注册i2c-dev.c后产生的,代表一个可操作的适配器。如果不使用i2c-dev.c的方式,就没有,也不需要这个节点。*/if(fd0){perror(openerror);}e2prom_data.nmsgs=2;/*因为操作时序中,最多是用到2个开始信号(字节读操作中),所以此将*e2prom_data.nmsgs配置为2*/e2prom_data.msgs=(structi2c_msg*)malloc(e2prom_data.nmsgs*sizeof(structi2c_msg));if(!e2prom_data.msgs){perror(mallocerror);exit(1);}

ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/ioctl(fd,I2C_RETRIES,2);/*重复次数*//***writedatatoe2prom**/e2prom_data.nmsgs=1;(e2prom_data.msgs[0]).len=2;//1个e2prom写入目标的地址和1个数据(e2prom_data.msgs[0]).addr=0x50;//e2prom设备地址(e2prom_data.msgs[0]).flags=0;//write(e2prom_data.msgs[0]).buf=(unsignedchar*)malloc(2);(e2prom_data.msgs[0]).buf[0]=0x10;//e2prom写入目标的地址(e2prom_data.msgs[0]).buf[1]=0x58;//thedatatowriteret=ioctl(fd,I2C_RDWR,(unsignedlong)e2prom_data);if(ret0){perror(ioctlerror1);}sleep(1);

/******readdatafrome2prom*******/e2prom_data.nmsgs=2;(e2prom_data.msgs[0]).len=1;//e2prom目标数据的地址(e2prom_data.msgs[0]).addr=0x50;//e2prom设备地址(e2prom_data.msgs[0]).flags=0;//write(e2prom_data.msgs[0]).buf[0]=0x10;//e2prom数据地址(e2prom_data.msgs[1]).len=1;//读出的数据(e2prom_data.msgs[1]).addr=0x50;//e2prom设备地址(e2prom_data.msgs[1]).flags=I2C_M_RD;//read(e2prom_data.msgs[1]).buf=(unsignedchar*)malloc(1);//存放返回值的地址。(e2prom_data.msgs[1]).buf[0]=0;//初始化读缓冲ret=ioctl(fd,I2C_RDWR,(unsignedlong)e2prom_data);if(ret0){perror(ioctlerror2);}printf(buff[0]=%x\n,(e2prom_data.msgs[1]).buf[0]);/***打印读出的值,没错的话,就应该是前面写的0x58了***/close(fd);return0;}

从UART口打印的调试信息如下:

i2c-adapteri2c-0:ioctl,cmd=0x,arg=0x01

i2c-adapteri2c-0:ioctl,cmd=0x,arg=0x02

i2c-adapteri2c-0:ioctl,cmd=0x,arg=0xbeb95d28

i2c-adapteri2c-0:master_xfer[0]W,addr=0x50,len=2

s3c-i2cs3c-i2c:START:d0toIICSTAT,a0toDS

s3c-i2cs3c-i2c:iiccon,e0

s3c-i2cs3c-i2c:STOP

s3c-i2cs3c-i2c:master_







































治疗白癜风专家
北京白癜风最佳最好的治疗方法

转载请注明原文网址:http://www.gzdatangtv.com/bbqb/5143.html

------分隔线----------------------------