c语⾔安卓驱动开发,android驱动学习1-驱动开发流程
(Android.mk)
QQ:971586331
软件环境:
操作系统:windows 10
IDE版本:Android Studio 3.4.2
JAVA版本:jdk-8u221-windows-x64
NDK版本:android-ndk-r20-windows-x86_64
Kernel版本:linux 3.0
开发板android版本:android 4.0.3
硬件环境:
开发板:itop-4412 精英版
本⽂内容:本⽂描述了如何使⽤android应⽤程序调⽤linux驱动控制LED灯的亮灭。要实现android应⽤程序控制LED,需要三个程
序,LED的linux驱动,JNI库和android应⽤程序。android应⽤程序通过JNI库调⽤LED驱动程序,从⽽实现android应⽤程序控制LED。
1.开发板环境搭建
开发环境搭建请参考《iTOP-4412开发板之精英版使⽤⼿册_V3.1.pdf》,本⽂使⽤的配置是
uboot:iTop4412_uboot_20180320.tar
kernel:iTop4412_Kernel_3.0_20180604.tar
android:iTop4412_ICS_git_20151120.tar
编译完成后将ramdisk-uboot.img,system.img,zImage,u-boot-iTOP-4412.bin⽂件通过OTG或SD烧写到开发板的EMMC中,如果在uboot下使⽤OTG,发现windows 10装不上光盘中的android_drv_驱动,可以⾕歌搜索安装
android_11000010001_。
2.LED的驱动程序
LED驱动在kernel的drivers/char/itop4412-leds.c中,从itop4412-leds.c中我们可以得知LED驱动的设备⽂件名叫“leds”。驱动程序实现了ioctl函数。
long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
printk("debug: leds_ioctl cmd is %d\n" , cmd);
switch(cmd)
{
case 0:
case 1:
if (arg > LED_NUM) {
return -EINVAL;
}
gpio_set_value(led_gpios[arg], cmd);
break;
default:
return -EINVAL;
制作android软件流程
}
return 0;
}
leds_ioctl的cmd参数表⽰灯的亮灯,arg参数表⽰灯的编号,根据⽂件中的定义可以知,0表⽰GPL2_0,也就是LED2,1表⽰GPK1_1,也就是LED3。
static int led_gpios[] = {
EXYNOS4_GPL2(0),
EXYNOS4_GPK1(1),
};
接下来我们查看drivers/char/Makefile⽂件,宏CONFIG_LEDS_CTL控制LED驱动是否编译
obj-$(CONFIG_LEDS_CTL)+= itop4412_leds.o
再查看drivers/char/Kconfig⽂件,默认就是y
config LEDS_CTL
bool "Enable LEDS config"
default y
help
Enable LEDS config
再查看.config,已经将LED驱动编⼊了内核
CONFIG_LEDS_CTL=y
看来板⼦的驱动已经做好了,完全不⽤我们动⼿,接下我们看怎么编写JNI接⼝调⽤linux驱动
3.JNI和NDK
因为android是使⽤java语⾔进⾏开发的,但linux驱动是⽤C语⾔进⾏开发的,所以⾯临java如果调⽤C
语⾔接⼝的问题,JNI提供的API就是解决java和其他语⾔通信的问题。NDK 是⼀套⼯具集合,允许你使⽤C语⾔来实现应⽤程序的部分功能。我们写好JNI接⼝后使⽤NDK打包成库⽂件,就可以提供给android应⽤程序调⽤了。接下来我们新建⼯程编写JNI。
新建⼀个空activity
填写⼯程名,选择⼯程路径,开发语⾔选择java,API选择15
创建⼯程后得待编译完成,然后在包名下创建⼀个名叫jni_led的类
⽂件内容如下:
ample.led_test;
public class jni_led {
public native static String Leds_Operation(int ledNum, boolean status); //操作接⼝
}
打开 Android Studio 的 Terminal,使⽤javac命令将java⽂件编译成.class⽂件
F:\OneDrive\Linux\android_project\led_test>javac .\app\src\main\java\com\example\led_test\jni_led.java
使⽤javah命令创建头⽂件。-encoding UTF-8表⽰指定编码格式,防⽌出现“错误: 编码GBK的不可映射字符”,-d jni表⽰在当前⽬录下创建jni⽬录,将⽣成的⽂件放在jni⽬录中,-classpath表⽰指定类⽂件的路径。这⾥有⼀个地⽅要注意,类⽂件在写的时候是包名+类名,所有路径只⽤写到java⽬录,后⾯的com,example和led_test虽然都是⽂件夹,但这⾥表⽰包名(第⼀次写在这⾥纠结了好久,我想我路径明明写对了啊,为什么不到\app\src\main\java\com\example\led_test⽂件夹下的类)
F:\OneDrive\Linux\android_project\led_test>javah -encoding UTF-8 -d jni -classpath ./app/src/main/java
指令执⾏完成后可以发现在jni⽬录下⽣成了包名加类名的头⽂件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include /* Header for class com_example_led_test_jni_led */
#ifndef _Included_com_example_led_test_jni_led
#define _Included_com_example_led_test_jni_led
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_led_test_jni_led
* Method: Leds_Operation
* Signature: (IZ)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_led_1test_jni_1led_Leds_1Operation
(JNIEnv *, jclass, jint, jboolean);
#ifdef __cplusplus
}
#endif
#endif
可以发现,头⽂件中根据jni_led.java中定义的java类接⼝⽣成了JNI接⼝函数,我们要实现这个接⼝函数。
然后在JNI下创建com_example_led_test_jni_led.c⽂件
在com_example_led_test_jni_led.c中,我们将头⽂件中的接⼝函数据复制过来,然后使⽤linux API操作linux设备⽂件//
// Created by shiyu on 2019/8/17.
//
#include#include#include #include //导⼊我们创建的头⽂件
#include "com_example_led_test_jni_led.h"
#define DEVICE_NAME"/dev/leds"
JNIEXPORT jstring JNICALL Java_com_example_led_JNITest_Leds_1Operation
(JNIEnv *env, jclass obj, jint ledsNum, jboolean status){
int leds_fd = 0;
leds_fd = open(DEVICE_NAME, O_RDWR); //打开设备节点
if (leds_fd == -1) {
return 1;
}
switch (ledsNum) {
case 0:
if (status)
ioctl(leds_fd, 0, 0);
else
ioctl(leds_fd, 1, 0);
break;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。