针对"Android 驱动编写LED-NDK程序",下面是详细的攻略过程:
1. 准备工作
开发过程中需要的一些准备工作:
(1)Android驱动编写LED开发板
正常情况下,开发板上都会有LED指示灯,我们可以通过控制这些指示灯达到验证驱动是否正常执行的效果。
(2)NDK
NDK 是一个让你用 C 或 C++ 来构建 Android 应用的工具集。通常情况下,NDK会集成在Android Studio中,我们不需要进行相应的下载安装。如果不存在,使用Android Studio自带的SDK Manager,安装NDK对应版本即可。
2. 搭建开发环境
(1)创建Android工程文件
首先,在Android Studio中创建一个新的 Native Activity 工程,选择 C++。如果不知道如何创建,可以参考 Android 官方文档:创建 Android 项目
(2)建立jni目录
\"jni\"目录是一个特殊的目录,用于存放我们编写的 C/C++ 源代码,将其放至位于\"app/src/main/"\"下。
(3)编写led.c驱动程序文件
此处我们提供两个示例:c_led_dev 和 c_gpio_led_dev,用于验证LED是否开启。
// c_led_dev.c示例
#include <linux/fs.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/gpio.h>
#include <asm/uaccess.h>
MODULE_AUTHOR("luojing3");
MODULE_LICENSE("GPL");
#define LED_DEV_NAME "c_led_dev"
static int c_gpio_led_open(struct inode *inode, struct file *file) {
printk("c_gpio_led_dev c_gpio_led_open!\n");
return 0;
}
static ssize_t c_gpio_led_read(struct file *file,
char __user *buf, size_t len, loff_t *pos) {
printk("c_gpio_led_dev c_gpio_led_read!\n");
return 0;
}
static ssize_t c_gpio_led_write(struct file *file,
const char __user *buf, size_t len, loff_t *pos) {
int res;
char kbuf[6] = {0};
memset(kbuf, 0, sizeof(kbuf));
res = copy_from_user(kbuf, buf, len);
if (res) {
printk("%s: copy_from_user failed!\n", LED_DEV_NAME);
return -EFAULT;
}
if (strcmp(kbuf, "on") == 0) {
printk("%s: led on!\n", LED_DEV_NAME);
gpio_direction_output(12, 1);
} else if (strcmp(kbuf, "off") == 0) {
printk("%s: led off!\n", LED_DEV_NAME);
gpio_direction_output(12, 0);
} else {
printk("%s: Unknown Command!\n", LED_DEV_NAME);
return -EINVAL;
}
return len;
}
static int c_gpio_led_release(struct inode *inode, struct file *file) {
printk("%s: c_gpio_led_release!\n", LED_DEV_NAME);
return 0;
}
static struct file_operations c_gpio_led_ops = {
.owner = THIS_MODULE,
.open = c_gpio_led_open,
.read = c_gpio_led_read,
.write = c_gpio_led_write,
.release = c_gpio_led_release,
};
static void c_register_led_dev(int led_port) {
gpio_request(led_port, "led");
gpio_direction_output(led_port, 0);
gpio_export(led_port, false);
}
static int c_gpio_led_init(void) {
dev_t devno;
int res;
struct device *dev;
devno = MKDEV(0, 0);
if (register_chrdev_region(devno, 1, LED_DEV_NAME) < 0) {
printk("Failed to register_chdev_region!\n");
return -1;
}
c_register_led_dev(12);
c_gpio_led_dev_major = MAJOR(devno);
c_led_dev = cdev_alloc();
c_led_dev->ops = &c_gpio_led_ops;
c_led_dev->owner = THIS_MODULE;
res = cdev_add(c_led_dev, devno, 1);
if (res) {
printk("Failed to add c_gpio_led_device!\n");
goto fail_1;
}
c_gpio_led_class = class_create(THIS_MODULE, LED_DEV_NAME);
if (IS_ERR(c_gpio_led_class)) {
printk("Failed to create class_c_gpio_led_device!\n");
goto fail_2;
}
dev = device_create(c_gpio_led_class, NULL, devno, NULL, LED_DEV_NAME);
if (IS_ERR(dev)) {
printk(KERN_ALERT "Failed to create device!\n");
goto fail_3;
}
return 0;
fail_3:
class_destroy(c_gpio_led_class);
fail_2:
cdev_del(c_led_dev);
fail_1:
unregister_chrdev_region(devno, 1);
return -1;
}
static void c_gpio_led_exit(void) {
dev_t devno = MKDEV(c_gpio_led_dev_major, 0);
device_destroy(c_gpio_led_class, devno);
class_destroy(c_gpio_led_class);
cdev_del(c_led_dev);
unregister_chrdev_region(devno, 1);
gpio_set_value(12, 0);
gpio_unexport(12);
gpio_free(12);
}
module_init(c_gpio_led_init);
module_exit(c_gpio_led_exit);
// c_gpio_led_dev.c示例
#include "jni.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_com_example_ledtest_MainActivity_nativeLedOn(JNIEnv *env, jobject instance) {
FILE *fp;
fp = fopen("/dev/c_led_dev", "w");
if (fp < 0) {
printf("open failed!\n");
return ;
}
fprintf(fp, "%s", "on");
fclose(fp);
}
JNIEXPORT void JNICALL
Java_com_example_ledtest_MainActivity_nativeLedOff(JNIEnv *env, jobject instance) {
FILE *fp;
fp = fopen("/dev/c_led_dev", "w");
if (fp < 0) {
printf("open failed!\n");
return ;
}
fprintf(fp, "%s", "off");
fclose(fp);
}
(4)修改Android.mk和Application.mk文件
在\"app/src/main/"\"下,我们需要修改\"Android.mk\"和\"Application.mk\"文件。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := c_led_dev
LOCAL_SRC_FILES := jni/c_led_dev.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all
APP_PLATFORM := android-21
(5)编译测试
执行\"make\"命令进行编译,执行\"ndk-build\"命令进行组合编译并生成相应的so文件和apk文件。
最后在Android设备中进行测试即可。示例中我们可以在MainActivity.java文件的相应按钮(如led on)进行检测,看看是否有输出。
以上为Android 驱动编写LED的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android 驱动编写LED-NDK程序 - Python技术站