问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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);
};
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号