一、 环境安装
按照官方操作安装开发环境和完成《Linux SDK——orangepi-build使用说明》章节
官方操作
linux内核源码的版本有6.1和5.4,我这选择的是6.1版本的
二、驱动开发
-
执行vim ~/.bashrc后,在文件最后加上
export CROSS_COMPILE=aarch64-none-linux-gnu- export ARCH=arm64 export PATH=/home/coolx/orangepi-build/toolchains/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin:$PATH#写入实际编译器地址 export GCC_COLORS=auto
-
拷贝orangepi-build/external/config/kernel/linux-6.1-sun50iw9-next.config到orangepi-build/kernel/orange-pi-6.1-sun50iw9目录下
-
修改orangepi-build/kernel/orange-pi-6.1-sun50iw9/scripts/setlocalversion 文件里的第142行,改为如下
139 # If the variable LOCALVERSION is set (including being set 140 # to an empty string), we don't want to append a plus sign. 141 scm=$(scm_version --short) 142 res="$res${scm:+}" 143 fi 144 145 echo "$res"
-
修改orangepi-build/kernel/orange-pi-6.1-sun50iw9/Makefile文件里的第5行,改为如下
1 # SPDX-License-Identifier: GPL-2.0 2 VERSION = 6 3 PATCHLEVEL = 1 4 SUBLEVEL = 31 5 EXTRAVERSION =-sun50iw9 6 NAME = Curry Ramen
进入orangepi-build/kernel/orange-pi-6.1-sun50iw9执行make menuconfig
先<Load>
linux-6.1-sun50iw9-next.config文件,然后<Save>
linux-6.1-sun50iw9-next.config这个文件,最后<Exit>
退出,执行make
进行内核编译
- 驱动代码led_dev.c如下
//led_dev.c
#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 devise声明
#include <linux/uaccess.h> //copy_from_user 的头文件
#include <linux/types.h> //设备号 dev_t 类型声明
#include <asm/io.h> //ioremap iounmap的头文件
static dev_t devno; //设备号
static int major =231; //主设备号
static int minor =0; //次设备号
static char *module_name="coolx_led"; //模块名
#define PC_CFG0_REG 0x0300B000 + 2 * 0x24 + 0x04 //PC配置寄存器 A:0 B:1 C:2 ....
#define PC_DATA_REG 0x0300B000 + 2 * 0x24 + 0x10//PC数据寄存器 A:0 B:1 C:2 ....
#define PIN_N 13 //第5个引脚
#define N (PIN_N % 8 * 4) //引脚x : x % 8 * 4
// 将该文件放在 orangepi-build-main/kernel/orange-pi-4.9-sun50iw9/drivers/char 下
static struct class *Coolx_class;
static struct device *Coolx_class_dev;
volatile unsigned int *gpio_con = NULL;
volatile unsigned int *gpio_dat = NULL;
/*打开设备*/
static int led_open (struct inode *node, struct file *filp)
{
if (gpio_con) {
/*打开成功*/
}
else {
return -1;
}
return 0;
}
/*写设备*/
static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
{
unsigned char val;
copy_from_user(&val, buf, 1);
printk("val = %c",val);
if (val)
{
*gpio_dat |= (1 << PIN_N);//引脚5设置1
}
else
{
*gpio_dat &= ~(1 << PIN_N);//引脚5设置0
}
return 1;
}
/*关闭设备*/
static ssize_t led_read (struct file *file1,char __user *buf,size_t count, loff_t *ppos)
{
return 0;
}
/*
* 设备操作函数结构体
*/
static struct file_operations file_operation = {
.owner = THIS_MODULE,
.open = led_open,
.write = led_write,
.read = led_read,
};
/* 设备初始化 */
int __init Coolx_led_init(void)
{
int ret;
devno = MKDEV(major,minor); //创建设备号
ret = register_chrdev(major, module_name, &file_operation);// cat /proc/devices
if (ret < 0) {
printk(KERN_ERR "fail\n");
return -1;
}
Coolx_class=class_create(THIS_MODULE,module_name);//由代码在Dev下自动生成设备 /sys/class
Coolx_class_dev =device_create(Coolx_class,NULL,devno,NULL,module_name); //创建设备文件 /dev/
printk(KERN_ERR "init \n");
gpio_con = (volatile unsigned int *)ioremap(PC_CFG0_REG, 1);//iounmap函数用于取消ioremap()所做的映射
//选择1
gpio_dat = (volatile unsigned int *)ioremap(PC_DATA_REG, 1);
//选择2
//gpio_dat = gpio_con + 4; //数据寄存器 指针+4是移动了4*4=16个字节 原来是0x24 现在是0x34
*gpio_con &= ~(7 << N); //7=111 取反000 20:22设置000 默认是0x7=111 失能
*gpio_con |= (1 << N); //设置输出 20:22设置001
*gpio_dat &= ~(1 << PIN_N); //第5个引脚初始化设置0
return 0;
}
void __exit Coolx_led_exit(void)
{
device_destroy(Coolx_class,devno);
class_destroy(Coolx_class);
/* 注销字符设备驱动 */
unregister_chrdev(major, module_name);
iounmap(gpio_con);//
iounmap(gpio_dat);
printk("exit!\r\n");
}
//注册模块加载函数
module_init(Coolx_led_init);
//卸载模块加载函数
module_exit(Coolx_led_exit);
//开源信息
MODULE_LICENSE("GPL");
- Makefile如下
#Makefile
# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
# 2.1 ARCH, 比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
# 请参考各开发板的高级用户使用手册
KERN_DIR = /home/coolx/orangepi-build/kernel/orange-pi-6.1-sun50iw9
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += led_dev.o
-
编译加载module
进入编写了led_dev.c 和 Makefile的目录下,执行make
编译module,完成后执行scp led_dev.ko orangepi@开发板局域网ip地址:/home/orangepi
将模块ko文件上传到开发板
进入开发板环境,加载模块,在/home/orangepi目录下执行
sudo insmod led_dev.ko
代码中将设备添加到了/dev下,手动添加方法:
查看设备:cat /proc/devices
==>得到 231 coolx_led
sudo mknod /dev/coolx_led c 231 0
查看设备文件:ls /dev
==>得到 coolx_led
关闭心跳灯:
sudo chmod 666 /sys/class/leds/green_led/trigger
sudo echo none > /sys/class/leds/green_led/trigger
可以看到绿色停止闪烁
给设备权限:sudo chmod 666 /dev/coolx_led
点亮led灯:echo -e -n "\x01" > /dev/coolx_led
(-e 是以16进制发送,-n 是不发送换行 , “\x01” 就是 0x01)
关闭led灯:echo -e -n "\x00" > /dev/coolx_led
恢复心跳灯:sudo echo heartbeat > /sys/class/leds/green_led/trigger
文章来源:https://www.toymoban.com/news/detail-772144.html
初学轻喷
参考:
https://blog.csdn.net/m0_53809203/article/details/134236670
http://www.orangepi.cn/orangepiwiki/index.php/%E4%B8%BB%E9%A1%B5
https://whycan.com/t_7577.html
https://www.100ask.net/文章来源地址https://www.toymoban.com/news/detail-772144.html
到了这里,关于orangepi zero2w H618驱动开发(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!