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子系統驅動的設備節點,可以參考下面的內核文檔:

Documentation\devicetree\bindings\leds\leds-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\n", argc);
    for (i = 0; i < argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);
    
    fd = open(device_path, O_RDWR);
    if (fd == -1) {
        printf("open device file failed\n");
        return fd;
    }

    if (0 == strcmp(argv[i-1], "on")) {
        ret = write(fd, "1", 1);
        printf("led open successfully\n");
    }
    else if (0 == strcmp(argv[i-1], "off")) {
        write(fd, "0", 1);
        printf("led close successfully\n");
    }
    else 
        printf("not define led state\n");
    
    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驅動設備節點。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM