您的位置:首页 > 其它

哈工大嵌入式设计与实践实验七 驱动程序开发

2013-04-09 10:50 323 查看
1.完成一个核心板上的LED驱动程序

驱动程序代码zcyled.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/cdev.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <plat/gpio.h>
#include <linux/moduleparam.h>

MODULE_LICENSE ("GPL");

#define GPIO6_OE  0x49058034
#define GPIO6_DATAIN  0x49058038
#define GPGO6_DATAOUT  0x4905803C

volatile unsigned long virt , phys;
static volatile unsigned long *GPGCON;
static volatile unsigned long *GPGDAT;
static volatile unsigned long *GPGUP;

static int zcy_open (struct inode *inode, struct file *file)
{
*GPGCON &= ~(1<<26);//CORE_LED1
*GPGCON &= ~(1<<3);//CORE_LED2
*GPGCON &= ~(1<<4);//CORE_LED3
*GPGUP &= ~(1<<26);//light LED1
*GPGUP &= ~(1<<3);//light LED2
*GPGUP &= ~(1<<4);//light LED3

printk("Device Opened.\n");
return 0;
}

static int zcy_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case 0: *GPGUP |= (1<<26);//unlight LED1
*GPGUP |= (1<<3);//unlight LED2
*GPGUP |= (1<<4);//unlight LED3
break;
case 1: *GPGUP |= (1<<26);//unlight LED1
*GPGUP |= (1<<3);//unlight LED2
*GPGUP &=~ (1<<4);//light LED3
break;
case 2: *GPGUP |= (1<<26);//unlight LED1
*GPGUP &=~ (1<<3);//light LED2
*GPGUP |= (1<<4);//unlight LED3
break;
case 3: *GPGUP |= (1<<26);//unlight LED1
*GPGUP &=~ (1<<3);//light LED2
*GPGUP &=~ (1<<4);//light LED3
break;
case 4: *GPGUP &=~ (1<<26);//light LED1
*GPGUP |= (1<<3);//unlight LED2
*GPGUP |= (1<<4);//unlight LED3
break;
case 5: *GPGUP &=~ (1<<26);//light LED1
*GPGUP |= (1<<3);//unlight LED2
*GPGUP &=~ (1<<4);//light LED3
break;
case 6: *GPGUP &=~ (1<<26);//light LED1
*GPGUP &=~ (1<<3);//light LED2
*GPGUP |= (1<<4);//unlight LED3
break;
case 7: *GPGUP &=~ (1<<26);//unlight LED1
*GPGUP &=~ (1<<3);//unlight LED2
*GPGUP &=~ (1<<4);//light LED3
break;
default:
;

}

return 0;
}

struct file_operations zcy_fops =
{
.owner = THIS_MODULE,
.open  = zcy_open,
.ioctl = zcy_ioctl,
};

int major;
static int __init zcy_init (void)
{
virt= (unsigned long)ioremap(GPIO6_OE, 16);
major = register_chrdev(0,"zcy",&zcy_fops);
printk("[KERNEL_INFO]:major=%d\n",major);
GPGCON =(unsigned long *)(virt + 0x00);
GPGDAT =(unsigned long *)(virt + 0x04);
GPGUP =(unsigned long *)(virt + 0x08);
return 0;
}

static void __exit zcy_exit (void)
{
iounmap(virt);
unregister_chrdev(major,"zcy");
printk("[KERNEL_INFO]:exit ok.\n");
return 0;

}

module_init (zcy_init);
module_exit (zcy_exit);

在ubuntu虚拟机下执行make 编译生成zcyled.ko文件 拷贝到SD卡的LABEL2目录中

Makefile

KERNELDIR :=/A8RP/source/linux-omap3-a8rp/

PWD := $(shell pwd)
default:
$(MAKE)  -C $(KERNELDIR) M=$(PWD) modules
clean:
$(RM) -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
$(RM) -rf Module.markers  Module.symvers  modules.order tags

obj-m := zcyled.o


测试文件zcy_test.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
int fd,i;
//unsigned int num;

fd = open("/dev/zcy", O_RDWR);

if ( fd < 0)
{
printf("open devices error\n");
return -1;
}

/*ioctl(fd,0);
printf("command:0\n");
ioctl(fd,1);
printf("command:1\n");
ioctl(fd,3);
printf("command:3\n");*/

ioctl(fd,0);

printf("command:0\n");
sleep(3);

ioctl(fd,1);
printf("command:1\n");

close(fd);
return 0;
}


测试文件在虚拟机下执行命令

arm-linux-gcc -o zcy_test zcy_test.c

生成可执行文件zcy_test拷贝到SD卡的LABEL2中

最后SD卡启动系统

1.加载驱动 insmod zcyled.ko

2.查看新加入的设备 cat /proc/devices

3.手动创建一个新的设备文件以便测试文件找到文件标识符fd

mknod /dev/zcy c 249 0

注意:保证 /dev/zcy 与测试文件中获得fd的路径一致

4.运行可执行文件zcy_test 即可

./zcy_test

结语:最后不要忘了在生成驱动前修改系统的Makefile即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: