文档章节

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

redstone5
 redstone5
发布于 2017/05/08 14:36
字数 762
阅读 23
收藏 0
点赞 0
评论 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
博文 22
码字总数 37304
作品 0
玉溪
Android Audio BSP工程师 需要清楚的基本知识点

原址 【前言】 这是我根据自己的工作经验所总结,有一定代表性,但可能不齐全。这只是个提纲。 【知识点】 按照在操作系统中的层次划分,从上到下依次为: 1、Android系统分层模型。知道 AP...

u010164190 ⋅ 05/30 ⋅ 0

介绍TTC CC2541 SDK 蓝牙4.0开发套件

简介 TTC CC2541 SDK 是由我司针对TI的CC2541芯片开发提供的快速开发工具。旨在让开发人员不再需要将大量精力放在蓝牙调试方面,只需将精力放在对CC2541芯片功能的应用开发上。 TTC CC2541 S...

昇润科技 ⋅ 05/21 ⋅ 0

用51单片机和esp8266实现通过手机app控制单片机小灯

这篇文章我在51黑电子论坛也发过,在这里再发一次。是自己在比赛的时候要使用这个esp8266模块,去查资料了解后,自己摸出来的方法。 用51单片机和esp8266实现通过手机app控制单片机小灯,也可...

brianna20022012 ⋅ 04/16 ⋅ 0

AndroidThings之基础一 基本概念

转载自:https://blog.csdn.net/weixin41636248/article/details/79069994 Android Things是什么 一句话说,AndroidThings就是让开发者可以使用Android开发工具开发嵌入式设备。 If you can...

qq_28831197 ⋅ 05/09 ⋅ 0

迅为iTOP-4412 开发板裸机开发环境

本文转自迅为:http://www.topeetboard.com 1.安装 DNW 驱动 DNW 动在”tools/USB 动/dnw_driver“目录下面,我们提供了 xp 系统, win732 位,win764 位三种系统下面的驱动。下面我们以 wi...

歌之王子殿下 ⋅ 2017/05/25 ⋅ 0

迅为iTOP-4412嵌入式开发板实现中断驱动例程

本文转自迅为:www.topeetboard.com 大家好,今天我们来学习一下 linux 中断处理驱动的编写,本节我们实现的功能是通过开发板上的按键来控制 led 发光二极管,在之前的章节我们学习了 led 驱...

topeet ⋅ 2016/02/23 ⋅ 0

AndroidThings之基础二 设计理念

转载自:https://blog.csdn.net/tangxiaoyin/article/details/75273491 (PS:目前AndroidThings已经走向消费级别,发布正式版本1.0版,开发板推荐树莓派3B+) 前言 2012 年 6 月,由 IoT-GSI(...

qq_28831197 ⋅ 05/09 ⋅ 0

RK3288开发板PopMetal上的GPIO驱动实例

楼主在这边给大家介绍下如何使用PopMetal的GPIO。先讲过程,再讲原理吧, 该驱动需要涉及到的知识点:1,DTS设备树的作用,2,platform虚拟总线驱动的编写。 第一步,添加DTS节点 在/kernel...

穿prada的008 ⋅ 2015/08/03 ⋅ 0

坐标上海或深圳:OPPO诚聘Linux内核和Android系统工程师

OPPO 是更多年轻人选择的拍照手机品牌。 十年来,OPPO 专注于手机拍照领域的技术创新,开创了手机自拍美颜时代,先后首发了前置 500 万像素和 1600 万像素的拍照手机,创造性地推出了全球首个...

jus3ve ⋅ 05/14 ⋅ 0

挂接在/proc上的对LED灯控制的驱动

通过一天的学习总结一下挂接在/proc上的对LED灯控制的驱动开发,代码和过程 1.驱动代码 #include include include include include include include MODULE_LICENSE("Dual...

长平狐 ⋅ 2012/08/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

VS2015配置并运行汇编(一步一步照图做)【vs2017的链接在最后】

x64: TITLE Add and Subtract (AddSub.asm) ; This program adds and subtracts 32-bit integers. ; Last update: 2/1/02 ;.MODEL flat,stdcall x64 not su......

simpower ⋅ 昨天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 昨天 ⋅ 0

Java桌球小游戏

其实算不上一个游戏,就是两张图片,不停的重画,改变ball图片的位置。一个左右直线碰撞的,一个有角度碰撞的。 左右直线碰撞 package com.bjsxt.test;import javax.swing.*;import j...

森林之下 ⋅ 昨天 ⋅ 0

你真的明白RPC 吗?一起来探究 RPC 的实质

你真的明白RPC 吗?一起来探究 RPC 的实质 不论你是科班出身还是半路转行,这么优秀的你一定上过小学语文,那么对扩句和缩句你一定不陌生。缩句就是去除各种修饰提炼出一句话的核心,而不失基...

AI9o後 ⋅ 昨天 ⋅ 0

z-index设置失效?

今天碰到了一个问题,就是在给li设置提示框的时候,有用到遮罩效果,本来想把对应的出现在最顶层,可是不管将li设置的z-index值设为多大,li都没有出现在遮罩层之上。 我在网上查了z-index设...

IrisHunag ⋅ 昨天 ⋅ 0

CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析

CyclicBarrier、CountDownLatch以及Semaphore是Java并发包中几个常用的并发组件,这几个组件特点是功能相识很容易混淆。首先我们分别介绍这几个组件的功能然后再通过实例分析和源码分析其中设...

申文波 ⋅ 昨天 ⋅ 0

Java对象的序列化与反序列化

Java对象的序列化与反序列化

Cobbage ⋅ 昨天 ⋅ 0

Sqoop

1.Sqoop: 《=》 SQL to Hadoop 背景 1)场景:数据在RDBMS中,我们如何使用Hive或者Hadoop来进行数据分析呢? 1) RDBMS ==> Hadoop(广义) 2) Hadoop ==> RDBMS 2)原来可以通过MapReduce I...

GordonNemo ⋅ 昨天 ⋅ 0

全量构建和增量构建的区别

1.全量构建每次更新时都需要更新整个数据集,增量构建只对需要更新的时间范围进行更新,所以计算量会较小。 2.全量构建查询时不需要合并不同Segment,增量构建查询时需要合并不同Segment的结...

无精疯 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部