OpenHarmony之内核层
OpenHarmony之内核层目录
OpenHarmony之内核层
目录
OpenHarmony简介
技术架构
技术特性
硬件互助,资源共享
一次开发,多端部署
统一OS,弹性部署
系统类型
内核层
内核子系统
LiteOS
LiteOS-M
LiteOS-A
Linux
内核增强特性
Patch合入流程
HCK
KAL
驱动子系统
驱动架构
驱动开发
平台驱动
外设驱动
驱动架构代码说明
思考
参考
OpenHarmony简介技术架构OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的组件。OpenHarmony技术架构如下所示:
技术特性硬件互助,资源共享主要通过下列模块达成
分布式软总线
分布式软总线是多设备终端的统一基座,为设备间的无缝互联提供了统一的分布式通信能力,能够快速发现并连接设备,高效地传输任务和数据。
分布式数据管理
分布式数据管理位于基于分布式软总线之 ...
OpenHarmony之HDF驱动框架
OpenHarmony之HDF驱动框架目录
OpenHarmony之HDF驱动框架
目录
概述
驱动模型
驱动加载
按需加载
按序加载(默认加载策略)
异常恢复(用户态驱动)
驱动服务管理
驱动消息机制管理
配置管理
配置语法
配置生成
平台驱动举例
统一服务模式
独立服务模式
外设驱动举例
思考总结
参考
概述HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的驱动管理的开发环境,力求做到一次开发,多系统部署。
驱动加载HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能
驱动服务管理HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务
驱动消息机制HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息
配置管理HCS是HD ...
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 ...