Android 从上到下写一个例子 驱动加载
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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文件放置目录
以上是关于Android 从上到下写一个例子 驱动加载的主要内容,如果未能解决你的问题,请参考以下文章