在调试芯片驱动的调试阶段,经常会碰到寄存器值不确定,需要不断更改寄存器的值来调试芯片驱动的效果到最佳状态,从而出现要不停的编译驱动代码,这样浪费了很多的时间,下面介绍一种调试的方法,通过创建节点,通过echo和cat来写和读设备寄存器的值,从而达到快速调试的效果。
首先要创建节点,在驱动的探测函数中,创建节点:device_create_file(devices*, device_attribute*);
在驱动的卸载函数中,删除节点: device_remove_file(devices*, device_attribute*);
具体的实现如下代码
#define tw9912_TEST 1//Harvey add for tw9912 test #if tw9912_TEST #define tp_major 555 #endif #if tw9912_TEST static u8 tw9912REG; static u8 tw9912VAL; static u8 cameramode; static u8 camerafmt; static ssize_t TEST_mode_show(struct device *dev, struct device_attribute *attr, char *_buf)//(struct class *cls, char *_buf) { int count; count = sprintf(_buf,"tw9912Mode:%d\n", cameramode); printk(KERN_INFO "tw9912_data.CameraDispMode %d\n",cameramode); return count; } static ssize_t TEST_mode_store(struct device *dev, struct device_attribute *attr, char *_buf,size_t _count)//(struct class *cls, const char *_buf, size_t _count) { int tmp_get_android = 0; tmp_get_android = simple_strtol(_buf, NULL, 10); printk(KERN_INFO "cameramode %d\n",tmp_get_android); cameramode=tmp_get_android; tw9912_init_Disp_mode(cameramode,camerafmt); return _count; } static ssize_t TEST_FMT_show(struct device *dev, struct device_attribute *attr, char *_buf)//(struct class *cls, char *_buf) { int count; count = sprintf(_buf,"tw9912FMT:%d\n", camerafmt); printk(KERN_INFO "tw9912_data.CameraDispFMT %d\n",camerafmt); return count; } static ssize_t TEST_FMT_store(struct device *dev, struct device_attribute *attr, char *_buf,size_t _count)//(struct class *cls, const char *_buf, size_t _count) { int tmp_get_android = 0; tmp_get_android = simple_strtol(_buf, NULL, 10); printk(KERN_INFO "tw9912_data.CameraDispFMT %d\n",tmp_get_android); camerafmt=tmp_get_android; tw9912_init_Disp_mode(cameramode,camerafmt); return _count; } static ssize_t TEST_REG_show(struct device *dev, struct device_attribute *attr, char *_buf)//(struct class *cls, char *_buf) { int count; count = sprintf(_buf,"tw9912REG:0x%x\n", tw9912REG); printk(KERN_INFO "tw9912REG 0x%x\n",tw9912REG); return count; } static ssize_t TEST_REG_store(struct device *dev, struct device_attribute *attr, char *_buf,size_t _count)//(struct class *cls, const char *_buf, size_t _count) { // int tmp_get_android = 0; tw9912REG = simple_strtol(_buf, NULL, 16); printk(KERN_INFO "tw9912REG %x\n",tw9912REG); return _count; } static ssize_t TEST_VAL_show(struct device *dev, struct device_attribute *attr, char *_buf)//(struct class *cls, char *_buf) { int count; tw9912VAL=tw9912_read(tw9912REG); // printk(KERN_INFO "tw9912Read ERROR\n"); count = sprintf(_buf,"tw9912VAL:0x%x\n", tw9912VAL); printk(KERN_INFO "tw9912VAL 0x%x\n",tw9912VAL); return count; } static ssize_t TEST_VAL_store(struct device *dev, struct device_attribute *attr, char *_buf,size_t _count)//(struct class *cls, const char *_buf, size_t _count) { // int tmp_get_android = 0; tw9912VAL = simple_strtol(_buf, NULL, 16); printk(KERN_INFO "tw9912VAL %x\n",tw9912VAL); if(tw9912_write_reg(tw9912REG,tw9912VAL)<0) printk(KERN_INFO "tw9912Write ERROR\n"); return _count; } static struct class *tw9912_TEST_class = NULL; static struct device *tw9912_TEST_dev=NULL; static DEVICE_ATTR(TESTMODE, 0666, TEST_mode_show, TEST_mode_store); static DEVICE_ATTR(TESTFMT, 0666, TEST_FMT_show, TEST_FMT_store); static DEVICE_ATTR(TESTREG, 0666, TEST_REG_show, TEST_REG_store); static DEVICE_ATTR(TESTVAL, 0666, TEST_VAL_show, TEST_VAL_store); #endif static int tw9912_probe(struct i2c_client *client, const struct i2c_device_id *id) { …… #if tw9912_TEST tw9912_TEST_class= class_create(THIS_MODULE, "tw9912Testclass"); tw9912_TEST_dev= device_create(tw9912_TEST_class, NULL, MKDEV(tp_major, 0), NULL, "tw9912Testdev"); device_create_file(tw9912_TEST_dev, &dev_attr_TESTMODE); device_create_file(tw9912_TEST_dev, &dev_attr_TESTFMT); device_create_file(tw9912_TEST_dev, &dev_attr_TESTREG); device_create_file(tw9912_TEST_dev, &dev_attr_TESTVAL); #endif …… } static int tw9912_remove(struct i2c_client *client) { …… #if tw9912_TEST device_remove_file(tw9912_TEST_dev, &dev_attr_TESTMODE); device_remove_file(tw9912_TEST_dev, &dev_attr_TESTFMT); device_remove_file(tw9912_TEST_dev, &dev_attr_TESTREG); device_remove_file(tw9912_TEST_dev, &dev_attr_TESTVAL); device_destroy(tw9912_TEST_dev, MKDEV(tp_major, 0)); class_destroy(tw9912_TEST_class); #endif …… }