zoukankan      html  css  js  c++  java
  • Android系统集成C程序访问驱动设备节点

    1、前言

    Android系统中,应用程序一般是使用Java语言进行开发的,但是通过C语言也可以进行Android中的可执行程序开发,接下来,将简单介绍在Android系统中如何通过C程序来访问内核中sysfs的属性文件,也可以理解为驱动设备节点。

    2、添加kernel驱动设备节点

    做过Linux内核驱动开发的都知道,内核里面提供了GPIO控制的LED设备驱动子系统,接下来,将通过添加内核配置和设备树节点来添加一个LED设备节点。

    首先是内核里面leds-gpio设备驱动的配置选项:

    make menuconfig
        Device Driver --->
            -*- LED Support --->
              <*> LED Support for GPIO connected LEDs

    添加完成LED子系统的config配置后,在编译内核的时候,将会该LED驱动模块集成到内核里面。

    接下来,添加LED设备的设备树节点,如下所示:

    gpio-leds {
       compatible = "gpio-leds";
       status = "ok";
       pinctrl-names = "default";
       pinctrl-0 = <&gpio_led_off>;
    
       led-red {
         gpios = <&msm_gpio 97 0>;
         label = "led-red";
         linux,default-trigger = "none";
         default-state = "off";
        };
    };

    在定义的设备节点里面,compatible属性的值,是用来和驱动程序进行匹配,gpios属性定义了使用到的GPIO号以及说明了是高电平有效,当引脚电平为高时,LED将会被点亮,关于如何定义LED子系统驱动的设备节点,可以参考下面的内核文档:

    Documentationdevicetreeindingsledsleds-gpio.txt

    将设备节点添加完成后,重新编译Linux内核boot.img,并使用fastboot烧写,便可以在sysfs系统中看到生成的LED设备节点信息了,如下所示:

    在该LED设备节点中,brightness为设备的属性文件,表示为LED设备的亮度,当该属性文件的值为0时,LED为熄灭状态,当属性文件的值大于0时,LED为点亮状态,使用cat和echo命令能对该设备的属性文件进行读写,还能控制LED的状态:

    # 查看当前LED状态
    cat brightness
    
    # 点亮LED灯
    echo 1 > brightness
    
    # 熄灭LED灯
    echo 0 > brightness

    能对LED的基本控制,就已经完成了内核驱动设备节点的添加了。

    3、编写集成C程序

    在上面已经完成了设备节点的添加了,那么,在Android系统中如何去集成C程序去访问该LED设备节点呢?

    首先,进入到Android源码的external目录,创建一个新的ledctrl目录:

    $ cd AOSP/external
    $ mkdir ledctrl

    然后在该目录下创建led-ctrl.c源文件和Android.mk编译脚本:

    ledctrl.c源文件如下所示:

    #include <stdio.h>
    #include <string.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define device_path "/sys/class/leds/led-red/brightness"
    
    int main(int argc, char *argv[])
    {
        int i,fd,ret;
        
        printf("argc = %d
    ", argc);
        for (i = 0; i < argc; i++)
            printf("argv[%d] = %s
    ", i, argv[i]);
        
        fd = open(device_path, O_RDWR);
        if (fd == -1) {
            printf("open device file failed
    ");
            return fd;
        }
    
        if (0 == strcmp(argv[i-1], "on")) {
            ret = write(fd, "1", 1);
            printf("led open successfully
    ");
        }
        else if (0 == strcmp(argv[i-1], "off")) {
            write(fd, "0", 1);
            printf("led close successfully
    ");
        }
        else 
            printf("not define led state
    ");
        
        close(fd);
        return 0;
    }

    该文件主要就是完成对设备文件的读写,接下来是Android.mk文件的内容,如下:

    # Android.mk for led-ctrl.c
    
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := led-ctrl
    LOCAL_SRC_FILES := $(call all-subdir-c-files)
    include $(BUILD_EXECUTABLE)

    最后一行的BUILD_EXECUTABLE表示,该模块将编译为可执行程序。

    编译完Android.mk文件后,使用mmm命令编译led-ctrl这个C程序模块:

    $ cd AOSP
    $ mmm ./external/ledctrl

    成功编译后,将会在out/target/product/msm8909/system/bin目录生成所需要的可执行文件led-ctrl。

    重新打包Android系统文件system.img,并使用fastboot命令重新烧写镜像文件:

    $ make snod
    
    # adb reboot bootloader
    # fastboot flash system system.img
    # fastboot reboot

    4、可执行程序运行测试

    先查看内核里面是否已经集成了led-ctrl这个C可执行程序:

    # adb root
    # adb shell
    
    $ cd /system/bin
    $ ls -al led*

    结果如下:

    在上面可以看到,led-ctrl这个执行程序已经集成到了Android系统里面,接下来使用控制LED设备节点的命令即可,如下:

    5、小结

    本文主要简单介绍了如何在内核里面添加LED子系统驱动的配置,并且添加LED设备树节点,并编写了一个简单的可执行程序来访问该LED驱动设备节点。

     
  • 相关阅读:
    常见数据结构使用场景
    Java与算法之(4)
    Java与算法之(3)
    Java与算法之(2)
    Java与算法之(1)
    Maven适配多种运行环境的打包方案
    从头开始基于Maven搭建SpringMVC+Mybatis项目(4)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(3)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(2)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(1)
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/11809178.html
Copyright © 2011-2022 走看看