Android从驱动到app,以LED控制系统简单示例
创作时间:
作者:
@小白创作中心
Android从驱动到app,以LED控制系统简单示例
引用
CSDN
1.
https://m.blog.csdn.net/JISHUQIANJIA/article/details/142823079
本文通过一个具体的LED控制系统案例,详细介绍了Android系统中从驱动程序到应用层的硬件控制实现流程。从驱动程序的编写,到HAL层的接口定义,再到Framework层的AIDL接口实现,层层递进,逻辑严谨,对于Android开发人员来说具有很高的参考价值。
以下实现一个简单的 LED 控制系统,包括驱动程序、HAL 层和 Framework 层的代码示例。
我们将使用 AIDL 来定义应用程序与 Framework 层之间的接口,并使用 Binder 机制在 Framework 层与 HAL 层之间进行通信。(仅简单示例,便于理解代码开发流程,不保证能运行)
1. LED 驱动程序
创建一个名为 led_driver.c 的文件,内容如下:
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "led"
#define CLASS_NAME "led_class"
static int major;
static struct class *led_class;
static struct cdev led_cdev;
static bool led_on = false;
static int led_open(struct inode *inode, struct file *file) {
printk(KERN_INFO "led: Device opened\n");
return 0;
}
static int led_release(struct inode *inode, struct file *file) {
printk(KERN_INFO "led: Device closed\n");
return 0;
}
static ssize_t led_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
char status = led_on ? '1' : '0';
if (copy_to_user(buf, &status, 1)) {
return -EFAULT;
}
printk(KERN_INFO "led: Read %c\n", status);
return 1;
}
static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
char command;
if (copy_from_user(&command, buf, 1)) {
return -EFAULT;
}
if (command == '1') {
led_on = true;
printk(KERN_INFO "led: LED turned on\n");
} else if (command == '0') {
led_on = false;
printk(KERN_INFO "led: LED turned off\n");
} else {
return -EINVAL;
}
return count;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = led_open,
.release = led_release,
.read = led_read,
.write = led_write,
};
static int __init led_init(void) {
dev_t dev;
int result;
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
if (result < 0) {
printk(KERN_WARNING "led: Can't get major number\n");
return result;
}
major = MAJOR(dev);
cdev_init(&led_cdev, &fops);
led_cdev.owner = THIS_MODULE;
result = cdev_add(&led_cdev, dev, 1);
if (result) {
printk(KERN_NOTICE "led: Error %d adding led", result);
unregister_chrdev_region(dev, 1);
return result;
}
led_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(led_class)) {
cdev_del(&led_cdev);
unregister_chrdev_region(dev, 1);
return PTR_ERR(led_class);
}
device_create(led_class, NULL, dev, NULL, DEVICE_NAME);
printk(KERN_INFO "led: Registered with major number %d\n", major);
return 0;
}
static void __exit led_exit(void) {
dev_t dev = MKDEV(major, 0);
device_destroy(led_class, dev);
class_destroy(led_class);
cdev_del(&led_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "led: Unregistered\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple LED driver");
MODULE_VERSION("1.0");
2. HAL 层代码
HAL 层代码需要实现一个标准的 HAL 接口,并通过 hw_device_t 结构体与驱动进行交互。
PS:关于HAL层的知识,老罗的《Android系统源代码情景分析》第二章有详细介绍:
这篇写得很详细:
第二章 硬件抽象层
2.1. 定义 HAL 接口
首先,我们定义一个 HAL 接口文件,用于描述 HAL 层提供的服务。创建一个名为 led_hal.h 的文件,内容如下:
#ifndef ANDROID_LED_HAL_H
#define ANDROID_LED_HAL_H
#include <hardware/hardware.h>
__BEGIN_DECLS
#define LED_HARDWARE_MODULE_ID "led"
struct led_device_t {
struct hw_device_t common;
int (*set_on)(struct led_device_t* dev);
int (*set_off)(struct led_device_t* dev);
int (*get_state)(struct led_device_t* dev, int* state);
};
热门推荐
陈翔新作《拳王妈妈》:一个草根妈妈的逆袭之路
34岁鹿晗惨被同剧演员催婚!粉丝冲到评论区嘲讽,当事人连忙解释
赵本山春晚经典:从“睡美人”到全球巡演
葡萄霜霉病的有效治疗方法,附带发病条件与症状分析
葡萄树病害大全图解:8种常见病害的症状识别与防治方法
经典作家|1924:流离者鲁迅的“彷徨”
葡萄霜霉病防治措施
白粉病害和霜霉病害发病情况不一样,种植农民要注意正确识别分类防治
赵本山春晚小品里的那些经典台词
“东北铁三角”的春晚传奇:从意外组合到经典永存
成都挂号费医保报销?成都挂号能用医保卡吗
异地报警是怎么受理的?异地报警的受理流程和注意事项是什么?
苏轼的“声音大”诗句:从《后赤壁赋》到音乐世界
响彻云霄:古汉语中的声音魔法
接下来的四姑娘山,将是秋季旅行的天花板!
四川四姑娘山登顶旅游攻略:人均一千的超详细攻略!
“蜀山皇后”四姑娘山:遗落人间的仙境
四姑娘山简介:四川第二大高峰,东方阿尔卑斯的壮丽景观
四姑娘山最佳旅游时间推荐
白云深处有“仙界”:走进贵阳蓬莱村
盘点我国历史上十大未解之谜,太平天国宝藏的去向只能位列第十
冬季防溺水安全教育:守护孩子健康成长
三氯异氰尿酸:泳池消毒的秘密武器
泳池防溺水黑科技,你知道多少?
四川泳池事故敲响警钟:泳池安全不容忽视
水中运动:让你清凉又燃脂的运动新选择
杰罗尼莫:阿帕奇族的传奇英雄
水上趣味运动会:泳池里的夏日狂欢
冬季室内泳池花式游泳技巧全攻略
杰罗尼莫:印第安最后的勇士