您的位置:首页 > 移动开发 > Android开发

TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(驱动篇)

2013-06-23 23:30 495 查看
开发板:TQ210

OS:Android 4.0.3

以下所有内容都是在TQ210开发板上实现,并且很多内容也是天嵌公司提供,我将一些内容进行了删减、替换,然后加入了一些自己的理解,同时也是记录自己学习的旅程。

废话不多说 先看硬件电路图 很简单 通过NPN三极管控制LED的阴极 NPN三极管的基极给高电平 则三级管导通 则LED等点亮 反之则熄灭



LED驱动源码

led_unders.c

#include <linux/miscdevice.h>  //包含miscdevice misc_register...
#include <linux/init.h> //包含__init __exit...
#include <linux/fs.h>  //包含file_operations...
#include <linux/err.h> //包含EINVAL..
#include <mach/gpio.h> //包含S5PV210_GPC0() ...
#include <plat/gpio-cfg.h> //包含S3C_GPIO_SFN() s3c_gpio_cfgpin() gpio_direction_output()..

#define DEVICE_NAME 	"led_unders"  //设备名
#define GPIO_CTIOL_ON 1    //控制LED亮
#define GPIO_CTIOL_OFF 0  //控制LED 灭

static unsigned int gpio_table[]=  //引用I/O引脚
{
S5PV210_GPC0(3), //开发板的手册上是GPC1 ,是错的
S5PV210_GPC0(4),
};

static unsigned int gpio_cfg_table[]= //设置IO为输出
{
S3C_GPIO_SFN(1), //设置引脚为输出
S3C_GPIO_SFN(1),
};

static int gpio_led_under_open(struct inode *inode,struct file *file) //打开led_unders设备
{
int ret=0,i;
for(i=0;i<sizeof(gpio_table)/sizeof(gpio_table[0]);i++)
{
s3c_gpio_cfgpin(gpio_table[i], gpio_cfg_table[i]); //设置引脚为输出
ret=gpio_direction_output(gpio_table[i],GPIO_CTIOL_OFF); //设置引脚为0
}
if(ret==0) printk("led_open success.\n");
else {ret=-1; printk("led_open failed.\n");}
return ret;
}

static int gpio_led_under_close(struct inode *inode,struct file *file)
{
printk(KERN_INFO "led_close success.\n");
return 0;
}

static long gpio_led_under_ioctl(struct file *file,unsigned int cmd,unsigned long arg) //控制哪个led灯亮或者灭
{
int ret=0;
printk(KERN_INFO "led ioctl.\n");
arg=arg-1;
if(arg>sizeof(gpio_table)/sizeof(gpio_table[0])) return -EINVAL; //判断传递的参数是否合法
switch(cmd)
{
case GPIO_CTIOL_ON:
gpio_direction_output(gpio_table[arg],GPIO_CTIOL_ON); //点亮LED
break;
case GPIO_CTIOL_OFF:
gpio_direction_output(gpio_table[arg],GPIO_CTIOL_OFF); //熄灭LED
break;
default:
ret=-1;
printk(KERN_INFO "led ioctl error");
}
return ret;
}

static struct file_operations dev_fops=
{
.owner=THIS_MODULE,
.unlocked_ioctl=gpio_led_under_ioctl,
.open=gpio_led_under_open,
.release=gpio_led_under_close,
};

static struct miscdevice misc_led=
{ //led混杂设备结构体定义
.minor=MISC_DYNAMIC_MINOR,  //动态分配次设备号
.name=DEVICE_NAME,    //设备名称
.fops=&dev_fops,    //设备操作结构体
};

static int __init led_init()  //led初始化
{
int ret;
ret=misc_register(&misc_led); //注册混杂设备成功注册返回0
if(ret==0) printk(KERN_INFO "led_init driver success.\n");
else { printk(KERN_INFO "led_init driver failed.\n"); ret=-1;}
return ret;
}

static void __exit led_exit() //led卸载
{
int ret=misc_deregister(&misc_led); //卸载混杂设备 ,成功返回0
if(ret==0) printk(KERN_INFO "led_exit driver success.\n");
else printk(KERN_INFO "led_exit driver failed.\n");
}

//模块入口与出口
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL"); //gpl许可


Makefile文件

obj-m	:=led_unders.o

KERNELDIR	:=~/java/Kernel_3.0.8_TQ210_for_Android_v1.0/
PWD	:=$(shell pwd)

build:kernel_module
kernel_module:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean


Makefile的详细编写 参看GUN的Makefile手册 给一个简单实例连接 http://www.embedu.org/Column/Column310.htm
该驱动模块采用混杂设备来表示led设备,通过使用misc_register函数告诉内核misc_led设备所拥有的功能,

对于混杂设备我看了看源码,个人理解misc_register主要做了三件事,

1.通过MISC_DYNAMIC_MINOR这个标志获取到次设备号

2.通过class_device_create创建/dev/led_unders设备文件

3.通过list_add将misc_led添加到混杂设备链表

测试文件

led_under_driver_test.c

#include <stdio.h>
#include <fcntl.h>   //文件操作

#define DEVICE_NAME "/dev/led_unders"  //设备名称

#define GPIO_IOCTL_ON 1   //打开led
#define GPIO_IOCTL_OFF 0  //关闭led

#define LED1 1
#define LED2 2

/*
usage: led1/led2 on/off
*/

int main(int argc,char **argv)
{
int fd,ison=0,isnumber=0;
fd=open(DEVICE_NAME,O_RDWR); //以可读可写的方式打开设备文件
if(fd<0)  //判断是否成功打开文件
{
printf("open %s failed.\n",DEVICE_NAME);
return 0;
}
if(argc!=3)   //判断参数是否合法
{
printf("usage:\n");
printf("led1/led2 on/off\n");
}
if(strcmp(argv[2],"on")==0) ison=GPIO_IOCTL_ON;  //判断是打开还是关闭LED
else ison=GPIO_IOCTL_OFF;
if(strcmp(argv[1],"led1")==0) isnumber=LED1;  //判断是操作哪一个LED
else isnumber=LED2;
if(ison!=0&&isnumber!=0) ioctl(fd,ison,isnumber);  //操作led
return 0;
}


通过输入的参数来控哪个led灯的亮或者灭

编译文件 Android.mk

LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS :=eng
LOCAL_SRC_FILES :=led_under_driver_test.c
LOCAL_MODULE :=led_unders
LOCAL_MODULE_PATH :=$(LOCAL_PATH)
include $(BUILD_EXECUTABLE)


对于android编译系统 可以查看官网 http://www.kandroid.org/online-pdk/guide/build_system.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐