网站安装,wordpress.模板,建个网站需要多少钱费用,安徽省建设工程信息网官方学习交流加 个人qq#xff1a; 1126137994个人微信#xff1a; liu1126137994学习交流资源分享qq群#xff1a; 962535112 文章目录一移植驱动程序心得体会二移植LCD驱动程序记录三移植按键输入子系统驱动程序四移植触摸屏驱动程序五移植USB驱动程序今天移植了按键#xff… 学习交流加 个人qq 1126137994个人微信 liu1126137994学习交流资源分享qq群 962535112 文章目录一移植驱动程序心得体会二移植LCD驱动程序记录三移植按键输入子系统驱动程序四移植触摸屏驱动程序五移植USB驱动程序今天移植了按键LEDLCD触摸屏等驱动程序移植驱动程序相对于写驱动程序就简单得多前提是得理解驱动程序。现在来大体总结一下如何移植一个新的驱动程序不是内核自带的驱动程序的大体思路以及流程。一移植驱动程序心得体会
首先呢我们拿到一个新的驱动程序直接先拿过来编译先修改Makefile关于内核的路径编译后一般都会报错因为我们的驱动程序一般不是针对我们这个内核来写的报错了不要怕我们一个一个解决。
错误一般不会太难解决因为驱动程序关于硬件的操作都是完全一样的除非你用的硬件都不一样那样就得换驱动程序了。一般的错误不会涉及修改硬件的操作一般都是因为新的内核里面某些函数的名字变了或者某些函数的定义的形式变了比如以前是一堆函数在定义但是有可能在新内核中这些函数有可能会统一放到一个结构体或者数组中被定义。也有可能这个函数的名字稍微有所变化也或者是头文件的名字变了或者缺少了某些头文件。总的来说大概的错误就是以下几种
错误
解决错误 1.1 头文件不对去掉或改名 1.2 宏不对改名使用新宏 1.3 有些函数没有了改名使用新函数
当我们遇到这样的错误如果不会解决就去参考内核中类似的驱动程序看看别人是怎么实现这些我们错误的功能的记住参考内核源码是一个非常好的办法随着经验的提高这个方法一定要越来越熟悉。然后大概的解决办法就是上面所说的几种。
之前移植过LED驱动程序按键等下面给出一两个移植的过程记录方便以后查阅复习 二移植LCD驱动程序记录
1.直接编译 首先把我们的LCD的驱动程序以及它的Makefile拿到Linux系统编译需要将Makefile里依赖的内核目录的路径修改为当前使用的内核路径然后直接make编译肯定会报错
2.一个个解决错误 首先解决前面的错误前三个错误都说没有相关头文件那么我们就把这三个头文件注释掉
//#include asm/arch/regs-lcd.h
//#include asm/arch/regs-gpio.h
//#include asm/arch/fb.h然后重新编译 这里竟然直接编译通过了说明新的内核关于LCD的变化不大。
3.测试驱动程序 我们把驱动生成的.ko文件拷贝到网络文件系统然后还需要重新配置一下内核去掉它本身自带的LCD的支持来验证我们的新编译的驱动是否可以驱动我们的LCD屏。 配置内核 make menuconfig 依次选择 Device Drivers --- Graphics support --- * Support for frame buffer devices --- M S3C2410 LCD framebuffer support //将这一项前面尖括号的*号改成m这样就去掉了内核自带的LCD驱动重新编译内核。 编译好内核映像后还需要make modules因为我们的LCD驱动程序还依赖于其他三个函数
static struct fb_ops s3c_lcdfb_ops {.owner THIS_MODULE,.fb_setcolreg s3c_lcdfb_setcolreg,.fb_fillrect cfb_fillrect, //下面这三个这三个函数在三个不同的文件我们需要把这三个文件编译为.ko文件加载到内核才能.fb_copyarea cfb_copyarea, //使用LCD驱动程序。.fb_imageblit cfb_imageblit,
};
然后我把内核映像文件以及生成的三个依赖文件cfb*ko拷贝到网络文件系统烧写内核重启开发板 设置环境参数 set bootargs consolettySAC0,115200 root/dev/nfs nfsroot192.168.1.101:/work/nfs_root/fs_mini_mdev_new ip192.168.1.104:192.168.1.101:192.168.1.1:255.255.255.0::eth0:off
保存环境参数 save
烧写内核 nfs 30000000 192.168.1.101:/work/nfs_root/uImage_nolcd; bootm 30000000
启动后先装载cfb*ko文件然后装载lcd.ko文件然后用测试程序测试是否可以操作显示屏。一切正常移植完毕 三移植按键输入子系统驱动程序
1.直接编译 同上lcd驱动的编译先修改Makefile后直接编译
2.改错误 第一个错误没有某个头文件那就直接先注释掉。 第二到五的错误没有定义那个宏通过搜索内核相关类似驱动程序以及类似函数的用法得知应该将下面的结构体
struct pin_desc pins_desc[4] {{IRQ_EINT0, S2, S3C2410_GPF0, KEY_L},{IRQ_EINT2, S3, S3C2410_GPF2, KEY_S},{IRQ_EINT11, S4, S3C2410_GPG3, KEY_ENTER},{IRQ_EINT19, S5, S3C2410_GPG11, KEY_LEFTSHIFT},
};改为
struct pin_desc pins_desc[4] {{IRQ_EINT0, S2, S3C2410_GPF(0), KEY_L},{IRQ_EINT2, S3, S3C2410_GPF(2), KEY_S},{IRQ_EINT11, S4, S3C2410_GPG(3), KEY_ENTER},{IRQ_EINT19, S5, S3C2410_GPG(11), KEY_LEFTSHIFT},
};第六个错误说是下面的IRQT_BOTHEDGE没有定义可能是新内核的这个标志有所变化双边沿触发 request_irq(pins_desc[i].irq, buttons_irq, IRQT_BOTHEDGE, pins_desc[i].name, pins_desc[i]);
搜索内核中request_irq函数的相通用法注意搜索范围可以缩小到/drivers/char目录最终查到可以用下面的代替 request_irq(pins_desc[i].irq, buttons_irq, (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING), pins_desc[i].name, pins_desc[i]);
先解决这上面的几个错误重新编译竟然编译成功了这说明后面没有看的错误其实是由前面的错误导致的。
3.测试驱动程序 我们把文件系统中/etc/inittab修改为加一行tty1::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
tty1::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
然后重启系统 那么开发板显示屏也会出现跟串口显示一样的内容按下按键可以直接操作了。按键驱动程序移植成功。 四移植触摸屏驱动程序
1.直接编译
2.改错误 这次我们的错误比较简单只需要把上面没有的头文件注释掉就行然后重新编译。
3.tslib测试触摸屏 我们用tslib这个应用程序库来校准测试触摸屏。 首先我们按照下面的步骤编译tslib的库 编译 tar xzf tslib-1.4.tar.gz cd tslib ./autogen.sh
mkdir tmp echo “ac_cv_func_malloc_0_nonnullyes” arm-linux.cache ./configure --hostarm-linux --cache-filearm-linux.cache --prefix$(pwd)/tmp make make install
安装tslib库 cd tmp cp * -rf /work/nfs_root/fs_mini_mdev_new/
然后修改添加好的ts库的文件系统的配置文件 修改 /etc/ts.conf第1行(去掉#号和第一个空格)
# module_raw input
改为
module_raw input然后设置环境变量 export TSLIB_TSDEVICE/dev/event1 export TSLIB_CALIBFILE/etc/pointercal export TSLIB_CONFFILE/etc/ts.conf export TSLIB_PLUGINDIR/lib/ts export TSLIB_CONSOLEDEVICEnone export TSLIB_FBDEVICE/dev/fb0
校准 然后输入 ts_calibrate
然后显示如下 selected device is not a touchscreen I understand
看来是遇到了错误,去百度搜索关键字最终得知
原因非常简单tslib中的输入系统和内核input系统版本不匹配当然也有其他原因不过这是最常见的情况先分析一下tslib代码观察这句话在什么情况下被打印就知道了。 将tslib库中c和H文件加入Source Insight跟踪源码发现在 input-raw.c文件中有这么一段代码
static int check_fd(struct tslib_input *i) {struct tsdev *ts i-module.dev;int version;u_int32_t bit;u_int64_t absbit;if (! ((ioctl(ts-fd, EVIOCGVERSION, version) 0) (version EV_VERSION) (ioctl(ts-fd, EVIOCGBIT(0, sizeof(bit) * 8), bit) 0) (bit (1 EV_ABS)) (ioctl(ts-fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), absbit) 0) (absbit (1 ABS_X)) (absbit (1 ABS_Y)) (absbit (1 ABS_PRESSURE)))) {fprintf(stderr, selected device is not a touchscreen I understand\n);return -1; } if (bit (1 EV_SYN))i-using_syn 1;return 0;}其中关键的是version EV_VERSION这个判断语句可以通过注释法测试到底是哪个判断语句导致的打印语句如果这俩不等那么就会打印出selected device is not a touchscreen I understand。
tslib中的input版本号是在交叉编译的时候指定的赋值给version而EV_VERSION是在内核中定义笔者做tslib时用的2.6.39内核这个EV_VERSION定义在include/linux/input.h中值是0x010001而tslib中的version是和交叉编译器相同查看编译器在/work/tools/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include/linux/input.h中值是0x010000这俩明显不相等当然不会满足version EV_VERSION所以导致错误。
解决办法 以下提供两种解决方法 1.将内核源代码里的include/linux/input.h中的
#define EV_VERSION 0x010001改为#define EV_VERSION 0x0100002.将arm交叉编译工具中的头文件库中的
linux/input.h中的#define EV_VERSION 0x010000改为#define EV_VERSION 0x010001然后再编译tslib库我们选用第二种。
然后重新编译tslib库 make clean make make install 然后将库拷贝到网络文件系统。
修改配置文件以及设置环境变量如上同 然后校准输入 ts_calibrate 可以正常校准触摸屏了。 输入ts_test可以在屏幕上进行画圆。
以上操作说明触摸屏驱动程序以及校准程序都可以正常使用。 五移植USB驱动程序
我们之前写过简单的USB鼠标驱动程序实现鼠标左键输出字符“l”右键输出字符“s”中键输出回车。 跟上面的一样直接编译USB驱动程序出现以下错误
去源码中看错误的行出现在 usb_buf usb_buffer_alloc(dev, len, GFP_ATOMIC, usb_buf_phys);。。。。。。。。。。。。usb_buffer_free(dev, len, usb_buf, usb_buf_phys);
错误说没有定义usb_buffer_alloc和usb_buffer_free通过查找找到如下内容
/* Compatible macros while we switch over */
static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size,gfp_t mem_flags, dma_addr_t *dma)
{return usb_alloc_coherent(dev, size, mem_flags, dma);
}static inline void usb_buffer_free(struct usb_device *dev, size_t size,void *addr, dma_addr_t dma)
{return usb_free_coherent(dev, size, addr, dma);
}说明新的内核中没有直接定义usb_buffer_alloc与usb_buffer_free而是让他们返回usb_alloc_coherent和usb_free_coherent所以我们将usb_buffer_alloc与usb_buffer_free分别替换为usb_alloc_coherent和usb_free_coherent应该就可以了
重新编译成功 测试步骤较简单省略
好了经过以上的分析过程自己对这种非内核自带的驱动程序的移植有了一定的理解与掌握相信以后随着经验的丰富会更加熟练
想一起探讨以及获得各种学习资源加我有我博客中写的代码的原稿 qq1126137994 微信liu1126137994 可以共同交流关于嵌入式操作系统C语言C语言数据结构等技术问题。