1.C++后端开发——POSIX网络API解析
2.什么是PSOS
3.如何保证 Java 应用安全?标准答案来了
4.å¦ä½å¦ä¹ nucleus os
C++后端开发——POSIX网络API解析
网络中进程之间如何通信?网络中进程通信的唯一标识是三元组(ip地址,协议,端口),利用此标识,网络进程可以进行交互。实现网络通信的pdfbox源码解析常用API是UNIX BSD的套接字(socket)和UNIX System V的TLI,而现代应用几乎都采用socket。
POSIX标准定义了操作系统为应用程序提供的接口标准,实现源代码级别的软件可移植性。不同内核提供的系统调用不同,POSIX标准通过统一接口解决了源代码移植问题。如创建进程的函数,Linux下是fork,Windows下是createprocess。编写程序时只需包含unistd.h,调用统一接口函数,实现源代码级别移植。
POSIX网络API是网络编程常用的接口,包括socket、bind、listen、connect、accept、send、recv等。socket函数用于创建句柄和TCB控制块,建立文件描述符与内部控制块的对应关系。bind函数将特定地址赋给socket,listen函数开始监听网络上的连接请求,connect函数向服务端发起连接请求,accept函数接收连接请求并分配新描述符,学校网站 discuz源码send和recv函数用于数据收发。
注意点包括:主机字节序与网络字节序的转换,listen、connect、accept三个函数与三次握手过程,send和recv数据收发策略,以及close关闭socket的四次挥手过程。实现网络中进程通信的关键在于正确使用这些API,并注意细节。
什么是PSOS
pSOS系统结构
pSOS是一个由标准软组件组成的,可剪裁的实时操作系统。其系统结构如图2.1所示
,它分为内核层、系统服务层、用户层。
1. 内核层
pSOS内核负责任务的管理与调度、任务间通信、内存管理、实时时钟管理、中断服
务;可以动态生成或删除任务、内存区、消息队列、信号灯等系统对象;实现了基于优
先级的、选择可抢占的任务调度算法,并提供了可选的时间片轮转调度。pSOS Kernel还
提供了任务建间通信机制及同步、互斥手段,如消息、信号灯、事件、异步信号等。
pSOS操作系统在Kernel层中将与具体硬件有关的dsa加密 c源码操作放在一个模块中,对系统服务层
以上屏蔽了具体的硬件特性,从而使得pSOS很方便地从支持Intel x系列转到支持MC
XXX系列,并且在系统服务层上对不同应用系统不同用户提供标准的软组件如PNA+、
PHILE+等。
2. 系统服务层
pSOS系统服务层包括PNA+、PRPC+、PHILE+等组件。PNA+实现了完整的基于流的TCP
/IP协议集,并具有良好的实时性能,网络组件内中断屏蔽时间不大于内核模块中断屏蔽时
间。PRPC+提供了远程调用库,支持用户建立一个分布式应用系统。PHILE+提供了文件系
统管理和对块存储设备的管理。PREPC+提供了标准的C、C++库,支持用户使用C、C++语言
编写应用程序。
由于pSOS内核屏蔽了具体的硬件特性,因此,pSOS系统服务层的软组件是标准的、与
硬件无关的。这意味着pSOS各种版本,无论是对X系列还是MCXXX系列,其系统服务
层各组件是标准的、同一的,这减少了软件维护工作,增强了软件可移植性。
每个软组件都包含一系列的系统调用。对用户而言,这些系统调用就象一个个可重入
的C函数,然而它们却是用户进入pSOS内核的唯一手段。
3. 用户层
用户指的是用户编写的应用程序,它们是以任务的形式出现的。任务通过发系统调
用而进入pSOS内核,并为pSOS内核所管理和调度。
pSOS为用户还提供了一个集成式的开发环境(IDE)。pSOS_IDE可驻留于UNIX或DOS
环境下,它包括C和C++优化编译器、CPU和pSOS模拟仿真和DEBUG功能。
pSOS内核机制
§3.1 几个基本概念
3.1.1 任务
在实时操作系统中,任务是参与资源竞争(如CPU、Memory、I/O devices等)
的基本单位。pSOS为每个任务构造了一个虚拟的、隔离的环境,从而在概念上,一个任务
与另一个任务之间可以相互并行、独立地执行。人脸识别源码app任务与任务之间的切换、任务之间的通
信都是通过发系统调用(在有些情况下是通过ISR)进入pSOS Kernel,由pSOS Kernel完
成的。
pSOS系统中任务包括系统任务和用户任务两类。关于用户任务的划分并没有一个固
定的法则,但很明显,划分太多将导致任务间的切换过于频繁,系统开销太大,划分太少又
会导致实时性和并行性下降,从而影响系统的效率。一般说来,功能模块A与功能模块B是
分开为两个任务还是合为一个任务可以从是否具有时间相关性、优先性、逻辑特性和功
能耦合等几个方面考虑。
3.1.2 优先级
每个任务都有一个优先级。pSOS系统支持0~级优先级,0级最低,级最高。0级
专为IDLE任务所有,~级为系统所用。在运行时,任务(包括系统任务)的优先级
可以通过t_setpri系统调用改变。
3.1.3 任务状态
pSOS下任务具有三种可能状态并处于这三个状态之一。只有通过任务本身或其他任
务、ISR对pSOS内核所作的系统调用才能改变任务状态。从宏观角度看,一个多任务应用
通过一系列到pSOS的系统调用迫使pSOS内核改变受影响任务而从运行一个任务到运行另
一任务向前发展的。
对于pSOS kernel,任务在创建前或被删除后是不存在的。被创建的任务在能够运行
前必须被启动。一旦启动后,一个任务通常处于下面三个状态之一:
①Executing (Ready)就绪
②Running运行
③Blocked阻塞
就绪任务是未被阻塞可运行的,只等待高优先级任务释放CPU的任务。由于一个任务
只能由正运行的任务通过调用来被启动,而且任何时刻只能有一个正在运行的任务,所
以新任务总是从就绪态开始。
运行态任务是正在使用CPU的就绪任务, 系统只能有一个running任务。一般runni
ng任务是所有就绪任务中优先级最高的,但也有例外。
任务是iapp源码制作教程由自身特定活动而变为阻塞的,通常是系统调用引起调用任务进入等待状态
的。所以任务不可能从ready态到blocked态,因为只有运行任务才能执行系统调用。
3.1.4 任务控制块
任务控制块TCB是pSOS内核建立并维护的一个系统数据结构,它包含了pSOS Kernel调
度与管理任务所需的一切信息,如任务名、优先级、剩余时间片数、当前寄存器状态等。
在有的RTOS中,任务的状态与任务TCB所处的队列是等同的。pSOS操作系统将二者分
为两个概念,例如任务处于阻塞状态,但它的TCB却处于消息等待队列、信号灯等待队列、
内存等待队列、超时队列之一。
pSOS启动时,将根据Configuration Table中的参数kc_ntask建立一个包含kc_ntask
个TCB块的TCB池,它表示最大并行任务数。在创建一个任务时,分配一个TCB给该任务,在
撤销一个任务时,该TCB将被收回。
3.1.5 对象、对象名及ID号
pSOS Kernel是一个面向对象的操作系统内核,pSOS系统中对象包括任务、memory
regions、memory partitions、消息队列和信号灯。
对象名由用户定义(4位ASCII字符),并且在该对象创建时作为系统调用obj_CREAT
E
的一个人口参数传给pSOS Kernel。pSOS Kernel反过来赋予该对象一个唯一的位ID号
。除obj_CREATE和obj_IDENT外,所有涉及对象的系统调用都要用到对象ID号。
创建对象的任务通过obj_CREATE就已经知道了该对象的ID号,其余任务可通过obj_
IDENT或通过全局变量(如果已经为该任务的ID号建立了一个全局变量的话)获取该对象
的ID号。对象ID号隐含了该对象控制块(如TCB、QCB)的位置信息,这一位置信息被pSO
S
Kernel用于对该对象的管理和操作,如挂起/解挂一个任务、删除一个消息队列等。
3.1.6 任务模式字Mode word.
每个任务带有一个mode word,用来改变调度决策或执行环境。主要有以下四个参
数
Preemption Enabled/Disabled.
Roundrobin Enabled/Disabled
Interupts Enabled/Disabled.
ASR Enabled/Disabled: 每个任务有一个通过as-catoh建立起来的异步信号服务例
程ASR。异步信号类似于软件中断。当ASR位为1时as-catch所指向的任务将会被改变执行
路径,先执行ASR,再返回原执行点。
§3.2 任务调度
3.2.1 影响动态调度效果的两个因素
pSOS采用优先级+时间片的调度方式。有两个因素将影响动态调度的效果:一是优先
级可变(通过t_setpri系统调用改变任务的优先级);二是任务模式字中的preemption
bit位和roundrobin bit位。preemption bit位决定不同优先级的任务是否可抢占,并和
roundrobin bit位一起决定任务的时间片轮转是否有效。
3.2.2 引起任务调度的原因及结果
pSOS系统中引起调度的原因有两条:
1. 在轮转方式下时间片到
2. pSOS系统调用引发任务调度。该系统调用可能是ISR发出的,也可能是某个任务发出的
pSOS任务调度的结果有两种:
1. 引起运行任务切换,这指的是
2. 不引起运行任务切换,这指的是
不论任务调度是否引发运行任务切换,都有可能引起一个或多个任务状态变迁。
3.2.3 运行任务的切换
一、何时切换
下面三种情况将引发运行任务切换:
1. 在时间片轮转方式下(此时任务模式字的roundrobin bit与preemption bit均为
enable),运行任务Task A的时间片用完,且Ready队列中有相同优先级的其它任务,则
Task A退出运行。
2. 在运行任务Task A的Mode word的preemption bit位为enable的前提下,若Task A发出
的某条相同调用引发一个优先级高于Task A的任务Task B从Block状态进入Reary状态,则
将Task B投入运行。
3. ISR使用I_RETURN系统调用,则ISR退出运行,pSOS Kernel选择Ready队列中优先级最高
的任务投入运行(这一任务并不一定是被ISR打断的前运行任务)。
二、如何切换
上述三类运行任务的切换,其具体的pSOS Kernel运作过程并非完全一样,但彼此之间
差别不大。为了简单起见,我们以
为例对切换过程作一简单叙述。这一过程可细分为4个步骤:
1. 任务A运行信息保存(_t_save proc far)
这一过程主要完成修改系统工作标志,保存切换点地址及运行信息、任务A栈调
整
栈
指针保存、栈切换、参数及返址入栈等一系列工作。
2.任务A入就绪队列(void t_in_chain)
这一过程将任务A的TCB块按优先级顺序插入就绪队列。
3.选择一个高优先级任务B(void t_choice( ))
按一定算法从就绪队列中选出最高优先级任务B的TCB块,并使运行指针指向它。
4.将任务B投入运行(_t_run proc far)
从系统栈切换到任务B栈,用任务B的TCB块中保存的信息恢复上次运行被打断的
地
,恢
复任务运行环境,于是任务B开始继续运行。
图3.1反映了典型任务切换过程中CPU控制权的转移、各堆栈活动生命期、任务活动
生命期等信息。图中
t1,t4为切换点 t2,t3为开/关中断
Tsch=t4-t1 // Tsch为任务切换时间
Tforbid=t3-t2 // Tforbid为中断禁止时间
它们是实时操作系统最重要的两个性能指标。
如何保证 Java 应用安全?标准答案来了
如何保证 Java 应用安全?
在 Java 程序内存中保护密码安全,可以通过引入机密计算技术来实现。龙蜥社区云原生机密计算 SIG 推出了 Java 机密计算实现技术——Teaclave Java TEE SDK。该技术具有显著优点,已经经过企业级内部场景验证并在 Apache 社区开源。它在软件工程顶级会议 ICSE 上发表的论文获得了 ACM SIGSOFT 杰出论文奖,是自 年以来,龙蜥社区云原生机密计算 SIG、上海交通大学、大连理工大学首次获此荣誉。
保护 Java 程序内存中密码的安全,关键在于如何在运行时环境中安全使用敏感数据。密码一旦解密后,即以明文形式存在于 Java 堆上,可能导致被攻击或主动泄漏。为了解决这一问题,Teaclave Java TEE SDK 通过将密码从内存中销毁,大大减少了敏感信息暴露的时间窗口。此外,通过将密码保存为 char 数组或 byte 数组,避免了反射调用,使得销毁过程更加便利。使用 byte 数组保存密码,更是增加了信息的隐蔽性,使其难以被解读。
然而,当前在网络上找到的解决方法,如缩短明文密码在内存中的存放时间,仅缩短了敏感信息暴露的时间窗口,并未真正保护明文密码。这些方法对密码的销毁时间判断弹性较大,开发人员未必能准确判断何时是最佳时机。更典型的案例,如著名的 log4j 漏洞问题,攻击者能够利用漏洞将恶意类文件上传至服务器,并通过 Java 动态类加载机制运行,窃取 Java 堆中的私钥,进而获得服务器与客户端之间通信内容的完全访问权限。
为了解决 Java 程序安全性问题,机密计算技术成为了一个标准答案。它通过提供硬件级的系统隔离,保障数据安全和程序运行安全。机密计算将执行环境分为富执行环境(REE)和可信执行环境(TEE),认为 REE 和 TEE 应该相互隔离,TEE 需要通过硬件加密来保证外界无法知晓其中的内容。这一机制在 年即已提出,并在随后的 多年中得到了发展。
其中,SGX、TrustZone 等提供了通用型机密计算的硬件基础,Intel、微软等开源的驱动和 SDK 则为通用型机密计算提供了软件基础。然而,直接在 TEE 中运行 Java 程序并不友好,因为 TEE 只能执行 native 程序。为解决这一问题,Occlum 作为介于 TEE 底层 SDK 与 JVM 之间的一层 LibOS,支持 JVM 在 TEE 中的运行。然而,Occlum 方案存在安全性和性能下降的问题,TCB(可信计算基)过大,导致安全性不佳;性能下降,TEE 硬件与 REE 相比存在性能退化。
针对上述问题,Teaclave Java TEE SDK 提出了一种在 TEE 中仅放入可信代码的解决方案。通过将可信代码从 Java 代码直接编译为 native code 放入 TEE 运行,Teaclave Java 采用模块分隔、机密计算服务化、简洁的机密计算服务生命周期管理 API、Java 静态编译等关键技术特性,将应用代码分为 Host、Enclave 和 Common 三个模块。Host 中为普通安全非敏感程序,Enclave 中为安全敏感程序,Common 中则是两者的公共代码。通过将可信代码放入 TEE 运行,实现了 Java 应用的机密计算,降低了安全性和性能的下降问题。Teaclave Java 提供了一站式快速实现 Java 机密计算应用的开发和构建能力,简化了 Java 机密计算的开发门槛。
在实际应用中,Teaclave Java 通过将应用的普通代码放在 REE 中执行,安全敏感的解密和私钥放在 TEE 中,实现了对敏感数据和运算过程的保护。在机密计算框架的对比中,Teaclave Java 的 TCB(可信计算基)大小仅为 Occlum 的大约 1/ 到 1/,具有更高的安全性。运行时性能方面,Teaclave Java 的 native image 会直接以 native 代码形式运行,启动速度非常快,适用于小型应用。对于长时间执行的应用,性能优势会逐渐减小。此外,Teaclave Java 的运行时内存使用量更少,为应用提供了更高效、安全的运行环境。
综上所述,Teaclave Java TEE SDK 是解决 Java 应用安全问题的有效方案,它通过硬件宽容性、安全沙箱隔离、高效的运行时性能和简洁的开发流程,为 Java 应用提供了全面的安全保障。未来,随着 GraalVM 的 Java 静态编译技术被贡献给 OpenJDK,Teaclave Java 方案将获得 JDK 的原生支持,进一步提升其性能和易用性。同时,Teaclave Java 项目的源代码已被贡献至 Apache 社区,加入机密计算框架 Teaclave 项目,正在开源孵化中。
å¦ä½å¦ä¹ nucleus os
å 容ï¼
ä¸ãnucleus plusç¹ç¹ï¼
1.å æ ¸éç¨å¾®å æ ¸ç设计ï¼æ¹ä¾¿ç§»æ¤ï¼èµæåçæ´reliableï¼ä½æ¯æä¸è¿ä¹è®¤ä¸ºï¼ä¸linuxç¸æ¯ï¼ä»¥ARMå¹³å°ä¸ºä¾ï¼NUåªç¨å°äºSVC modeï¼å æ ¸ä¸ç¨æ·ä»»å¡é½è¿è¡å¨åä¸ä¸ªç¶æä¸ï¼ä¹å°±æ¯è¯´ææçtaské½æ¥æ访é®ä»»ä½èµæºçæéï¼è¿æ ·å¾reliableä¹ï¼
2.real-time OSï¼NUæ¯ä¸ä¸ªè½¯å®æ¶æä½ç³»ç»ï¼VxWorksæ¯ç¡¬å®æ¶ï¼ï¼thread control componentæ¯æå¤ä»»å¡ä»¥åä»»å¡çæ¢å ï¼å¯¹äºä¸æçå¤çå®ä¹äºä¸¤ç§æå¡æ¹å¼ï¼LISRåHISRï¼è¿ä¸ªä¸linuxä¸çä¸ãä¸åé¨æºå¶ç±»ä¼¼ï¼linuxä¸çä¸åé¨æ¯éè¿è½¯ä¸ææ¥å®ç°çï¼NUçHISRåªæ¯ä½ä¸ºä¸ç§ä¼å 级æ»æ¯é«äºtaskçä»»å¡åºç°ã
3.NUæ¯ä»¥libraryçæ¹å¼åºç¨çï¼éè¿åèªå·±çapp taskä¸è£åªåçNUå æ ¸åç»ä»¶é¾æ¥èµ·æ¥ï¼NU并没æCLI
äºãç»ä»¶
1.IN component
åå§åç»ä»¶ç±ä¸ä¸ªé¨åç»æï¼ç¡¬ä»¶å¨resetåé¦å è¿å ¥INT_initialize()ï¼è¿è¡æ¿çº§çç¸å ³åå§åï¼é¦å 设置SVC modeï¼å ³ä¸æï¼ç¶åå°å æ ¸ä»romä¸æ·è´è³ramä¸ï¼å»ºç«bss段ï¼ä¾æ¬¡å»ºç«sys stack, irq stackåfiq stackï¼æååå§åtimerï¼å»ºç«timer HISRçæ 空é´ï¼çäºä¸ä¸å¹³å°ç代ç ï¼ä¸ä¸ªtick大æ¦æ¯.8msï¼å®ææ¿çº§çåå§ååå°±è¿å ¥äºINC_initializeï¼åå§åå个ç»ä»¶ï¼å ¶ä¸å æ¬Application initializeï¼create taskåHISRï¼æåå°æ§å¶æ交ç»scheduleï¼ä¸»è¦çäºä¸ä¸RAMä¸å°å空é´çå®æ
|timer HISR stack = |
|FIQ stack = |
|IRQ stack = |
|SVC stack = |
|.bss|
|.data|
|.text|
å ¶ä¸SVC stackç大å°ä¸ä¸ææºç个æ°ç¸å ³ï¼nested irqåçæ¶ï¼irq_contextä¿åå¨SVC stackä¸ï¼IRQçstackåªæ¯åäºä¸´æ¶æ çä½ç¨ã
2.thread control component
TCç»ä»¶æ¯NUå æ ¸çæéè¦ç»æé¨åï¼ä¸»è¦æ¶µçäºè°åº¦ãä¸æãä»»å¡çç¸å ³æä½ãéãæ¶éå 个æ¹é¢ï¼ä¸é¢åå«ä»ç»ã
è°åº¦ï¼scheduleï¼
NUä¸ç线ç¨ç±»åï¼å¨åä¸ä¸ªå°å空é´å ï¼æ两ç§ï¼HISRåtaskï¼HISRå¯ä»¥ç解为ä¸ç§ä¼å 级è¾é«çtaskï¼ä½åä¸æ¯taskï¼HISRä¼å 级é«äºtaskçå®ç°æ¹å¼å°±æ¯schduleæ¶ï¼å å»æ¥çå½åæ¯å¦æactiveçHISRï¼åå»æ¥çtaskãtaskæsuspendãreadyãfinishedåterminatedåç§ç¶æï¼èHISRåªæexecutingåno-activeè¿ä¸¤ç§ç¶æã
æ¯ä¸ä¸ªtaské½æä¸ä¸ªçº¿ç¨æ§å¶çæ°æ®ç»æï¼TCB thread control blockï¼,å ¶ä¸å æ¬äºtaskçä¼å 级ãç¶æãæ¶é´çãtaskæ ãprotectä¿¡æ¯ãsignalæä½çæ å¿ä½åsignal_handlerçï¼taskå¨å建æ¶åå§åè¿äºä¿¡æ¯ï¼å°taskæå°ä¸ä¸ªcreate_listä¸ï¼åå§è®¾å®task为pure_suspendï¼å¦æ设å®auto startï¼è°ç¨resume_taskï¼ï¼å¤étaskï¼è¿éæ个ç»èï¼å¦æå¨application initializeä¸create_task()ï¼åtaskä¸ä¼èªå¨è¿è¡ï¼å 为åå§åè¿æªå®æï¼æ§å¶æè¿æ²¡æ交ç»scheduleï¼æ æ³è°åº¦taskãtask被å¤éåç¶ææ¹å为readyï¼å¹¶æå¨ä¸ä¸ªTCD_Priority_List[]ä¸ï¼æ°ç»çæ¯ä¸ªå ç´ æ¯ä¸ä¸ªæåTCBç¯å½¢ååé¾è¡¨çæéï¼æ ¹æ®taskçtc_priorityæ¾å°å¯¹åºä¼å 级çTCB head pointerã
æ¯ä¸ä¸ªHISRé½æä¸ä¸ªHISRæ§å¶çæ°æ®ç»æï¼HCB HISR control blockï¼,å ¶ä¸åªæä¼å 级ï¼HISRæ åHISR entryä¿¡æ¯ï¼å æ¤HISRæ¯ä¸å¯ä»¥suspendï¼åæ¶ä¹æ²¡ætime slice以åsignalçç¸å ³æä½ï¼ä¸è¬æ åµä¸å½åçäºä¸æåï¼HISR被activateï¼scheduleå°±ä¼è°åº¦HISRè¿è¡ï¼æé´å¦æä¸åçä¸æï¼HISRçæ§è¡æ¯ä¸ä¼è¢«ææçï¼HISRçä¼å 级åªæ0ã1ã2ï¼timerçHISRä¼å 级为2ï¼ä¹å°±æ¯è¯´ç±å¤é¨ä¸ææ¿æ´»çHISRå¾é¾è¢«æ¢å çï¼åªææ´é«ä¼å 级çä¸æHISRæå¯ä»¥ãä¸taskä¸åï¼è¢«æ¿æ´»çHISR使ç¨head_liståtail_listå°HCBæå¨ä¸ä¸ªå项çé¾è¡¨ä¸ï¼å 为ç¸åä¼å 级çHISRä¸ä¼æ¢å 对æ¹ï¼å æ¤ä¸éè¦ååé¾è¡¨ï¼ä½¿ç¨ä¸¤ä¸ªæéç®çæ¯å å¿«HISRæ§è¡çé度ã
ä¸ä¸ªå®æ¶æä½ç³»ç»çæ ¸å¿å°±æ¯å¯¹äºä»»å¡çè°åº¦ï¼NUçè°åº¦çç¥æ¯time sliceåround robinçç®æ³ï¼
è°åº¦çé¨å主è¦æä¸ä¸ªå½æ°control_to_system()ç¨äºä¿åä¸ä¸æï¼å»ºç«solicited stackï¼å ³ä¸æï¼å ³system time sliceï¼å¹¶éç½®taskçtime slice为é¢è®¾å¼ï¼å°spæ´æ°ä¸ºsystem_stack_pointerï¼è°ç¨schedule()ï¼è°åº¦çè¿ç¨æ¯é常ç®åçæ¥è¯¢ï¼å°±æ¯æ¥çä¸¤ä¸ªå ¨å±çåéï¼TCD_Execute_HISRåTCD_Execute_Taskï¼scheduleé¨åçå ³é®æ¯æå¼äºä¸æï¼ä¸ç¶å¦æå½å没æreadyçtaskææ¯è¢«æ¿æ´»çHISRï¼åsheduleæ»å¾ªç¯ä¸å»ï¼æ¥è¯¢å°ä¸ä¸ä¸ªåºè¯¥æ§è¡ç线ç¨å跳转è³control_to_thread(),å¨è¿ééæ°å¼å¯system time sliceï¼ç¶åå°çº¿ç¨çtc_stack_ptrå å ¥å°spä¸ï¼åæ¢è³çº¿ç¨çæ ä¸ï¼ä¾æ¬¡popåºæ¥ï¼å³å®æäºä»»å¡è°åº¦ã
ä»»å¡çåæ¢ä¸»è¦æ¯ä¸ä¸æçåæ¢ï¼ä¹å°±æ¯taskæ çåæ¢ï¼å½æ°çè°ç¨ä¼ä¿åé¨åregsåè¿åå°åï¼è¿äºå¨ä½é½æ¯ç¼è¯å¨æ¥å®æçï¼èOSä¸çä»»å¡åæ¢æ¯è¿è¡æ¶ï¼runtimeï¼çä¸ç§ç¶æååï¼å æ¤ç¼è¯å¨ä¹æ è½ä¸ºåï¼æ以对äºä¸ä¸æçä¿åéè¦ä»£ç æ¥å®ç°ã
ä»»å¡çæ¢å æ¯å¼æ¥çå æ¤å¿ é¡»è¦éè¿ä¸ææ¥å®ç°ï¼ä¸è¬æ¯æ¬¡timerçä¸æå³å®å½åçtaskçslice timeæ¯å¦expiredï¼ç¶å设置TCT_Set_Execute_Task为ç¸åä¼å 级çå ¶ä»taskææ´é«ä¼å 级çtaskï¼é«ä¼å 级çtaskæ¢å ä½ä¼å 级çtaskï¼ä¸è¬æ¯å¤é¨ä¸æ触åï¼å¨HISRä¸resume_task()å¤éé«ä¼å 级çtaskï¼ç¶åscheduleå°é«ä¼å 级çtaskä¸ï¼å 为timerçHISRæ¯å¨ç³»ç»åå§å就已ç»æ³¨åçï¼åªæ¯æ§è¡timeoutåtime sliceè¶ æ¶åçæä½ï¼å¹¶æ²¡ææ§è¡resume_taskçå¨ä½ã
NUä¸çstackæ两ç§solicited stackåinterrupt stackï¼solicited stackæ¯ä¸ç§minmum stackï¼èinterrupt stackæ¯å¯¹å½åææå¯åå¨å ¨é¨ä¿åï¼TCBä¸çminimum stack size = ç³è¯·å¾å°stack size - solicited stackï¼å¨arm modeä¸å åèï¼thumb modeä¸å åèï¼ï¼thumbæ å¿ç¨æ¥è®°å½ä¸ä¸æä¿åæ¶çARMçå·¥ä½æ¨¡å¼ï¼c代ç ç¼è¯ä¸ºthumb模å¼ï¼è¿æ ·å¯ä»¥åå°code sizeï¼æé«ä»£ç å¯åº¦ï¼assembly代ç ç¼è¯ä¸ºarm模å¼æå代ç çæçï¼NUä¸å æ ¸ç代ç ä¸å¤ï¼ä¸»è¦æ¯assembly代ç ãstackçç±»åä¸å ¶ä¸PCæåçshellæ å ³ï¼interrupt stackä¿åçæ¯taskææ¯HISRå¨æ§è¡çè¿ç¨ä¸è¢«ä¸ææ¶çç°åºï¼solicited stack建ç«çå°æ¹å æ¬ control_to_system()ãschedule_protect()åsend_signals()åéç»å æprotectèµæºçtaskçæ åµï¼HISR_Shell()æ§è¡å®åä¼å»ºç«solicited stackï¼å跳转è³scheduleã
(Lower Address) Stack Top -> 1 (Interrupt stack type)
CPSR Saved CPSR
r0 Saved r0
r1 Saved r1
r2 Saved r2
r3 Saved r3
r4 Saved r4
r5 Saved r5
r6 Saved r6
r7 Saved r7
r8 Saved r8
r9 Saved r9
r Saved r
r Saved r
r Saved r
sp Saved sp
lr Saved lr
(Higher Address) Stack Bottom-> pc Saved pc
(Lower Address) Stack Top -> 0 (Solicited stack type)
!!FOR THUMB ONLY!! 0/0x Saved state mask
r4 Saved r4
r5 Saved r5
r6 Saved r6
r7 Saved r7
r8 Saved r8
r9 Saved r9
r Saved r
r Saved r
r Saved r
(Higher Address) Stack Bottom-> pc Saved pc
ä¸ä¸ªç®åçä¾å说æstackçæ åµï¼é¦å æ¯ä¸ä¸ªtaskå¨ready(executing)çç¶æä¸ï¼èä¸time sliceè¶ æ¶äºï¼timerä¸æåçåï¼ä¿åtaskä¸ä¸æinterrupt_contex_save()ï¼å¨taskçtc_stack_ptræåçå°æ¹å»ºç«ä¸ææ
taskA |interrupt stack|___tc_stack_ptr æ 顶端æ¯pc=lr-4
ARM对äºä¸æçå¤å®åçå¨å½åæ令å®æexecuteæ¶ï¼åæ¶pipelineçåå pc=pc+8ï¼å ¥æ æ¶å°±ælr-4é¦å æ¾å¨stackçæé«ç«¯ï¼highï¼ã
timerçLISRå®æåæ¿æ´»äºHISRï¼æ§è¡TCC_Time_slice()å°å½åtask移å°ç¸åä¼å 级ç尾端ï¼å¹¶ä¸è®¾ç½®ä¸ä¸ä¸ªè¦æ§è¡çtaskï¼HISRå¨æ 顶端ä¿åçæ¯è¿ä¸ªHISR_shellçå ¥å£å°åï¼å 为taskçæ§è¡å®å°±finishedï¼HISRæ¯å¯éå ¥ç
HISR |solicited stack| æ 顶端æ¯HISR_shell_entry
ä¸æï¼interruptï¼
åé¢å·²ç»æåäºä¸æçåºæ¬æä½ï¼è¿éå°±åä¸äºä»£ç è·¯å¾çç»èï¼ä¸æçæ§è¡ä¸»è¦æ¯ä¸¤ä¸ªé¨åLISRåHISRï¼åæ两个é¨åçç®çå°±æ¯å°å ³ä¸æçæ¶é´æå°åï¼å¹¶ä¸å¨LISRä¸å¼ä¸æå 许ä¸æçåµå¥ï¼ä»¥å建ç«ä¸æä¼å 级ï¼é½å¯ä»¥åå°ä¸æç延è¿ï¼ä¿è¯OSçå®æ¶æ§ã
NUçä¸æ模å¼æ¯å¯éå ¥çä¸æå¤çæ¹å¼ï¼ä¹å°±æ¯åºäºä¸æä¼å 级ååµå¥ç模å¼ï¼ä¸æçåµå¥å¨å¤ççè¿ç¨ä¸åºå¯¹lr_irq_modeå¯åå¨è¿è¡ä¿åï¼å 为é«ä¼å 级çä¸æåçæ¶ä¼è¦çæä½ä¼å 级ä¸æçråspsrï¼å æ¤è¦å©ç¨ç³»ç»çæ æ¥ä¿åä¸ææ ã
NU对äºä¸æä¸ä¸æçä¿åå ·ä½æä½å¦ä¸ï¼
ï¼1ï¼å¨ä¸æåçåæ§è¡çå ¥å£å½æ°INT_IRQ()ä¸ï¼å°r0-r4ä¿åè³irqçæ ä¸
ï¼2ï¼æ¥æ¾å°å¯¹åºçinterrupt_shell()ï¼clearä¸ææºï¼æ´æ°å ¨å±çä¸æ计æ°å¨ï¼ç¶åè¿è¡interrupt_contex_save
ï¼3ï¼é¦å å©ç¨r1,r2,r3ä¿åirq模å¼ä¸çsp,lr,spsrï¼è¿éspæ¯ç¨æ¥åæ¢è³ç³»ç»æ åæ·è´lråspsrç,è¿éä¿ålråspsræ¯ç®çæ¯task被æ¢å åï¼å½å次scheduleæ¶å¯ä»¥è¿åtaskä¹åçç¶æã
ï¼4ï¼åæ¢è³SVC模å¼ï¼å¦ææ¯éåµå¥çä¸æåä¿åä¸ä¸æè³task stackä¸ï¼å°irq模å¼ä¸çlrä½ä¸ºé¡¶ç«¯PCçè¿åå¼å ¥æ ï¼å°SVC模å¼ä¸çr6-rå ¥æ ï¼å°irq模å¼ä¸çspä¿åè³r4ä¸å ¥æ ï¼æåå°ä¿åå¨irq_stackä¸çr0-r4å ¥æ
ï¼5ï¼å¦ææ¯åµå¥ä¸æï¼ä¸æçåµå¥åçå¨LISRä¸ï¼å¨æ§è¡LISRæ¶å·²ç»åæ¢è³system stackï¼å æ¤åµå¥ä¸æè¦å°ä¸æçä¸ä¸æä¿åè³system stackä¸ï¼ä¸task stackä¸interrupt stackç¸æ¯åªæ¯å°äºæ 顶ç¨æ¥æ è®°åµå¥çæ å¿ï¼1 not nestedï¼
ï¼6ï¼æä¸ä¸ªåæ¯å¤æï¼å°±æ¯å¦æå½å线ç¨æ¯ç©ºï¼å³TCD_Current_Thread == NULLï¼è¡¨æå½åæ¯scheduleä¸ï¼å 为åå§å线ç¨æ¯å ³ä¸æçï¼è¿æ ·å°±ä¸ä¸ºschedule线ç¨å»ºç«æ 帧ï¼å 为scheduleä¸éè¦ä¿åä¸ä¸æï¼å¨restoreä¸æä¸ä¸ææ¶ç´æ¥è·³è½¬è³scheduleã
ä¸æä¸ä¸æçæ¢å¤
å ¨å±çä¸æ计æ°å¨INT_Countæ¯å¦ä¸º0æ¥å¤å®å½ååºæ çä¿¡æ¯ï¼å¦ææ¯åµå¥åè¿åLISRä¸ï¼å¦ååæ¢è³system stackæ§è¡schedule
timer
timerä¸ä¸æç´§å¯ç¸å ³ï¼å ¶å®timerä¹æ¯ä¸æçä¸ç§ï¼åªæ¯åçä¸æçé¢çè¾é«ï¼ä¸ä½ç¨é大ï¼ä¸ä¸ªå®æ¶æä½ç³»ç»ï¼æ¶é´æ¯é常éè¦çä¸é¨åï¼NUä¸çtimer主è¦æå个ä½ç¨ï¼
ï¼1ï¼ç»´æ¤ç³»ç»æ¶é TMD_system_clock
ï¼2ï¼taskçtime slice
ï¼3ï¼taskçsuspend timeout timer
ï¼4ï¼application timer
å ¶ä¸ï¼3ï¼ï¼4ï¼å ±ç¨ä¸ç§æºå¶ï¼ä¸ä¸ªå ¨å±çæ¶é´è½´TMD_timerï¼timeout timeråapp timeré½å»ºç«å¨ä¸ä¸ªTM_TCBçæ°æ®ç»æä¸ï¼éè¿tm_remaining_timeæ¥è¡¨å¾å½åtimerçå©ä½æ¶é´ï¼ä¾å¦å½åætimer_listä¸æä¸ä¸ªTM_TCBï¼ä¾æ¬¡æ¯Ta = 5ï¼Tb = 7, Tc = ,é£ä¹å»ºç«çé¾è¡¨ä¸å©ä½æ¶é´ä¾æ¬¡æ¯5ï¼2ï¼8ï¼å¦æç°å¨è¦å å ¥ä¸ä¸ªæ°çtimeræ ¹æ®timerå¼æå ¥è³åéçä½ç½®ï¼å¦ææå ¥çtimer为ï¼åå®æå¨Tbåé¢ï¼å©ä½æ¶é´ä¸º1ï¼åé¢ç8æ¹ä¸º7ï¼å½åçäºtimer expiredï¼å触åtimer_HISRï¼å¦ææ¯app timeråæ§è¡timer callbackï¼å¦ææ¯task timeout timerï¼åæ§è¡TCC_Task_Timeoutå¤étaskã
ï¼2ï¼çå®ç°ä¹æ¯ä¾èµäºå ¨å±çtime sliceæ¶é´è½´ï¼æ¯ä¸ä¸ªtaskå¨æ§è¡æ¶é½ä¼å°èªå·±çæ¶é´çä¿¡æ¯æ´æ°è³å ¨å±çæ¶é´è½´ä¸ï¼å½ä¸ä¸ªtaskçtime sliceæ§è¡å®å¨timer HISRä¸è°ç¨TCC_task_Timeoutå°å½åçtaskæ¾å¨ç¸åä¼å 级listçæ尾端ï¼å¹¶è®¾ç½®ä¸ä¸ä¸ªæé«ä¼å 级çä»»å¡ãtaskå¨æ§è¡çè¿ç¨ä¸åªæ被ä¸æåtime sliceä¼ä¿åä¸æ¥ï¼å ¶ä»è®©åºå¤çå¨çæ åµé½ä¼å°time sliceæ´æ°ä¸ºé¢è®¾å¼ã
protect
protectä¸linuxçéæºå¶ç±»ä¼¼ï¼äºæ¥è®¿é®ï¼å©ç¨å¼å ³ä¸ææ¥å®ç°ï¼å¹¶ä¸æ¥æprotectçtaskæ¯ä¸å¯ä»¥suspendçï¼å¿ é¡»è¦å°protectéæ¾åæå¯ä»¥æèµ·ï¼å½ä¸ä¸ªä¼å 级è¾ä½çtaskå æprotectèµæºï¼å¦æ被æ¢å ï¼ä¸ä¸ªé«ä¼å 级çtaskæHISRå¨è¯·æ±protectèµæºæ¶ä¼æ§è¡TCC_schedule_protect()让åºå¤çå¨ç»ä½ä¼å 级çtaskæ§è¡ï¼ç´å°ä½ä¼å 级çtaskæ§è¡unprotect()为æ¢ï¼æ¤æ¶taskæHISR建ç«çæ¯solicited stackï¼åæ¶å¨control_to_threadåå¼å ³ä¸æä¸æ¬¡ï¼è¿æ ·å¯ä»¥åå°ä¸æ¬¡ä¸ä¸æçåæ¢ãNUä¸å¸¸ç¨å°çæ¯system_protectï¼å®å°±æ¯ä¸æ大éï¼ä¿æ¤å æ ¸ä¸ææå ¨å±æ°æ®ç»æç顺åºè®¿é®ï¼ç²åº¦å¾å¤§ã
LISRä¸ä¸å¯ä»¥è¯·æ±protectèµæºï¼å 为LISRæ¯ä¸ætaskåæ§è¡ï¼å¦ætaskå æprotectèµæºï¼è¿æ¶LISRåå»è¯·æ±protectèµæºï¼ä¼åçæ»éï¼å 为LISR让åºå¤çå¨åï¼schedule没åæ³å次è°åº¦å°LISRæ§è¡ï¼ååçæ»éé误ï¼å æ¤å¨LISRä¸é¤äºactivate_HISRï¼ï¼ä»¥å¤ä¸å¯ä»¥ä½¿ç¨system callï¼ä¾å¦resume_taskççï¼è¿åç³»ç»è°ç¨é½ä¼è¯·æ±protectèµæºã
对äºprotectç请æ±æç §ä¸å®ç顺åºå¯ä»¥é²æ¢æ»éï¼NUçæºç ä¸ä¸è¬å°system_protectèµæºç请æ±æ¾å¨åé¢ï¼å ¶ä»å¦DM_protectå 请æ±ã