1.STM32L431移植华为LiteOS 物联网手把手教程
2.手把手教你丨小熊派移植华为 LiteOS-M
3.TinyML-TVM是如何驯服Tiny的(上)
4.鸿蒙轻内核M核源码分析:中断Hwi
5.为ä»ä¹è¦ç¨CMSIS RTOS
STM32L431移植华为LiteOS 物联网手把手教程
STML移植华为LiteOS教程
摘要本教程详细分享了将华为LiteOS移植到STML单片机EVB_M1开发板上的过程。1. 环境准备
硬件:EVB_M1开发板,专为NB-IoT设计,支持丰富传感器和STML4单片机,是开发利器。
软件:MDK ARM集成开发环境(MDK5.),加密c 程序源码 需安装STML4xx器件支持包,以及STMCubeMX生成裸机工程所需的JDK环境。
2. 软件配置
MDK安装与芯片支持包安装:通过Keil官网获取并安装。
STMCubeMX裸机工程:使用STMCubeMX生成STMLRCT6的工程,配置串口、时钟和功能模块。
LiteOS源码:从GitHub下载LiteOS的develop分支,主要关注arch、components/cmsis和kernel目录。
3. 内核移植步骤
使用STMCubeMX创建STML裸机工程,配置引脚、时钟和模块。
添加LiteOS源码,包括内核、CMSIS和arch相关代码。
配置OS,包括target_config.h文件的修改,如CPU频率、内存配置等。
在main.c中创建和初始化LiteOS任务,调用LOS_Start启动内核。
解决编译时的重复定义问题,如在stml4xx_it.c中使用__weak修饰Systick和pendsv函数。
4. 结果验证
成功编译并烧写后,运动源码通过串口可以看到两个任务交替运行,显示LiteOS已成功运行在STML EVB_M1开发板上。手把手教你丨小熊派移植华为 LiteOS-M
手把手教你:小熊派移植华为 LiteOS-M 的详细教程 本文将指导你如何将 LiteOS 适配到小熊派开发板,以便在 STM + LiteOS 等技术栈上实现高效功能。首先,我们来了解移植的前言和所需准备。一、硬件与软件环境
1.1 小熊派开发板 这款板子的外观图和具体参数在此处不再详述,但它是基于STML芯片的。 1.2 LiteOS简介 华为 LiteOS 是为物联网设计的轻量级RTOS,支持任务管理、内存管理等基础功能,还集成了IoT协议栈,方便与云平台交互。移植时,主要关注官方提供的调度内核代码和通过STMCubeMX配置的HAL库。二、STMCubeMX配置
利用CubeMX配置小熊派的时钟树、SystemTick定时器和GPIO口,以配合 LiteOS 的工作。设置完毕后生成MDK项目。三、获取与整理源码
由于新版本未支持MDK,使用旧版本代码,通过Git克隆仓库至本地。四、源码移植
在MDK工程目录下创建移植目录,将LiteOS内核文件、findbug源码CMSIS接口、配置文件和kernel源码逐一分类导入并配置编译路径。五、MDK配置与编译
导入文件后,调整路径,遇到缺少头文件问题时,根据芯片型号修改。注释掉部分STMCubeMX生成的中断处理代码,确保编译通过。六、验证与实验
编写测试代码,通过创建任务和初始化函数,验证移植是否成功。通过点灯操作,检查系统是否运行正常。TinyML-TVM是如何驯服Tiny的(上)
低成本、人工智能驱动的消费类设备的激增,激发了研究者对“裸智能”(低功耗、通常无操作系统)设备的兴趣。传统上,专家能在这些设备上运行某些模型,但为不同设备优化模型是个挑战,往往需要针对设备的手动优化。尤其是针对没有Linux支持的平台,没有可扩展的模型部署解决方案。因此,开发者通常需要创建一次性的定制软件堆栈,以管理资源和调度模型执行。easyhmi源码
尽管机器学习软件的优化并不是裸机领域特有的难题,它与GPU和FPGA等硬件后端的开发人员共同面对。TVM展现出了适应新硬件目标的能力,但在微控制器独特配置的挑战下,它之前还未能提供足够的支持。为解决这一问题,TVM扩展了微控制器后端,即µTVM(发音为“MicroTVM”),以在裸机设备上执行张量程序,并通过TVM内置的张量程序优化器AutoTVM自动优化这些程序。上图展示了µTVM+AutoTVM基础设施的概览。
µTVM+AutoTVM的实际应用
在讨论TVM/MicroTVM及其工作原理之前,我们先看一个实际应用示例。假设我们使用STMFZG板,它配备了一个强大的ARM Cortex-M7处理器,非常适合边缘人工智能应用。通过USB-JTAG端口将板连接至桌面,使用OpenOCD打开与设备的JTAG连接,从而通过µTVM使用设备无关的TCP套接字控制M7处理器。在桌面上运行TVM代码,执行CIFAR-分类器,如完整脚本所示:
在这个设置中,性能表现可能不佳,但AutoTVM提供了一线生机。通过为设备编写调度模板并进行一轮自动调整,可以显著提升性能。具体来说,只需替换原始构建行:
然后替换为:
这样,4480源码结果将显著提升,性能大约提升2倍,与CMSIS-NN版本5.7.0(commit ab7c9a)相比,后者是一个手工优化的ML内核库。
µTVM的性能表现与CMSIS-NN模型相比较具竞争力,但工作才刚刚开始,利用TVM的优化特性还有更多空间。通过加速密集/全连接运算(如密集/全连接操作)并利用TVM的模型特定量化和运算符融合功能,可以进一步优化性能。µTVM与TVM能够协同工作,发挥最佳性能。
µTVM的设计理念
µTVM旨在满足设备最低公分母的要求,只需提供设备的C交叉编译器工具链、读/写设备内存的方法、设备内存布局和体系结构特征的规范以及为设备准备函数执行的代码段。大多数裸机设备都支持C和JTAG,因此(1)和(2)通常是免费的。此外,(3)和(4)要求通常较小。例如,STMF系列板的(3)和(4)示例如下:
µTVM基础设施和设备runtime的构建是为了满足这些需求,正努力通过支持常见的开源runtime平台(如mBED OS)来简化编译和链接过程。
µTVM的设备会话
考虑到微控制器的网络特性,引入了微会话的概念,它稍微偏离了标准的TVM代码。µTVM中的每一项功能都依赖于与目标设备的开放会话。在第一个代码片段中,一行代码偏离了规范,即这一行:
通过这个with块内的每一行,都可以调用µTVM中的函数,上下文是device_config指定的设备。这条线背后做了很多工作,让其拆分如下:
首先,它初始化与设备的连接,使用指定的任何通信方法(通常是OpenOCD)。然后使用指定的交叉编译器交叉编译µTVM设备runtime。最后,主机为编译后的二进制文件分配空间,并使用打开的连接将二进制文件加载到设备上。
由于runtime现在位于设备上,自然需要一些函数来运行它。
模块加载
TVM的核心抽象之一是模块。模块为特定设备/ runtime目标存储一组相关函数。考虑到微控制器通常没有操作系统,µTVM需要额外的工作来维护这种高级抽象。跟踪创建和加载µTVM兼容模块的过程:
假设有一个微型会议打开设备,并实现二维卷积的TVM调度。如果想把它加载到微控制器上,需要将C代码发出。为了实现这一点,只需要设定目标tvm.build或relay.build,例如:
然后,通过µTVM基础设施中的核心功能运行它:create_micro_mod:
这样,交叉编译模块中的C源代码,为生成的二进制文件分配空间,然后将二进制文件的每个部分发送到设备上分配的插槽中。一旦模块二进制文件在设备内存中处于合适的位置,二进制文件中的函数指针将被修补,使模块能够在设备runtime访问帮助函数(例如,分配草稿行)。
加载内核后,可以获取卷积函数的远程句柄,如下所示:
张量加载
如果要调用运算符,首先需要一些张量作为参数:
然后,根据其数据类型(例如int8、float等)和形状,计算每个张量的字节大小,主机在设备堆上分配内存区域。接着将张量的数据加载到分配的区域中。
函数调用
运算符执行可能是系统中最复杂的部分。为了简化表示,我们首先讨论严格执行(运算符一被调用就立即执行),然后是延迟执行(只有在需要运算符的结果时才执行运算符),这是系统的实际工作方式。
严格执行
调用函数时,输入和输出张量都作为参数传递,这就是目标传递样式:
考虑到这些张量已经在设备上分配,只需要向设备发送元数据(设备地址、形状和数据类型),设备就能知道使用哪个驻留张量。下面显示了一个名为“runtime”的函数调用。在构造这个表示之前,需要将元数据序列化到设备上专门为此目的而存在的arguments部分中。
µTVM会有一个全局UTVMTask实例,从主机端写入该实例。一旦写入任务,runtime就拥有了执行函数所需的一切,可以在runtime的入口点开始执行。runtime执行一些轻量级初始化,运行运算符,然后将控制权返回给主机。
鸿蒙轻内核M核源码分析:中断Hwi
在鸿蒙轻内核源码分析系列中,本文将深入探讨中断模块,旨在帮助读者理解中断相关概念、鸿蒙轻内核中断模块的源代码实现。本文所涉及源码基于OpenHarmony LiteOS-M内核,读者可通过开源站点 gitee.com/openharmony/k... 获取。中断概念介绍
中断机制允许CPU在特定事件发生时暂停当前执行的任务,转而处理该事件。这些事件通常由外部设备触发,通过中断信号通知CPU。中断涉及硬件设备、中断控制器和CPU三部分:设备产生中断信号;中断控制器接收信号并发出中断请求给CPU;CPU响应中断,执行中断处理程序。中断相关的硬件介绍
硬件层面,中断源分为设备、中断控制器和CPU。设备产生中断信号;中断控制器接收并转发这些信号至CPU;CPU在接收到中断请求后,暂停当前任务,转而执行中断处理程序。中断相关的概念
每个中断信号都附带中断号,用于识别中断源。中断优先级根据事件的重要性和紧迫性进行划分。当设备触发中断后,CPU中断当前任务,执行中断处理程序。中断处理程序由设备特定,且通常以中断向量表中的地址作为入口点。中断向量表按中断号排序,存储中断处理程序的地址。鸿蒙轻内核中断源代码
中断相关的声明和定义
在文件 kernel\arch\arm\cortex-m7\gcc\los_interrupt.c 中定义了结构体、全局变量和内联函数。关键变量 g_intCount 记录当前正在处理的中断数量,内联函数 HalIsIntActive() 用于检查是否正在处理中断。中断向量表在中断初始化过程中设置,用于映射中断号到相应的中断处理程序。中断初始化 HalHwiInit()
系统启动时,在 kernel\src\los_init.c 中初始化中断。HalHwiInit() 函数在 kernel\arch\arm\cortex-m7\gcc\los_interrupt.c 中实现,负责设置中断向量表和优先级组,配置中断源,如系统中断和定时器中断。创建中断 HalHwiCreate()
开发者可通过 HalHwiCreate() 函数注册中断处理程序,传入中断号、优先级和中断模式。函数内部验证参数,设置中断处理程序,最终通过调用 CMSIS 函数完成中断创建。删除中断 HalHwiDelete()
中断删除操作通过 HalHwiDelete() 实现,接收中断号作为参数,调用 CMSIS 函数失能中断,设置默认中断处理程序,完成中断删除。中断处理执行入口程序
默认的中断处理程序 HalHwiDefaultHandler() 仅用于打印中断号后进行死循环。HalInterrupt() 是中断处理执行入口程序的核心,它包含中断数量计数、中断号获取、中断前后的操作以及调用中断处理程序的逻辑。开关中断
开关中断用于控制CPU是否响应外部中断。通过宏 LOS_IntLock() 关闭中断, LOS_IntRestore() 恢复中断状态, LOS_IntUnLock() 使能中断。这组宏对应汇编函数,使用寄存器 PRIMASK 控制中断状态。小结
本文详细解析了鸿蒙轻内核中断模块的源代码,涵盖了中断概念、初始化、创建、删除以及开关操作。后续文章将带来更多深入技术分享。欢迎在 gitee.com/openharmony/k... 分享学习心得、提出问题或建议。关注、点赞、Star 和 Fork 到个人账户,便于获取更多资源。为ä»ä¹è¦ç¨CMSIS RTOS
1ãéæå¨keilä¸ï¼æ²¡ææè°ç§»æ¤æ¦å¿µãé对任ä½MCUé½å¯ä»¥ä¸é®æ·»å ï¼è¯æ³ä¸ä¸ï¼å¦æä½ å°æ¥ç¨çä¸æ¯STMï¼é£ä¹ç§»æ¤OSæ¯ä¸æ¯è¿æ¯é£ä¹å®¹æï¼ï¼
2ãå ç¨èµæºæå°ã大约5kBï¼èä¸é对cortexç³»åARMå®æ¹ä¼åï¼æçä¸è¨èªæï¼
3ãç»ä»¶ä¸°å¯ã常ç¨ä¸é´ä»¶USB/network/GUI/æ件系ç»çï¼ARMå®æ¹å·²ç»åå¤å¥½ï¼åªéè¦å¨keilä¸ä¸é®æ·»å ï¼åæ ·æ²¡æ移æ¤æ¦å¿µï¼
4ã仿çé常æ¹ä¾¿ãå¨keilçdebug模å¼ä¸ï¼è½»æ¾æ¥çä»»å¡çCPUãå åå ç¨ï¼è¿æåä»»å¡çè¿è¡æ¶é´ãè¿è¡ç¶æï¼åä»»å¡ä¹é´å¦ä½æ¢å ï¼é常ç´è§ï¼ä¸éè¦åå ¶ä»RTOSé£æ ·è°ç¨ä¸ç¨çæ¥çå½æ°ï¼
5ãCMSIS RTOSæ¯ARMç°å¨çæ¨çç©èç½æä½ç³»ç»mbedOSçåºç¡ï¼ææè¿ä¸ªRTOS APIï¼mbedOSæ´å®¹æä¸æï¼ç©èç½æ¯å¤§å¿æè¶ï¼ARMçå¨è¿ä¸ªæµªæ½®ä¸çå°ä½ä¼æå¨ç¥ï¼è½¯é¶æ¶è´ARMçæ ¸å¿åå ï¼ï¼ç©èç½ä»¥å估计ä¼äº§ç大éçç¸å ³å·¥ä½æºä¼ï¼
6ã使ç¨æç®åãå次æéï¼CMSIS RTOSåªæ¯ä¸å¥APIï¼æå ´è¶£çå¯ä»¥å»ç 究å®å°è£ OSæºç ï¼æ²¡å ´è¶£çï¼ççAPIæ¿æ¥å°±ç¨ï¼
7ãå è´¹ï¼è¿ç¹åfreeRTOSä¸æ ·ï¼æ¯uc/oSæ´ææ½åï¼ä¸è¿freeRTOSæ¯ä¸ªäººå¼æºé¡¹ç®ï¼åç»å级维æ¤ç¼ºä¹åä¸æ¨¡å¼ï¼èARMåä»è½¯é¶é£éææ¥å¤§ç¬é±ï¼ä¼°è®¡åç»åå±æ¨å¹¿æ´ä¸ºå¼ºå²ï¼è¯è¯´åæ¥ï¼å¦æfreeRTOSççé常ä¼ç§ï¼ARMä¹å¯ä»¥å¯¹å®è¿è¡å°è£ ã