[RK3399][Android7.1]编写一个安卓的GPIO驱动

【技术分享】RK356X Android 使用 libgpiod 测试gpio 此项目包含六种命令行工具(gpiodetect、gpioinfo、gpioset、gpioget、gpiomon),使用这些工具可以在命令行设置和获取GPIO的状态信息;Purple Pi OH作为一款兼容树莓派的开源主板,采用瑞芯微RK3566 (Cortex-A55) 四核64位超强CPU,主频最高达1.8 GHz,算力高达1Tops,支持INT8/INT16,支持TensorFlow/MXNet/PyTorch/Caffe框架,多路视频输出和输入,支持4K、H.265/H.264视频解码,接口丰富。 阅读详情

1、在kernel/drivers目录下新建ioctrl文件夹

# cd kernel/drivers

# mkdir ioctrl

在/driver/ioctrl目录下,新建ioctrl.c ,ioctrl.h , Kconfig, Makefile 等4个文件。

2、在Kconfig下添加代码:

config IOCTRL
        tristate "io Control"
        default y
        help
          when system setup,change the io state

在Makefile下添加代码:

obj-$(CONFIG_IOCTRL)                    += ioctrl.o

在ioctrl.c中添加代码:

/*
 * Driver for pwm demo on Firefly board ioctrl.
 *
 * Copyright (C) 2022, Zhongshan T-chip Intelligent Technology Co.,ltd.
 * Copyright 2006  Sam Chan
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/**********************************************************************
 * version control
 *
 * version: v1.0.0_20191022
 * creater: dulc
 * creat date: 2019.10.22
 * changer: 
 * chang date:
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/delay.h>


#define IOCTRL_MAJOR	97


struct firefly_ioctrl_info {
    int gpio_wireless_en;        // 3g/4g power control
    int gpio_we_value;
};



static int firefly_ioctrl_probe(struct platform_device *pdev);

// ioctrl operation 
ssize_t ioctrl_read( struct file * file, char * buf, size_t count, loff_t * f_ops );
ssize_t ioctrl_write( struct file * file, const char * buf, size_t count, loff_t *f_ops );
long ioctrl_ioctl( struct file *file, unsigned int cmd, unsigned long arg);
int ioctrl_open( struct inode * inode, struct file *file );
int ioctrl_release(struct inode *inode, struct file *file );
int ioctrl_led_control( char cmd, char subcmd );



/*********************************GPIO*************************************/
static struct of_device_id firefly_ioctrl_match_table[] = {
	{ .compatible = "firefly,rk3399-gpio1",},
	{},
};

static struct platform_driver firefly_ioctrl_driver = {
	.driver = {
		.name = "firefly-ioctrl",
		.owner = THIS_MODULE,
		.of_match_table = firefly_ioctrl_match_table,
	},
	.probe = firefly_ioctrl_probe,
};
/*********************************GPIO*************************************/





// the ioctrl operations device
static const struct file_operations io_ctrl_ops = {
	.owner		= THIS_MODULE,
	.open		= ioctrl_open,
	.read		= ioctrl_read,
	.write		= ioctrl_write,
	.unlocked_ioctl	= ioctrl_ioctl,
	.release	= ioctrl_release,
};



// gpio device
struct firefly_ioctrl_info *ioctrl_device_ctrl = NULL;




ssize_t ioctrl_read( struct file * file, char * buf, size_t count, loff_t * f_ops )
{
	ssize_t size = 0;

	return size;
}


ssize_t ioctrl_write(struct file * file, const char * buf, size_t count, loff_t *f_ops )
{
	ssize_t size = 0;

	return size;
}



long ioctrl_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
{
	long ret = 0;
	
	if ( cmd == 0 )
        {
            gpio_direction_output(ioctrl_device_ctrl->gpio_wireless_en, false);
        }
	else
	{
            gpio_direction_output(ioctrl_device_ctrl->gpio_wireless_en, true);
	}

	return ret;
}



int ioctrl_open( struct inode * inode, struct file *file )
{
	return 0;
}



int ioctrl_release(struct inode *inode, struct file *file )
{
	return 0;
}



static int firefly_ioctrl_probe(struct platform_device *pdev)
{
    int gpio;
    enum of_gpio_flags flag;
    struct firefly_ioctrl_info *gpio_info;
    struct device_node *firefly_ioctrl_node = pdev->dev.of_node;

	gpio_info = devm_kzalloc(&pdev->dev,sizeof(struct firefly_ioctrl_info *), GFP_KERNEL);
	if (!gpio_info) {
        dev_err(&pdev->dev, "devm_kzalloc failed!\n");
		return -ENOMEM;
	}
	
    // 3g/4g power control
     gpio = of_get_named_gpio_flags(firefly_ioctrl_node, "firefly-gpio-wireless", 0, &flag);
    if (!gpio_is_valid(gpio)) {
        dev_err(&pdev->dev, "firefly-gpio-wireless: %d is invalid\n", gpio);
        return -ENODEV;
    }
    if (gpio_request(gpio, "firefly-gpio-wireless")) {
        dev_err(&pdev->dev, "firefly-gpio-wireless: %d request failed!\n", gpio);
        gpio_free(gpio);
        return -ENODEV;
    }
    
    printk("ioctrl driver register success!\n");

    gpio_info->gpio_wireless_en = gpio;
   // gpio_info->gpio_pe_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;
    gpio_direction_output(gpio_info->gpio_wireless_en, false);

    ioctrl_device_ctrl = gpio_info;


    return 0;
}




// init the ioctrl driver
static int ioctrl_init(void)
{
	int ret = -ENODEV;
	int ret_val = 0xFFFFFFFF;
	struct class *ioctrl_dev_class;


	// register GPIO driver
	platform_driver_register(&firefly_ioctrl_driver);
	
	// register driver
	ret = register_chrdev( IOCTRL_MAJOR, "ioctrldrive", &io_ctrl_ops );
	if ( ret < 0 )
	{
		printk("register ioctrl driver error! \n");
		return ret;
	}
	// creat class
	ioctrl_dev_class = class_create( THIS_MODULE, "ioctrldrive" );
	if ( IS_ERR(ioctrl_dev_class) )
	{
		unregister_chrdev( IOCTRL_MAJOR, "capi20");
		return PTR_ERR(ioctrl_dev_class);
	}
	// creat node
	device_create( ioctrl_dev_class, NULL, MKDEV(IOCTRL_MAJOR,0),NULL, "ioctrl");

	
	return ret_val;
}
module_init(ioctrl_init);


static void ioctrl_exit(void)
{
	platform_driver_unregister(&firefly_ioctrl_driver);

}
module_exit(ioctrl_exit);


MODULE_AUTHOR("dulc <service@t-firefly.com>");
MODULE_DESCRIPTION("Firefly ioctrl demo driver");
MODULE_ALIAS("platform:firefly-ioctrl");
MODULE_LICENSE("GPL");

在kernel/drivers目录下的Makefile文件下,添加以下代码:

obj-$(CONFIG_IOCTRL)            += ioctrl/

在kernel/drivers目录下的Kconfig文件下,添加以下代码:

source "drivers/ioctrl/Kconfig"

这时代码默认就编译到了kernel中,在kernel文件夹下,执行指令

# make menuconfig

选择Device Drivers,可看到编译进去的驱动

(默认为选中状态(*),是由于ioctrl文件夹下的Kconfig配置为 tristate  "io Control"   default y,  io Control是名称,default y是默认开启,默认关闭用default n)

 

3、编写C语言测试程序。

在 your_android_src/external目录下,新建文件夹

# mkdir ioctrltest

在该文件夹下添加两个文件:Android.mk 、ioctrltest.c

在Android.mk文件中添加代码:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= ioctrltest.c
LOCAL_MODULE:=ioctrlapp
include $(BUILD_EXECUTABLE)

其中 LOCAL_SRC_FILES为测试程序的源文件,LOCAL_MODULE为生成的可执行文件。

在ioctrltest.c中添加代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define DEVICE_NAME "/dev/ioctrl"


int main( int argc, char ** argv )
{
	int fd;
	char cmd, subcmd;
	int i;

	printf("\n -----turn on the 3g power ----- \n");
	fd = open(DEVICE_NAME, O_RDWR );
	printf("fd = %d \n", fd );

	if ( fd == -1 )
	{
		printf("open device %s error \n", DEVICE_NAME );
	}
	else
	{
		// turn on the 3g power
		ioctl(fd, 1, 0);
	}
}

在安卓目录下,执行

# make ioctrlapp

会在  out/target/product/rk3399_firefly_box/system/bin/ioctrlapp  生成相应的ioctrlapp (目录可能不同,根据自己实际情况操作)

把ioctrlapp拷贝到优盘中,启动rk3399,将优盘插入3399,然后在调试模式下,执行如下操作,可运行该程序

$su
#cp mnt/medea_rw/(upan_name)/ioctrlapp /mnt/ioctrlapp
#cd mnt
./ioctrlapp

注:在dev下生成的ioctrl驱动,要获取权限才可打开,临时获取权限,使用以下指令:

# chmod 777 /dev/ioctrl

永久获取权限,参照以下链接执行即可:

https://blog.csdn.net/d4l6c8/article/details/101345756

 

4、开启启动该程序ioctrlapp。

在device/rockchip/rk3399/device.mk中添加以下语句:

PRODUCT_COPY_FILES += \
        out/target/product/rk3399_firefly_aiojd4_mipi_box/system/bin/ioctrlapp:system/bin/ioctrlapp

在/device/rockchip/rk3399/rk3399_firefly_aiojd4_mipi_box目录下的init.rc 下添加以下语句:

#dlc add
service service_ioctrl /system/bin/ioctrlapp
    user root
    group root
    disabled
    oneshot

on property:sys.boot_completed=1

注意 service_ioctrl这个服务名称不能超过16个字节,否则认为该服务有问题,不会启动该服务。

在/device/rockchip/common/sepolicy目录下新增文件service_ioctrl.te,添加如下代码:

type service_ioctrl, domain;
type service_ioctrl_exec, exec_type, file_type;
permissive service_ioctrl;
init_daemon_domain(service_ioctrl)

在/device/rockchip/common/sepolicy目录下新增文件ioctrl_device.te,添加如下代码:

type ioctrl_device,file_type,dev_type;

在file_contexts文件中添加如下代码:

#service_ioctrl
/system/bin/ioctrlapp           u:object_r:service_ioctrl_exec:s0
/dev/ioctrl                     u:object_r:ioctrl_device:s0

到这里基本完成,路径根据自己的工程修改。

 

 

[RK3399][Android7.1] WiFi中的SDIO和电源框架 Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 框架: 引用网友一张框图,画得很不错 从硬件角度来看: CPU -&amp;gt; SDIO -&amp;gt; AP6356S 从软件角度来看分: 电源/IO管理 SDIO通道(Host和Client) WiFi驱动 电源/GPIO管理模块: 主要完成对电源、GPIO的初始化... 阅读详情

相关推荐

[RK3399][Android7.1] 调试笔记 --- HDMI IN video配置添加

Platform: RK3399 OS: Android 7.1 industry Kernel: v4.4.83 说明: 芯片使用的是东芝的TC358749X 大概的数据流程就是: HDMI -> TC358749X -> MIPI CSI -> kernel driver -> Camera HAL -> APP 配置: 主要分dts驱动和Camera Hal两...

Kris Fei's blog 6383

Android驱动开发:应用层读写GPIO

本文用于简单总结近期调试应用层读写gpio。 应用层操作gpio的主要思路:编写驱动->驱动编译进内核->创建设备节点,赋予读写权限->应用层以文件读写的方式对设备节点进行读写操作。 需要修改的地方: 1.内核设备树里面增加gpio节点 / { gpio_usb_otg_host { compatible = "qcom,usb_otg_host"; ...

Android 3062

告别触摸失灵!手把手教你为Android 7.1系统下的RK3399设备移植GT1X驱动(以GT5688为例)

本文详细介绍了在RK3399平台上为Android 7.1系统移植GT1X触摸驱动的全过程,包括硬件接口配置、驱动源码定制、内核调试及性能优化。特别针对GT5688触摸芯片的兼容性问题,提供了从设备树配置到信号完整性诊断的解决方案,帮助开发者彻底解决触摸失灵问题。

weixin_28684757的博客 299

androidgpio操作

在嵌入式设备中对GPIO的操作是最基本的操作。一般的做法是写一个单独驱动程序,网上大多数的例子都是这样的。其实linux下面有一个通用的GPIO操作接口,那就是我要介绍的 “/sys/class/gpio” 方式。  首先,看看系统中有没有“/sys/class/gpio”这个文件夹。如果没有请在编译内核的时候加入   Device Drivers  —>  GPIO Support  —>  

Sam 的专栏 4628

RK3399 Android 7.1平台GSL5680触摸驱动编译调试全解析

在嵌入式Linux开发中,内核驱动移植是常见需求,其中触摸屏驱动涉及I2C通信、中断处理、设备树等多个环节,是工程实践中的难点。在RK3399平台搭配Android 7.1 BSP的环境下,内核版本与驱动接口的差异容易引发编译错误。以GSL5680触摸屏驱动移植为例,分析编译报错的根因,包括API变更、Kconfig配置缺失等问题,并给出验证编译产物是否生效的工程方法。通过解析这一典型案例,为嵌入式驱动开发者提供一套可复用的问题排查路径,帮助缩短驱动适配周期,提升开发效率。

weixin_32770423的博客 202

Firefly RK3399开发板外接GT5688触摸屏,手把手教你搞定Android 7.2驱动配置(附DTS文件详解)

本文详细介绍了如何在Firefly RK3399开发板上外接GT5688触摸屏并配置Android 7.2驱动的完整流程。从硬件原理分析到软件驱动配置,包括I2C接口设置、中断与复位引脚配置、驱动源码修改及编译调试技巧,帮助开发者解决非官方屏幕的兼容性问题。特别提供了DTS文件详解和常见问题排查方法,适用于嵌入式开发者和硬件工程师。

weixin_33701294的博客 393

[RK3399][Android7.1] 移植笔记 --- 9.7寸eDP显示屏添加

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 由于此屏在rk3288平台上使用过,原以为接上去就可以点亮,谁知道花了一天多时间折腾,最后还是发现是自己的大意造成的,ORZ… 原理图: LCD: 背光: EDP屏硬件直接按照上电时序连接好控制,软件无需干预。 EDP_HPD pin可接可不接。 所以要做的就是配...

Kris Fei's blog 1万+

告别触摸失灵:手把手教你为Android 7.2系统下的RK3399移植GT1X驱动(以GT5688为例)

本文详细介绍了在Android 7.2系统下为RK3399开发板移植GT1X触摸驱动的完整过程,重点解析了I2C地址配置、GPIO映射、内核调试等关键技术点。通过实战案例(以GT5688为例),帮助开发者解决触摸失灵、坐标偏移等常见问题,提升驱动适配效率。

weixin_30316097的博客 316

[RK3399][Android7.1] 移植笔记 --- GT9XX系列Touch添加

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 原理图: 1.使用的是I2C3 2.TOUCH_RST_L对应GPIO是GPIO4_C6 3.TOUCH_INT_L对应GPIO是GPIO4_C7 4.电源默认上电提供 5.原理图上I2C在画图时候忘记上拉了 驱动移植: DTS配置: diff --git...

Kris Fei's blog 7996

[RK3399][Android7.1] 移植笔记 --- 网卡RTL8211配置添加

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 由于在 RK 系列的 SoC 中内置了以太网 MAC 控制器,所以只需要搭配一颗以太网 PHY 芯片, 即可实现以太网卡功能。 按照规范,即使是不同厂家的 PHY,仍然有一部分寄存器的定义是通用的, 只要配置了这些通用的寄存器,基本上 PHY 就可以正常工作。 因此,在 Linux 驱动...

Kris Fei's blog 1万+

Android平台简单GPIO驱动教程

在本教程中,我们将探讨如何在Android平台上编写简单的GPIO驱动程序。在我们的Android应用程序中使用GPIO驱动代码,我们可以在任何需要控制GPIO的地方调用GPIOControl类中的方法。以下是一个简单的示例,演示了如何控制GPIO引脚的方向和值。上述代码是一个简单的Android应用程序,其中包含两个按钮:一个用于切换GPIO引脚的方向,另一个用于切换GPIO引脚的值。在Android项目的Java源代码目录中,创建一个新的Java类,命名为GPIOControl。步骤1:设置开发环境。

HackSquad的博客 885

[RK3399][Android7.1] 调试笔记 --- USB type-c插入后无法识别到

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 现象: 用update.img制作了一个升级包之后可以升级,但是无法识别到type-c。 Log: 插上usb后提示: [ 35.192416] rk818-charger: pmic: plug in [ 35.679779] phy phy-ff770000.sy...

Kris Fei's blog 1万+

使用Android进行GPIO驱动开发

在Android平台上,使用JNI(Java Native Interface)可以与底层C代码进行交互,从而实现GPIO的访问和控制。在上述示例代码中,我们通过打开/sys/class/gpio/gpioX/value文件来访问GPIO引脚,其中X是GPIO引脚的编号。通过以上步骤,您可以在RK3568平台上使用Android创建和使用GPIO驱动程序。在gpio.c文件中,我们将编写与GPIO相关的C代码。在本文中,我们将详细讲解如何在RK3568平台上使用Android进行GPIO驱动开发。

HackDashX的博客 855

RK3399平台GSL5680触摸驱动移植:编译错误排查与修复

嵌入式Linux内核驱动移植中,硬件平台差异是开发者常遇的挑战。随着ARM64架构普及,设备树(DTS)成为描述硬件资源的标准方式,传统mach头文件与早期中断、休眠接口逐渐被新机制取代。RK3399平台基于Android 7.1(内核4.4),在适配GSL5680触摸屏驱动时,因老驱动依赖旧API而引发一系列编译错误。本文以实际移植过程为例,详细解析mach/gpio.h缺失、request_irq参数不匹配、early_suspend失效等典型编译问题,并给出基于gpiolib、threaded irq

weixin_29166013的博客 212

西门子OMAC PackML V2022在S7-1200/S7-1500中的状态机设计与应用实践

本文详细解析了西门子OMAC PackML V2022在S7-1200/S7-1500中的状态机设计与应用实践。通过实际案例和代码示例,介绍了状态机的基础认知、硬件配置、逻辑开发、调试技巧以及与MES系统集成的高级应用,帮助工程师高效实现设备自动化控制。

weixin_29255731的博客 525

【光学仿真】基于Matlab的LG/BG/PV/HG光束生成与特性分析【附完整源码】

本文详细介绍了如何使用Matlab进行拉盖尔-高斯(LG)、贝塞尔-高斯(BG)、完美涡旋(PV)和厄米-高斯(HG)四种特殊光束的仿真与特性分析。通过提供完整的Matlab源码,手把手指导读者生成光束、分析其强度、相位、传播特性及轨道角动量,为光学研究、激光应用及教学提供了直观高效的数值实验平台。

3a9bq4r8t2y的博客 486

RK3399 Android 7蓝牙移植实战:从内核到Framework全解析

蓝牙串口通信与音频传输在嵌入式设备中应用广泛,其核心在于HCI协议与UART接口的协同。通过RFKILL实现电源管理,结合设备树配置GPIO和时钟,确保硬件层稳定。技术价值在于打通从内核HCI驱动到HAL层固件加载,再到Framework服务集成的完整链路,实现蓝牙设备扫描、配对与数据传输。典型场景包括工业平板、广告机等Android 7设备。本文聚焦RK3399平台,详细拆解蓝牙移植各层配置与避坑经验,助力开发者高效完成系统集成。

weixin_32239523的博客 193

STM32G474串口调试避坑指南:从CubeMX配置到中断收发,手把手教你搞定USART1

本文详细解析了STM32G474串口调试中的常见问题,从CubeMX配置到中断收发,提供USART1的避坑指南。涵盖时钟树同步、GPIO模式选择、中断接收逻辑、波特率偏差修正等关键点,帮助开发者高效解决串口通讯难题,提升嵌入式开发效率。

weixin_29191081的博客 208

11.6寸eDP显示屏添加以及所遇问题总结

11.6寸eDP显示屏添加以及所遇问题总结

Android framework 4991

跨厂商网络设备的RADIUS认证:Windows NPS的兼容性与最佳实践

本文详细探讨了Windows NPS在多厂商网络环境中的RADIUS认证实践,特别针对华为、华三、思科等主流设备的兼容性问题提供解决方案。从基础配置到高级优化,涵盖VSA属性映射、认证协议选择及安全加固措施,帮助企业实现统一身份认证并提升网络安全性。

weixin_29213827的博客 415

《深入 UFS Explorer:自定义 RAID 配置指南》

UFS Explorer支持以虚拟模式组装任何受支持的RAID配置,以便后续访问其内容或恢复丢失数据。启动RAID构建器;向RAID构建器主内容区域的列表中添加RAID组件;为不可用组件插入占位符(需当前RAID级别支持且软件兼容);调整组件的准确顺序;在“虚拟RAID配置”区域设置RAID参数;以虚拟模式组装阵列各部分。程序主窗口“存储设备导航面板”中打开的任何存储设备(包括驱动器、逻辑卷、磁盘镜像、虚拟磁盘及其他复杂存储设备)均可作为RAID组件。

melonbo的专栏 1395

RK3399 GT1X触摸屏驱动调试笔记

硬件环境 1.Firefly AIO-3399(AI)开发版; 2.恒智的5寸电容触摸屏800X480,I2C驱动支持GT5688。 操作系统 Android 7.2 for rockship Step-1 查阅AIO-3399(AI)原理图,确定I2C的Slave Device Addr地址长度 通过RK3399的原理图可以了解到I2C的Slave Addr地址长度为7Bita,这个地址长度十分...

Bin 7200

Linux CentOS7文件系统(/dev/var)的容量扩充

原因是之前安装docker后,再想安装Nessus,系统说home、var文件系统的内存都不够。

JHoanna的博客 3215

RK3399学习

RK3399学习 韦东山rk3399:http://dev.t-firefly.com/forum-460-1.html firefly官网教程:http://wiki.t-firefly.com/zh_CN/Firefly-RK3399/started.html firefly官网3399资料:http://dev.t-firefly.com/forum-263-1.html 100ask 3399-pc教程:http://wiki.100ask.org/100ask_roc-rk3399-pc 韦东山全

weixin_43209963的博客 4748

装上大模型翅膀,程序员入职新公司如何快速上手代码(老员工如何选择大模型编程如虎添翼)

入职新公司,尤其是行业知识不懂的,面对前人堆积的屎山代码,各种文档又缺少的,有些技术自己又不懂的,如何快速上手代码,特别是借助AI大模型事半功倍的上手项目代码。进入新公司,我做的第一件事就是收集情报。我主动向同事们索要项目的相关资料,包括项目介绍文档、功能说明文档和业务流程图等。通过仔细阅读这些资料,可以对项目的背景和架构有了初步的了解。同时要逮住机会就向同事们请教项目的迭代历程和技术选型背后的考量。有时他们三言二语,可以为自己节省很多探索时间。在了解了项目的基本情况后,可以开始深入探究项目的业务流程。

大模型大数据攻城狮的专栏 1122

在armv8架构中,有哪些是serror

(3)、RAS(Reliability, Availability, and Serviceability)错误:一些对于系统的可靠性、可用性和可维护性有影响的错误可能会触发 SError。(2)、ECC(Error Correction Code)错误:在访问带有错误校验的内存(如ECC内存)时,如果发现错误校验失败,可能会产生SError。2、其实呢,大多数Serror都是实现定义的,真正实现的serror就没有多少个。Serror(也称System Error),是异步异常的一种,一般是来自。

baron-周贺贺-代码改变世界ctw 1011
上一篇: [RK3399][Android7.1]触摸屏TP,敦泰FT5436驱动移植
下一篇: [RK3399][Android7.1]适配 FIBOCOM的4G模块 NL668
杜杜dalek
博客等级 码龄17年 111粉丝 51原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值