orangepi zero2w H618驱动开发(一)

本文详细介绍了在Linux环境下使用orangepi-build进行内核源码6.1版本安装,配置驱动开发环境,如添加编译器路径,修改kernel配置,以及编写并加载LED设备驱动程序led_dev.c。作者还展示了如何通过Makefile编译模块并将其加载到开发板上进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 环境安装

按照官方操作安装开发环境和完成《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进行内核编译

  1. 驱动代码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");

  1. 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
  1. 编译加载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://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/

<think>好的,用户想了解如何在面试中描述基于全志芯片的智能家居项目经验。首先,我需要确定用户的需求是什么。用户可能在准备面试,特别是技术岗位,需要展示他们在嵌入式系统或智能家居项目中的经验。全志芯片,比如H616,常用于开发板如Orange Pi,所以需要结合具体的技术细节。 接下来,我应该考虑如何结构化回答。通常,面试中描述项目经验可以采用STAR法则(情境、任务、行动、结果)。但用户可能需要更具体的指导,比如技术选型、开发流程、问题解决等。需要结合全志芯片的特点,比如低功耗、多媒体处理能力,以及智能家居的应用场景。 然后,要参考用户提供的引用内容。引用[2]提到了Orange Pi Zero2和全志H616的配置、刷机、网络设置和基于外设的开发,比如wiringPi。这提示在项目中可能涉及系统配置、外设驱动开发、网络功能等。需要将这些技术点融入项目描述中,展示实际的操作和解决问题的能力。 用户可能没有明确说出的是,他们需要具体例子或关键词来让面试官印象深刻。例如,如何优化系统启动时间,如何处理多线程数据采集,如何集成云服务等。需要强调技术细节和成果,比如功耗降低百分比、响应时间提升等量化指标。 还需要考虑面试官可能关心的问题,比如团队合作、遇到的挑战、创新点等。在描述项目时,不仅要讲技术,还要体现软技能,比如问题解决、学习能力。 最后,确保回答结构清晰,分点列出,涵盖项目概述、技术细节、成果,并附上相关问题,帮助用户进步准备。同时,引用相关参考资料,如引用[2]中的系统配置和开发流程,增强可信度。</think>### 如何描述基于全志芯片的智能家居项目经验 在面试中描述基于全志芯片的智能家居项目时,建议从**技术选型、开发流程、核心功能、难点突破**四方面展开,结合具体案例和量化成果,体现技术深度与综合能力。 --- #### 1. **项目背景与技术选型** - **需求场景**:明确项目目标,例如“开发支持语音控制、环境监测的低功耗智能家居网关,兼容Zigbee/Wi-Fi协议”。 - **芯片选型**:说明选择全志芯片(如$H616$)的原因,例如: - 低功耗设计(待机功耗<$0.5$W) - 多媒体处理能力(支持$4K$视频解码) - 丰富外设接口(如$GPIO$、$I2C$、$SPI$)[^2]。 --- #### 2. **开发流程与核心功能** - **系统搭建**: - 基于$Linux$系统定制镜像(参考Orange Pi Zero2的刷机流程[^2]) - 优化启动时间(从$30$秒缩短至$15$秒) - **关键模块实现**: ```python # 示例:传感器数据采集(伪代码) def read_sensor_data(): with spi.open(0) as bus: data = bus.read(reg_address, length) return decode_data(data) ``` - 多线程数据采集(温湿度、光照传感器) - 云端通信(通过$MQTT$协议上传至阿里云) --- #### 3. **难点与解决方案** - **功耗优化**: - 动态调整CPU频率(空闲时降至$408$MHz) - 传感器轮询间隔优化(能耗降低$20\%$) - **稳定性问题**: - 通过$wiringPi$库调试GPIO时,发现中断响应延迟,最终采用硬件去抖电路解决。 --- #### 4. **成果与延伸价值** - 量产设备$5000$台,平均故障率<$0.5\%$ - 项目代码开源至社区,推动全志生态发展[^3]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值