字符设备驱动基础中-作业

Led驱动编程实验

1. 查阅芯片手册找到相关引脚

    led---  GPX2_7 ---  GPX2CON ==0x11000C40
                        GPX2DAT ==0x11000C440x11000C40映射成虚拟地址
    对虚拟地址中到[32:28] = 0x1

2.驱动程序代码

代码展示:

//------------------chr_drv.c------------------
//驱动程序代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <asm/io.h>

#define GPX2CON_ADDR 0x11000c40
#define GPX2CON_SIZE 8
 
unsigned int major_id = 502;
const char major_name[] = "test";
struct class* pmyclass = NULL;
struct device* pmydevice =NULL;
volatile unsigned int* GPX2CON;
volatile unsigned int* GPX2DAT;

int chr_drv_open (struct inode *inode, struct file *filp)
{
	printk("------------%s----------\n",__FUNCTION__);
	return 0;
}
ssize_t chr_drv_read (struct file * filp, char __user *buf, size_t count, loff_t *fpos)
{
	int buf_read = 666;
	int ret;
	
	ret = copy_to_user(buf,&buf_read,count);
	if(ret == 0)
	{
		printk("------------%s----------\n",__FUNCTION__);
	}
	else 
	{
		printk("KERN:Error to read\n");
		return -EFAULT;
	}
	return 0;
}

ssize_t chr_drv_write (struct file *filp, const char __user *buf, size_t count, loff_t *fpos)
{
	int buf_write = 0;
	int ret; 
	
	ret = copy_from_user(&buf_write,buf,count);

	if(ret == 0)
	{
		printk("__KERN__:%d\n",buf_write);
		if(buf_write == 0){
			*GPX2DAT &= ~(0x1<<7);								
		}
		else{
			*GPX2DAT |= (0x1<<7);
		}
	}
	else 
	{
		printk("KERN:Error to read\n");
		return -EFAULT;
	}
	return 0;
}

int chr_drv_close (struct inode *inode, struct file *filp)
{
	printk("------------%s----------\n",__FUNCTION__);
	return 0;
}

const struct file_operations major_fops = {
		.open = chr_drv_open,
		.read = chr_drv_read,
		.write = chr_drv_write,
		.release = chr_drv_close,
	};

static int __init my_chrdrv_init(void)
{
	//一般都是申请资源
	//申请设备号
	int ret = register_chrdev(major_id, major_name, &major_fops);
	if (ret == 0){
		printk("register ok\n");
		}
	else{
		printk("register failed");
		return -EFAULT;
	}

	pmyclass = class_create(THIS_MODULE,"TEST1");
	pmydevice = device_create(pmyclass,NULL,MKDEV(502, 0),NULL,"mychr0");

	GPX2CON = (unsigned int*)ioremap(GPX2CON_ADDR,GPX2CON_SIZE) ;
	GPX2DAT = GPX2CON + 1;
	*GPX2CON &= ~(0xf << 28);
	*GPX2CON |= (0x1 << 28);
	
	return 0;
}

static void __exit my_chrdrv_exit(void)
{
	//一般都是释放资源
	//释放设备号资源
	unregister_chrdev(major_id, major_name);	
	device_destroy(pmyclass,MKDEV(502, 0));
	class_destroy(pmyclass);
	iounmap(GPX2CON);
}

MODULE_LICENSE("GPL");

module_init(my_chrdrv_init);
module_exit(my_chrdrv_exit);

3.APP 代码

//--------------drvtest.c-------------------
//APP 代码 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv)
{
	int fd;
	int buf = 233;
	
	fd = open("/dev/mychr0",O_RDWR);
	
	if(fd < 0)
	{
		perror("open");
		exit(1);
	}
	
	while(1){
		buf = 0;
		write(fd, &buf, 4);
		sleep(1);
		
		buf = 1;
		write(fd, &buf, 4);
		sleep(1);
	}
		
	read(fd, &buf, 4);
		
	close(fd);

	return 0;
}

4.Makefile代码

Makefile代码

ROOTFS_DIR = /home/linux/Level11

APP_NAME = drvtest

CROSS_COMPILE = arm-none-linux-gnueabi-
CC = $(CROSS_COMPILE)gcc

ifeq ($(KERNELRELEASE), )

KERNEL_DIR = /home/linux/Level10/day6/linux-5.4.79
CUR_DIR = $(shell pwd)

all :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
		$(CC) $(APP_NAME).c -o $(APP_NAME)

clean :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean

install:
		cp -raf  *.ko  $(APP_NAME)   $(ROOTFS_DIR)/drv_module
		
else
obj-m += chr_drv.o

endif

5效果展示:

[root@farsight ]# insmod chr_drv.ko
[  287.317368] register ok
[root@farsight ]# ./drvtest
[  291.632356] ------------chr_drv_open----------
[  291.635357] __KERN__:0
[  292.638023] __KERN__:1
[  293.639042] __KERN__:0
[  294.640062] __KERN__:1
[  295.641081] __KERN__:0
[  296.642106] __KERN__:1
[  297.643127] __KERN__:0
[  298.644145] __KERN__:1
[  299.645167] __KERN__:0
[  300.646187] __KERN__:1
[  301.647281] __KERN__:0
[  302.648296] __KERN__:1
[  302.732408] ------------chr_drv_close----------

开发板上灯一闪一灭。