 
- UID
- 1023229
- 来自
- 中国
|

如何在ZYNQ下写驱动程序????? 首先,要下一个内核源码:使用git命令下载似乎不是很好使,提供个下载地址: https://github.com/Digilent/linux-digilent/releases 解压源码: tar -xvzf linux-digilent-3.6-digilent-13.01.tar.gz 直接make会出现错误 配置内核源码: 在arch/arm/configs/目录下有这个配置文件 digilent_zed_defconfig root@ubuntu:/home/jumn/linux-digilent-3.6-digilent-13.01# make ARCH=arm digilent_zed_defconfig###########################root@ubuntu:/opt/zedboard/kernel# cd linux-digilent-3.6-digilent-13.01root@ubuntu:/opt/zedboard/kernel/linux-digilent-3.6-digilent-13.01# make ARCH=arm digilent_zed_defconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf## configuration written to .config# 编译Linux内核:root@ubuntu:/home/jumn/linux-digilent-3.6-digilent-13.01# make编译过程在arch/arm/boot目录下生成Image和zImage文件 这样以后就可以写驱动了。。。。。。 下面是一个简单的驱动模块例子:#include #include #include #include #include #include #include #include #define DEVICE_NAME "my_gpio_dev" #define MY_GPIO_PHY_ADDR 0x75c80000 //Modify the address to your peripheral #define MY_GPIO_REG_NUM 2 #define MY_GPIO_REG_WIDTH 32 static void __iomem *GPIO_Regs; /****************************************************************GPIO_Regs指针指向映射后的空间,通过ioremap函数,为I/O地址为MY_GPIO_PHY_ADDR的设备分配了MY_GPIO_REG_NUM大小的空间。****************************************************************/ static int my_gpio_open(struct inode * inode , struct file * filp) { return 0; } static int my_gpio_release(struct inode * inode, struct file *filp) { return 0; } static int my_gpio_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { int bytes_read = 0; int i=0; if (filp->f_flags & O_NONBLOCK) return -EAGAIN; if (length>0 && length<=(MY_GPIO_REG_NUM*4)) { for(i=0;i { *(buffer+i)=(char)ioread8(GPIO_Regs+i); } bytes_read=i; } return bytes_read; } //ioctl就是写寄存器操作的封装函数了,使用的方法依旧是iowrite32 static int my_gpio_ioctl(struct file *filp, unsigned int reg_num, unsigned long arg) { if(reg_num>=0 && reg_num { iowrite32(arg, GPIO_Regs+reg_num*4); //通过iowrite32和ioread32就可以简单便捷地实现写入和读 printk("my_gpio: Write 0x%x to 0x%x!\n", arg, GPIO_Regs+reg_num*4); } else { printk("my_gpio:[ERROR] Wrong register number!\n"); return -EINVAL; } return 0; } //在MicroBlaze中,就可以通过of_platform实现读取DeviceTree的compatible信息,来匹配设备和驱动://{ .compatible = "xlnx, my_gpio-1.00.a", } static const struct file_operations my_gpio_fops = //文件系统 { .owner = THIS_MODULE, .open = my_gpio_open, .release = my_gpio_release, .read = my_gpio_read, .unlocked_ioctl = my_gpio_ioctl, }; static struct miscdevice my_gpio_dev = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &my_gpio_fops, }; int __init my_gpio_init(void) { int ret, val; //Map device to the virtual address of kernel GPIO_Regs = ioremap(MY_GPIO_PHY_ADDR, MY_GPIO_REG_NUM); /* Verify it's non-null! */ //GPIO_Regs指针指向映射后的空间,通过ioremap函数,为I/O地址为MY_GPIO_PHY_ADDR的设备分配了MY_GPIO_REG_NUM大小的空间。 printk("my_gpio: Access address to device is:0x%x\n", (unsigned int)GPIO_Regs); if(GPIO_Regs == NULL) { printk("my_gpio:[ERROR] Access address is NULL!\n"); return -EIO; } //misc_register函数对设备进行注册 ret = misc_register(&my_gpio_dev); if (ret) { printk("my_gpio:[ERROR] Misc device register failed\n"); return ret; } printk("my_gpio: Tata! Module init complete\n"); val = ioread32(GPIO_Regs); printk("my_gpio: Read 0x%x from switches, writing to LED...", val); iowrite32(val, GPIO_Regs+4); printk("OK!\n"); return 0; /* Success */ } void __exit my_gpio_exit(void) { iounmap(GPIO_Regs); //release_mem_region(GPIO_Regs, MY_GPIO_REG_NUM*MY_GPIO_REG_WIDTH); misc_deregister(&my_gpio_dev); printk("my_gpio: Module exit\n"); } module_init(my_gpio_init); module_exit(my_gpio_exit); MODULE_AUTHOR("Jumn"); MODULE_ALIAS("my_gpio"); MODULE_DESCRIPTION("ZYNQ my_gpio module"); MODULE_LICENSE("GPL"); 程序在这里:GPIO_Driver.zip 还有MAKEFILE文件# Cross compiler makefile for my_gpio KERN_SRC=/opt/zedboard/kernel/linux-digilent-3.6-digilent-13.01obj-m := my_gpio.o all: make -C $(KERN_SRC) ARCH=arm M=`pwd` modulesclean: make -C $(KERN_SRC) ARCH=arm M=`pwd=` clean其中,对于KERNELDIR:=/opt/zedboard/kernel/linux-digilent-3.6-digilent-13.01如果你认为太麻烦了,可以用 mv 旧文件名 新文件名改为KERN_SRC=/opt/zedboard/kernel/linux-3.6-digilentmake结果为:root@ubuntu:/home/jumn/DRIVER__MODULE/My_GPIO_Driver# lsMakefile Module.symvers my_gpio.ko my_gpio.mod.omodules.order my_gpio.c my_gpio.mod.c my_gpio.o其中,my_gpio.ko 就是我们要的文件。。。。。。 |
|