Kconfig相关
Kconfig相关背景以前准备写一下Linux内核里的Kconfig,但一直迟迟没有动手,最近在看 Openharmony 相关的东西,发现它也可以通过Kconfig和Kconfiglib进行可视化配置,所以想借此机会在这一起记录一下
作用#define配置宏主要用来使能/关闭代码,如下面:
#define CONFIG_TEST_ENABLE
#ifdef CONFIG_TEST_ENABLE
... ... ...
#endif
或来定义配置参数,如下:
#define CONFIG_TEST_SHOW_STRING "Test 123"
#define CONFIG_TEST_SHOW_INT (123)
但是如果参数越来越多,或者配置之间的关系越来越复杂,就会让代码的可读性越来越差,管理越麻烦,且不直观。所以Kconfig就是用来解决这些问题的,管理这些配置参数,而且能够可视化地去配置它们
Kconfig简介Kconfig语言定义了一套完整的规则来表述配置项及配置项间的关系Kconfig是配置项的描述文件,支持设置配置项及其默认值,依赖关系等等,该文件还会继续依赖各 ...
OpenHarmony基于HDF简单驱动开发实例
OpenHarmony基于HDF简单驱动开发实例背景
OpenHarmony-3.0-LTS
qemu_small_system_demo
liteos_a
qemu
添加配置device/qemu/arm_virt/liteos_a/hdf_config/device_info/device_info.hcs
device_info 新增:
sample_host :: host {
hostName = "sample_host";
sample_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
preload = 1;
permission = 0664;
moduleName = "sample_driver&qu ...
OpenHarmony开发环境搭建
OpenHarmony开发环境搭建背景因为没有实体的开发硬件,且不想破坏原有的Linux环境,所以这里基于 Docker + QEMU 搭建开发环境
宿主机Linux系统
命令行方式
Docker
QEMU 6.2
Docker环境准备安装Docker在Ubuntu中,可以使用下面的命令来安装Docker:
sudo apt install docker.io
获取Docker镜像#获取小型系统镜像
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/docker_oh_small:3.2
#获取轻量系统镜像
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/docker_oh_mini:3.2
#获取标准系统镜像
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/docker_oh_standard:3.2
运行构建环境# 运行小型系统Docker ...
Linux之IR驱动
Linux之IR驱动背景在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。红外遥控成本很低,以前广泛应用在电视,空调等电器的控制上面,现在随着蓝牙遥控器慢慢普及,红外遥控越来越少,但在某些场景,还保留着红外通信
红外属于media子系统里面的rc(remote control)模块,所以相关驱动代码目录为 drivers/media/rc/
相关内核文档:
Documentation/devicetree/bindings/media/gpio-ir-receiver.txt
Documentation/devicetree/bindings/media/rc.yaml
下面就从红外的接收、发送和编解码协议简单记录下
接收红外接收的处理有很多种方式,有些soc有专门的硬件模块,有些使用的是通用的gpio,这里以常见的gpio为例,其他的都大同小异。
用通用的GPIO来接收红外原理比较简单,代码实现主要在:
drivers/media/rc/gpio-ir-recv.c
drivers/media/rc/rc-main.c
drivers/me ...
Python简单udp测试环境
Python简单udp测试环境有时候,在写UDP通信代码的时候,需要一个简单的测试环境,下面记录了UDP通信的2种简单的测试代码,可以根据自己的需求稍微修改
udp服务端:import socket
# AF_INET 表示使用IPv4, SOCK_DGRAM 则表明数据将是数据报(datagrams)
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp.bind(('0.0.0.0', 8999))
while True:
rec_msg, addr = udp.recvfrom(1024)
client_ip, client_port = addr
print('client_ip:', client_ip, 'client_port:', client_port)
print('msg from client:', rec_msg.decode('utf8'))
ack_msg = 'Hello, udp client.'
udp.sendto(ack_ms ...
Linux之PWM风扇驱动
Linux之PWM风扇驱动背景该驱动主要是用于PWM模块去驱动散热风扇,使用通用的PWM接口,只要主控Soc的PWM模块使用的是标准通用的PWM框架,则可以适用于任何主控Soc,与具体的硬件无关。
用户空间接口驱动程序给用户空间提供了相应hwmon的sysfs接口: /sys/class/hwmon/hwmon-x/,主要是对PWM的读写操作和风扇转速的读操作:
static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
int ret;
if (val < 0 || val > MAX_PWM)
return -EINVAL;
ret = __set_pwm(ctx, val);
if (ret)
return ret;
...
USB转串口CH343驱动
USB转串口CH343驱动背景在网上用9.9淘的一块ESP32-C3(RISC-V)的小开发板上,用的CH343的USB转串口。最近打算学习用Rust开发ESP32-C3,在Ubuntu上搭建开发环境的时候发现,Ubuntu20.04上默认使用的是 CDC-ACM 驱动,即生成的节点为/dev/ttyACM0,但是用Rust开发ESP32-C3,需要使用 VCP 驱动,于是在网上找到了官方(WCH-南京沁恒)的一份Linux驱动源码:https://github.com/WCHSoftGroup/ch343ser_linux
里面的文档也说明了使用 CDC-ACM 驱动的一些局限性:
The CDC-ACM driver has limited capabilities to control specific devices. This generic driver does not have any knowledge about specific device protocols. Because of this, device manufacturers can create ...
Rust之cargo简单熟悉
Rust之cargo简单熟悉还记得上一篇文章 –《Rust简单开发环境搭建》中,helloworld的例子是用cargo来管理的,今天我们就来聊聊这个cargo
cargo是什么?为什么需要这个cargo?cargo是Rust的包管理器,Rust的包分为2种,一种是二进制可执行的包,一种是库的包,默认情况下就是第一种binary包
在Rust里,一个库或者可执行程序叫做一个crate,一般简单情况下,我们可以直接使用Rust的编译器rustc来编译这个crate,但如果编译这个crate需要许多编译参数,包含许多依赖,或者需要其他构建工具,手动去操作就会很麻烦,而且也很难管理,这样包管理器cargo就应运而生了
cargo主要做以下4个工作:
引入两个包含包信息的元数据文件
获取并构建包的依赖项
用正确的参数调用rustc或其他构建工具来生成包
引入规则约定,使使用Rust包变得更容易
包结构下面是用cargo生成的包目录结构:
.
├── Cargo.lock
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── main.rs
│ └ ...
Rust简单开发环境搭建
Rust简单开发环境搭建整个环境搭建默认在X86的Linux环境(Ubuntu)下进行
环境搭建首先,要熟悉下 Rust 的几个基本东东:
rustup: Rust 版本管理器
cargo: Rust 包管理器
rustc: Rust 编译器
安装使用官方推荐的rustup方式进行安装,使用下面的一条命令即可:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
耐心等待,安装完成后,查看 Rust 版本:
$ rustc --version
rustc 1.69.0 (84c898d65 2023-04-16)
$ cargo version
cargo 1.69.0 (6e9a83356 2023-04-12)
切换版本切换 rustc 的版本, nightly或stable:
rustup install xxx(nightly/stable)
rustup default xxx(nightly/stable)
卸载Rust同样的,卸载 Rust 使用rustup即可:
rustup self un ...
fb的notifier
fb的notifier背景最近调试了一个BUG:一个平板使用hall传感器检测键盘保护套的开合,但是发现有时候合上保护套时,屏幕并没有关闭。
最后发现是CONFIG_FB=y配置没打开,导致hall传感器驱动里的fb的notifier没起作用,从而使获取的 suspend/resume 的状态异常,具体的细节不在这详述了,这里主要想扩展并记录下这个fb的notifier。
使用有时候,我们需要监听显示屏的一些事件,根据事件的状态来进行一些操作,比如常见的关闭显示屏时,触摸屏进入休眠等等
确认内核配置确认已打开CONFIG_FB_NOTIFY配置, 只要CONFIG_FB打开默认就打开了CONFIG_FB_NOTIFY
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB=y
代码实现这里主要以常用的FB_EVENT_BLANK事件为例,下面是部分伪代码实现:
struct yyy {
...
struct notifier_block fb_notif; /*FB callbac ...
SPI接口的ADC驱动调试
SPI接口的ADC驱动调试背景最近在学习IIO子系统,顺带调试了个SPI接口的ADC驱动,所以在这简单记录下。这里只简单介绍了适配一个简单SPI接口ADC驱动的流程,不过多深入框架子系统,更多关于IIO子系统的介绍,请见下一篇:
驱动开发dtsdts主要修改或新增以下几点:
spi master控制器相关配置
spi设备节点配置
引脚复用配置
如spi节点配置例子:
&spi0 {
status = "okay";
num-cs = <1>; /* Total number of chip selects */
aaa: aaa@0 {
status = "okay";
reg = <0>; /* Chip select used by the device. */
compatible = "yyy,xxx&quo ...
spidev相关
spidev相关背景有时候会发现,一些外挂的spi的flash或者外设用了spidev这个驱动,没有适配特定的驱动,到底spidev是个啥呢?
spidev:SPI userspace API下面是内核官方文档解释:
SPI devices have a limited userspace API, supporting basic half-duplexread() and write() access to SPI slave devices. Using ioctl() requests,full duplex transfers and device I/O configuration are also available.
它主要包括核内的spidev驱动,相当于spi设备的万能通用驱动, 类似于通用phy驱动,主要代码:
drivers/spi/spidev.c
include/uapi/linux/spi/spidev.h
使用dts匹配驱动设备匹配通用的spidev驱动即可,其他属性参数根据设备硬件特性来写,都是通用的spi属性,和spi.h头文件里面 ...