lEDS 驱动
一 硬件原理简单介绍
- 三极管 NPN 锗管
- 电流控制电流源
- 三极端CE间的电阻可变,可以把Rce看成一个可调电阻,可调电阻的变量是电源
- IO 管脚拉高之后BF 之间达到一定电流,可变电阻RCE就从无限大降低到大概几百欧姆 高点平灯亮,低点平灯灭
二 LED 管脚的调用,赋值以及配置
- linux 中申请gpio 的头文件 include/linux/gpio.h (linux 中统一的)
- 三星平台的GPIO 配置函数的头文件 arch/arm/plat-samsung/plat/gpio-cfg.h
- 包括三星所有的处理器配置函数
- 三星平台exynose 系列,gpio 配置参数宏定义头文件 arch/arm/mach-exynose/include/mach/gpio.h
- gpio 管脚拉高拉低配置参数等
- 三星4412平台,GPIO 宏定义头文件,已经包含在头文件gpio.h 中 arch/arm/mach-exynose/include/mach/gpio-exynos4.h
- 包括4412 处理器的所有GPIO 的宏定义
- linux gpio 申请函数和赋值函数:
gpio_request
gpio_set_value - 三星平台配置GPIO 的函数
s3c_gpio_cfgpin - GPIO 配置输出模式的宏变量
S3C_GPIO_OUTPUT -
使用 源码
/*三星平台的GPIO头文件*/
/*三星平台exynose 系列头文件*/
#include <plat/gpio_cfg.h>
#include <mach/gpio.h>
/*三星4412平台头文件*/
#include <mach/gpio-exynos4.h>
/*linux 申请头文件*/
#include <linux/gpio.h>
#defind DRIVER_NAME "hello_ctl";
#include <linux/init.h>
#include <linux/module.h>
// 驱动注册的头文件和设备注册的头文件和卸载函数
#include <linux/platform_device.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("xubaipei")
struct platform_driver_hello_driver={
.probe = hello_probe,
.remove = hello_remove,
.suspend = hello_suspend,
.shutdown = hello_shutdown,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
static struct file_operation hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.unlocked_ioctl = hello_ioctl,
};
static struct miscdevice hello_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DRIVER_NAME,
.fops = &hello_ops,
};
static int hello_ioctl (struct file *file ,unsigned int cmd,unsigned long arg)
{
printk("cmd is %d,arg is %d \n",amd,arg);
if(cmd > 1){
printk(KERN_EMERG,"cmd is 0 or 1 \n");
}
if(arg > 1){
printk(KERN_EMERG,"arg is only 1 \n");
}
gpio_set_value(EXYNOS4_GPL2(0),cmd;
return 0;
}
static int hello_release(struct inode *inode,struct file * file)
{
printk(KERN_EMERG,"hello_release");
return 0;
}
static int hello_open(struct inode *inode,struct file * file)
{
printk(KERN_EMERG,"hello_open\n");
return 0;
}
static int hello_probe(struct platform_device *pdv)
{
printk(DRIVER_NAME,"\t initialized \n");
int ret = gpio_request(EXYNOS4_GPL2(0),"LED");
if(ret < 0 ){
printk(DRIVER_NAME,"\t gpio_request EXYNOS4_GPL2(0) failed!\n");
return ret;
}
// 三星平台配置 from to 设置为输出
s3c_gpio_cfpin(EXYNOS4_GPL2(0),S3C_GPIO_OUTPUT);
gpio_set_value(EXYNOS4_GPL2(0),0);
return 0;
}
static int hello_remove(struct platform_device *pdv)
{
return 0;
}
static int hello_suspend(struct platform_device *pdv)
{
return 0;
}
static void hello_shutdown(struct platform_device *pdv)
{
}
static int hello_resume(struct platform_device *pdv)
{
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
static int hello_init(void)
{
int driverstate = -1;
printk(KERN_EMERG "HELLO_WORD init enter~\n");
driverstate = platform_driver_register(&hello_driver);
printk(DRIVER_NAME,"\t driver_state is:%d\n ",driverstate);
return 0;
}
static int hello_exit(void)
{
// 紧急权限打印,超级终端中查看
printk(KERN_EMERG "HELLO_WORD exit enter~\n");
platform_driver_unregister(&hello_driver);
return 0;
}
三 编写简单的应用调用LED管脚并测试
//将内核中的LED 驱动去掉,编译并烧写
char * device_node = "/dev/hello_ctl";
int main(void){
int fd;
if((fd = open(hello_node,O_RDWR|O_NDELAY)) < 0){
printf("APP open %s failed\n",hello_node);
return 0;
}
printf("APP open %s success\n",hello_node);
ioctl(fd,1,1);
sleep(3);
ioctl(fd,0,1);
sleep(3);
ioctl(fd,0,1);
close(fd);
}
修改makefile 中生成文件为led.o 编译运行