Allwinner orangepi-zero2 driver writing

Compile kernel

Before writing the driver, go to the official website to download the manual, skip to 5. First compile the kernel and follow
the manual, no problem. (The article said that the source of Tsinghua University needs to be switched) (I did not switch) (On the contrary, many errors occurred when switching)

http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-Zero-2.html

Kernel compilation and driver writing are required, and a compiled kernel is required.
After the compilation is successful, you will see that there is vmlinux in the source tree directory. If it fails, there will be no such file.

To expand, there are several ways to compile the kernel for other boards (you don’t need to look at it): The following is the kernel compilation for the Raspberry Pi board

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
指定ARM架构   指定编译器                      树莓派          主要核心指令
第一种方式:
	cp 厂家.config .config
第二种方式:
	make menuconfig 一项项配置,通常是基于厂家的config来配置
第三种方式:
	完全自己来

Compile :

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs

After the compilation is successful, you will see that there is vmlinux in the source tree directory. If it fails, there will be no such file.
After success, the target zImage image will be under arch/arm/boot.

Package zImage into xxx.img available for Raspberry Pi
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img

Let’s use this as an extension. Each kernel compilation may be different. Please check the merchant’s manual for details.

Driver writing framework

There are two ways to load the driver:

  • * Compiled into the kernel zImage includes the driver
  • Generate the driver file xxx.ko in M ​​module mode. After the system is started, load it through the command inmosd xxx.ko

driver framework

#include <linux/fs.h>				//file_operations声明
#include <linux/module.h>			//module_init module_exit声明
#include <linux/init.h>				//__init__exit 宏声明
#include <linux/device.h>			//class device 声明
#include <linux/uaccess.h>			//copy_from_user的头文件
#include <linux/types.h>			//设备号dev_t类型声明
#include <asm/io.h>					//ioremap iounmap的头文件


static struct class *pin4_class;
static struct device *pin4_class_dev;

static dev_t devno;            //设备号
static int major =231;       //主设备号
static int minor =0;          //次设备号
static char *module_name="pin4";   //模块名

//ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
static ssize_t pin4_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    
    
        printk("pin4_read\n");
        return 0;
}

static int pin4_open(struct inode *inode,struct file *file)
{
    
    

        printk("pin4_open\n");		//内核打印函数,和printf类似
        return 0;
}

static ssize_t pin4_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)
{
    
    
        printk("pin4_write\n");
        return 0;
}

static struct file_operations pin4_fops = {
    
    
        .owner = THIS_MODULE,
        .open  = pin4_open,
        .write = pin4_write,
        .read  = pin4_read,
};
//static int __init
static int  pin4_drv_init(void)
{
    
    
        int ret;
        devno = MKDEV(major,minor);
        ret   = register_chrdev(major, module_name,&pin4_fops);
        pin4_class=class_create(THIS_MODULE,"myfirstdemo");
        pin4_class_dev =device_create(pin4_class,NULL,devno,NULL,module_name);

        return 0;
}

static void pin4_drv_exit(void)
{
    
    

        device_destroy(pin4_class,devno);
        class_destroy(pin4_class);
        unregister_chrdev(major, module_name);
}

module_init(pin4_drv_init);
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");

This framework needs to cooperate with functions such as open in user mode. If you need to know the Linux kernel block diagram, you can
directly put the code here to cooperate with the driver framework.

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

int main()
{
    
    
    int fd;
    fd = open("/dev/pin4",O_RDWR);
    if(fd < 0){
    
    
        printf("open fail\n");
    }else {
    
    
        printf("open success\n");
    }
    fd = write(fd,'1',1);
}

Here are two files, first put them into the virtual machine for cross-compilation.
The driver code needs to be compiled into a module by the kernel, and then uploaded to the development board using scp.
After the ordinary code is compiled, it can also be uploaded to the development board.

Compile into module method:

使用aarch64-none-linux-gnu-先设置环境变量
cd ~
vi .bashrc
最后一行添加export PATH = $PATH: /……/bin//aarch64-none-linux-gnu-命令所在地位置
(在内核编译完成之后个toolchain文件夹在里面找)

In this folder, put your driver code

orangepi-build-main/kernel/orange-pi-4.9-sun50iw9/drivers/char

Modify the Makefile

vi Makefile

Add the driver we wrote

obj-m +=pin4Dev.o(文件名是啥就写啥后缀为.o即可)

Insert image description here
Save and exit wq

Compile using command

Go back to the path here in the kernel source code to compile.

orangepi-build-main/kernel/orange-pi-4.9-sun50iw9

input the command

ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- KERNEL=kernel make modules

Put the .ko file (if there is no ko, there is a problem with the kernel compilation, recompile it)

Cooperate with the following command

sudo insmod 文件.ko	//加载驱动
//加载驱动以后,在/dev/pin4就会看到

//但是此时运行我们的测试代码是打不开的,需要添加权限
sudo chmod 666 /dev/pin4	//所有用户可读可写
./a.out//测试文件,看到打开成功
//如果看不到输出信息可以输入

dmesg |grep pin4//可查看内核态输出信息

lsmod //查看驱动
sudo rmmod 文件//卸掉驱动

success;

Finish

If you have any questions, you are welcome to ask them and make progress together.

Guess you like

Origin blog.csdn.net/qq_52749711/article/details/132409329