FreeRTOS学习——接口宏portmacro.h

news2024/9/21 13:38:32

FreeRTOS学习——接口宏portmacro.h,仅用于记录自己阅读与学习源码

FreeRTOS Kernel V10.5.1

portmacro版本:GCC/ARM_CM7

portmacro.h是什么

portmacro.h头文件,用于定义与特定硬件平台相关的数据类型和常量。

在移植过程中,portmacro.h文件是必须修改的文件之一。它主要负责为内核提供平台相关的定义,以确保在不同的硬件平台上正确运行FreeRTOS。

在portmacro.h中,通常会定义几个重要的类型,例如任务句柄、栈指针、上下文保存和恢复函数等。这些定义对于编写能够正确调度和管理任务的代码至关重要。此外,该文件还会包含关于中断处理的配置,以确保任务可以在中断触发时正确运行和切换。

移植FreeRTOS时,如果C编译器允许在C代码中插入汇编,并且支持用C语言编写的中断处理函数,那么port.asm文件的内容可以合并到port.c文件中,这样可以减少文件数量,简化项目结构

参考文章:
FreeRTOS 移植要点(1)

portmacro.h内容

我移植的是
GCC
ARM_CM7内核的接口
在这里插入图片描述

Type definitions

/* Type definitions. */
    #define portCHAR          char
    #define portFLOAT         float
    #define portDOUBLE        double
    #define portLONG          long
    #define portSHORT         short
    #define portSTACK_TYPE    uint32_t
    #define portBASE_TYPE     long

    typedef portSTACK_TYPE   StackType_t;
    typedef long             BaseType_t;
    typedef unsigned long    UBaseType_t;

    #if ( configUSE_16_BIT_TICKS == 1 )
        typedef uint16_t     TickType_t;
        #define portMAX_DELAY              ( TickType_t ) 0xffff
    #else
        typedef uint32_t     TickType_t;
        #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL

/* 32位架构上的32-bit tick type
 * 所以读取它不需要临界区进行保护. */
        #define portTICK_TYPE_IS_ATOMIC    1
    #endif

当configUSE_16_BIT_TICKS为1时(在FreeRTOSConfig.h中配置),TickType_t就是uint32_t否则TickType_t为uint16_t。

portTICK_TYPE_IS_ATOMIC

默认configUSE_16_BIT_TICKS为0,也就是使用32位的。这时会配置另一个宏portTICK_TYPE_IS_ATOMIC为1。翻译一下就是TICK_TYPE是原子性的,此宏用于标识时间片(tick)类型是否为原子类型的宏定义

首先什么是原子操作?
原子操作的定义:原子操作是指在多线程或多任务环境中,**一个操作要么完全执行成功,要么完全不执行,不会在中间被挂起或打断。**对于时间片操作,若标识为原子,在此期间所有对时间片的修改和读取都是一个不可分割的动作。

当portTICK_TYPE_IS_ATOMIC为1时,就是32位架构上的32-bit tick type,所以读取它不需要临界区进行保护

当宏定义为原子时,它可以保证当前的时间片计数在操作期间不会被修改,避免了由于并发访问导致的错误。

如果没有原子性保证,在进行时间片相关的操作(如增加或减少时间片计数)时可能会有其他任务进行切换或者中断服务例程被激活。这种情况下会对时间片的值产生竞争条件,导致数据不一致或错误的调度结果。

通过确保时间片相关的操作是原子的,可以提高系统的稳定性和可靠性,确保调度行为按照预期进行,避免由于任务切换产生的不可预测行为。

我们来看看如果portTICK_TYPE_IS_ATOMIC为0,会有如下定义,即增加了TICK_TYPE临界区宏,对时间片操作时,要进行保护

#if ( portTICK_TYPE_IS_ATOMIC == 0 )

/* tick type非原子读取
 * portTICK_TYPE_IS_ATOMIC == 0.
 * 当tick count返回时映射临界区代码到标准临界区宏*/
    #define portTICK_TYPE_ENTER_CRITICAL()                      portENTER_CRITICAL()
    #define portTICK_TYPE_EXIT_CRITICAL()                       portEXIT_CRITICAL()
    #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR()         portSET_INTERRUPT_MASK_FROM_ISR()
    #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x )    portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) )
#else

Architecture specifics

/* Architecture specifics. */
    #define portSTACK_GROWTH      ( -1 )
    #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
    #define portBYTE_ALIGNMENT    8
    #define portDONT_DISCARD      __attribute__( ( used ) )

portSTACK_GROWTH
portSTACK_GROWTH为 -1 ,这个定义表示堆栈是向下增长的,即从高地址向低地址增长。

portTICK_PERIOD_MS
其中configTICK_RATE_HZ 在FreeRTOSConfig.h中配置,默认为1000Hz,所以TICK周期也就是1ms。

portBYTE_ALIGNMENT
在 FreeRTOS 中使用 portBYTE_ALIGNMENT 进行内存对齐,可以确保任务栈、队列和其他数据结构的正确对齐。这通常与内存分配器的实现配合使用。例如,在使用动态内存分配时,如 pvPortMalloc,内存对齐可以保证分配到的内存块是按照指定的对齐方式返回。

如果 portBYTE_ALIGNMENT 被定义为 8,那么所有与 FreeRTOS 相关的数据结构和任务栈都会在内存中位于 8 字节的边界上。

portDONT_DISCARD
#define portDONT_DISCARD attribute((used)) 是一个用于防止编译器丢弃某些未使用变量或函数的宏定义。

在编译过程中,编译器会进行一些优化,包括去除那些被认为没有使用的代码(如未调用的函数或未使用的变量)。使用 attribute((used)) 可以告诉编译器,即使该变量或函数在代码中未被直接引用,也要保留它。

Scheduler utilities

/* Scheduler utilities. */
    #define portYIELD()                                 \
    {                                                   \
        /* 挂起 PendSV来请求上下文切换. */ \
        portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
                                                        \
        /* Barriers are normally not required but do ensure the code is completely \
         * within the specified behaviour for the architecture. */ \
        __asm volatile ( "dsb" ::: "memory" );                     \
        __asm volatile ( "isb" );                                  \
    }

    #define portNVIC_INT_CTRL_REG     ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
    #define portNVIC_PENDSVSET_BIT    ( 1UL << 28UL )
    #define portEND_SWITCHING_ISR( xSwitchRequired )    do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
    #define portYIELD_FROM_ISR( x )                     portEND_SWITCHING_ISR( x )

taskYIELD就是portYIELD用来发起调度,切换任务
在这里插入图片描述
portYIELD做的就是挂起 PendSV来请求上下文切换

__asm volatile ( “dsb” ::: “memory” ); 和 __asm volatile ( “isb” );
这是使用内嵌汇编实现的一些特定指令,通常在嵌入式系统或对实时性能有严格要求的程序中使用。__asm volatile ( “dsb” ::: “memory” ); 和 __asm volatile ( “isb” ); 是 ARM 体系结构中用于内存屏障操作的指令。它们的作用如下:

dsb(Data Synchronization Barrier):是一个数据同步屏障指令。
它的作用是确保在它之前的所有内存访问(读取或写入)在执行后续的指令之前完成。
通常用于确保数据的一致性,尤其是在多处理器系统中,确保一个处理器对内存的写入在另一个处理器读取之前完成。

isb(Instruction Synchronization Barrier):是一个指令同步屏障指令。
它的作用是使得所有之前的指令都必须完成执行,之后再执行后续的指令。
一般用于整个流水线刷新,以确保新加载的指令在它之前的指令已经完成之后才能执行。

volatile 关键字
使用 volatile 关键字表明这些汇编语句是“易变”的,这意味着编译器不会对它们进行优化,即编译器每次运行时都会实际执行这些汇编代码,而不是在某些情况下跳过它。

::: “memory” 语法
这个语法中的 ::: “memory” 表示告诉编译器在执行这些指令时,内存的状态可能会发生变化。这提示编译器在这段代码之前和之后都不要做一些可能依赖于内存状态的优化。

portNVIC_INT_CTRL_REG
关于portNVIC_INT_CTRL_REG,首先找到cortex m7内核手册。内容如下:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将1写入此位是将PendSV异常挂起的唯一方法

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

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

相关文章

VulhubDC-4靶机详解

项目地址 https://download.vulnhub.com/dc/DC-4.zip实验过程 将下载好的靶机导入到VMware中&#xff0c;设置网络模式为NAT模式&#xff0c;然后开启靶机虚拟机 使用nmap进行主机发现&#xff0c;获取靶机IP地址 nmap 192.168.47.1-254根据对比可知DC-4的一个ip地址为192.1…

无人机光电吊舱的技术!!

1. 成像技术 可见光成像&#xff1a;通过高分辨率相机捕捉地面或空中目标的清晰图像&#xff0c;提供直观的视觉信息。 红外热成像&#xff1a;利用红外辐射探测目标的温度分布&#xff0c;实现夜间或恶劣天气条件下的隐蔽目标发现。 多光谱成像&#xff1a;通过不同波段的光…

日用百货小程序如何渠道经营开店

将货更多的卖出去是每位商家的心声&#xff0c;日用百货商家手中的货具备多样性&#xff0c;挑选的用户也多&#xff0c;由于货单价较低&#xff0c;因此不断获客并其多买/复购/留存/裂变等是长期发展的关键点。 如何获得更多经营渠道&#xff0c;线上找寻出路是方法之一&…

ROS和ROS2借助智能大模型的学习和研究方法

机器人相关知识的本身和价值-CSDN博客 知识本身在智能时代毫无价值&#xff0c;需要基于知识应用和创新才有价值。 学历报废并非来自扩招&#xff0c;而是智能模型的快速发展。-CSDN blink-领先的开发者技术社区 2024年中秋&#xff0c;智能模型实力已经如此&#xff0c;但还…

智算筑基,九章云极DataCanvas公司闪耀2024年服贸会

9月12日&#xff0c;2024年中国国际服务贸易交易会&#xff08;以下简称“服贸会”&#xff09;在北京隆重开幕&#xff0c;九章云极DataCanvas公司携AI智算产品系列深度参展本届服贸会&#xff0c;为观众奉上技术与应用深度融合的参展盛宴。 本届服贸会由中华人民共和国商务部…

文心一言 VS 讯飞星火 VS chatgpt (349)-- 算法导论23.2 8题

八、Borden教授提出了一个新的分治算法来计算最小生成树。该算法的原理如下:给定图 G ( V , E ) G(V,E) G(V,E)&#xff0c;将 V V V划分为两个集合 V 1 V_1 V1​和 V 2 V_2 V2​&#xff0c;使得 ∣ V 1 ∣ |V_1| ∣V1​∣和 ∣ V 2 ∣ |V_2| ∣V2​∣的差最多为1。设 E 1 E_…

2.使用 VSCode 过程中的英语积累 - Edit 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…

【每日刷题】Day124

【每日刷题】Day124 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. LCR 079. 子集 - 力扣&#xff08;LeetCode&#xff09; 2. 1863. 找出所有子集的异或总和再求和 …

超详细超实用!!!零基础java开发之云风笔记接口开发之删除笔记(十一)

云风网 云风笔记 云风知识库 一、service/NoteApi新增delNode接口定义 public interface NoteApi {...int deleteNote(NoteManage noteManage); }二、service/impl/NoteServiceImpl接口实现逻辑 public class NoteServiceImpl implements NoteApi {AutowiredNoteMapper note…

LVM硬盘挂载

LVM硬盘挂载 一、基础概念 sda/sdb/nvme0n1/nvme0n2&#xff1a; 硬盘的命名方式&#xff0c;中括号的字母为第三位按不同硬盘的加载顺序排序。sda1/sda2/sdb1&#xff1a; 第4位为分区号&#xff0c;数字为不同分区的依序命名lvm: LVM是一种逻辑卷管理器&#xff0c;允许管理…

springboot实战学习笔记(2)

目录 1、手动创建springboot工程&#xff0c;选择Maven构建。 2、Maven生成的&#xff0c;可能需要再main目录下new一个resources目录&#xff0c;再在其下目录new一个配置文件。 3、 pom文件中让当前的工程继承父工程依赖&#xff1a;、删去无用依赖。 4、引入后端环境所需要的…

STL,智能指针和线程安全,线程安全的单例模式和懒汉饿汉的实现,以及读者写者问题

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f4da;STL&#xff0c;智能指针和线程安全 &#x1f4d5;STL中的容器是否是线程安全的?&#x1f4a1;智能指针是否是线程安全…

【C语言零基础入门篇 - 7】:拆解函数的奥秘:定义、声明、变量,传递须知,嵌套玩转,递归惊艳

文章目录 函数函数的定义与声明局部变量和全局变量、静态变量静态变量和动态变量函数的值传递函数参数的地址传值 函数的嵌套使用函数的递归调用 函数 函数的定义与声明 函数的概念&#xff1a;函数是C语言项目的基本组成单位。实现一个功能可以封装一个函数来实现。定义函数的…

图片转PDF技巧揭秘:四款高效工具推荐!

在数字化办公和学习的今天&#xff0c;将图片或其他文件格式转换为PDF已成为一种常见需求。以下是几款推荐的转换工具&#xff0c;它们各自具有独特的功能和使用体验&#xff0c;可帮助大家轻松实现图片转PDF及其他PDF相关操作。 福昕PDF转换大师&#xff08;365客户端&#x…

关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142341544 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

【重学 MySQL】三十三、流程控制函数

【重学 MySQL】三十三、流程控制函数 IF函数IFNULL函数CASE函数总结 在MySQL中&#xff0c;流程控制函数是用于在SQL查询、存储过程或函数中根据特定条件执行不同流程的重要工具。这些函数可以帮助我们实现复杂的逻辑判断和数据转换。 IF函数 IF函数是MySQL中最基本的流程控制…

泛微E-Mobile client/cdnfile 任意文件读取漏洞复现

0x01 产品简介 泛微E-Mobile是一款由泛微网络科技股份有限公司开发的移动办公产品,该产品专门为手机、平板电脑等移动终端用户设计,旨在提供便捷、高效的移动办公体验。适用于企业高管和有移动办公需求的业务部相关员工使用,特别适合于已有内部OA系统的大中型企业机构,尤其…

算法-排序算法(冒泡选择插入希尔快速归并堆)

1.算法概述 1.1什么是算法 算法是特定问题的求解步骤的描述&#xff0c;是独立存在的一种解决问题的思想和方法。对于算法而言计算机编程语言并不重要&#xff0c;可以用任何计算机编程语言来编写算法。 程序数据结构算法 1.2数据结构和算法的区别和联系 数据结构只是静态…

闲置物品交易系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;卖家管理&#xff0c;广场管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;广场&#xff0c;商…

欧盟禁用PFAS材料!线材该如何应对?

了应对欧盟即将在2027年1月开始强制执行禁用PFAS材料的法规&#xff0c;一众线材厂商纷纷研发出了对应的替代材料&#xff0c;第二十三届华东磁性元件峰会现场&#xff0c;多家线材企业均带来了PFAS材料的替代产品。 宇盛电子 苏州宇盛电子有限公司&#xff08;下称“宇盛电子…