当前位置: 首页 > news >正文

嵌入式实时操作系统的设计与开发(aCoral线程学习)

真正的RTOS,基本上没有做到进程,只是停留在多线程,因为多进程要解决很多问题,且需要硬件支持,这样就使得系统复杂了,从而就可能影响系统实时性。

线程之间是共享地址的,也就是说当前线程的地址相对于其它线程的地址是可见的,如果修改了地址的内容,其它线程是可以知道,并且能访问的。

int i = 1;
test()
{sleep(10);printf("%d",i);
}int main()
{create_task(test,...);i++;
}

如果create_task对应的是创建线程的接口,则test输出2.
如果是创建进程的接口,则test输出1.
如果是多进程,main函数所在进程和test所在进程是不能相互访问彼此之间的变量的。

  1. 地址保护。每个进程都有自己的地址空间,如果当前进程跨界访问到了其它进程的区域,则会出错,就访问不了这个地址,这种地址保护需要硬件有存储器保护单元MPU(Memory Protectin Unit)的支持。
  2. 虚拟地址。各个进程仅管都是访问同一地址,但是由于虚拟地址隐射,他们对应的物理地址不一样,所以读取的值就会不一样。这种虚拟地址需要有内存管理单元MMU(Memory Managment Unit)的支持。

进程之间相互独立、隔离,一个进程的崩溃或错误操作不会影响其它进程。但无法直接访问全局变量,因为全局变量变成了进程范围内的全局变量了,这样进程之间的共享和通信就变得困难。

描述线程

线程就是一段代码的执行体。
线程保护了“执行代码+执行环境”,执行环境就是“堆栈+寄存器”。
线程控制块(TCB)是acoral_thread_t。

typedef struct{acoral_res_t res; //线程控制块是一种资源unsigned char state;...
}acoral_thread_t;

ACORAL_THREAD_EXIT为退出状态,意味着某个线程退出了,也就是说不会再参与调度,但此时该线程的资源,如线程控制块TCB、堆栈等资源还未释放,而RELEASE状态意味着可以释放这些资源。

  • CPU:指示线程在哪个CPU上运行,当前不支持线程迁移,也就是说,线程创建时在哪个CPU上,以后的整个执行过程也是在该CPU上。
  • acoral_list_t ready;
    acoral_list_t timeout;
    acoral_list_t waiting;
    acoral_list_t global_list;
  • stack:表示线程的堆栈。在当前线程被其它线程抢占,并在切换到其它线程的时候,当前线程的stack会赋值为CPU堆栈寄存器sp的值。每个线程都有自己的堆栈,用以存放自己的运行环境。
  • stack_buttom:这时栈底,一个线程的堆栈是有大小的,所以就有个栈底,当堆栈指针超过了栈底,是会出问题的。这时sp指向的内存地址已经不是本线程自己的内存空间,这样可能会破坏了其它线程的数据结构,严重时会导致系统崩溃。
  • stack_size:堆栈大小
  • delay:当用户需要延迟某个线程的执行时,用它来指定延迟的时间,单位是Ticks,当用户调用acoral_delay_self()时传入的时间参数转化为Tick再赋给delay成员。
  • private_deta:长久备用数据指针,用于线程策略私有数据指针。

res

typedef union{int id;int next_id;
}acoral_res_t;

由于线程控制块是一种资源,id表示线程的资源ID。
当某个资源空闲时,id的高16位表示该资源在资源池的编号,分配后表示该资源的ID。
next_id表示下一资源的ID,它是个空闲链表指针,指向下一个空闲的资源的编号,属于资源ID的一部分。
总之,res代表了线程的ID。
资源ID由资源类型Type和空闲内存池两部分组成。

采用了资源池的内存管理方式,资源池由结构acoral_pool_t定义。
若要创建某一新线程,将调用函数acoral_get_free_pool(),从空闲资源池中获取一空闲内存,并获取其ID号。将申请到的内存空间供该线程使用。

typedef struct {void *base_adr; //这有两个作用,在为空闲的时候,它指向下一个pool,否则为它管理的资源的基地址void *res_free; //指向下一空闲资源int id;unsigned int size;unsigned int num;unsigned int position;unsigned int free_num;acoral_pool_ctrl_t *ctrl;acoral_list_t ctrl_list;acoral_list_t free_list;
}acoral_pool_t;

空闲内存池ID由内存管理模块在初始化分配内存时,根据当前块数而定。

void acoral_res_sys_init()
{acoral_pool_t *pool;unsigned int i;pool = &acoral_pools[0];for(i=0; i<(ACORAL_MAX_POOLS-1); i++){pool->base_adr = (void *)&acoral_pools[i+1]; //初始化时所有pool为空闲,故成员base_adr指向下一个poolpool->id = i;pool++;}pool->base_adr = (void *)0;acoral_free_res_pool = &acoral_pools[0];//空闲资源池指针
}
//创建资源内存池
unsigned int acoral_create_pool(acoral_pool_ctr_t *pool_ctrl)
{acoral_pool_t *pool;if(pool_ctr->num >= pool_ctrl->max_pools){return ACORAL_RES_MAX_POOL;}pool = acoral_get_free_pool();if(pool == NULL)return ACORAL_RES_NO_POOL;pool->id = pool_ctrl->type << ACORAL_RES_TYPE_BIT | pool->id;pool->size = pool_ctrl->size;pool->num = pool_ctrl->num_per_pool;pool->base_adr = (void *)acoral_malloc(pool_size * pool->num);if(pool->base_adr == NULL)return ACORAL_RES_NO_MEM;pool->res_free = pool->base_adr;pool->free_num = pool->num;pool->ctrl = pool_ctrl;acoral_pool_res_init(pool);acoral_list_add2_tail(&pool->ctrl_list, pool_ctrl->pools);acoral_list_add2_tail(&pool->free_list, pool_ctrl->free_pools);pool_ctrl->num++;return 0;
}

Prio

#define CFG_MAX_THREAD (40)
#definne ACORAL_MAX_PRIO_NUM ((CFG_MAX_THREAD +1) & 0xff) //41,总共有40个线程,有0~40共41个优先级
#define ACORAL_MINI_PRIO CFG_MAX_THREAD //最低优先级40typedef enum{ACORAL_INIT_PRIO, //init线程独有的0优先级ACORAL_MAX_POOL, //系统允许的最高优先级ACORAL_HARD_RT_PRIO_MAX, //硬实时任务最高优先级ACORAL_HARD_RT_PRIO_MIN = ACORAL_HARD_RT_PRIO_MAX+CFG_HARD_RT_PRIO_NUM,ACORAL_NOHARD_RT_PRIO_MAX, //非硬实时任务最高优先级ACORAL_DAEMON_PRIO = ACORAL_MINI_PRIO-2,ACORAL_NOHARD_RT_PRIO_MIN; //非硬实时任务最低优先级ACORAL_IDLE_PRIO;
}PrioEnum;

优先级与数字成反比,数字越大,优先级越低。
aCoral的初始优先级为0,最高优先级是1,最小优先级是总的优先级数减1。

#define CFG_MEM2 1 //任意大小内存分配系统是否启用
#define CFG_MEM2_SIZE (1024000) //任意大小内存分配系统的大小,是从伙伴系统管理的内存中拿出一部分
#define CFG_MIN_STACK_SIZE (512) //线程最小拥有的字节数

双向链表

acoral_list_t ready; //用于挂载全局就绪队列
acoral_list_t timeout; //超时阻塞
acoral_list_t waiting; //延时
acoral_list_t global_list; //全局线程列表
struct acoral_list{struct acoral_list *next,*prev;
};
typedef struct acoral_list acoral_list_t;

这4个acoral_list_t成员用来将线程结构挂到相应链表队列上。
在这里插入图片描述
以就绪队列ready为例,当用户调用了acoral_rdy_thread或acoral_resume_thread接口时,就会将线程挂到就绪队列acoral_ready_queue上,这就是将就绪队列ready成员挂到这个链表上。

挂到相应链表队列上的方式与Linux类似,这种方式的优点是:可以用相同的数据处理方式来描述所有双向链表,不用再单独为各个链表编写各种函数。

线程优先级

aCoral是一个支持多核的RTOS,因此,在开发初期就得考虑线程数量的问题。

aCoral的就绪队列采用的是优先级链表,每个优先级是一个链表,相同的优先级的线程都挂在该链表上。

对于RTOS而言,几乎都是采用了基于优先级的抢占调度策略。

typedef struct{unsigned int num; //就绪的线程数unsigned int bitmap[PRIO_BITMAP_SIZE];//优先级位图,每一位对应一个优先级,为1表示这个优先级有就绪线程acoral_list_t queue[ACORAL_MAX_PRIO_NUM]; //每一个优先级都有独立的队列
}acoral_rdy_queue_t;
  • num:定义了就绪任务的总数
  • bitmap[PRIO_BITMAP_SIZE]:用来标识某一优先级是否有就绪队列,这样才能确保以O(1)复杂度找出最高优先级的线程。
#define PRIO_BITMAP_SIZE ((ACORAL_MAX_PRIO_NUM+31)/32)

就绪队列中的优先级位图的大小,目前等于2,优先级数目除以32向上取整。

每个变量从右到左每一位依次代表一个优先级。

aCoral采用私有就绪队列,也就是每个CPU有一个就绪队列。

相关文章:

嵌入式实时操作系统的设计与开发(aCoral线程学习)

真正的RTOS&#xff0c;基本上没有做到进程&#xff0c;只是停留在多线程&#xff0c;因为多进程要解决很多问题&#xff0c;且需要硬件支持&#xff0c;这样就使得系统复杂了&#xff0c;从而就可能影响系统实时性。 线程之间是共享地址的&#xff0c;也就是说当前线程的地址…...

JAVA基础(JAVA SE)学习笔记(二)变量与运算符

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 第一阶段&#xff1a;Java基本语法 1. Java 语言概述 JAVA基础&#xff08;JAVA SE&#xff09;学习…...

chatgpt 接口 和 jupyter版本安装

一 接口代码 有时间继续测试 import openai # 填入你的api_key openai.api_key ""models openai.Model.list()# 定义API参数 params {role: "user", "content": }# 定义循环 while True:# 获取用户输入user_input input("请输入您的消…...

ubuntu20.04 nerf开山之作

源码 GitHub - yenchenlin/nerf-pytorch: A PyTorch implementation of NeRF (Neural Radiance Fields) that reproduces the results. 代码的相关解读 NeRF代码解读-相机参数与坐标系变换 - 知乎 原文题目&#xff1a;NeRF: Representing Scenes as Neural Radiance Field…...

Java 中实现单例模式

单例模式 单例模式&#xff0c;就是一个类在任何情况下绝对只有一个实例&#xff0c;并且提供一个全局访问点来获取该实例。 要实现单例&#xff0c;至少需要满足两个点&#xff1a; 私有化构造方法&#xff0c;防止被外部实例化造成多实例问题 提供一个静态方位作为全局访问点…...

标签页的使用

目录 1、引用TabSheet.h和TabSheet.cpp文件&#xff1a; 2、主窗口添加标签页&#xff1a; &#xff08;1&#xff09;、标签页的创建和属性更改 &#xff08;2&#xff09;、添加俩个标签页的类 &#xff08;3&#xff09;、主窗口添加成员变量 &#xff08;4&#xff09…...

新一代开源语音库CoQui TTS冲到了GitHub 20.5k Star

Coqui TTS 项目介绍 Coqui 文本转语音&#xff08;Text-to-Speech&#xff0c;TTS&#xff09;是新一代基于深度学习的低资源零样本文本转语音模型&#xff0c;具有合成多种语言语音的能力。该模型能够利用共同学习技术&#xff0c;从各语言的训练资料集转换知识&#xff0c;来…...

CSS 效果:多列文字,第一行对齐,flex方式元素被挤压

如图效果&#xff1a;2列&#xff0c;第一列只有一行&#xff0c;第二列多行。要求第一行对齐 实现&#xff1a;使用flex 如果不配置flex-shrink的话&#xff0c;第一列会被挤压 给第一列&#xff1a;备注配置压缩属性&#xff1a; flex-shrink&#xff1a;0。 <!DOCTYPE…...

优维低代码实践:片段

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…...

【计算机网络】第一章、计算机网络体系结构

1.1计算机网络的组成与分类 1.计算机网络的组成 从不同的角度来看内容从组成上看硬件、软件、协议从工作方式上岸边缘部分、核心部分从功能上看通信子网、资源子网 2.计算机网络的分类 角度内容分布范围广域网、城域网、局域网、个域网传输技术广播式网络、点对点网络拓扑结…...

vr火灾逃生安全科普软件开展消防突击教育安全有效

VR火灾逃生自救虚拟体验是一种利用虚拟现实技术来模拟火灾逃生自救场景的教育工具。以下是这个体验的几个优点&#xff1a;VR消防安全体验馆的出现&#xff0c;为城市的安全教育开辟了新的途径。这种创新的体验方式&#xff0c;能够让市民在模拟的火灾场景中学习并掌握消防安全…...

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…...

logback-spring.xml 中根据不同的业务表示,分类打印到不同的文件夹、时区动态设置

logback-spring.xml 中根据不同的业务表示&#xff0c;分类打印到不同的文件夹、时区动态设置 logback-spring.xml 完整配置 <?xml version"1.0" encoding"UTF-8"?> <configuration debug"false" scan"true" scanPeriod&…...

linux系统编程之一

1&#xff09;fcntl的使用方法 fcntl作用:可以用fcntl函数改变一个已打开的文件属性而不必重新打开文件&#xff1b; 堆排序是完全二叉树&#xff0c;但不是排序二叉树&#xff1b; 排序二叉树要求兄弟节点之间有大小关系&#xff0c;比如说左小右大&#xff1b; 堆排序仅要求…...

【LeetCode】《LeetCode 101》第十三章:链表

文章目录 13.1 数据结构介绍13.2 链表的基本操作206. 反转链表&#xff08;简单&#xff09;21. 合并两个有序链表&#xff08;简单&#xff09;24.两两交换链表中的节点&#xff08;中等&#xff09; 13.3 其它链表技巧160. 相交链表&#xff08;简单&#xff09;234. 回文链表…...

Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总

Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值&#xff0c;这里提到了 file://前缀&#xff0c;以及静态目录 static 怎么获取 实际代码&#xff0c;其中__static就是我们存放静态文件的地方&#xff0c;这个 static 是 electron 源代码根目录下的文件…...

AI人工训练师,提升外呼机器人的运营效果

外呼机器人是企业客服和营销的重要工具&#xff0c;外呼机器人可以通过语音识别和语音合成技术&#xff0c;自动拨打电话并进行客户服务和营销推广等工作。由于外呼机器人错误识别和理解偏差容易影响外呼效果&#xff0c;许多外呼机器人厂商选择通过AI人工训练师的技术手段来提…...

nginx正向代理、反向代理、负载均衡(重中之重)

nginx中有两种代理方式&#xff1a; 七层代理&#xff08;http协议&#xff09; 四层代理&#xff08;基于tcp或udp的流量转发&#xff09; 一、七层代理 原理&#xff1a;客户端请求代理服务器&#xff0c;由代理服务器转发客户端的http请求&#xff0c;转发到内部的服务器…...

MySQl_2

目录 函数 一.字符串函数 二.数值函数 三.日期函数 四.流程控制函数 约束 多表查询 多表关系 一.内连接 二.外连接 三.自连接 四.联合查询 五.子查询 标量子查询 列子查询 行子查询 表子查询 函数 一.字符串函数 二.数值函数 SELECT LPAD(FLOOR(RAND()*1000000),…...

使用Filter AND Interceptor校验等录(全网独一份,机不可失)

说明&#xff1a;基于spring boot进行的校验 1.熟悉如何使用jwt令牌。&#xff08;不会的看这里&#xff1a;带你领略JWTl令牌的魅力&#xff01;&#xff01;&#xff01;-CSDN博客&#xff09; Filter和Interceptor共用文件&#xff1a;&#xff08;可以仿照&#xff0c;根据…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...