2025-04-11 09:40:32 +08:00

6.9 KiB
Raw Permalink Blame History

openHAL

openHAL对硬件资源统一管理对上层提供统一的硬件层API接口对底层芯片层API如CMSIS进行二次封装提供类Android Things、PikaPython、linux等风格接口。

  • 提供可靠且稳定的标准化接口,统一管理外设,实现资源的灵活复用;
  • 提供和主流软件平台兼容或适配的操作层,例如各种开源工程及系统;
  • openHAL和openAPP、openDDK构建open开发框架可用于对接各类SDK

功能单元 调用关系

开发准则

  • 暴露的接口尽量统一,用户可用的接口尽量全面,参数尽量封装在内部
  • 时间测量接口,初始化对应时间数组,每次调用会计时,通过导出数据可以分析时间消耗

功能矩阵

HAL startup create/delete open/close read/write ioctl/pmctl query
PAD
GPIO
UART
I2C
KPC - - - - - -
SCR - - - - - -
  • EC7XX系列PAD类比传统MCU的GPIO具有唯一标识作为其余外设的依赖
  • 除依赖IO的还有DMA/TIM等不依赖IO的IP

接口分类

OPEN API param[in] param[out] return brief
api_xxx_startup - - - 上电初始化
api_xxx_default - - - 数据解析
api_xxx_query - enum 查询接口
api_xxx_create 创建设备,动态表更新
api_xxx_open timeout inf enum 开启,回调,系统通知
api_xxx_apply func cnf enum 预注册
api_xxx_ioctl enum 配置设备
api_xxx_pmctl enum 配置设备功耗/模式
api_xxx_write - 写操作
api_xxx_read - 读操作
api_xxx_close func - enum 关闭,回调,系统通知
api_xxx_delete - enum 删除设备,动态表更新
api_test_xxx 测试接口

基本功能接口(兼容接口):

  • 获取/释放资源create()/delete()
  • 针对状态的查询接口 query()
  • 针对设备的操作和配置 ioctl()
  • startup()用于执行上电初始化相关数据可配置传入或读特定区域flash
  • default()用于解析对应数据存储到该模块的flash区域结构化数据读取

调用类接口:

  • create兼容传统api参数实现对资源初始化和delete接口都会更新设备列表
  • open接口获取操作接口超时返回和close接口组合实现实现分时复用
  • apply接口预申请资源注册预配置接口在预申请资源被释放同时执行
  • ioctl是一个多功能可扩展接口可配置硬件参数直接操作底层设备

释放类接口:

  • close接口用于释放设备占用可传入执行函数用于配置在idle状态的执行内容
  • delete将还原设备状态发送系统通知之后设备可以被重新create和apply

单元测试:

  • 通过api_test_xxx()执行所有接口调用遍历,通过返回值确认执行情况

参考

Android Things

gpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
gpio.registerGpioCallback(mGpioCallback);
gpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_HIGH);// 低电平有效
gpio.setActiveType(Gpio.ACTIVE_LOW);...            // 将值切换为LOW
gpio.setValue(true);

Pika Python

采用类linux的设计所有类型的设备操作有且仅有类似于文件的5个标准APIopen()、close()、write()、read()、ioctl()

pika_dev* pika_hal_open(PIKA_HAL_DEV_TYPE dev_type, char* name);
int pika_hal_close(pika_dev* dev);
int pika_hal_ioctl(pika_dev* dev, PIKA_HAL_IOCTL_CMD cmd, ...);
int pika_hal_read(pika_dev* dev, void* buf, size_t len);
int pika_hal_write(pika_dev* dev, void* buf, size_t len);

使用方式

SUBSYS_OPENHAL_ENABLE           = y

配置文件通过CSV表格打包烧录内部文件系统更新方式包括

  • 在工程路径下,通过编译打包直接烧录
  • 通过Python脚本上传文件到文件系统

转存逻辑从文件中提取配置信息生成响应数据结构体再将对应的RAM结构体数据备份到指定区域开机加载指定区域校验后写入硬件配置。

相较于devicemanage的目标芯片属性openHAL支持更多外设资源扩展可以作为驱动标准件。

pad

API param[in] param[out] return brief
api_pad_startup - 加载默认配置
api_pad_default - enum
api_pad_create paddr config enum 申请接口
api_pad_open timeout enum 申请接口
api_pad_apply cb - 申请接口
api_pad_query paddr/usrId - enum 查询接口
api_pad_ioctl 配置接口
api_pad_pmctl 运行状态/功耗模式
api_pad_close usrId enum 关闭接口
api_pad_delete usrId enum 删除接口
api_test_pad usrId 测试接口
  • 如果其他虚拟设备占用了IO需要从所有可用IO列表中删除对应IO避免再分配

api_pad_startup

默认配置数据导出加载pad默认配置并初始化配置文件存储区域固定存储内容可通过文件升级方式更新

api_pad_default

默认配置数据的解析导入

api_pad_create

api_pad_open

系统级接口和close接口成对使用会malloc相应任务堆栈依赖freeRTOS消息机制管理状态和超时。

api_ret_t api_pad_open(uint32_t usrId,PadConfig_t *config,uint32_t timeout);
  • 如果在超时时间内申请的usrId是free状态则获取成功并以传入的config参数初始化;
  • 如果在超时时间内申请的usrId是close状态则获取成功pad的配置参数以config传出;
  • 超时未获取成功通过open_hal_ack_t枚举返回状态;

api_pad_apply

系统级接口非阻塞获取pad成功后回调可用于共用外设端口情况

int api_pad_apply(uint32_t usrId,void *cb);

gpio

  • 当前实现是基于单IO为单位所以不需要bit操作如果以port为单位可以进行16bit组合封装

uart

i2c

kpc

KpcConfig_t kpcConfig;
KPC_getDefaultConfig(&kpcConfig);

kpcConfig.validRowMask = KPC_ROW_3 | KPC_ROW_2 | KPC_ROW_1 | KPC_ROW_0;
kpcConfig.validColumnMask = KPC_COLUMN_2 | KPC_COLUMN_1 | KPC_COLUMN_0;

// 480ms (12*40ms) autorepeat delay
kpcConfig.autoRepeat.delay = 12;

KPC_init(&kpcConfig, KPC_callback);
KPC_eventQueueInit();
KPC_startScan();