luckfox-pico-max学习记录

0.文件编译及烧录

  1. SDK包在文件夹/home/tao/linux/luckfox/luckfox-pico-spi
  2. 应用程序样例在文件夹/home/tao/linux/luckfox-pico-spi/demo
  3. 编译:sudo ./build.sh生成的镜像文件在./luckfox-pico-spi/output/image中,将所有文件复制到windows电脑文件夹I:\BaiduNetdiskDownload\Luckfox_Pico_Pro_Max_Flash中
    在这里插入图片描述
  4. 打开桌面SocTool文件夹,启动soctool烧录软件,开发板按住boot键再上电,此时usb设备处弹出maskdown 134 搜索路径按钮找到镜像所在文件夹,点击下载
  5. 若有时一直烧录完一直重启可能是由于rkipc命令默认执行,将摄像头撤掉即可

1.编写IIC-MPU6050驱动

1.1buildroot中添加命令

  1. 我们需要使用 depmod、modprobe 或 insmod 这三个命令来加载驱动模块,所以根文件系统要存在这两个命令。卸载驱动模块的时候需要用到 rmmod 命令,所以需要确保 depmod、modprobe、insmod 和 rmmod 这四个命令都存在。因此需要在buildroot中进行添加
  2. 在busybox目录下,使用make menuconfig命令之后弹出编译菜单选项,​​确保 kmod 或者depmod被选中,​​勾选 kmod 后,depmod 会自动包含在根文件系统中。配置好后连续按esc,保存后重新进行编译:
make savedefconfig 
make
#(可选)export LD_LIBRARY_PATH= #若make时出现You seem to have the current working directory in your LD_LIBRARY_PATH environment variable.使用LD_LIBRARY_PATH=命令使变量为空
  1. 如果使用的是buildroot文件系统,则直接修改config文件,sysdrv/source/buildroot/buildroot-2023.02.6/package/busybox/busybox.config 将#CONFIG_DEPMOD is not set修改为CONFIG_DEPMOD=y
    在这里插入图片描述

  2. 重新烧录固件:编译选择分支,指定开发板型号

 ./build.sh lunch
 ./build.sh

如果报错权限不足,使用su切换超级用户;固件在output/img文件夹中

1.2 编写驱动程序

  1. 设备树文件
    在dts文件中对应接口i2c3下添加设备
&i2c3 {
	status = "okay";
	pinctrl-0 = <&i2c3m1_xfer>;
	clock-frequency = <100000>;
	status = "okay";
	mpu6050@68 {//添加设备,0x68是iic7位地址,
			compatible = "taojian,mpu6050";//用于匹配
			reg = <0x68>;
	 };
};
  1. mpu6050.h
#ifndef MPU6050_H
#define MPU6050_H
 
#define MPU6050_ADDR 0X68 /* AP3216C 器件地址 */
#define MPU6050_ADDRESS 0x68
#define	WHO_AM_I		    0x75	//IIC地址寄存器(默认数值0x68,只读)
#define	PWR_MGMT_1		  0x6B	//电源管理,典型值:0x00(正常启用)
#define	SMPLRT_DIV		  0x19	//陀螺仪采样率,典型值:0x07(125Hz)
#define	CONFIG			    0x1A	//低通滤波频率,典型值:0x06(5Hz)
#define	GYRO_CONFIG		  0x1B	//陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define	ACCEL_CONFIG	  0x1C	//加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define INT_PIN_CFG     0x37 	//旁路设置
#define USER_CTRL       0x6A 	//用户控制寄存器

/* mpu6050读取数据的寄存器地址 */
#define	ACCEL_XOUT_H	  0x3B
#define	ACCEL_XOUT_L	  0x3C
#define	ACCEL_YOUT_H	  0x3D
#define	ACCEL_YOUT_L	  0x3E
#define	ACCEL_ZOUT_H	  0x3F
#define	ACCEL_ZOUT_L	  0x40
#define	TEMP_OUT_H		  0x41
#define	TEMP_OUT_L		  0x42
#define	GYRO_XOUT_H		  0x43
#define	GYRO_XOUT_L		  0x44	
#define	GYRO_YOUT_H		  0x45
#define	GYRO_YOUT_L		  0x46
#define	GYRO_ZOUT_H		  0x47
#define	GYRO_ZOUT_L		  0x48
#endif
  1. mpu6050.c
/***************************************************************
 文件名 : mpu6050.c
 作者 : tj
 版本 : V1.0
 描述 : mpu6050 驱动程序
 其他 : 无
 ***************************************************************/
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/gpio.h>
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/of_gpio.h>
 #include <linux/semaphore.h>
 #include <linux/timer.h>
 #include <linux/i2c.h>
 //#include <asm/mach/map.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include "mpu6050.h"

 #define mpu6050_CNT 1
 #define mpu6050_NAME "mpu6050"//驱动加载后节点为/dev/mpu6050

 struct mpu6050_dev {
        struct i2c_client *client; /* i2c 设备 */
        dev_t devid; /* 设备号 */
        struct cdev cdev; /* cdev */
        struct class *class; /* 类 */
        struct device *device; /* 设备 */
        struct device_node *nd; /* 设备节点 */
        unsigned short xyzData[7];//存放数据,分别是xyz角加速度,温度,xyz偏移量
 };

 /*
 * @description : 从 mpu6050 读取多个寄存器数据
 * @param – dev : mpu6050 设备
 * @param – reg : 要读取的寄存器首地址
 * @param – val : 读取到的数据
 * @param – len : 要读取的数据长度
 * @return : 操作结果
 */
 static int mpu6050_read_regs(struct mpu6050_dev *dev, u8 reg,void *val, int len)
 {
    int ret;
    struct i2c_msg msg[2];
    struct i2c_client *client = (struct i2c_client *)dev->client;

    /* msg[0]为发送要读取的首地址 */
    msg[0].addr = client->addr; /* mpu6050 地址 */
    msg[0].flags = 0; /* 标记为发送数据 */
    msg[0].buf = &reg; /* 读取的首地址 */
    msg[0].len = 1; /* reg 长度 */

    /* msg[1]读取数据 */
    msg[1].addr = client->addr; /* mpu6050 地址 */
    msg[1].flags = I2C_M_RD; /* 标记为读取数据 */
    msg[1].buf = val; /* 读取数据缓冲区 */
    msg[1].len = len; /* 要读取的数据长度 */

    ret = i2c_transfer(client->adapter, msg, 2);//调用i2c_transfer进行发送数据
    if(ret == 2) {
        ret = 0;
    } else {
        printk("i2c rd failed=%d reg=%06x len=%d\n",ret, reg, len);
        ret = -EREMOTEIO;
    }
    return ret;
 }

 /*
 * @description: 向 mpu6050 多个寄存器写入数据
 * @param - dev: mpu6050 设备
 * @param - reg: 要写入的寄存器首地址
 * @param - val: 要写入的数据缓冲区
 * @param - len: 要写入的数据长度
 * @return : 操作结果
 */
 static s32 mpu6050_write_regs(struct mpu6050_dev *dev, u8 reg,u8 *buf, u8 len)
 {
        u8 b[256];
        struct i2c_msg msg;
        struct i2c_client *client = (struct i2c_client *)dev->client;
        
        b[0] = reg; /* 寄存器首地址 */
        memcpy(&b[1],buf,len); /* 将要写入的数据拷贝到数组 b 里面 */
        
        msg.addr = client->addr; /* mpu6050 地址 */
        msg.flags = 0; /* 标记为写数据 */
        msg.buf = b; /* 要写入的数据缓冲区 */
        msg.len = len + 1; /* 要写入的数据长度 + 寄存器长度*/

        return i2c_transfer(client->adapter, &msg, 1);//写数据就只有一个msg
 }
static void mpu6050_write_reg(struct mpu6050_dev *dev, u8 reg,u8 data)//向 mpu6050 1个寄存器写入数据
{
        u8 buf = 0;
        buf = data;
        mpu6050_write_regs(dev, reg, &buf, 1);
}

 /** @description : 读取 mpu6050 的数据*/
 void mpu6050_readdata(struct mpu6050_dev *dev)
 {
    unsigned char buf[14];//7组数据每组两字节
    /* 循环读取所有传感器数据 */
    mpu6050_read_regs(dev, ACCEL_XOUT_H,buf,14); 
    for(int i=0;i<7;i++)
        dev->xyzData[i]=((unsigned short )buf[i*2] << 8) | buf[i*2+1];
    dev->xyzData[3] = (365 + ( (unsigned short )(dev->xyzData[3]) /34)) ;//温度数据转换
 }

 /*
 * @description : 打开设备
 * @param – inode : 传递给驱动的 inode
 * @param - filp : 设备文件,file 结构体有个叫做 private_data 的成员变量
 * 一般在 open 的时候将 private_data 指向设备结构体。
 * @return : 0 成功;其他 失败
 */
 static int mpu6050_open(struct inode *inode, struct file *filp)//c程序使用open调用时执行的函数
 {
        /* 从 file 结构体获取 cdev 指针,再根据 cdev 获取 mpu6050_dev 首地址 */
        struct cdev *cdev = filp->f_path.dentry->d_inode->i_cdev;
        struct mpu6050_dev *mpu6050dev = container_of(cdev,struct mpu6050_dev, cdev);

        /* 初始化 mpu6050 */
        printk("Init mpu6050 start\r\n");
        mpu6050_write_reg(mpu6050dev,PWR_MGMT_1 , 0x00); 
        mpu6050_write_reg(mpu6050dev,SMPLRT_DIV, 0x07); 
        mpu6050_write_reg(mpu6050dev,CONFIG , 0x06); 
        mpu6050_write_reg(mpu6050dev, INT_PIN_CFG,0x42 ); 
        mpu6050_write_reg(mpu6050dev,USER_CTRL ,0x40 ); 
        mpu6050_write_reg(mpu6050dev, ACCEL_CONFIG,0x00 ); 
        mpu6050_write_reg(mpu6050dev, GYRO_CONFIG,0x18 ); 
        mdelay(50); 
        printk("Init mpu6050 over!!\r\n");
        return 0;
 }

 /*
 * @description : 从设备读取数据
 * @param - filp : 要打开的设备文件(文件描述符)
 * @param - buf : 返回给用户空间的数据缓冲区
 * @param - cnt : 要读取的数据长度
 * @param - offt : 相对于文件首地址的偏移
 * @return : 读取的字节数,如果为负值,表示读取失败
 */
 static ssize_t mpu6050_read(struct file *filp, char __user *buf,size_t cnt, loff_t *off)
 {
       
        unsigned short data[7];
        long err = 0;
       
        struct cdev *cdev = filp->f_path.dentry->d_inode->i_cdev;
        struct mpu6050_dev *dev = container_of(cdev, struct mpu6050_dev,cdev);
    
        mpu6050_readdata(dev);
        for(int i=0;i<7;i++)
            data[i] = dev->xyzData[i];
       
        err = copy_to_user(buf, data, sizeof(data));
        return 0;
 }

 /*
 * @description : 关闭/释放设备
 * @param - filp : 要关闭的设备文件(文件描述符)
 * @return : 0 成功;其他 失败
 */
 static int mpu6050_release(struct inode *inode, struct file *filp)
 {
    return 0;
 }

 /* mpu6050 操作函数 */
 static const struct file_operations mpu6050_ops = {
        .owner = THIS_MODULE,
        .open = mpu6050_open,
        .read = mpu6050_read,
        .release = mpu6050_release,
 };

 /*
 * @description : i2c 驱动的 probe 函数,当驱动与设备匹配以后此函数就会执行
 * @param – client : i2c 设备
 * @param - id : i2c 设备 ID
 * @return : 0,成功;其他负值,失败
 */
 static int mpu6050_probe(struct i2c_client *client,const struct i2c_device_id *id)
 {
    int ret;
    struct mpu6050_dev *mpu6050dev;
    
    mpu6050dev = devm_kzalloc(&client->dev, sizeof(*mpu6050dev),GFP_KERNEL);
    if(!mpu6050dev)
        return -ENOMEM;
    
    /* 注册字符设备驱动 */
    /* 1、创建设备号 */
    ret = alloc_chrdev_region(&mpu6050dev->devid, 0, mpu6050_CNT,mpu6050_NAME);
    if(ret < 0) {
        pr_err("%s Couldn't alloc_chrdev_region, ret=%d\r\n",mpu6050_NAME, ret);
        return -ENOMEM;
    }

    /* 2、初始化 cdev */
    mpu6050dev->cdev.owner = THIS_MODULE;
    cdev_init(&mpu6050dev->cdev, &mpu6050_ops);
    
    /* 3、添加一个 cdev */
    ret = cdev_add(&mpu6050dev->cdev, mpu6050dev->devid,mpu6050_CNT);
    if(ret < 0) {
        goto del_unregister;
    }
 
    /* 4、创建类 */
    mpu6050dev->class = class_create(THIS_MODULE, mpu6050_NAME);
    if (IS_ERR(mpu6050dev->class))
        goto del_cdev;

    /* 5、创建设备 */
    mpu6050dev->device = device_create(mpu6050dev->class, NULL,mpu6050dev->devid, NULL, mpu6050_NAME);
    if (IS_ERR(mpu6050dev->device)) 
        goto destroy_class;
    
    mpu6050dev->client = client;
    /* 保存 mpu6050dev 结构体 */
    i2c_set_clientdata(client,mpu6050dev);

    return 0;

destroy_class:
    device_destroy(mpu6050dev->class, mpu6050dev->devid);
del_cdev:
    cdev_del(&mpu6050dev->cdev);
del_unregister:
    unregister_chrdev_region(mpu6050dev->devid, mpu6050_CNT);
    return -EIO;
 }

 /*
 * @description : i2c 驱动的 remove 函数,移除 i2c 驱动的时候此函数会执行
 * @param - client : i2c 设备
 * @return : 0,成功;其他负值,失败
 */
 static int mpu6050_remove(struct i2c_client *client)
 {
    struct mpu6050_dev *mpu6050dev = i2c_get_clientdata(client);
    /* 注销字符设备驱动 */
    /* 1、删除 cdev */
    cdev_del(&mpu6050dev->cdev);
    /* 2、注销设备号 */
    unregister_chrdev_region(mpu6050dev->devid, mpu6050_CNT);
    /* 3、注销设备 */
    device_destroy(mpu6050dev->class, mpu6050dev->devid);
    /* 4、注销类 */
    class_destroy(mpu6050dev->class);
    return 0;
 }

 /* 传统匹配方式 ID 列表 */
 static const struct i2c_device_id mpu6050_id[] = {
    {"taojian,mpu6050", 0}, //字符串和设备树文件中一致
    {}
 };

 /* 设备树匹配列表 */
 static const struct of_device_id mpu6050_of_match[] = {
    { .compatible = "taojian,mpu6050" },
    { /* Sentinel */ }
 };

 /* i2c 驱动结构体 */ 
 static struct i2c_driver mpu6050_driver = {
    .probe = mpu6050_probe,
    .remove = mpu6050_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name = "mpu6050",
        .of_match_table = mpu6050_of_match,
    },
    .id_table = mpu6050_id,
 };
 
 /*
 * @description : 驱动入口函数
 * @param : 无
 * @return : 无
 */
 static int __init mpu6050_init(void)
 {
    int ret = 0;
    ret = i2c_add_driver(&mpu6050_driver);
    return ret;
 }

 /*
 * @description : 驱动出口函数
 * @param : 无
 * @return : 无
 */
 static void __exit mpu6050_exit(void)
 {
    i2c_del_driver(&mpu6050_driver);
 }

 /* module_i2c_driver(mpu6050_driver) */

 module_init(mpu6050_init);
 module_exit(mpu6050_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("TAOJIAN");
 MODULE_INFO(intree, "Y");
  1. Makefile文件
KERNELDIR := /home/tao/linux/luckfox/luckfox-pico-spi/sysdrv/source/kernel#内核文件所在目录
CURRENT_PATH := $(shell pwd)
obj-m := mpu6050.o
ccflags-y += -std=gnu11 
build: kernel_modules
kernel_modules:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
  1. 编译生成
make ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf-

此时在文件夹内生成mpu6050.ko驱动文件

1.3编写测试应用程序

  1. mpu6050App.c
#include "stdio.h"
 #include "unistd.h"
 #include "sys/types.h"
 #include "sys/stat.h"
 #include "sys/ioctl.h"
 #include "fcntl.h"
 #include "stdlib.h"
 #include "string.h"
 #include <poll.h>
 #include <sys/select.h>
 #include <sys/time.h>
 #include <signal.h>
 #include <fcntl.h>
 /*
 * @description : main 主程序
 * @param - argc : argv 数组元素个数
 * @param - argv : 具体参数
 * @return : 0 成功;其他 失败
 */
 int main(int argc, char *argv[])
 {
        int fd;
        char *filename;
        unsigned short databuf[7];
        unsigned short ir, als, ps;
        int ret = 0;

        if (argc != 2) {
            printf("Error Usage!\r\n");
            return -1;
        }
        filename = argv[1];
        fd = open(filename, O_RDWR);
        if(fd < 0) {
            printf("can't open file %s\r\n", filename);
            return -1;
        }
        while (1) {
            ret = read(fd, databuf, sizeof(databuf));
            if(ret == 0) { /* 数据读取成功 */
                for(int i=0;i<7;i++)
                    printf(" %d ", databuf[i]);
                printf("\r\n");
            usleep(200000); /*100ms */
        }
        close(fd); /* 关闭文件 */ 
 return 0;
 }
  1. 交叉编译生成可执行程序mpu
    ./mpu /dev/mpu6050运行

1.4加载驱动

  1. 运行depmod命令:
    depmod: can’t change directory to ‘lib/modules/5.10.110’: No such file or directory
mkdir -p /lib/modules/5.10.110
cd /lib/modules/5.10.110#将ko驱动复制到此文件夹
depmod
modprobe mpu6050.ko

在这里插入图片描述

2.LCD2Inch4

  1. 连接示意:
  2. 连接后记得重启上电:
cat  /dev/urandom > /dev/fb0#测试命令屏幕花屏
cat /dev/zero > /dev/fb0     #清屏

请添加图片描述

<think>好的,我现在需要帮助用户了解如何配置BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk这个文件。首先,我得确定这个文件的作用和结构。 用户提到的文件名中有Buildroot和RV1106,这应该是一个Buildroot的板级配置文件,用于Luckfox Pico Pro开发板的IPC(网络摄像机)应用,并且配置为从SD卡启动。我需要回忆Buildroot的配置机制,通常Board Config文件会定义目标设备的硬件特性、内核配置、分区表等。 接下来,我需要考虑用户可能的配置需求,比如启动方式、存储设置、外设支持等。用户可能想修改分区大小、启动参数、内核选项,或者添加特定的驱动和软件包。 然后,我需要检查文件中的常见配置项,例如: - 目标架构(ARM或RISC-V) - Linux内核版本和配置 - 根文件系统类型和大小 - 启动加载器(U-Boot)设置 - 硬件特性,如GPU、DSP支持 - 预安装的软件包列表 还要注意SD卡启动相关的配置,比如分区表、boot分区的位置和大小,可能涉及到的脚本或环境变量设置。例如,是否定义了BOARD_BOOT_CMD来指定从SD卡加载内核和根文件系统。 另外,用户可能需要调整根文件系统的大小,或者启用特定的功能模块,比如摄像头驱动、视频编码、网络服务等,这些都是IPC应用的关键部分。 需要提醒用户注意配置项的语法,比如使用:=进行赋值,避免空格等常见错误。同时,修改后可能需要重新编译整个系统,并生成SD卡镜像,所以需要指导用户如何执行编译步骤,比如运行make命令。 可能还需要解释一些变量,例如BR2_TARGET_ROOTFS_EXT2_SIZE用来设置根文件系统的大小,BR2_PACKAGE_LUCKFOX_PACKAGE可能会包含一些预装的软件。 最后,应该建议用户参考Buildroot的官方文档和Luckfox的开发者指南,确保配置的正确性,并在修改前备份原文件,避免配置错误导致系统无法启动。</think>以下是对 `BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk` 文件的配置解析及操作指南: --- ### **一、文件作用** 该文件是 **Buildroot 构建系统**的板级配置文件,专为 Luckfox Pico Pro 开发板(RV1106 芯片)的 IPC(网络摄像机)应用设计,主要控制: - **硬件特性**(CPU 架构/外设驱动) - **存储介质**(SD 卡分区/文件系统) - **内核配置**(Linux 内核选项) - **软件包选择**(预装应用程序) --- ### **二、关键配置项解析** #### **1. 基础硬件配置** ```makefile # 芯片架构 ARCH := arm # 交叉编译工具链 BR2_TOOLCHAIN_EXTERNAL_PATH := "$(TOPDIR)/../prebuilts/gcc/linux-x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf" ``` #### **2. 存储与分区** ```makefile # SD 卡启动配置 BOARD_BOOT_DEVICE := SDCARD # 根文件系统类型与大小 BR2_TARGET_ROOTFS_EXT2_SIZE := "512M" # 根据实际需求调整 ``` #### **3. 内核与设备树** ```makefile # 内核版本 LINUX_VERSION := 4.19.193 # 设备树文件 BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_LUCKFOX_PATH)/board/luckfox/rv1106/linux.config" ``` #### **4. 功能模块** ```makefile # 摄像头驱动 BR2_PACKAGE_MIPI_CAMERA=y # 视频编码库 BR2_PACKAGE_RK_MPP=y # 网络服务 BR2_PACKAGE_LIBV4L=y BR2_PACKAGE_ALSA_LIB=y # 音频支持 ``` #### **5. 应用层配置** ```makefile # 预装 IPC 应用程序 BR2_PACKAGE_LUCKFOX_IPC=y # 开机启动脚本 BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_LUCKFOX_PATH)/board/luckfox/rv1106/post-build.sh" ``` --- ### **三、典型配置场景** #### **场景 1:扩展根文件系统** ```makefile # 修改根文件系统大小 (默认 512MB → 1GB) BR2_TARGET_ROOTFS_EXT2_SIZE := "1024M" ``` #### **场景 2:启用 RTSP 流媒体** ```makefile # 添加 RTSP 服务器 BR2_PACKAGE_LIVE555=y BR2_PACKAGE_FFMPEG_GPL=y ``` #### **场景 3:调整启动参数** ```makefile # 修改内核启动参数 (例如设置静态 IP) BR2_LINUX_KERNEL_CMDLINE="console=ttyFIQ0 root=/dev/mmcblk0p2 rootwait rootfstype=ext4 ip=192.168.1.100" ``` --- ### **四、操作流程** 1. **备份原文件** ```bash cp BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk.bak ``` 2. **修改配置** ```bash vim BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk ``` 3. **重新编译系统** ```bash make clean && make ``` 4. **烧录镜像** ```bash sudo dd if=output/images/sdcard.img of=/dev/sdX bs=4M status=progress ``` --- ### **五、注意事项** 1. **变量语法**:使用 `:=` 赋值避免递归展开 2. **依赖关系**:启用功能模块时需确认依赖包是否选中 3. **分区对齐**:修改分区大小时保持 4K 对齐(例如 `512M` → `516M`) 建议参考官方文档: - [Buildroot 手册](https://buildroot.org/downloads/manual/manual.html) - [Luckfox SDK 说明](https://wiki.luckfox.com/Luckfox-Pico-Pro/Start)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值