ubuntu22.04搭建orangepi5plus开发环境

搭建orangepi5plus的开发环境可谓是一波三折,为此我总结了一个脚本文件全自动搭建环境

buiild_env_5p_driver.sh 文件内容

#!/bin/sh 

## 1.创建文件夹
ROOTPATH=$(pwd)/orangepi-5plus
mkdir -p ${ROOTPATH} && cd ${ROOTPATH}

## 2.下载交叉编译工具
wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz

tar xf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz

## 3.下载内核源码
git clone --depth=1 -b orange-pi-5.10-rk3588 https://github.com/orangepi-xunlong/linux-orangepi/

cd ${ROOTPATH}/linux-orangepi/

## 4.生成内核编译脚本
cat > make.sh << EOF
#!/bin/sh

## 0.clean
make ARCH=arm64 distclean

## 1.config
make -j 24 ARCH=arm64 CROSS_COMPILE=\${CROSS_COMPILE} rockchip_linux_defconfig

## 2.cross compile Image
make -j 24 ARCH=arm64 CROSS_COMPILE=\${CROSS_COMPILE}  Image

## 3.cross compile DTB
make -j 24 ARCH=arm64 CROSS_COMPILE=\${CROSS_COMPILE} rockchip/rk3588-orangepi-5-plus.dtb

## 4.cross compile modules
make -j 24 ARCH=arm64 CROSS_COMPILE=\${CROSS_COMPILE} modules

sync
exit 0
EOF

chmod +x make.sh
sync

## 5.编译内核源码
export CROSS_COMPILE=$(realpath ${ROOTPATH}/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-)
export KERNEL_SRC=$(realpath ${ROOTPATH}/linux-orangepi/)

./make.sh

cd ${ROOTPATH}

## 6.编译外部驱动
mkdir -p ${ROOTPATH}/drivers/helloworld/ && cd ${ROOTPATH}/drivers/helloworld/

### 6.1 生成Makefile文件
cat > Makefile << EOF
#obj-m则表示该文件要作为模块编译,目标编译成.ko模块。
obj-m := helloworld.o

ARCH=arm64

CC=\$(CROSS_COMPILE)gcc

PWD := \$(shell pwd)
#shell pwd会取得当前工作路径

all: 
XXX@\$(MAKE) -C \$(KERNEL_SRC) M=\$(PWD) modules ARCH=\$(ARCH) CROSS_COMPILE=\$(CROSS_COMPILE)

clean:
XXX@rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *.symvers *.mod
.PHONY:clean

EOF
sed -i "s/XXX/\t/g" Makefile
sync

### 6.2 驱动程序源码
cat > helloworld.c << EOF
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>

#define DRV_VERSION             ("V1.0.0")
#define DEV_NAME                ("helloworld")

static char buffer[128] = {0};

/* 读sys文件,例如cat /sys/class/misc/helloworld/drv_version */
static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRV_VERSION);
}

//定义一个名字为drv_version的设备属性文件
static DEVICE_ATTR(drv_version, S_IRUSR, version_show, NULL);

/* 读sys文件,例如cat /sys/class/misc/helloworld/buffer */
static ssize_t sys_buffer_write_usage(struct device *dev, struct device_attribute *attr, char *buf)
{
#if 1
        return sprintf(buf, "%s \n", buffer);
#else
        return sprintf(buf, "Usage:\n"
                                        "\t[echo \"xxx\" > /sys/class/%s/%s/buffer] \n",
                                                dev->class->name, dev_name (dev));
#endif
}

/* 写sys文件,例如 echo "xxx" > /sys/class/misc/helloworldister_rdwr/buffer */
static ssize_t sys_buffer_write_ops(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
        memset (buffer, 0, sizeof (buffer));
        count = snprintf (buffer, sizeof (buffer), "%s", buf);
    return count;
}
//定义一个名字为 buffer 的设备属性文件
static DEVICE_ATTR(buffer, S_IWUSR|S_IRUSR, sys_buffer_write_usage, sys_buffer_write_ops);

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

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

static long helloworld_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
        return 0;
}

static struct file_operations helloworld_fops = {
        .owner          = THIS_MODULE,
        .compat_ioctl           = helloworld_ioctl,
        .unlocked_ioctl = helloworld_ioctl,
        .open           = helloworld_open,
        .release        = helloworld_close
};

static struct miscdevice helloworld_dev = {
        MISC_DYNAMIC_MINOR,//255
        DEV_NAME,
        &helloworld_fops,
};

static int __init helloworld_module_init(void)
{
        int ret = -1;
        struct device *dev = NULL;
        ret = misc_register(&helloworld_dev);
        if (ret)
        {
                printk("[%s]ERROR: could not register %s devices\n", DEV_NAME, DEV_NAME);
                return ret;
        }
        // printk ("[%s] PAGE_SIZE=0X%lX \n", DEV_NAME, PAGE_SIZE);
        dev = helloworld_dev.this_device;

        //在设备目录下创建一个drv_version属性文件
        if(sysfs_create_file(&(dev->kobj), &dev_attr_drv_version.attr)) {
                printk ("[%s] sysfs_create_file error!\n", DEV_NAME);
                //return -1;
        }
        //在设备目录下创建一个buffer属性文件
        if(sysfs_create_file(&(dev->kobj), &dev_attr_buffer.attr)) {
                printk ("[%s] sysfs_create_file error!\n", DEV_NAME);
                // return -1;
        }

        printk ("[%s] load %s successfully! version is %s\n", DEV_NAME, DEV_NAME, DRV_VERSION);
        return 0;
}

static void __exit helloworld_module_exit(void)
{
        struct device *dev = helloworld_dev.this_device;

        sysfs_remove_file (&(dev->kobj), &dev_attr_buffer.attr);
        sysfs_remove_file (&(dev->kobj), &dev_attr_drv_version.attr);

        misc_deregister(&helloworld_dev);

        printk("[%s] rmmod %s ok!\n", DEV_NAME, DEV_NAME);
}

module_init(helloworld_module_init);
module_exit(helloworld_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");
MODULE_DESCRIPTION("Helloworld driver");
EOF
sync

## 6.3 编译驱动
make clean && make

sync
exit 0

把这个文件放在任意目录下,然后执行:chmod +x buiild_5p_driver.sh && ./buiild_5p_driver.sh 即可。在运行前请确保能打开github(建议使用翻墙软件)
中图不报错的话就可以了,然后在makefile中把交叉编译链和内核路径修改一下。有问题请加微信:lingtu15679003191

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零涂

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值