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);
};
热门推荐
情人节感动话语,让爱升温
OPEC+会议在即,油价走势如何?
最适合存储比特币的操作系统是什么?
王者荣耀李白的技能介绍(王者荣耀英雄攻略)
诸暨珍珠闪耀香港国际珠宝展,成交额突破15亿元
零基础小白,如何学习油画?
洛阳春夏之旅:探秘千年古都的魅力与现代活力(附攻略)
吉利熊猫耐力熊购车优惠大揭秘:最高直降1.37万!
勒沃库森为什么这么强?他们这个赛季到底做对了什么事情?
站长之家教你用AI工具高效写作
广州试管婴儿医院大全
商业分析的最核心:行业洞察
M.2固态硬盘无法识别?BIOS CSM设置来帮忙!
如何安全停用帕罗西汀?听听专家怎么说!
日常小习惯提升新陈代谢:从饮食、运动到生活方式全覆盖指南
李正教你画古风小美女
中国航天科工“高速飞车”突破:时速1000公里,京沪1.5小时可达
自动汇总与分类展现:项目文档管理的智能化升级
商务谈判的心理战术大揭秘!
如何在技术分析中合理调整均线参数?这些调整对投资决策的影响如何?
火塔拜寿,福州人给齐天大圣过生日!
Debian系统下UFW防火墙配置最佳实践
心理周刊|《眼泪女王》里被细分的“恋爱脑”蕴含多种心理知识
MBTI INTJ:程序员的性格密码
17岁高中生做AI App,不到4个月入账百万美元,独立开发者迎来春天?
地震后防疫指南:保护家人健康
仿制药和原研药到底有没有差别?用视频让你眼见为实
引起眼睛看东西模糊的常见疾病有哪些?如何判断眼睛模糊的原因?
从《哪吒 2》透视中国家庭娱乐生态:用户其实从来都没有抛弃电视
张泽羊肉:七百年非遗技艺的传承与创新