s5p4418 Android 4.4.2 驱动层 HAL层 服务层 应用层 开发流程记录(二 硬件抽象层HAL 第二种 ioctl操作方法)

欢迎转载,务必注明出处:http://blog.csdn.net/wang_shuai_ww/article/details/44407641


本篇与http://blog.csdn.net/wang_shuai_ww/article/details/44305599该篇文章不同的仅仅在HAL层的.so方面,操作方法前面一篇是使用普通接口write来操作,write接口操作单个LED没有问题,当有多个LED时可能就不是那么方便了,所以本篇介绍使用unlocked_ioctl的方法。

驱动程序已经写好了unlocked_ioctl方法,这里不再对驱动程序做修改了,这里修改的仅仅是硬件抽象层HAL,硬件服务层和JNI层也不需要修改,可以兼容。

注意:现在的Linux内核已经使用unlocked_ioctl取代ioctl了,写驱动程序时就不再使用ioctl了。

修改后的源码如下:

#include <hardware/hardware.h>
#include "led.h"

#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>

// 引入log头文件
#include <android/log.h>  
// log标签
#define  TAG    "Led_Load_HAL"
// 定义info信息
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG,__VA_ARGS__)
// 定义debug信息
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
// 定义error信息
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)

#define DEVICE_NAME		"/dev/real_led"
#define MODULE_NAME		"led"
#define MODULE_AUYHOR	"wsh_sean@qq.com"

#define LED_ON 		1
#define LED_OFF		0

static int led_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t **device);
static int led_device_close(struct hw_device_t *device);

static int led_set_on(struct led_device_t *dev, int num);
static int led_set_off(struct led_device_t *dev, int num);

static struct hw_module_methods_t led_module_methods = {
	open: led_device_open
};

struct led_module_t HAL_MODULE_INFO_SYM = {
	common: {
		tag: HARDWARE_MODULE_TAG,
		version_major: 1,
		version_minor: 0,
		id: LED_HARDWARE_MODULE_ID,
		name: DEVICE_NAME,
		author: MODULE_AUYHOR,
		methods: &led_module_methods,
	}
};

static int led_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t **device) {
	if(!strcmp(id, LED_HARDWARE_DEVICE_ID)) {
		struct led_device_t *dev;
		dev = (struct led_device_t *)malloc(sizeof(struct led_device_t));
		if(!dev) {
			LOGE("Failed to alloc space for led_device_t");
			return -EFAULT;
		}
		
		memset(dev, 0, sizeof(struct led_device_t));
		
		dev->common.tag = HARDWARE_MODULE_TAG;
		dev->common.version = 0;
		dev->common.module = (hw_module_t *)module;
		dev->common.close = led_device_close;
		dev->set_on = led_set_on;
		dev->set_off = led_set_off;
		
		if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
			LOGE("Failed to open device file "DEVICE_NAME"-- %s.", strerror(errno));
			free(dev);
			return -EFAULT;
		}
		*device = &(dev->common);
		LOGI("Open device file "DEVICE_NAME" successfully.");
		return 0;
	}
	return -EFAULT;
}

static int led_device_close(struct hw_device_t *device){
	struct led_device_t *led_device = (struct led_device_t *)device;
	if(led_device){
		close(led_device->fd);
		free(led_device);
	}
	return 0;
}

static int led_set_on(struct led_device_t *dev, int num){
	if(!dev){
		LOGE("Null dev pointer.");
		return -EFAULT;
	}
	LOGI("Set the first %d LED lights.", num);
	ioctl(dev->fd, LED_ON, num);
	
	return 0;
}

static int led_set_off(struct led_device_t *dev, int num){
	if(!dev){
		LOGE("Null dev pointer.");
		return -EFAULT;
	}
	LOGI("Set the first %d LED close.", num);
	ioctl(dev->fd, LED_OFF, num);
	
	return 0;
}

读者可以跟前面的代码进行对比不同。

编译,打包下载使用,具体的参考前面的方法。


这里说明,我使用的是本篇的操作方法。后面的记录也都是基于这个版本的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值