嵌入式轻量级开源操作系统:HeliOS的使用

news2025/9/14 20:45:25

嵌入式轻量级开源操作系统:HeliOS的使用


  • 📍项目地址:https://github.com/heliosproj/HeliOS
  • HeliOS项目是一个社区交付的开源项目,用于构建和维护HeliOS嵌入式操作系统(OS)。HeliOS是一个功能齐全的操作系统,旨在满足由爱好者、研究人员、STEM教育工作者和学者组成的广泛用户社区的需求。HeliOS还旨在满足各种技能水平用户的需求,从在其Arduino项目中实施操作系统的电子爱好者,以及到开发将部署到现场的遥感仪器的研究科学家。
  • 🎉当前该系统支持的开发环境或平台:Arduino IDEPlatformIO IDEARM Cortex-M

✨请注意,当使用ESP32 Arduino内核时,Espressif ESP32微控制器上不支持HeliOS。这是因为ESP32 Arduino内核是基于FreeRTOS构建的,HeliOSFreeRTOS不能在同一个应用程序中共存。要针对ESP32,HeliOS必须使用Espressif的SDK构建,而不是使用ESP32 Arduino内核。 /src/port.h/src/port.c的文件也需要更新必要的代码来控制中断和访问微控制器的滴答计时器。

  • 对于微控制器的MMU或MPU(内存保护单元)启用时,可能无法从用户代码中访问内存映射寄存器和I/O。
  • 📜 HeliOS API文档说明:https://github.com/heliosproj/HeliOS/blob/master/doc/HeliOS_Developers_Guide.pdf
  • 🔖本文主要测试Arduino IDE平台的使用和用Keil MDK以 ARM Cortex-MMCU移植HeliOS的使用。

📘Arduino IDE平台构建和测试

  • 🔧安装依赖库HeliOS
    在这里插入图片描述
  • 📑库所提供的相关测试例程:
    在这里插入图片描述
- 📝测试例程代码一:

一个基础的点灯程序。

/*UNCRUSTIFY-OFF*/
/**
 * @file Blink.ino
 * @author Manny Peterson <manny@heliosproj.org>
 * @brief An example Arduino sketch
 * @version 0.4.1
 * @date 2023-03-19
 * 
 * @copyright
 * HeliOS Embedded Operating System Copyright (C) 2020-2023 HeliOS Project <license@heliosproj.org>
 *  
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  
 * 
 */
/*UNCRUSTIFY-ON*/
#include <Arduino.h>
#include <HeliOS.h>


void blinkTask_main(xTask task_, xTaskParm parm_) {
  int ledState = DEREF_TASKPARM(int, parm_);


  if(ledState) {
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.println("LED colosed");
    ledState = 0;
  } else {
    digitalWrite(LED_BUILTIN, LOW);
    Serial.println("LED open");
    ledState = 1;
  }

  DEREF_TASKPARM(int, parm_) = ledState;

  return;
}


void setup() {
  xTask blink;
  int ledState;
  Serial.begin(115200);

  pinMode(LED_BUILTIN, OUTPUT);
	//初始化系统
  if(ERROR(xSystemInit())) {
    xSystemHalt();//停止HeliOS
  }
	//创建一个任务:传入任务指针 task、任务名称 "PRINTTSK"、任务函数 taskPrint_main 和任务函数参数
  if(ERROR(xTaskCreate(&blink, (const xByte *) "BLINKTSK", blinkTask_main, &ledState))) {
    xSystemHalt();
  }
	//将任务置于“等待”状态。
  if(ERROR(xTaskWait(blink))) {
    xSystemHalt();
  }
//同步扫描来更改任务计时器的时间间隔周期。任务被调度执行的间隔时间
  if(ERROR(xTaskChangePeriod(blink, 1000))) {
    xSystemHalt();
  }
	//启动HeliOS调度程序
  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }
	
  xSystemHalt();
}


void loop() {


}
  • 🔖以上代码,上传到328PB上传测试结果:
    在这里插入图片描述
- 📝测试例程代码二:

运行两个占用不同时间的任务函数

/*UNCRUSTIFY-OFF*/
/**
 * @file Coop.ino
 * @author Manny Peterson <manny@heliosproj.org>
 * @brief An example Arduino sketch
 * @version 0.4.1
 * @date 2023-03-19
 * 
 * @copyright
 * HeliOS Embedded Operating System Copyright (C) 2020-2023 HeliOS Project <license@heliosproj.org>
 *  
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  
 * 
 */
/*UNCRUSTIFY-ON*/
#include <Arduino.h>
#include <HeliOS.h>


void taskShort_main(xTask task_, xTaskParm parm_) {
  /* Arduino's delay() is only used here to demonstrate HeliOS functionality and
   * must not be used in a real application built on HeliOS. */
  delay(500);
  Serial.print("S");
  digitalWrite(LED_BUILTIN, LOW);
}


void taskLong_main(xTask task_, xTaskParm parm_) {
  /* Arduino's delay() is only used here to demonstrate HeliOS functionality and
   * must not be used in a real application built on HeliOS. */
  delay(1000);
  Serial.println("L");
  digitalWrite(LED_BUILTIN, HIGH);
}


void setup() {
  xTask shortTask;
  xTask longTask;


  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);

  if(ERROR(xSystemInit())) {
    xSystemHalt();
  }

  if(ERROR(xTaskCreate(&shortTask, (const xByte *) "SHORTTSK", taskShort_main, null))) {
    xSystemHalt();
  }

  if(ERROR(xTaskCreate(&longTask, (const xByte *) "LONGTSK ", taskLong_main, null))) {
    xSystemHalt();
  }

  if(ERROR(xTaskResume(shortTask))) {
    xSystemHalt();
  }

  if(ERROR(xTaskResume(longTask))) {
    xSystemHalt();
  }

  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }

  xSystemHalt();
}


void loop() {


}
- 📝测试例程代码三:

查询系统和任务信息

/*UNCRUSTIFY-OFF*/
/**
 * @file GetInfo.ino
 * @author Manny Peterson <manny@heliosproj.org>
 * @brief An example Arduino sketch
 * @version 0.4.1
 * @date 2023-03-19
 * 
 * @copyright
 * HeliOS Embedded Operating System Copyright (C) 2020-2023 HeliOS Project <license@heliosproj.org>
 *  
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  
 * 
 */
/*UNCRUSTIFY-ON*/
#include <Arduino.h>
#include <HeliOS.h>


void taskPrint_main(xTask task_, xTaskParm parm_) {
  String str;
  xTaskInfo tinfo;
  xSystemInfo sinfo;

  //用于获取关于单个任务的信息。提供了任务的状态和名称以及任务的运行时统计信息。
  if(OK(xTaskGetTaskInfo(task_, &tinfo))) {
    str = "taskPrint_main(): id = ";
    str += tinfo->id;
    str += ", name = ";
    str += xByte2String(CONFIG_TASK_NAME_BYTES, tinfo->name);
    str += ", state = ";
    str += tinfo->state;
    str += ", ltime = ";
    str += tinfo->lastRunTime;
    str += ", ttime = ";
    str += tinfo->totalRunTime;
    Serial.println(str);
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  //释放堆内存
    if(ERROR(xMemFree(tinfo))) {
      xSystemHalt();
    }
  }
  //获取系统信息:名称、版本和任务的数量
  if(OK(xSystemGetSystemInfo(&sinfo))) {
    str = "taskPrint_main(): ";
    str += xByte2String(OS_PRODUCT_NAME_SIZE, sinfo->productName);
    str += " ";
    str += sinfo->majorVersion;
    str += ".";
    str += sinfo->minorVersion;
    str += ".";
    str += sinfo->patchVersion;
    str += " has ";
    str += sinfo->numberOfTasks;
    str += " task.";
    Serial.println(str);

    if(ERROR(xMemFree(sinfo))) {
      xSystemHalt();
    }
  }
}


void setup() {
  xTask task;


  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);

  if(ERROR(xSystemInit())) {
    xSystemHalt();
  }

  if(ERROR(xTaskCreate(&task, (const xByte *) "PRINTTSK", taskPrint_main, null))) {
    xSystemHalt();
  }

  if(ERROR(xTaskWait(task))) {
    xSystemHalt();
  }

  if(ERROR(xTaskChangePeriod(task, 1000))) {
    xSystemHalt();
  }

  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }

  xSystemHalt();
}


void loop() {


}

在这里插入图片描述

📗Keil MDK以 ARM Cortex-MMCU移植HeliOS的使用

  • 🔖这里以常见的stm32f103为例,基于STM32CubeMX生成必要的工程代码作为基础。来实现对HeliOS系统的移植使用。
📄STM32移植HeliOS使用步骤
  • 🌿使用STM32CubeMX创建工程。
  • 🔧修改默认时基:由于HeliOS需要使用到滴答定时器作为时基,所以这里换成一个没有使用到的基本定时器。
    在这里插入图片描述
  • 🔨NVIC修改,取消默认滴答定时器中断回调代码生成的勾选:由于HeliOS原驱动代码中已经包含相关代码。
    在这里插入图片描述
  • 🔖其他的外设,可以按需配置即可。
📑移植部分
  • 🌿将HeliOS原项目下载下来,拷贝项目中src,文件夹到自己所创建的项目文件夹中。
    在这里插入图片描述
    在这里插入图片描述
  • 🌿将源文件(.c)添加到工程中:
    在这里插入图片描述
  • 🌿将头文件(.h)路径添加到工程目录中:
    在这里插入图片描述
  • 🌿添加宏CMSIS_ARCH_CORTEXM

在这里插入图片描述

  • 🔧修改头文件port.h:
  #elif defined(CMSIS_ARCH_CORTEXM)

//    #include "stm32f429xx.h"
	 #include "stm32f1xx_hal.h"//mcu型号头文件

    #define DISABLE_INTERRUPTS() __disable_irq()

    #define ENABLE_INTERRUPTS() __enable_irq()

//    #define SYSTEM_CORE_CLOCK_FREQUENCY 0xF42400u /* 16000000u */
	#define SYSTEM_CORE_CLOCK_FREQUENCY 0x44AA200u /* 72000000u 修改主频*/

    #define SYSTEM_CORE_CLOCK_PRESCALER 0x3E8u /* 1000u 分频系数*/
  • 📝main.c,添加必要的HeliOS.h头文件,创建任务。
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "HeliOS.h"
/* USER CODE END Includes */
  • 创建任务:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void blinkTask_main(xTask task_, xTaskParm parm_) {
  int ledState = DEREF_TASKPARM(int, parm_);


  if(ledState) {
		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
		printf("LED colosed.\r\n");
    ledState = 0;
  } else {
		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
		printf("LED open.\r\n");
    ledState = 1;
  }

  DEREF_TASKPARM(int, parm_) = ledState;

  return;
}
/* USER CODE END 0 */
  • main函数:
int main(void)
{

  /* USER CODE BEGIN 1 */
		  xTask blink;
   GPIO_PinState ledState;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
if(ERROR(xSystemInit())) {
    xSystemHalt();
  }

  if(ERROR(xTaskCreate(&blink, (const xByte *) "BLINKTSK", blinkTask_main, &ledState))) {
    xSystemHalt();
  }

  if(ERROR(xTaskWait(blink))) {
    xSystemHalt();
  }

  if(ERROR(xTaskChangePeriod(blink, 1000))) {
    xSystemHalt();
  }

  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }

  xSystemHalt();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  • 驱动代码效果和上面的Arduino代码差不多。
    在这里插入图片描述
📚移植后的工程测试源码
通过网盘分享的文件:HeliOS_Temp.rar
链接: https://pan.baidu.com/s/1PTqbM2gSwFqDfamEW_w-tA?pwd=pmdm 提取码: pmdm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2265976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux复习3——管理文件系统2

修改文件权限命令 chmod 功能&#xff1a; chmod 命令主要用于修改文件或者目录的权限 只有文件所有者和超级用户可以修改文件或目录的权限 (1)使用数字表示法修改权限 所谓数字表示法是指将读取(r)、写入(w)和执行(x)分别以4、2、1来表示&#xff0c;没有授予的部分就表示…

ECharts散点图-气泡图,附视频讲解与代码下载

引言&#xff1a; ECharts散点图是一种常见的数据可视化图表类型&#xff0c;它通过在二维坐标系或其它坐标系中绘制散乱的点来展示数据之间的关系。本文将详细介绍如何使用ECharts库实现一个散点图&#xff0c;包括图表效果预览、视频讲解及代码下载&#xff0c;让你轻松掌握…

嵌入式驱动开发详解21(网络驱动开发)

文章目录 前言以太网框架ENET 接口简介MAC接口MII \ RMII 接口MDIO 接口RJ45 接口 PHY芯片以太网驱动驱动挂载wifi模块挂载后续 前言 linux驱动主要是字符设备驱动、块设备驱动还有网络设备驱动、字符设备驱动在本专栏前面已经详细将解了&#xff0c;网络设备驱动本文会做简要…

论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 王志豪&#xff0c;厦门大学博士生 刘诗雨&#xff0c;厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型&#xff08;LLMs&#xff…

FFmpeg 的常用API

FFmpeg 的常用API 附录&#xff1a;FFmpeg库介绍 库介绍libavcodec音视频编解码核心库编码 (avcodec_send_frame, avcodec_receive_packet)。解码 (avcodec_send_packet, avcodec_receive_frame)。libavformat提供了音视频流的解析和封装功能&#xff0c;多种多媒体封装格式&…

trap命令

信号 linux信号是由一个整数构成的异步消息&#xff0c;可以由某个进程发给其他的进程&#xff0c;也可以在用户按下特定键发生某种异常事件时&#xff0c;由系统发给某个进程 信号列表 kill -l trap -l 在使用信号名时&#xff0c;需要省略SIG前缀 trap trap命令用于指定…

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

Llama 3 模型系列解析(一)

目录 1. 引言 1.1 Llama 3 的简介 1.2 性能评估 1.3 开源计划 1.4 多模态扩展 ps 1. 缩放法则 2. 超额训练&#xff08;Over-training&#xff09; 3. 计算训练预算 4. 如何逐步估算和确定最优模型&#xff1f; 2. 概述 2.1 Llama 3 语言模型开发两个主要阶段 2.2…

【多时段】含sop的配电网重构【含分布式电源】【已更新视频讲解】

1 主要内容 之前分享了很多配电网重构的程序&#xff0c;每个程序针对场景限定性比较大&#xff0c;程序初学者修改起来难度较大&#xff0c;本次分享一个基础程序&#xff0c;针对含sop的配电网重构模型&#xff0c;含风电和光伏&#xff0c;优化了33节点网络电压合理性&…

使用 Elastic AI Assistant 简化威胁情报报告

作者&#xff1a;来自 Tommy Bumford 了解 SRE 不断扩展的角色以及所需的新技能&#xff1a;成本管理和 AI。 通过 AI 驱动的报告为分析师提供支持 在不断发展的网络安全领域&#xff0c;威胁分析师不断被新的威胁情报 (threat intelligence - TI) 数据淹没。挑战不仅在于理解…

64.基于SpringBoot + Vue实现的前后端分离-新闻资讯系统(项目 + 论文)

项目介绍 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;文章信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

word无法创建工作文件,检查临时环境变量。

word无法创建工作文件&#xff0c;检查临时环境变量。 word preview版本&#xff0c;关联打开文件出现报错。word无法创建工作文件&#xff0c;检查临时环境变量。 打开注册表&#xff0c;删除键 Word Preview: HKCR\CLSID{84F66100-FF7C-4fb4-B0C0-02CD7FB668FE} PowerPoint …

人工智能ACA(七)——计算机视觉基础

一、自然语言处理基本介绍 1. 自然语言处理的定义 1-1 自然语言 人类使用的在社会生活中自然形成的语言 1-2 自然语言处理 目标是让计算机能够理解、解析、生成和处理人类的自然语言 包含自然语言理解和自然语言生成两部分组成 2. 自然语言处理的发展趋势 3.自然语言处理…

(带源码)宠物主题商场系统 计算机项目 P10083

项目说明 本号所发布的项目均由我部署运行验证&#xff0c;可保证项目系统正常运行&#xff0c;以及提供完整源码。 如需要远程部署/定制/讲解系统&#xff0c;可以联系我。定制项目未经同意不会上传&#xff01; 项目源码获取方式放在文章末尾处 注&#xff1a;项目仅供学…

编程考古-传奇的开始Delphi(中)

发布会 这是 Delphi 发布的邀请&#xff1a; 许多曾经风靡一时的开发工具已逐渐淡出人们的视野&#xff0c;被历史的洪流所淹没。然而&#xff0c;Delphi不仅没有被遗忘&#xff0c;反而持续保持着其独特的魅力和广泛的用户基础。这不仅彰显了Delphi在快速变化的技术领域中的持…

山景BP1048增加AT指令,实现单片机串口控制播放音乐(一)

1、设计目的 山景提供的SDK是蓝牙音箱demo&#xff0c;用户使用ADC按键或者IR遥控器&#xff0c;进行人机交互。然而现实很多场景&#xff0c;需要和单片机通信&#xff0c;不管是ADC按键或者IR接口都不适合和单片机通信。这里设计个AT指令用来和BP1048通信。AT指令如下图所示…

IntelliJ IDEA Docker集成

一、概述 Docker是一种用于在隔离和可复制环境中部署和运行可执行文件的工具。这可能很有用&#xff0c;例如&#xff0c;在与生产相同的环境中测试代码。 IntelliJ IDEA集成了Docker功能&#xff0c;并为创建Docker映像、运行Docker容器、管理Docker Compose应用程序、使用公…

43. Three.js案例-绘制100个立方体

43. Three.js案例-绘制100个立方体 实现效果 知识点 WebGLRenderer&#xff08;WebGL渲染器&#xff09; WebGLRenderer是Three.js中最常用的渲染器之一&#xff0c;用于将3D场景渲染到网页上。 构造器 WebGLRenderer(parameters : Object) 参数类型描述parametersObject…

Linux------进程处理(system库函数)

视频&#xff1a; 【尚硅谷嵌入式Linux应用层开发&#xff0c;linux网络编程&#xff0c;linux进程线程&#xff0c;linux文件io】https://www.bilibili.com/video/BV1DJ4m1M77z?p34&vd_source342079de7c07f82982956aad8662b467 #include <stdlib.h> #include <…

自然语言处理与知识图谱的融合与应用

目录 前言1. 知识图谱与自然语言处理的关系1.1 知识图谱的定义与特点1.2 自然语言处理的核心任务1.3 二者的互补性 2. NLP在知识图谱构建中的应用2.1 信息抽取2.1.1 实体识别2.1.2 关系抽取2.1.3 属性抽取 2.2 知识融合2.3 知识推理 3. NLP与知识图谱融合的实际应用3.1 智能问答…