文档章节

x6818开发板安卓驱动开发(1)-LED-driver

redstone5
 redstone5
发布于 2017/05/08 14:36
字数 762
阅读 35
收藏 0

通过sysfs,即kobject实现LED灯的控制。
x6818_led_drv.c:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#include <mach/platform.h>
#include <mach/soc.h>

#define X6818_LEDS_MODULE_NAME	"x6818-leds"

/*
* X6818 LED:
* LED1 -> D22 -> GPIO_B26
* LED2 -> D23 -> GPIOC11
* LED3 -> D24 -> GPIOC7
* LED4 -> D25 -> GPIOC12
* 4个LED为供阳极LED,相关的GPIO电压拉低灯亮,拉高灯灭
*/
#define X6818_LEDS_NUMBER	4
#define X6818_LED1_GPIO		(PAD_GPIO_B + 26)
#define X6818_LED2_GPIO		(PAD_GPIO_C + 11)
#define X6818_LED3_GPIO		(PAD_GPIO_C + 7)
#define X6818_LED4_GPIO		(PAD_GPIO_C + 12)

#define X6818_LED_ON		0
#define X6818_LED_OFF		1

typedef struct __led{
	char * name;
	unsigned gpio;
	int status;
}led;
static led x6818_leds[X6818_LEDS_NUMBER] ={
	{ .name = "led1", .gpio = X6818_LED1_GPIO, .status = 0},
	{ .name = "led2", .gpio = X6818_LED2_GPIO, .status = 0},
	{ .name = "led3", .gpio = X6818_LED3_GPIO, .status = 0},
	{ .name = "led4", .gpio = X6818_LED4_GPIO, .status = 0},
}; 


static void __x6818_leds_probe(void)       //初始化LED对应GPIO口
{
	int ret = 0;
	int i;
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		nxp_soc_gpio_set_io_func(x6818_leds[i].gpio, NX_GPIO_PADFUNC_1); //gpio mode
		nxp_soc_gpio_set_io_dir(x6818_leds[i].gpio, 1);		 //output mode
		nxp_soc_gpio_set_io_pull_sel(x6818_leds[i].gpio, 1); // pull up select
		nxp_soc_gpio_set_io_pull_enb(x6818_leds[i].gpio, 1); // pull up  enable
		nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_OFF); //默认led关
		x6818_leds[i].status = 0;
	}

}
static void __x6818_leds_remove(void)    
{

}
static ssize_t x6818_leds_read(struct device *dev, struct device_attribute *attr, char *buf)
{
	int i;
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		if(!strcmp(attr->attr.name, x6818_leds[i].name)){
			if(x6818_leds[i].status)
				return strlcpy(buf, "1\n", 3);
			else
				return strlcpy(buf, "0\n", 3);
					
		}

	}
	return strlcpy(buf, "\n", 3);
}
static ssize_t x6818_leds_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	int i;
	unsigned long on = simple_strtoul(buf, NULL, 10);//convert a string to an unsigned long 从应用读取需要写入的数据 10进制
	for(i = 0; i < X6818_LEDS_NUMBER; i++){
		if(!strcmp(attr->attr.name, x6818_leds[i].name)){
			if(on){
				nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_ON); //默认led关
				x6818_leds[i].status = 1;
			}
			else{
				nxp_soc_gpio_set_out_value(x6818_leds[i].gpio,X6818_LED_OFF); //默认led关
				x6818_leds[i].status = 0;
			}
			break;
		}
	}	
	return count;
}



//kobject目录下的四个文件对应的属性,读写函数
static DEVICE_ATTR(led1, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led2, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led3, 0666, x6818_leds_read, x6818_leds_write);
static DEVICE_ATTR(led4, 0666, x6818_leds_read, x6818_leds_write);
static struct attribute * x6818_leds_sysfs_entries[] = {		  //对应kobject目录下的四个文件
		 &dev_attr_led1.attr,
		 &dev_attr_led2.attr,
		 &dev_attr_led3.attr,
		 &dev_attr_led4.attr,
		 NULL,
};

static struct attribute_group x6818_leds_attr_group = {
         .name   = NULL,
         .attrs  = x6818_leds_sysfs_entries,   //指定注册的kobject对应的文件属性接入点
};
static int x6818_leds_probe(struct platform_device *pdev)
{
         __x6818_leds_probe();                                       //初始化LED对应GPIO口
         return sysfs_create_group(&pdev->dev.kobj, &x6818_leds_attr_group);//注册kobject
}
static int x6818_leds_remove(struct platform_device *pdev)
{
         __x6818_leds_remove();                                     //释放GPIO
         sysfs_remove_group(&pdev->dev.kobj, &x6818_leds_attr_group);//注销kobject
         return 0;
}


static struct platform_driver x6818_leds_driver = {
	.probe		= x6818_leds_probe,
	.remove 	= x6818_leds_remove,
	.driver 	= {
		.name	= X6818_LEDS_MODULE_NAME,
	},
};
		
static struct platform_device x6818_leds_device = {
	.name      = X6818_LEDS_MODULE_NAME,
	.id        = -1,
};		
	
static int __devinit x6818_leds_init(void)
{
	int ret;

	printk("x6818 leds driver\r\n");

	ret = platform_device_register(&x6818_leds_device);
	if(ret)
		printk("failed to register x6818 leds device\n");

	ret = platform_driver_register(&x6818_leds_driver);
	if(ret)
		printk("failed to register x6818 leds driver\n");

	return ret;
}

static void x6818_leds_exit(void)
{
	platform_device_unregister(&x6818_leds_device);
	platform_driver_unregister(&x6818_leds_driver);
}

module_init(x6818_leds_init);
module_exit(x6818_leds_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("x6818 leds driver");

Makefile:

KERN_DIR = /home/wzs/Android/x6818/kernel/
all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= x6818_led_drv.o

通过adb上传驱动文件到安卓文件系统:

adb push ./x6818_led_drv.ko /data/local/tmp

内核加载驱动:

insmod x6818_led_drv.ko

相关目录下将自动产生设备节点:

测试:

开启led1:

echo 1 > /sys/devices/platform/x6818-leds/led1

关闭led1:

echo 0 > /sys/devices/platform/x6818-leds/led1

读取led1当前状态:

cat /sys/devices/platform/x6818-leds/led1

其余led类似。

© 著作权归作者所有

共有 人打赏支持
redstone5
粉丝 2
博文 49
码字总数 37304
作品 0
玉溪
简单分析下Android 内核

通过和标准的Linux 2.6.25 Kernel的对比,我们可以发现,其主要增加了以下的内容: 1.增加了yaffs2 FLASH文件系统,相应增加的目录为: kernel/fs/yaffs2 实际上,Android包经过编译后生成的syste...

sprinl
2011/07/03
0
0
android之wifi移植全过程(二)

六、android的wifi移植。 现在底层的都通了,接下来就把wifi移植到android系统中。 1.提供固件firmware给驱动。 WIFI需要的firmware要复制到/etc/firmware。 或者复制到WIFI驱动指定的位置,...

sflfqx
2013/09/06
0
0
android之wifi移植全过程(一)

硬件环境 WIFI模块:Marvell8686 SDIO WIFI 开发板:S5PC100 软件环境 Linux 2.6.29 Android 2.1 项目目标:实现WIFI上网功能、并对WIFI休眠进行改善。 项目开发流程: 硬件分析:对Marvell...

sflfqx
2013/09/06
0
0
Android实践:做一个可视频交互的智能小车

本文的三位作者正阳、海洋、阿力,是来自不同公司的工程师,在Agora RTC Hack 上海站编程马拉松上,开发了一款可实时视频远程看房的智能小车。本文将从方案设计、硬件开发、Android 端开发、...

Agora
08/01
0
0
android-- A10开发板--Tslib 移植心得体会

tslib,其实从他的名字就可以看出它的,它是touchscreen的lib,其实这样还不够具体,其实它开始确实是为了touchscreen的鼠标驱动而发展起来的,且只是一个中间处理库,即将原始数据进行调整,...

雨焰
2012/09/27
0
2

没有更多内容

加载失败,请刷新页面

加载更多

Linux命令备忘录: jobs 显示Linux中的任务列表及任务状态命令

jobs命令用于显示Linux中的任务列表及任务状态,包括后台运行的任务。该命令可以显示任务号及其对应的进程号。其中,任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的...

开元中国2015
53分钟前
1
0
springboot Whitelabel Error Page(Not Found)解决方案

当出现上图图的错误时注意 报错信息 There was an unexpected error (type=Not Found, status=404). Not Found代表未访问到资源 解决方案:比较访问路径和代码的路径有没有写错 正确的访问路...

斩神魂
53分钟前
2
0
记一次hbase master停止服务的原因以及恢复

在Hdfs空间不足的情况下,拒绝写入,hbase会down掉。如果hdfs空间没有清理的情况下,重新启动hbase,会报splitlog失败,原因是wal日志重写过程中会写hdfs,写不进去导致的。重启不成功。 解决...

PageYi
57分钟前
1
0
如何从平面设计转行到UI设计?

时代的变迁,科技的进步,工具的发展,薪资的差距,促使许多人转行的原因,但平面与界面两者之间有着哪些的差异呢?如果,想要转行又该具备哪些条件呢? 平面、界面设计之间的差异性 平面设计...

mo311
今天
4
0
线程池整理

一般在生产环境中,我们都不会直接new一个Thread,然后再去start(),因为这么做会不断频繁的创建线程,销毁线程,过大的线程会耗尽CPU和内存资源,大量的垃圾回收,也会给GC带来压力,延长GC停顿时间...

算法之名
今天
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部