1.OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
2.LoRaWAN网关搭建
3.STM32H7教程第17章 STM32H7之GPIO的库l库HAL库API
4.HUAWEI LiteOS 移植过程
5.HAL库驱动框架简介
6.标准库和HAL库到底有什么不同?怎么选?
OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
市场上针对终端操作系统3GPP协议开发的相关资料较为稀缺,即便在Android领域,源码源码相关学习文档也较为有限,库l库更不用说专门的源码源码协议开发书籍了。这可能与市场需求有关,库l库目前市场上从事前后端软件开发的源码源码专题整顿网站源码人员最多,包括我自己。库l库
鉴于我在某手机协议开发团队工作过一段时间,源码源码对协议的库l库AP侧和CP侧开发都有所涉猎,因此我尝试基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)源码编写一些内容,源码源码旨在帮助大家了解协议开发领域,库l库尽可能将3gpp协议内容与OpenHarmony电话子系统模块相结合进行讲解。源码源码据我所知,库l库目前终端协议开发人才非常紧缺。源码源码首先声明,库l库我不是协议专家,且已离开该领域五六年,如有错误,欢迎指正。
谈到终端协议开发,我首先想到的就是RIL。
CP:Communication Processor(通信处理器),通常理解为modem侧,也可以理解为底层协议,这部分由各个modem芯片厂商完成(如海思、高通)。
AP:Application Processor(应用处理器),通常指手机终端,通常理解为上层协议,主要由操作系统Telephony服务进行处理。
RIL:Radio Interface Layer(无线电接口层),通常理解为硬件抽象层,即AP侧将通信请求传给CP侧的中间层。
AT指令:AT指令是应用于终端设备与PC应用之间连接与通信的指令。
常规的Modem开发与调试可以使用AT指令进行操作,而各家的Modem芯片的AT指令都会有各自的差异。因此,手机终端厂商为了能在各种不同型号的产品中集成不同modem芯片,需要进行解耦设计来屏蔽各家AT指令的差异。
于是,OpenHarmony采用RIL对Modem进行HAL(硬件抽象),作为系统与Modem之间的通信桥梁,为AP侧提供控制Modem的接口,各Modem厂商则负责提供对应于AT命令的Vender RIL(这些一般为封装好的so库),从而实现操作系统与Modem间的解耦。
框架层:Telephony Service,电话子系统核心服务模块,主要功能是初始化RIL管理、SIM卡和搜网模块。对应OpenHarmony的源码仓库OpenHarmony/telephony_core_service。这个模块也是非常重要的一个模块,后期单独再做详细解读。
硬件抽象层:即我们要讲的RIL,对应OpenHarmony的源码仓库OpenHarmony/telephony_ril_adapter。RIL Adapter模块主要包括厂商库加载,业务接口实现以及事件调度管理。主要用于屏蔽不同modem厂商硬件差异,为上层提供统一的接口,通过注册HDF服务与上层接口通讯。
芯片层:Modem芯片相关代码,乌海房卡麻将源码即CP侧,这些代码各个Modem厂商是不开放的,不出现在OpenHarmony中。
硬件抽象层又被划分为hril_hdf层、hril层和venderlib层。
hril_hdf层:HDF服务,基于OpenHarmony HDF框架,提供hril层与Telephony Service层进行通讯。
hril层:hril层的各个业务模块接口实现,比如通话、短彩信、数据业务等。
vendorlib层:各Modem厂商提供的对应于AT命令库,各个厂商可以出于代码闭源政策,在这里以so库形式提供。目前源码仓中已经提供了一套提供代码的AT命令操作,至于这个是针对哪个型号modem芯片的,我后续了解清楚再补充。
下面是ril_adapter仓的源码结构:
本文解读RIL层很小一部分代码,RIL是如何通过HDF与Telephony连接上的,以后更加完整的逻辑梳理会配上时序图讲解,会更加清晰。首先,我们要对OpenHarmony的HDF(Hardware Driver Foundation)驱动框架做一定了解,最好是动手写一个Demo案例,具体的可以单独去官网查阅HDF资料。
首先,找到hril_hdf.c文件的代码,它承担的是驱动业务部分,源码中是不带中文注释的,为了梳理清楚流程,我给源码关键部分加上了中文注释。
上述代码中配置了对应该驱动的moduleName为"hril_hdf",因此我们需要去找到对应驱动的配置文件,以HiDV开发板为例,它的驱动配置在vendor_hisilicon/HiDV/hdf_config/uhdf/device_info.hcs代码中可以找到,如下:
这里可以发现该驱动对应的服务名称为cellular_radio1,那么telephony_core_service通过HDF与RIL进行通信肯定会调用到该服务名称,因此无查找telephony_core_service的相关代码,可以很快定位到telephony_core_service/services/tel_ril/src/tel_ril_manager.cpp该代码,该代码中有一个关键类TelRilManager,它用来负责管理tel_ril。
看tel_ril_manager.cpp中的一个关键函数ConnectRilAdapterService,它就是用来通过HDF框架获取RIL_ADAPTER的服务,之前定义过RIL_ADAPTER_SERVICE_NAME常量为"cellular_radio1",它就是在vendor_hisilicon/XXXX/hdf_config/uhdf/device_info.hcs中配置的hril_hdf驱动对应的服务名称。
LoRaWAN网关搭建
搭建LoRaWAN网关的方案使用南京仁珏的LoRaWAN网关开发组件M-GWS-EV。该组件以树莓派的CM3+作为主要处理器,搭载南京仁珏自研的M-GWS射频模块,集成GPS、RJ和4G模块,方便软件开发。
M-GWS-EV的接口包括GPS、RJ和4G模块等,与CM3+的SPI0接口相连接。GPIO7连接到M-GWS的LoRa_PERST管脚,确保硬件接口的正确配置。
搭建过程中,选择使用官方带桌面的酷q源码如何查看Raspberry Pi OS作为运行系统,直接运行CM3+模块。Semtech的官方代码库sx_hal提供快速搭建网关接入LoRaWAN服务器的方案,简化了开发过程。在本地目录下获取gws源码,通过编译工程生成可执行文件,然后安装到CM3+上,执行make install_conf完成配置项的安装。
为了解决复位问题,修改reset_lgw.sh脚本,使用Raspberry Pi OS提供的gpio操作工具替代,确保了启动gwstart.sh脚本的正确执行。配置global.json文件,修改server_address为自建服务器地址,完成基本配置。
接入Chirpstack服务器,通过浏览器登录后台,选择Gateways选项,添加网关的gateway_ID,完成服务器接入。至此,LoRaWAN网关的构建和服务器接入流程全部完成。
STMH7教程第章 STMH7之GPIO的HAL库API
.1 初学者重要提示
1、 如何阅读HAL库源码的问题
HAL库实现的函数有复杂的,也有简单的,简单的可以直接阅读代码。复杂的代码阅读起来比较耗时间,如果再配合参考手册抠每个寄存器的配置,那就更消耗时间了。所以对于这种函数,用户仅需了解每个部分实行的功能即可,而且HAL库都做了关键注释,以说明这部分实现的功能。所以用户没有必要去抠每个配置是如何实现的,仅需知道实现了什么功能。以后工程项目有需要了解具体配置时,再看即可。
2、 学习本章节前,务必保证已经学习了第章。
.2 GPIO涉及到的寄存器
GPIO外设涉及到的寄存器比较少,也容易理解,推荐大家阅读GPIO源码的时候将参考手册中对应的寄存器功能做一个了解。
很多时候,我们会直接调用GPIO的寄存器进行配置,而不使用HAL进行调用,以提高执行效率,特别是中断里面执行时。
.3 源文件stmh7xx_hal_gpio.c
这个文件主要是实现GPIO的引脚配置,学习这个文件注意事项:
.3.1 函数HAL_GPIO_Init
函数原型:
函数描述:
此函数用于初始化GPIO,此函数主要实现如下功能:
函数参数:
下面将结构体每个成员做个说明:
成员Pull用于配置上拉下拉电阻:
成员Speed用于配置GPIO速度等级,有下面四种可选:
成员Alternate用于配置引脚复用,可选择的复用方式在文件stmh7xx_hal_gpio_ex.h里面进行了定义,比如串口复用:
注意事项:
如果是程序运行期间的引脚状态切换,最好采用下面的方式或者直接寄存器操作:
.3.2 函数HAL_GPIO_DeInit
函数原型:
函数描述:
此函数用于复位IO到初始化状态,具体状态看函数原型中的注释即可。
函数参数:
使用举例:
此函数的使用比较简单,需要调用的时候直接调用即可。
.3.3 函数HAL_GPIO_ReadPin
函数原型:
函数描述:
此函数用于读取引脚状态,通过GPIO的网游租号平台源码IDR寄存器读取。
函数参数:
使用举例:
此函数的使用比较简单,需要调用的时候直接调用即可。
.3.4 函数HAL_GPIO_WritePin
函数原型:
函数描述:
此函数用于设置引脚输出高电平或者低电平。使用GPIO的BSRR寄存器进行设置,使用这个寄存器的好处是支持原子操作,由硬件支持的。原子操作的含义是操作过程不会被中断打断,而我们使用GPIO中另一个设置输出的寄存ODR是会被中断打断的。大家看下寄存器赋值操作对应的反汇编,是由多条汇编指令组成的。
函数参数:
使用举例:
此函数的使用比较简单,需要调用的时候直接调用即可。
.3.5 函数HAL_GPIO_TogglePin
函数原型:
函数描述:
此函数用于设置引脚的电平翻转,使用GPIO的ODR寄存器进行设置。
函数参数:
使用举例:
此函数的使用比较简单,需要调用的时候直接调用即可。
.3.6 函数HAL_GPIO_LockPin
函数原型:
函数描述:
此函数用于锁住GPIO引脚所涉及到的寄存器,这些寄存器包括GPIOx_MODER,GPIOx_OTYPER,GPIOx_OSPEEDR,GPIOx_PUPDR,GPIOx_AFRL 和 GPIOx_AFRH。
函数参数:
注意事项:
使用举例:
此函数的使用比较简单,需要调用的时候直接调用即可。
.4 如何使用HAL库的GPIO驱动
使用方法由HAL库提供(本章.3.1小节提供的例子就是这种方式):
第1步:使能GPIO所在总线的AHB时钟,__HAL_RCC_GPIOx_CLK_ENABLE()。
第2步:通过函数HAL_GPIO_Init()配置GPIO。
(1) 通过结构体GPIO_InitTypeDef的成员Mode配置输入、输出、模拟等模式。
(2) 通过结构体GPIO_InitTypeDef的成员Pull配置上拉、下拉电阻。
(3) 通过结构体GPIO_InitTypeDef的成员Speed配置GPIO速度等级。
(4) 如果选择了复用模式,那么就需要配置结构体GPIO_InitTypeDef的成员Alternate。
(5) 如果引脚功能用于ADC、DAC的话,需要配置引脚为模拟模式。
(6) 如果是用于外部中断/事件,结构体GPIO_InitTypeDef的成员Mode可以配置相应模式,相应的上升沿、下降沿或者双沿触发也可以选择。
第3步:如果配置了外部中断/事件,可以通过函数HAL_NVIC_SetPriority设置优先级,然后调用函数HAL_NVIC_EnableIRQ使能此中断。
第4步:输入模式读取引脚状态可以使用函数HAL_GPIO_ReadPin。
第5步:输出模式设置引脚状态可以调用函数HAL_GPIO_WritePin()和HAL_GPIO_TogglePin。
另外注意下面三个问题:
.5 总结
本章节就为大家讲解这么多,建议大家将GPIO的驱动源码结合参考手册中的寄存器通读一遍,对于我们后面章节的学习大有裨益。
HUAWEI LiteOS 移植过程
本文主要介绍了将LiteOS系统移植到STMFZGT6单片机开发板的过程。
在开发环境中,主要使用的工具包括以下几种。
本文主要记录了基于gcc开发的LiteOS移植过程,如果使用vscode的朋友,其原理相同,也可以作为参考。
在基础工程准备阶段,我使用的文字类页面游戏 源码是STMCubeMX生成的工程文件。生成过程如下:
1. 打开STMCubeMX程序。
2. 选择对应的芯片(STMFZGT6)。
3. 设置时钟来源为外部晶振。
4. Debug设置为串行(我用的是Jlink下载程序),为了方便移植,将系统tick来源设置为TIM1。
5. 配置LED的引脚为输出,我的开发板两个可控led分别为GPIOF_9和GPIOF_。
6. 设置系统时钟,配置为MHz。
7. 分别设置头文件和.c文件。
8. 中着急打了个病句...
9. 最后生成工程,选择为makefile生成格式。
工程将在对应文件夹内生成。
切换到文件夹内,执行make指令构建工程,将在build文件夹下生成你在cubemx里设置的工程名.elf文件。
此时修改Core文件夹下的main.c文件,就可以实现基础的基于HAL库的单片机控制。
修改Makefile文件,添加烧录命令如下:
此时执行make run就可以将.elf文件烧录到单片机中。
在移植LiteOS源码下载过程中,我所使用的源码是GitHub上的LiteOS代码的develop分支。
下载该仓库的代码,得到文件夹结构如下。
在STMCubeMX创建的工程下面新建文件夹为LiteOS(具体什么名看你心情),并将以下几个文件夹导入:
得到
OS_CONFIG文件夹下的target_config包含头文件是stmf的HAL头文件,如果是cortex-m3或者其他内核的单片机需要在这里修改包含的头文件,我的工程将之改为了#include "stmf4xx.h"。
此时需要修改你工程的Makefile文件,将新添加的LiteOS的代码添加到你的工程当中去。
具体修改如下:
此时执行make构建工程,会出现报错,说是重复定义了PendSV_Handler和SysTick_Handler,这是因为这两个函数在LiteOS系统中已经有了定义。这时要到Core/Src文件夹下的stmf4xx_it.c将重复定义的两个处理函数注释掉。
注释掉两个函数的定义。
此时再执行make clean删除原来的构建生成文件,重新make构建。
构建成功,能够生成elf文件,移植成功。
可以修改OS_CONFIG文件夹下的target_config文件,适配自己的开发板。
在移植测试阶段,可以根据STMCubeMX构建工程时所用的GPIO引脚在程序中定义任务。我的测试任务如下:
我的任务定义位于main.c,也可以将任务定义移动到单独的文件中。
功能就是两个led灯实现不同频率的闪烁。
可以观察到上面的led灯闪烁频率低于下面的led,任务创建成功,移植成功。
HAL库驱动框架简介
HAL库驱动框架简介旨在简化硬件抽象层,使得硬件操作对上层软件而言更加便捷。理解HAL库的关键在于其对外设的封装,以下为驱动框架的主要使用主线与功能。
首先,外设初始化是HAL库驱动框架中的重要一步,通过调用特定的初始化函数,可以完成外设的配置,如时钟、引脚等,确保外设在程序运行前处于正确的状态。初始化后,外设便可以被上层代码直接访问和控制。
在使用外设时,HAL库提供了丰富的API,将复杂的底层操作抽象为简洁的接口。例如,对GPIO的读写、定时器的计数等,使得开发者无需深入底层硬件细节,仅需调用对应的函数即可完成所需功能。
阻塞轮询(Polling)和中断(Interrupt)是两种常见的外设访问方式。阻塞轮询通过循环检查外设状态,直至满足特定条件后执行相应操作。这种方式简单直观,但效率较低,尤其是在高频率操作场景下可能会导致CPU资源浪费。相比之下,中断机制允许外设在状态改变时主动通知处理器,从而触发相应处理逻辑,实现更加高效的异步操作。
数据传输方面,DMA(Direct Memory Access)提供了硬件辅助的数据传输机制,使得数据可以在外设与内存之间直接移动,无需CPU介入。这对于数据密集型应用而言,能够显著提升系统性能。
全面了解HAL库涉及其各个层面的功能与实现细节。开发者需要熟练掌握初始化、外设访问、中断处理、DMA等核心概念,并通过实际项目实践,逐步积累经验。通过查阅官方文档、源代码注释以及社区资源,可以深入理解HAL库的内部机制,进而灵活运用其功能,解决实际问题。
标准库和HAL库到底有什么不同?怎么选?
通常新手在入门STM时,都会面临选择开发方式的决策,不同的方式对编程架构影响显著。主要选择为标准库和HAL库,而较少选择直接配置寄存器。虽然网络上有大量关于标准库、HAL库的描述,但对刚入门的朋友来说,可能难以直观理解这些开发方式之间的差异。本篇将以直白的方式,用作者的理解来阐述标准库、HAL库的区别,如有不妥之处,欢迎提出不同意见。
一、配置寄存器
对于熟悉单片机的开发者,可能有一部分会直接使用汇编语言操作寄存器实现功能。但到了STM,这种方法变得不太可行,因为STM的寄存器数量远超单片机的十倍,无法全部记忆。直接操作寄存器变得非常繁琐,需要频繁查阅芯片数据手册。然而,仍有一小部分人偏好直接配置寄存器,因其能更深入理解原理。
二、标准库
面对众多寄存器导致的开发困难,ST公司为每款芯片提供库文件,如stmF1xx...,包含常用宏定义和外设封装结构体。我们只需配置结构体变量成员即可修改外设配置寄存器,实现不同功能。这是目前最常用的方式,也是接触STM开发最常见的方式。
三、HAL库
HAL库是ST公司力推的开发方法,全称为Hardware Abstraction Layer(硬件抽象层)。库如其名,功能抽象,一眼难辨其作用。与标准库相比,它更注重节省开发时间,提供更高效的集成功能。例如,标准库可能需要多行代码实现的功能,HAL库只需一行。它还有效解决了程序移植问题,使用相通外设的程序可以轻松复制粘贴,前提是遵循相同外设设计。STMcube软件通过图形化配置生成HAL库工程文件,极大方便开发。然而,其高效性也带来了执行效率的低下,常被用户吐槽。
四、总结
综合上述,强烈推荐HAL库,原因有两个:一是自F7系列开始,ST公司已停止更新标准库,F7及以后无法使用标准库,表明公司主推HAL库。二是追求方便、模块化是行业趋势,高效、便捷的HAL库必将迅速发展。
学习HAL库的同时,底层原理同样重要,这是每个学有所成者共识。HAL库并非万能,结合底层理解,开发水准会显著提高。
五、STM HAL库与标准库的区别
1. 句柄
在标准库中,初始化外设(如USART)需要配置多个寄存器,通过结构体变量+初始化函数实现。而在HAL库中,使用全局句柄贯穿初始化流程,不仅包含基本参数,还包含更多与单片机相关的设置,如中断处理、DMA相关变量等。
2. MSP函数
MSP函数负责与单片机相关的初始化,与标准库不同,HAL库在初始化外设时,还会初始化与单片机相关的外设配置,如引脚配置。这使得HAL库具有极强的移植性,但同时增加了代码量和嵌套层级。
3. Callback函数
Callback函数简化应用层代码编写,用户只需设置句柄参数,由HAL库自动处理中断、数据读取等操作,无需手动清除标志位,增强代码逻辑性。
六、HAL库结构
STM的HAL库在STMCubeMX可视化配置工具的支持下,大大节省了开发时间。HAL库结构包含多个层次,从主头文件开始,到具体型号头文件,再到源码文件。其包含三大类API,宏定义用于中断、配置等操作,用户代码分为处理外设句柄、MSP、回调函数等。
整体来看,HAL库通过句柄、MSP、回调等机制,提供了强大的移植性和更清晰的编程结构,但带来了代码量增加和编译速度降低的挑战。开发者需根据项目需求权衡选择。
STM HAL库的框架结构
全文链接:
HAL库的框架结构涉及了Cortex系列微控制器软件接口标准(CMSIS)的背景,以及STM微控制器库的构建方式。CMSIS标准由ARM与芯片厂商共同制定,旨在解决不同芯片厂商生产的Cortex微控制器软件兼容性问题,提供通用API接口以简化移植工作。STM的库遵循CMSIS标准,分为三种类型,提供硬件抽象层,屏蔽硬件差异,便于软件移植。
MCU固件包包含HAL库,它是STM芯片开发的核心部分,文件结构清晰,分为Src和Inc两个主要部分,分别存储源码和头部文件。HAL库API函数遵循特定命名规则,提供初始化、读写、控制、状态和错误查询等功能。对寄存器位操作使用宏定义,便于高效操作。
HAL库设计借鉴面向对象思想,采用句柄概念抽象外设,简化用户代码编写。句柄贯穿整个外设操作流程,例如USART2初始化时定义句柄huart2,用于管理串口操作。句柄内部结构包含串口初始化数据类型,用于配置串口参数。初始化过程涉及配置寄存器和中断处理,确保外设功能正常。
总之,STM HAL库通过CMSIS标准和面向对象设计,提供了高效、统一的微控制器软件接口,简化了开发流程,提高了代码可移植性。
STMH7教程第章 STMH7的USART串口基础知识和HAL库API
本章内容深入讲解了STMH7的USART串口基础知识,包括其HAL库API的使用。相较于STMF1和F4系列,H7系列在串口功能上有所增强。.1 初学者须知
USART(通用同步异步收发器)是通信核心,异步串口(UART)是其常见形式。理解串口硬件框图至关重要,它展示了唤醒中断、中断处理、DMA传输、寄存器位置、FIFO功能及引脚互换等。.2 串口详解
串口硬件框图揭示了中断、DMA、时钟配置及数据传输路径。
STMH7串口功能强大,常用模式包括异步通信,支持多种中断和高级特性,如自适应波特率检测。
串口支持的数据帧格式和校验,以及发送时序图帮助理解中断机制。
.3 HAL库操作
使用HAL库配置串口涉及USART_TypeDef结构体、UART_HandleTypeDef的配置,以及GPIO、时钟、中断和DMA的底层设置。HAL库提供了操作寄存器和配置高级特性的便利。
串口初始化流程包括初始化结构体、GPIO配置、中断和DMA设置,以及高级特性和基础参数的配置。
.4 源码文件概述
主要函数如HAL_UART_Init、HAL_UART_Transmit和HAL_UART_Receive展示了HAL库API的使用示例。这些函数涉及的数据发送、接收和中断传输功能提供了实际操作指导。
.5 总结
深入理解USART的基础知识和HAL库API是STMH7开发的关键。随着实践的积累,这些内容将变得熟练。更多细节和实例可以参考原文链接获取。STM SPI DMA 源码解析及总结
一 前言
在调试STM的SPI接口时,我遇到了一个复杂的难题。解决这一问题花费了大量时间,这次经历促使我回顾并总结了STM的SPI代码。本文将以此为主线,分享我在这个过程中的心得。
二 初始化
STM SPI接口的初始化遵循标准流程,包括初始化和配置两部分。确保接口正确初始化,需注意以下几点:
1. 避免重复使用接口,确保其唯一性。
2. 检查接口硬件部分是否正常连接,可通过GPIO端口的电平检测。
3. 选择合适的系统主频,避免设置过高,以匹配SPI接口的速率。
三 数据收发
数据收发功能通过HAL库的API实现,主要包括:
1. 数据发送:`HAL_SPI_Transmit_DMA`函数。
2. 数据接收:`HAL_SPI_Receive_DMA`函数。
使用时应特别注意CS(Chip Select)信号的控制,确保在DMA操作期间保持CS低电平,避免数据丢失。
四 总结
在SPI开发中,遵循正确流程至关重要。面对问题,应基于对代码的理解和实践经验进行分析,而不是依赖计算机自动解决。正确处理初始化、数据收发等环节,避免常见错误,能有效提升开发效率。
STM驱动DHT(HAL库版)
一、DHT传感器工作原理
1. DHT传感器使用单总线通信方式,实现数据传输与控制。在操作中,其工作过程如下:
(1)设备首先检查总线上是否存在DHT设备,并确认设备的响应。
(2)随后,DHT传感器发送数据至STM。
二、STMCubeMX配置开发环境
选用STMFZET6开发板,DHT模块与PG5引脚连接,使用模拟IIC信号驱动。
1. 设置高速外部时钟。
2. 配置STLink烧录。
3. 配置定时器3。
4. 配置串口。
5. 配置时钟电路。
6. 设置项目名。
注意:使用Keil时,工具链选择MDK-ARM,STMCubeIDE选择STMCubeIDE,CLion选择SW4STM。
7. 选择生成的.h和.c文件。
三、DHT传感器驱动程序
编写dht.h和dht.c文件,实现传感器驱动程序。
主函数中重定义printf函数。
四、源码下载
代码可在github.com/LMFzzz/DHT...
2024-11-26 09:21
2024-11-26 08:58
2024-11-26 08:31
2024-11-26 08:24
2024-11-26 08:16
2024-11-26 07:55