Android 从上到下写一个例子 驱动加载(四)

本文继上一篇文章继续写代码Android 从上到下写一个例子 HAL(三)_we1less的博客-CSDN博客

驱动代码 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/mm.h>
#include <asm/io.h>
		//GPF2
#define PAD_LEDCON 0x01c208b4
#define PAD_LEDDAT 0x01c208c4

static struct cdev obj;  //define cdev struct
struct class *cls;
static int major = 0;    //主设备号
static int minor = 0;    //次设备号
static int count = 1;    //设备的数量
dev_t dev;    //设备号
int i;
unsigned int *pad_con = NULL;
unsigned int *pad_dat = NULL;

char buf[] = {"hello world!"};

static int led_open(struct inode *inode, struct file *filp)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

	return 0;
}
static ssize_t led_read(struct file *filp, char __user *buffer, size_t size, loff_t *offset)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
	return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buffer, size_t size, loff_t *offset)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
	return 0;
}

static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

	switch(arg){
		case 1: 
			writel((readl(pad_dat)&(~(1<<2))),pad_dat);
			break;
		case 0:
			writel((readl(pad_dat)|(1<<2)),pad_dat);
			break;
		default :break;
	}

	return 0;
}


static struct file_operations fops = {
	.owner          = THIS_MODULE,
	.open           = led_open,
	.read           = led_read,
	.write          = led_write,
	.unlocked_ioctl = led_ioctl,
};

static int __init kmmap_init(void)
{

	int ret;
	struct device *device;

	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
	
	cdev_init(&obj,&fops);
	
	ret = alloc_chrdev_region(&dev,minor,count,"myled");
	if(ret < 0){                     //proc/device设备名
		printk("register device num fail.\n");
		goto ERROR1;
	}

	major = MAJOR(dev);

	ret = cdev_add(&obj,dev,count);
	if(ret < 0){
		printk("register to kernel fail.\n");
		goto ERROR2;
	}
	
	cls = class_create(THIS_MODULE,"myled"); //sys/class下的名字
	if (IS_ERR(cls)) {
		ret = PTR_ERR(cls);
		goto ERROR2;
	}
	
	for(i=minor; i<count; i++){
		device = device_create(cls,NULL,MKDEV(major,i),NULL,\
				"%s%d","myled",i);
		if (IS_ERR(device)) {
			ret = PTR_ERR(device);
			goto ERROR3;
		}        
	}

	pad_con = (unsigned int *)ioremap(PAD_LEDCON,4);
	pad_dat = (unsigned int *)ioremap(PAD_LEDDAT,4);
	
	writel(((readl(pad_con)&(~(0xf<<8)))|(1<<8)),pad_con);
	writel((readl(pad_dat)|(1<<2)),pad_dat);

	return 0;

ERROR3:
	for(i--; i >= minor; i--){
		device_destroy(cls, MKDEV(major, i));
	}

	class_destroy(cls);

ERROR2:
	unregister_chrdev_region(dev,count);

ERROR1:
	cdev_del(&obj);
	return ret;
}

static void __exit kmmap_exit(void)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

	for(i = minor; i < count+minor; i++){
		device_destroy(cls, MKDEV(major, i));
	} 

	class_destroy(cls);

	unregister_chrdev_region(dev,count);

	cdev_del(&obj);
}

module_init(kmmap_init);
module_exit(kmmap_exit);
MODULE_LICENSE("GPL");

makefile

export ARCH=arm
export CROSS_COMPILE:=arm-linux-gnueabi-
KERNELDIR:=/home/linux/fspad-733-6.0/lichee/linux-3.4/
PWD:=$(shell pwd)
all:
	make -C $(KERNELDIR) M=$(PWD) modules
clean:
	make -C $(KERNELDIR) M=$(PWD) clean

obj-m:=fspad_led.o

这就可以生成一个ko文件,可以用insmod将驱动挂载上这里将fspad_led.ko文件放置目录

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值