Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 開發Android硬件抽象層代碼

開發Android硬件抽象層代碼

編輯:關於Android編程

1、開發Android硬件抽象層代碼

~/android-2.3_r1/hardware/libhardware

----include

----hardware

----freg.h

----hareware.h

-----modules

----freg

----freg.cpp

----Android.mk

hareware.h

.........
#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H
#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H

#include 
#include 

#include 

__BEGIN_DECLS

/*
 * Value for the hw_module_t.tag field
 */

#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))

#define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T')
#define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T')

struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;

/**
 * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
 * and the fields of this data structure must begin with hw_module_t
 * followed by module specific information.
 */
typedef struct hw_module_t {
    /** tag must be initialized to HARDWARE_MODULE_TAG */
    uint32_t tag;

    /** major version number for the module */
    uint16_t version_major;

    /** minor version number of the module */
    uint16_t version_minor;

    /** Identifier of module */
    const char *id;

    /** Name of this module */
    const char *name;

    /** Author/owner/implementor of the module */
    const char *author;

    /** Modules methods */
    struct hw_module_methods_t* methods;

    /** module's dso */
    void* dso;

    /** padding to 128 bytes, reserved for future use */
    uint32_t reserved[32-7];

} hw_module_t;

typedef struct hw_module_methods_t {
    /** Open a specific device */
    int (*open)(const struct hw_module_t* module, const char* id,
            struct hw_device_t** device);

} hw_module_methods_t;

/**
 * Every device data structure must begin with hw_device_t
 * followed by module specific public methods and attributes.
 */
typedef struct hw_device_t {
    /** tag must be initialized to HARDWARE_DEVICE_TAG */
    uint32_t tag;

    /** version number for hw_device_t */
    uint32_t version;

    /** reference to the module this device belongs to */
    struct hw_module_t* module;

    /** padding reserved for future use */
    uint32_t reserved[12];

    /** Close this device */
    int (*close)(struct hw_device_t* device);

} hw_device_t;

/**
 * Name of the hal_module_info
 */
#define HAL_MODULE_INFO_SYM         HMI

/**
 * Name of the hal_module_info as a string
 */
#define HAL_MODULE_INFO_SYM_AS_STR  "HMI"

/**
 * Get the module info associated with a module by id.
 * @return: 0 == success, <0 == error and *pHmi == NULL
 */
int hw_get_module(const char *id, const struct hw_module_t **module);

........

__END_DECLS

#endif  /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */
hw_module_t結構體:

(1)在結構體hw_module_t的定義前面有一段注釋,意思是硬件抽象層中的每一個模塊都必須自定義一個硬件抽象層模塊結構體,而且它的第一個成員變量的類型必須為hw_module_t。

(2)硬件抽象層中的每一個模塊都必須存在一個導出符號HAL_MODULE_IFNO_SYM,即“HMI”,它指向一個自定義的硬件抽象層模塊結構體。

(3)結構體hw_module_t的成員變量tag的值必須設置為HARWARE_MODULE_TAG,即設置為一個常量值('H'<<24|'W'<<16|'M'<<8|'T'),用來標志這是一個硬件抽象層模塊結構體。

(4)結構體hw_module_t的成員變量dso用來保存加載硬件抽象層模塊後得到的句柄值。

(5)結構體hw_module_t的成員變量methods定義了一個硬件抽象層模塊的操作方法列表,它的類型為hw_module_methods_t,接下來我們就介紹它的定義。

hw_module_methods_t結構體:

(1)只有一個成員變量,它是一個函數指針,用來打開硬件抽象層模塊中的硬件設備。其中,參數module表示要打開的硬件設備所在的模塊;參數id表示要打開的硬件設備的ID;參數device是一個輸出參數,用來描述一個已經打開的硬件設備。由於一個硬件抽象層模塊可能會包含多個硬件設備。因此,在調用結構體hw_module_methods_t的成員變量open來打開一個硬件設備時,我們需要指定它的ID。

hw_device_t結構體:

(1)硬件抽象層模塊中的每一個硬件設備都必須自定義一個硬件設備結構體,而且它的第一個成員變量的類型必須為hw_device_t。

(2)結構體hw_device_t的成員變量tag的值必須設置為HARDWARE_DEVICE_TAG,即設置為一個常量值('H'<<24|'W'<<16|'D'<<8|'T'),用來標志這是一個硬件抽象層中的硬件設備結構體。

(3)結構體hw_device_t的成員變量close是一個函數指針,它用來關閉一個硬件設備。

至此,硬件抽象層模塊接口的編寫規范就介紹完了。

freg.h

#ifndef ANDROID_FREG_INTERFACE_H
#define ANDROID_FREG_INTERFACE_H

#include 

__BEGIN_DECLS

/**
 * The id of this module
 */
#define FREG_HARDWARE_MODULE_ID "freg"

/**
 * The id of this device
 */
#define FREG_HARDWARE_DEVICE_ID "freg"

struct freg_module_t {
	struct hw_module_t common;
};

struct freg_device_t {
	struct hw_device_t common;
	int fd;
	int (*set_val)(struct freg_device_t* dev, int val);
	int (*get_val)(struct freg_device_t* dev, int* val);
};

__END_DECLS

#endif
宏FREG_HARDWARE_MODULE_ID和FREG_HARDWARE_DEVICE_ID分別用來描述模塊ID和設備ID。結構體freg_module_t用來描述自定義的模塊結構體,它的第一個成員變量的類型為hw_module_t。結構體freg_device_t用來描述虛擬硬件設備freg,它的第一個成員變量的類型為freg_device_t。此外,結構體freg_device_t還定義了其他三個成員變量,其中,成員變量fd是一個文件描述符,用來描述打開的設備文件/dev/freg,成員變量set_val和get_val是函數指針,它們分別用來寫和讀虛擬硬件設備freg的寄存器val的內容。


freg.cpp

#define LOG_TAG "FregHALStub"

#include 
#include 

#include 
#include 

#include 
#include 

#define DEVICE_NAME "/dev/freg"
#define MODULE_NAME "Freg"
#define MODULE_AUTHOR "[email protected]"
//因為在實現前,要用到這些函數,所以先定義
static int freg_device_open(const struct hw_module_t* module, const char* id, struct hw_device_t** device);
static int freg_device_close(struct hw_device_t* device);
static int freg_set_val(struct freg_device_t* dev, int val);
static int freg_get_val(struct freg_device_t* dev, int* val);

static struct hw_module_methods_t freg_module_methods = {
	open: freg_device_open
};

struct freg_module_t HAL_MODULE_INFO_SYM = {//一個硬件抽象層模塊必須導出一個名稱為HAL_MODULE_INFO_SYM的符號
	common: {
		tag: HARDWARE_MODULE_TAG,//tag值必須設置為HARDWARE_MODULE_TAG	
		version_major: 1,
		version_minor: 0,
		id: FREG_HARDWARE_MODULE_ID,
		name: MODULE_NAME,
		author: MODULE_AUTHOR,
		methods: &freg_module_methods,
	}
};

static int freg_device_open(const struct hw_module_t* module, const char* id, struct hw_device_t** device) {
	if(!strcmp(id, FREG_HARDWARE_DEVICE_ID)) {//首先要匹配ID
		struct freg_device_t* dev;

		dev = (struct freg_device_t*)malloc(sizeof(struct freg_device_t));//分配freg_device_t結構體
		if(!dev) {
			LOGE("Failed to alloc space for freg_device_t.");
			return -EFAULT;	
		}

		memset(dev, 0, sizeof(struct freg_device_t));

		dev->common.tag = HARDWARE_DEVICE_TAG;//必須初始化為HARDWARE_DEVICE_TAG
		dev->common.version = 0;
		dev->common.module = (hw_module_t*)module;
		dev->common.close = freg_device_close;//關閉函數
		dev->set_val = freg_set_val;
		dev->get_val = freg_get_val;
	
		if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
			LOGE("Failed to open device file /dev/freg -- %s.", strerror(errno));
			free(dev);
			return -EFAULT;
		}

		*device = &(dev->common);

		LOGI("Open device file /dev/freg successfully.");	

		return 0;
	}

	return -EFAULT;
}

static int freg_device_close(struct hw_device_t* device) {
	struct freg_device_t* freg_device = (struct freg_device_t*)device;
	if(freg_device) {
		close(freg_device->fd);
		free(freg_device);
	}

	return 0;
}

static int freg_set_val(struct freg_device_t* dev, int val) {
	if(!dev) {
		LOGE("Null dev pointer.");
		return -EFAULT;
	}

	LOGI("Set value %d to device file /dev/freg.", val);
	write(dev->fd, &val, sizeof(val));

	return 0;
}

static int freg_get_val(struct freg_device_t* dev, int* val) {
	if(!dev) {
		LOGE("Null dev pointer.");
		return -EFAULT;
	}
	
	if(!val) {
		LOGE("Null val pointer.");
		return -EFAULT;
	}

	read(dev->fd, val, sizeof(*val));

	LOGI("Get value %d from device file /dev/freg.", *val);

	return 0;
}

在這段代碼中,最值得關注的就是模塊變量HAL_MODULE_INFO_SYM的定義。按照硬件抽象層模塊編寫規范,每一個硬件抽象層模塊必須導出一個名稱為HAL_MODULE_INFO_SYM的符號,它指向一個自定義的硬件抽象層模塊結構體,而且它的第一個類型為hw_module_t的成員變量tag值必須設置為HARDWARE_MODULE_TAG。除此之外,還初始化了這個硬件抽象層模塊結構體的版本號、ID、名稱、作者和操作方法列表等。


Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := freg.cpp
LOCAL_MODULE := freg.default
include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY),表示要將硬件抽象層模塊編譯成一個動態鏈接庫文件,名稱為freg.default。


2、編譯

編譯硬件抽象層:

\

生成的動態鏈接庫文件,名稱為freg.default.so,保存在out/target/product/generic喎?/kf/ware/vc/" target="_blank" class="keylink">vc3lzdGVtL2xpYi9od8S/wrzPwqGjPC9wPgo8cD48YnI+CjwvcD4KPHA+ICAgICAgtPKw/KO6PC9wPgo8cD48aW1nIHNyYz0="/uploadfile/Collfiles/20140609/20140609091226145.png" alt="n塊肢侂顧侁鐉竴澸鑹幀"/os/" target="_blank" class="keylink">系統鏡像文件system.img。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved