FreeRTOS posix 实现低功耗tickless

文章目录

    • 打印重定向
    • FreeRTOSConfig.h 配置
    • portmacro.h 实现
    • 低功耗流程
    • vPortSuppressTicksAndSleep 实现
    • 测试
    • 效果
    • 注意事项

打印重定向

为了观察睡眠时间,重定向打印函数,打印的时候将时间戳打印出来,实现如下

#define printf(fmt, ...)                                                    \do                                                                      \{                                                                       \char time_buf[20];                                                  \time_t now = time(NULL);                                            \struct tm *tm_info = localtime(&now);                               \strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm_info); \fprintf(stdout, "[%s] " fmt, time_buf, ##__VA_ARGS__);              \} while (0)

FreeRTOSConfig.h 配置

#define configTICK_RATE_HZ                         ( 1000 )                  /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */#define configUSE_TICKLESS_IDLE                   1
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP     10

portmacro.h 实现

#ifndef portSUPPRESS_TICKS_AND_SLEEPextern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )    vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif

低功耗流程

task.c 文件中

if (xExpectedIdleTime >= (TickType_t)configEXPECTED_IDLE_TIME_BEFORE_SLEEP)
{vTaskSuspendAll();{/* Now the scheduler is suspended, the expected idle* time can be sampled again, and this time its value can* be used. */configASSERT(xNextTaskUnblockTime >= xTickCount);xExpectedIdleTime = prvGetExpectedIdleTime();/* Define the following macro to set xExpectedIdleTime to 0* if the application does not want* portSUPPRESS_TICKS_AND_SLEEP() to be called. */configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING(xExpectedIdleTime);if (xExpectedIdleTime >= (TickType_t)configEXPECTED_IDLE_TIME_BEFORE_SLEEP){traceLOW_POWER_IDLE_BEGIN();portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime);traceLOW_POWER_IDLE_END();}else{mtCOVERAGE_TEST_MARKER();}}(void)xTaskResumeAll();
}
else
{mtCOVERAGE_TEST_MARKER();
}

低功耗函数主要在 vPortSuppressTicksAndSleep函数,睡眠时间阈值通过宏 configEXPECTED_IDLE_TIME_BEFORE_SLEEP,如果睡眠时间小于改值,就不进入睡眠。

vPortSuppressTicksAndSleep 实现

void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime)
{struct timespec xSleepTime;TickType_t xModifiableIdleTime;uint64_t xStartTime, xEndTime, xElapsedTime;/* Stop the timer interrupt here (emulated by blocking SIGALRM). */pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);/* Record the start time. */xStartTime = prvGetTimeNs();/* Prepare the sleep time in nanoseconds. */xSleepTime.tv_sec = xExpectedIdleTime / configTICK_RATE_HZ;xSleepTime.tv_nsec = (xExpectedIdleTime % configTICK_RATE_HZ) * (1000000000 / configTICK_RATE_HZ);/* Enter low-power state. */nanosleep(&xSleepTime, NULL);/* Record the end time. */xEndTime = prvGetTimeNs();/* Calculate elapsed time. */xElapsedTime = (xEndTime - xStartTime) / (1000000000 / configTICK_RATE_HZ);printf("sleep time: %d\r\n", xExpectedIdleTime);/* Adjust system ticks. */vTaskStepTick((TickType_t)xElapsedTime);/* Restart the timer interrupt. */pthread_sigmask(SIG_UNBLOCK, &xAllSignals, NULL);
}

测试

新建一个 task,1000ms 打印一次

static void printf_task( void * pvParameters )
{( void ) pvParameters;for( ; ; ){vTaskDelay(1000);console_print( "task1\n" );}
}
xTaskCreate( printf_task,            "Rx",                           configMINIMAL_STACK_SIZE,       NULL,                           tskIDLE_PRIORITY + 2,NULL );                         

效果

[2024-11-29 12:36:14] sleep time: 1000
[2024-11-29 12:36:14] task1
[2024-11-29 12:36:15] sleep time: 1000
[2024-11-29 12:36:15] task1
[2024-11-29 12:36:16] sleep time: 1000
[2024-11-29 12:36:16] task1
[2024-11-29 12:36:17] sleep time: 1000
[2024-11-29 12:36:17] task1
[2024-11-29 12:36:18] sleep time: 1000
[2024-11-29 12:36:18] task1
[2024-11-29 12:36:19] sleep time: 1000
[2024-11-29 12:36:19] task1
[2024-11-29 12:36:20] sleep time: 1000
[2024-11-29 12:36:20] task1

从结果中可以看到,每次睡眠 1000ms,任务还是 1000ms 打印一次。

注意事项

移植 vPortSuppressTicksAndSleep 到 MCU 上时,最重要的是利用 MCU 的硬件支持来管理低功耗模式,合理配置系统的时钟源和中断源,以确保系统能在需要时唤醒并继续精确计时。需要考虑的核心问题包括:

  • 低功耗模式选择和外设管理。
  • 定时器和中断的正确配置。
  • 实际休眠时间的计算和系统时钟同步。
  • 调试和验证。

通过以上方法,能确保移植后的系统能在保证精度的同时有效降低功耗。

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

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

相关文章

解析客服知识库搭建的五个必要性

在当今竞争激烈的商业环境中,客服知识库的搭建已成为企业提升服务质量、优化客户体验的重要手段。一个完善的客服知识库不仅能帮助企业高效管理客户服务流程,还能显著提升客户满意度和忠诚度。以下是搭建客服知识库的五个必要性: 1. 提升服务…

淘宝Vision Pro:革新购物体验的沉浸式未来

引言 简要介绍淘宝Vision Pro版的背景,包括它在美区AppStore的发布及WWDC上的展示。阐述本文的目的:为读者提供一个全面的功能概览与设计背后的思考。设计原则 列出并简要解释5条设计原则(熟悉、直观、真实、实用、易用)。说明这些原则如何指导整个产品设计过程。核心功能详…

网站怎么防御https攻击

HTTPS攻击,它不仅威胁到网站的数据安全,还可能影响用户隐私和业务稳定运行。 HTTPS攻击主要分为以下几种类型: 1.SSL劫持:攻击者通过中间人攻击手段,篡改HTTPS流量,从而实现对数据的窃取或伪造。 2.中间人攻…

【从0学英语】 04.句型 - 英语句子的骨架

在学习英语的过程中,句型就像建筑的骨架一样,是构建完整句子的基础。俗话说,万变不离其宗,即使英语句子千变万化,也离不开几种基本的句型结构。本节内容将从零开始,带您逐步了解英语句子的五种核心骨架&…

【CSS in Depth 2 精译_062】第 10 章 CSS 中的容器查询(@container)概述 + 10.1 容器查询的一个简单示例

当前内容所在位置(可进入专栏查看其他译好的章节内容) 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 ✔️ 10.1.1 容器尺寸查询的用法 ✔️ 10.2 深入理解容器10.3 与容器相关的单位10.4 容器样式查询的用法10.5 本章小结 文章目录 第 10…

openjdk17 jvm 对象 内存溢出 在C++源码体现

##java大对象类 public class MiBigObject {private String f1;private String f2;private String f3;private String f4;private String f5;private String f6;private String f7;private String f8;private String f9;private String f10;private String f11;private String…

HCIE:详解OSPF,从基础到高级特性再到深入研究

目录 前言 一、OSPF协议基本原理 简介 基本原理 OSPF路由器类型 OSPF网络类型 OSPF报文类型和封装 OSPF邻居的建立的维护 DR和BDR的选举 伪节点 LSDB的更新 OSPF的配置 二、OSPF的高级特性 虚连接(Virtual-Link) OSPF的LSA和路由选择 OSPF…

C++算法练习-day45——236.二叉树的最近公共祖先

题目来源:. - 力扣(LeetCode) 题目思路分析 题目要求在一个二叉树中找到两个给定节点的最低公共祖先(Lowest Common Ancestor, LCA)。最低公共祖先是指在树中同时包含两个给定节点的所有节点中,深度最大的…

think php处理 异步 url 请求 记录

1、需求 某网站 需要 AI生成音乐,生成mp3文件的时候需要等待,需要程序中实时监听mp3文件是否生成 2、用的开发框架 为php 3、文件结构 配置路由设置 Route::group(/music, function () {Route::post(/musicLyrics, AiMusic/musicLyrics);//Ai生成歌词流式…

【VRChat 改模】开发环境搭建:VCC、VRChat SDK、Unity 等环境配置

一、配置 Unity 相关 1.下载 UnityHub 下载地址:https://unity.com/download 安装打开后如图所示: 2.下载 VRChat 官方推荐版本的 Unity 跳转界面(VRChat 官方推荐页面):https://creators.vrchat.com/sdk/upgrade/…

AJAX 实时搜索

AJAX 实时搜索 AJAX(Asynchronous JavaScript and XML)实时搜索是一种无需刷新整个网页就能从服务器获取数据并在网页上展示的技术。这种技术极大地提升了用户体验,尤其是在搜索引擎、在线购物网站、社交媒体平台等应用中。本文将详细介绍AJ…

ollama部署bge-m3,并实现与dify平台对接

概述 这几天为了写技术博客,各种组件可谓是装了卸,卸了装,只想复现一些东西,确保你们看到的东西都是可以复现的。 (看在我这么认真的份上,求个关注啊,拜托各位观众老爷了。) 这不,为了实验在windows上docker里运行pytorch,把docker重装了。 dify也得重装: Dify基…

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一:是先有HTTP还是先有RPC&…

Paddle Inference部署推理(十五)

十五:Paddle Inference推理 (python)API详解 枚举类型 DataType DataType 定义了 Tensor 的数据类型,由传入 Tensor 的 numpy 数组类型确定。 # DataType 枚举定义 class paddle.inference.DataType:# 获取各个 DataType 对应…

blender 视频背景

准备视频文件 首先,确保你有想要用作背景的视频文件。视频格式最好是 Blender 能够很好兼容的,如 MP4 等常见格式。 创建一个新的 Blender 场景或打开现有场景 打开 Blender 软件后,你可以新建一个场景(通过点击 “文件” - “新建…

Elasticsearch与NLP的深度融合:文本嵌入与向量搜索实战指南

Elasticsearch与NLP的深度融合:文本嵌入与向量搜索实战指南 引言 在当今信息爆炸的时代,如何从海量文本数据中快速准确地检索出相关信息,成为了一个迫切需要解决的问题。自然语言处理(NLP)技术的发展为这一挑战提供了新的解决方案。Elasticsearch,作为一个强大的搜索引…

Lesson 10 GNN

听课(李宏毅老师的)笔记,方便梳理框架,以作复习之用。本节课主要讲了生成式对抗网络(GNN)。 目录 Generation Network as Generator 到目前为止,我们学习到的是类似于函数的network&#xf…

Delphi 内置的用于 SOAP WebService 的数据类型定义

记录一下备查。 数据定义在这个单元:unit Soap.InvokeRegistry; 比如: TByteSOAPArray array of Byte;TIntegerSOAPArray array of Integer;TCardinalSOAPArray array of Cardinal;TWordSOAPArray array of Word;TSmallIntSOAPArray array of Sma…

Qt creator设置程序图标

1.windows 在.pro加入 RC_ICONS XXX.ico Qt 只能使用.ico图片设置为程序图标,若是其他图片,需转换为.ico. png在线转ico:PNG to ICO | Convert PNG to ICO online for free 2.其他平台 Qt 设置应用程序图标并没有跨平台: https://doc…

JSON数据转化为Excel及数据处理分析

在现代数据处理中,JSON(JavaScript Object Notation)因其轻量级和易于人阅读的特点而被广泛使用。然而,有时我们需要将这些JSON数据转化为Excel格式以便于进一步的分析和处理。本文将介绍如何将JSON数据转化为Excel文件&#xff0…