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);
};
热门推荐
湿疹患者的自我救赎:如何保持良好心态?
秋冬湿疹高发?试试这些营养搭配!
霍金警告:高度智慧外星人可能危险!
德雷克公式的新突破:地球文明或为银河系独苗?
适合70岁女老人的十种礼物 献给70岁女性的十大最佳生日礼物指南
立春后 用这些方法能帮你睡得更好
什么是安全意识培训?为什么企业需要进行员工网络安全培训?
多模态AI:整合多种数据类型的未来技术
多家航司推宠物进客舱服务:仅接收家庭驯养的狗、猫
海南非遗文化之旅:特色体验旅游景点推荐
关岭:花树摇曳迎新春,苗族欢歌庆团圆
上海非遗打卡地,春节必玩清单!
非遗贺新春:2025年春节亮点纷呈
春节申遗成功,消费补贴引爆购物潮!
AI助力外星信号解析,揭秘宇宙神秘信号
中国天眼:探寻外星文明的“超级耳朵”
克拉克系外卫星带:寻找外星文明的新希望?
TRAPPIST-1系统:外星信号探测的新突破
BMI之外:身体圆度指数与健康生活方式新解
BMI vs FFMI:科学评估体重的双刃剑
协和科普推荐:科学评估你的体重
乙肝患者可以食用黄芪吗?专业医生解答
陵水:树立文化旅游新标杆 焕发疍家“民俗之花”
三代疍家人从靠海吃海到主动探索文旅融合发展
冬季浴室清洁全攻略:从清洁技巧到防霉方法
量子通信新突破:爱丁堡大学揭秘外星信号探测新方法
中国天眼:用大数据解读宇宙深处的神秘电磁波
乔姆斯基理论视角下的幼儿语言习得:从模仿到创造
2-6岁宝宝语言启蒙,你做对了吗?
2岁娃口齿伶俐的秘密:亲子互动大揭秘