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	"[email protected]"

#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;
}

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

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


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

你可能感兴趣的:(android,hal,ioctl)