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

本文介绍了在哈工大的嵌入式设计与实践实验七中,如何开发LED驱动程序。详细步骤包括编写zcyled.c驱动代码,使用Makefile编译生成ko文件,将文件拷贝到SD卡,通过insmod加载驱动,查看设备,创建设备文件,并运行测试程序zcy_test进行验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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即可


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值