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条设计原则(熟悉、直观、真实、实用、易用)。说明这些原则如何指导整个产品设计过程。核心功能详…

【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…

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

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

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/…

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

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

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

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

Lesson 10 GNN

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

Scala入门基础(20)数据集复习拓展

一.Stack栈二.Queue 队列 一.Stack栈 Stack:栈,特殊的结构。它对元素的操作是在头部:栈顶 先进后出的队列。pop表示取出,push表示在栈中添加元素 二.Queue 队列 Queue 队列;先进先出.enqueue入队,dequeue出队。

Ubuntu20.04运行DM-VIO

目录 环境配置非ROS环境运行编译运行结果图 ROS环境参考 环境配置 Ubuntu20.04 将项目中Cmakelists.txt中C 和 opencv版本修改下 C 使用 14 opencv使用4 非ROS环境运行 编译 按照官网即可 cd dm-vio mkdir build cd build cmake .. make -j运行 DM-VIO给的命令是 bin/d…

TDengine 签约深圳综合粒子,赋能粒子研究新突破

在高能物理和粒子研究领域,实验装置的不断升级伴随着海量数据的产生与处理。尤其是随着大湾区综合性国家科学中心的建设步伐加快,深圳综合粒子设施研究院(以下简称“研究院”)作为承载“双区驱动”战略的重要科研机构,…

IDEA连接Apifox客户端

IDEA连接Apifox客户端 一、下载Apifox安装包二、IDEA配置三、配置Apifox和IDEA项目同步 一、下载Apifox安装包 Apifox官网,根据自己的操作系统下载对应的Apifox安装包,我是windows系统所以下载的是windows版。 下载 默认仅为我安装,点击下一…

(C语言) 8大翻译阶段

(C语言) 8大翻译阶段 文章目录 (C语言) 8大翻译阶段⭐前言🗃️8大阶段🗂️1. 字符映射🗂️2. 行分割🗂️3. 标记化🗂️4. 预处理🗂️5. 字符集映射🗂️6. 字符串拼接🗂️7. 翻译&…

php反序列化1_常见php序列化的CTF考题

声明: 以下多内容来自暗月师傅我是通过他的教程来学习记录的,如有侵权联系删除。 一道反序列化的CTF题分享_ctf反序列化题目_Mr.95的博客-CSDN博客 一些其他大佬的wp参考:php_反序列化_1 | dayu’s blog (killdayu.com) 序列化一个对象将…

Spring Boot拦截器(Interceptor)详解

拦截器Interceptor 拦截器我们主要分为三个方面进行讲解: 介绍下什么是拦截器,并通过快速入门程序上手拦截器拦截器的使用细节通过拦截器Interceptor完成登录校验功能 1. 快速入门 什么是拦截器? 是一种动态拦截方法调用的机制&#xff…

使用zabbix监控k8s

一、 参考文献 小阿轩yx-案例:Zabbix监控kubernetes云原生环境 手把手教你实现zabbix对Kubernetes的监控 二、部署经验 关于zabbix监控k8s,总体来说是分为两块内容,一是在k8s集群部署zabbix-agent和zabbix- proxy。二是在zabbix进行配置。…

GitCode 平台设置访问令牌 从而git仓库(附pycharm创建版本控制项目)

GitCode 背靠CSDN搞了国产的git平台,但在实际使用过程中,我直接感受就是坑爹!在查找用户令牌(账号密码)这一基本功能上,因为是csdn直接登录跳转过去的用户令牌,没有设置过密码,默认就…

神经网络入门实战:(五)本地数据集的读取,以及从pytorch官网下载数据集的操作

本地带标签图片数据集的读取 代码里面的注释写的都比较清楚,也有拓展的部分,这里就不详细列出。 from torch.utils.data import Dataset # 从torch.utils.data导入Dataset类,用于创建自定义的数据集类 from PIL import Image #引入PIL库中的I…

【Maven】继承和聚合

5. Maven的继承和聚合 5.1 什么是继承 Maven 的依赖传递机制可以一定程度上简化 POM 的配置,但这仅限于存在依赖关系的项目或模块中。当一个项目的多个模块都依赖于相同 jar 包的相同版本,且这些模块之间不存在依赖关系,这就导致同一个依赖…