单片机
返回首页

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

2025-02-14 来源:cnblogs

开发板:TQ210


OS:Android 4.0.3


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


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

LED驱动源码


led_unders.c


#include   //包含miscdevice misc_register...

#include //包含__init __exit...

#include   //包含file_operations...

#include //包含EINVAL..

#include //包含S5PV210_GPC0() ...

#include //包含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 {

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

#include    //文件操作


#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/offn');

}

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

进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章