树莓派4B android系统,Led三色灯驱动添加

一、去淘宝买一个led 三色灯配件,三色灯连接GPIO 接口。

连接方式参考下图,red 脚连GPIO17,green 脚连GPIO 18,blue 脚连GPIO19,GND脚连任意的GND

对照图片的引脚进行连接。做完这一步,可以通过以下步骤验证led是否能点亮,以下可以点亮红灯

adb shell chmod 0666 /sys/class/gpio/export  //export赋权限0666

adb shell chmod 0666 /sys/class/gpio/unexport //unexport赋权限0666

adb shell echo 17 > /sys/class/gpio/export  //通知系统需要导出控制的GPI017

adb shell chmod 0666 /sys/class/gpio/gpio17/direction //给GPIO17的direction属性赋权限0666

adb shell chmod 0666 /sys/class/gpio/gpio17/value //给GPIO17的value属性赋权限0666

adb shell echo out > /sys/class/gpio/gpio17/direction  //往GPIO17的direction属性写入out,设置GPIO为输出

adb shell echo 1 > /sys/class/gpio/gpio17/value  //往GPIO17的value属性写入1,设置GPIO为高电平

参考链接:https://blog.csdn.net/qq_29848853/article/details/130256038

二、添加驱动程序

1.在内核源码根目录,我的源码目录为kernel,在kernel/common/drivers/char下添加LedDriver目录,并在LedDriver目录下添加文件Kconfig,led_drv.c,Makefile。  

Kconfig

# SPDX-License-Identifier: GPL-2.0-only
#
# HELLO_MODULE
#

config LED_DRV
	bool "LED support"
	default y

led_drv.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/string.h>


#define RED_PIN 17
#define GREEN_PIN 18
#define BLUE_PIN 19


/* 1. 确定主设备号                                                                 */
static int major = 0;
static struct class *led_drv_class;

static int on_or_off(const char *buf,char *key){
    return NULL != strstr(buf, key) ? 1 : 0;
}

static ssize_t led_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}

static ssize_t led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
    char buffer[20];
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    if (size > sizeof(buffer))
        return -EINVAL;

    if (copy_from_user(buffer, buf, size))
        return -EFAULT;

    buffer[size] = '\0';
    gpio_set_value(RED_PIN, on_or_off(buffer,"red"));
    gpio_set_value(GREEN_PIN, on_or_off(buffer,"green"));
    gpio_set_value(BLUE_PIN, on_or_off(buffer,"blue"));
    return size;
}

static int led_drv_open (struct inode *node, struct file *file)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

static int led_drv_close (struct inode *node, struct file *file)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

// 2. 定义自己的file_operations结构体                                              */
static struct file_operations led_drv = {
        .owner	 = THIS_MODULE,
        .open    = led_drv_open,
        .read    = led_drv_read,
        .write   = led_drv_write,
        .release = led_drv_close,
};




static int __init rgbled_init(void)
{
    int err;
    printk(KERN_INFO "RGB LED driver initialized\n");

    // 初始化GPIO引脚
    gpio_request(RED_PIN, "red");
    gpio_request(GREEN_PIN, "green");
    gpio_request(BLUE_PIN, "blue");
    gpio_direction_output(RED_PIN, 0);
    gpio_direction_output(GREEN_PIN, 0);
    gpio_direction_output(BLUE_PIN, 0);


    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    major = register_chrdev(0, "led_drv", &led_drv);  /* /dev/led_drv */

    //提供设备信息,自动创建设备节点。
    led_drv_class = class_create(THIS_MODULE, "led_drv_class");

    err=PTR_ERR(led_drv_class);
    if (IS_ERR(led_drv_class)) {
        printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
        unregister_chrdev(major, "led_drv");
        return -1;
    }

    device_create(led_drv_class, NULL, MKDEV(major, 0), NULL, "led_drv"); /* /dev/led_drv */
    return 0;
}

static void __exit rgbled_exit(void)
{
    // 释放GPIO引脚
    gpio_set_value(RED_PIN, 0);
    gpio_set_value(GREEN_PIN, 0);
    gpio_set_value(BLUE_PIN, 0);
    gpio_free(RED_PIN);
    gpio_free(GREEN_PIN);
    gpio_free(BLUE_PIN);

    printk(KERN_INFO "RGB LED driver exited\n");
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    device_destroy(led_drv_class, MKDEV(major, 0));
    class_destroy(led_drv_class);
    unregister_chrdev(major, "led_drv");
}

module_init(rgbled_init);
module_exit(rgbled_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("RGB LED driver for Raspberry Pi 4B");

Makefile

# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for led driver
#

obj-$(CONFIG_LED_DRV)       += led_drv.o

2.接着加配置

在kernel/common/drivers/char/Kconfig 增加

source "drivers/char/LedDriver/Kconfig"

在kernel/common/drivers/char/Makefile 增加

obj-$(CONFIG_LED_DRV)       += LedDriver/

在kernel/common/arch/arm64/defconfig增加

CONFIG_LED_DRV=y

3.重新编译内核build/build.sh

三、编写测试代码led_drv_test.c ,CMakeLists.txt,build_led_test.sh

led_drv_test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

/*
 * ./led_drv_test -w red,blue,green
 */
int main(int argc, char **argv)
{
	int fd;
	char buf[1024];
	int len;

	/* 1. 判断参数 */
	if (argc < 2) 
	{
		printf("Usage: %s -w <string>\n", argv[0]);
		printf("       %s -r\n", argv[0]);
		return -1;
	}

	/* 2. 打开文件 */
	fd = open("/dev/led_drv", O_RDWR);
	if (fd == -1)
	{
		printf("can not open file /dev/led_drv\n");
		return -1;
	}

	/* 3. 写文件或读文件 */
	if ((0 == strcmp(argv[1], "-w")) && (argc == 3))
	{
		len = strlen(argv[2]) + 1;
		len = len < 1024 ? len : 1024;
		write(fd, argv[2], len);
	}
	close(fd);

	return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project(leddrvtest)

add_executable(${PROJECT_NAME} led_drv_test.c)

build_led_test.sh

export ANDROID_NDK=/home/liquanan/Android/Sdk/ndk/25.2.9519653

rm -r build
mkdir build && cd build 

# CMake的内置支持
# cmake -DCMAKE_SYSTEM_NAME=Android \
# 	-DCMAKE_SYSTEM_VERSION=29 \
# 	-DCMAKE_ANDROID_ARCH_ABI=x86_64 \
# 	-DANDROID_NDK=$ANDROID_NDK \
# 	-DCMAKE_ANDROID_STL_TYPE=c++_shared \
# 	..
# x86_64 armeabi-v7a
# 工具链文件支持
cmake \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=arm64-v8a \
    -DANDROID_PLATFORM=android-29 \
	  -DANDROID_STL=c++_shared \
	  ..

cmake --build .

执行脚本./build_led_test.sh

会在build目录下生成 leddrvtest  可执行文件

adb push leddrvtest /data/local/tmp

在/data/local/tmp 目录下执行./leddrvtest -w red  

可以看到红灯点亮

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值