uClinux学习笔记之三
其中mydevice,c,254,0就是我们添加的内容,各项的含义分另是: mydevice :设备名
c 254 0
:字符设备 :主设备号 :副设备号
下面来看看我们的测试程序: //----------------------------------hello.c-------------------------------------#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> int main(void) { int fd,num; fd = open("/dev/mydevice",O_RDWR,S_IRUSR | S_IWUSR); if(fd != -1 ) { read(fd,&num,sizeof(int)); printf("The globalvar is %d /n",num); printf("please input the num written to globalvar /n"); scanf("%d",&num);
printk("unable to get major %d for memory devs/n", MEM_MAJOR); memory_devfs_register(); rand_initialize(); #ifdef CONFIG_MYDEVICE mydevice_init(); #endif #ifdef CONFIG_I2C i2c_init_all(); #endif
uClinux学习笔记之三 uClinux驱 动开发初步
uClinux和linux的驱动开发是一致的,只是调试的方式不一样,学 习uClinux的驱动开发也就是学习linux驱动开发的过程。linux驱动的调 试需要至少一台电脑,外加像GDB,KDBG这样的源码级的内核调试工 具,如果装一个虚拟机的话,那么只需要一台电脑即可了,但这样对电 脑的性能有更高的要求。对于像uClinux的驱动调试,则最好是有开发 板,也可以用模拟器。在ARM芯片上的移植是uClinux的一个重要应用。 而最常用的仿真ARM的模拟器有国人开发的开源软件skyeye,不仅可 以仿真ARM内核,并对以ARM作为内核的芯片作了进一步的支持。可以 用skyeye -h 开查看skyeye能仿真的ARM芯片。当然,也可以对skyeye 作一些扩展以满足自己的要求。以下是如何在uClinux添加驱动的过 程。
#include <linux/fs.h> #include <asm/uaccess.h> MODULE_LICENSE("GPL"); #define MAJOR_NUM 254 //主设备号 #define DRIVER_NAME "mydevice" static ssize_t mydevice_read(struct file *, char *, size_t, loff_t*); static ssize_t mydevice_write(struct file *, const char *, size_t, loff_t*); //初始化字符设备驱动的file_operations结构体 struct file_operations mydevice_fops = { .read = mydevice_read, .write = mydevice_write, }; static int global_var = 0; //"mydevice"设备的全局变量
到此,我们已经开始uClinux驱动开发之旅了
参考资料: /1保存设置 用make dep和make命令生成内核镜像和内存文件系统镜像
三、测试我们的驱动
如何与我们的驱动打交道呢,答案当然是建立一个应用程序了,在 《学习笔记之二》中已经详细讲解了如何将一个应用程序加 入uClinux,现在我们就来看看怎样在应用程序里调用我们的驱动。 为了让我们驱动能够为应用程序所用,必须事先创建一个文件结点, 在通用linux 系统中我们可以用mknod命令,建立的结点会出现在/dev 目录下。但是在嵌入式linux系统uClinux中,更好的办法是让uClinux在 启动时为我们做这些事: 打开(uClinux目录)/vendors/GDB/ARMulator-EB目录下的Makefile文 件,作些修改,如下: (注:请根据配置时在Vendor/Product Selection菜单里的选择来选择 vendors下的相应Makefile) DEVICES = / mydevice,c,254,0 / tty,c,5,0 console,c,5,1 cua0,c,5,64 cua1,c,5,65 /
二、将驱动静态编译进uClinux内核
要将一个写好的驱动加入uClinux,需要对配置文件和Makefile作一些修 改,由于我们的这个驱动程序是作为一个字符型驱动程序,我们把
mydevice.c拷到(uClinux目录)/(linux 内核目录)/drivers/char目录下。并 对这个目录下的Config.in和Makefile以及mem.c作一些修改。 1、 修改Config.in: 在comment 'Character devices' 这行底下加上以下一行: bool 'support for mydevice' CONFIG_MYDEVICE y 2、 修改Makefile 在 # # uClinux drivers # 下加上以下内容: obj-$(CONFIG_MYDEVICE) += mydevice.o 3、 修改mem.c mem.c主要是初始化一些以虚拟设备,这些设备通常是以内存作 为基础“设备”的,我们把mydevice的初始化代码加入其中: 在mem.c文件的起始位置加上以下代码: #ifdef CONFIG_MYDEVICE extern int mydevice_init(void); #endif 修改mem.c的chr_dev_init函数 if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
4、
编译mydevice驱动 所有要作的修改就是这么简单,接下来的问题就是怎样将我们的 驱动编译进内核了 (1) 配置内核 运行make menuconfig 进入Kernel/Library/Defaults Selection菜单 选上Customize Kernel Settings 退出并保存设置 在新出现的菜单中进入Character devices子菜单 选上support for mydevice
int mydevice_init(void) { int ret; //注册设备驱动 printk("<0> mydevice_init /n"); ret =
register_chrdev(MAJOR_NUM,DRIVER_NAME,&mydevice_fops); printk("<0> register_chr_dev return %d /n",ret); if (ret < 0) { printk("<0>mydevice register failed /n"); } else { printk("<0>mydevice register success /n"); } return ret; } void mydevice_exit(void) { printk("<0>mydevice_exit!/n"); unregister_chrdev(MAJOR_NUM,DRIVER_NAME); } static ssize_t mydevice_read(struct file *filp,char *buf,size_t len,loff_t *off) { //copy global_var from kernel space to user space
一、编写一个简单的字符驱动程序
//---------------------------------------------mydevice.c-----------------------------------------#include <linux/module.h> #include <linux/init.h>
write(fd,&num,sizeof(int)); read(fd,&num,sizeof(int)); printf("the globalvar is %d /n",num); close(fd); } else { printf("device open failure /n"); } } 这段代码应该很好理解,首先打开设备,然后写入再读出来 配置好后重新编译内核,用skyeye仿真
if(copy_to_user(buf,&global_var,sizeof(int))) { return -EFAULT; } return sizeof(int); } static ssize_t mydevice_write(struct file *filp,const char *buf,size_t len,loff_t *off) { //copy data from user sapce to kernel space if(copy_from_user(&global_var,buf,sizeof(int))) { return -EFAULT; } return sizeof(int); } //----------------------------------------------------------------------------------------------------------------