实时系统RTX之理解一

2023-11-11

文献来源:http://wzhyblog.yo2.cn/articles/%e5%ae%9e%e6%97%b6%e7%b3%bb%e7%bb%9frtx%e5%ae%98%e6%96%b9%e6%96%87%e6%a1%a3%e4%b8%ad%e6%96%87%e7%bf%bb%e8%af%91.html#comment-26472

 

首先对且歌且行 表示感谢!

新手看这个文档,可以按以下顺序阅读:Welcome to IntervalZero-->Using the RTX SDK-->Using RTX Runtine-->Using RTX Tools-->Developing RTSS Applications-->Debugging RTSS Applications,这样比较好理解一些,本中文翻译也是按照这个顺序发布。

 

 

实时系统RTX官方文档中文翻译_2

Using the RTX SDK_1

本文档包括以下内容:

=======================================================

理解RTX特点

RTX介绍

RTX所定义的“实时”为硬实时(hard real-time)。

尽管RTX给Windows带来了无与伦比的实时性,但有两个方面需要全面认识清楚:

1. 因为最坏响应时间这个指标非常有意义,开发者和用户必须仔细选择他们的系统。不同的板卡经销商,尤其是视频卡经销商,在价格、各部分和确定性动作之间作了不同的权衡。使用RTX性能分析工具,开发者和用户可以选择能够满足他们需求的系统。

2. 开发者必须在应用中合理使用RTX。否则RTX可能会提升很少的功能,也可能影响其他Windows程序的运行,甚至会导致系统回环不稳定。


RTX架构

RTX向Windows添加一个实时子系统,即RTSS(见上图)。RTSS从概念上类似于其他Windows子系统(如Win32、POSIX、WOW、DOS),支持自己的运行环境和API。但是RTSS在一个方面有点重要区别:不是使用Windows调度器,RTSS执行它自己的实时线程调度。更进一步,在一个单处理器环境中,所有的RTSS线程调度都发生在所有Windows调度之前,包括Windows管理的中断和延迟过程调用Deferred Procedure Calls (DPCs)。

实时进程间通讯

RTSS支持可以被其他RTSS或Win32进程控制的IPC对象;这使得实时程序与非实时程序之间可以简单和标准的进行通讯和同步。最后,RTX为RTSS程序提供了其他严格时序的服务——如时钟、定时器和中断管理。

HAL扩展

RTX包括一个有实时功能的HAL扩展。此扩展保持了RTSS和Windows之间的中断隔离。Windows不能接管由RTSS负责的中断(在中断控制器层),而在RTSS运行时Windows中断被接管。这个实时HAL扩展支持高分辨率的时钟和定时器,同时也支持Windows的非实时时钟和定时器。其他的一些特性包括:RTSS和Windows之间的软件中断机制、基本异常管理和大量确定性任务的增强。

单处理器和多处理器系统

多处理器系统上的RTX运行时,设计了一个独占处理器模型。在此模型中,RTSS在一个处理器上运行,而其余的处理器继续运行Windows。当Windows启动过程中,多处理器HAL获取最后一个逻辑处理器的控制,并为RTSS所保留。RTSS程序就可以被加载和运行于此独占的处理器之上。

不管是单处理器还是多处理器系统,软件的编写都是一样的。


RTX API

RTX API基于Win32。使得开发者可以借鉴Win32经验、基础代码和开发工具以加速硬实时程序的开发。Win32和RTSS程序都支持全部的RTX API,但是有不同的响应时间和性能特点。

1. Win32 and Real-Time API

RTX支持Win32 API的一个子集,加附加了一个特殊的实时函数集,即RTAPI(实时API)。RTAPI函数在函数名的最前面都有标识“Rt”,一些RTAPI函数只是在标识头方面与Win32不同,而有一些则是RTX所特有的,如中断管理函数。RTX API仔细挑选了对实时应用有关的函数,而刻意忽略了一些对实时编程用处不大的函数(如GUI相关的函数调用)。一个期望的目标是大多数程序包含至少两个同时工作的部分——一个是基于Win32的进程(利用GUI和其他的Win32-only函数),另一个是执行实时处理的基于RTSS的进程。

2. RTX可执行映像

RTX提供了三种类型的可执行映像:RTSS程序,RTSS DLL和RTDLL。RTSS程序等同于Win32程序。RTSS DLL是用来链接以提供一个导出函数库供其他RTSS程序使用的RTSS程序。RTSS DLL是纯RTSS程序,并且必须在调用它的RTSS程序之前被手工运行。RTDLL是被动的代码容器,在功能上与Win32 DLL类似,但在RTSS中运行。

3. 实时库

RTX也支持众多的实时库,并提供了一个基于MS VC++的C运行时库。RTSS程序可以静态链接这些库,以提供不支持的Win32函数。

4. Unicode

RTX支持Unicode程序。一个RTSS程序可以使用wmain()函数,并接受宽字节输入参数。对WCS家族函数的支持作为RTX支持的C运行时库的一部分引入进来。


中断延迟的原因和管理

中断延迟是实时系统开发人员普遍关注的问题。本小节检查其成因和RTX管理它们的技术。

软件原因

包括:

l PIC(可编程中断控制器programmable interrupt controller)或APIC(advanced programmable interrupt controller高级可编程中断控制器)级掌管(masking)中断。Windows内核和驱动通过HAL IRQL manipulation 调用来改变中断掌管。驱动从程序上掌管中断需要几个us。

l 处理器级掌管中断。Windows内核、HAL和一些系统中断可能会掌管中断最多达到100ms。

l 中断——处理overhead。

硬件原因

包括:

l 外围设备的总线“hijacking”。例如,一个视频卡可能会拖延CPU读取卡上面I/O空间寄存器的尝试。

l SCSI控制器的Burst DMA。

l Windows和应用程序引起的脏缓存(cache dirty)。

l 大多数系统,尤其是移动系统,外围设备可以在一个设定的时间之后进入低功耗状态,但是“唤醒”延迟对一个实时系统来说是无法忍受的。

l 使用SMI(System Management Interrupt系统管理中断)的电源管理特性导致最高为数百ms的延迟。

l 对于使用Intel Pentium M处理器的系统,Intel的SpeedStep技术可以根据负载的大小改变处理器速度。

RTX对中断延迟的管理

有以下几种方式:

l RTX通过隔离中断(通过RTX HAL扩展)屏蔽了PIC或者APIC级中断。

l Windows和其驱动不能禁用RTSS中断。

l 当RTSS运行时,所有Windows中断被接管。

RTX对Windows(非Vista)的电源管理

如果有RTSS程序运行在一个UP PIC系统上,包括RT-TCP/IP协议栈,RTX电源管理会阻止系统电源状态从工作状态(S0)到睡眠状态(S1-S5)的切换。一个消息会显示出来通知用户。在一个UP PIC系统上如果没有RTSS程序运行,那么这种切换将不会受到阻止。

在一个多处理器系统或者UP APIC系统中,如果RTSS被加载,则从工作状态(S0)到睡眠状态(S1-S5)的切换都将被阻止。

 

 

实时系统RTX文档中文翻译_3

Posted on 2011-03-20 by wzhy

Using the RTX SDK_2


进程和线程管理

进程和线程

RTSS和Win32进程和线程只能在他们自己的环境中获取进程和线程。

使用进程

以下内容讨论进程在RTSS和Win32环境中是如果运行的。

RTSS环境中的进程

一个运行在RTSS环境中的进程包括一些对象的句柄、进程地址空间、至少一个线程和一个可执行文件。当一个进程被创建时,RTSS执行以下任务:

l 像加载驱动一样加载进程的可执行文件

l 从非分页池中分配中进程堆(process heap)

l 创建主线程

一个进程可能通过以下方法中的任一一个来启动:

l 在系统启动时像加载驱动一样加载它(使用RTSSrun /b)

l 从命令行中运行RTSS可执行文件

l 从Win32程序中启动RTSS进程

以下情况任一一个发生时,进程退出:

l 最后一个线程退出

l 一个线程中调用了ExitProcess

l 使用RTSSkill或者RTSS Task Manager杀掉

Win32环境中的进程

当运行在Win32环境中的进程调用一个RTAPI时,它就开始和RTX进行交互。然后RTX可能会从此进程中分配资源、改变其优先级、执行和它Windows32进程状态相关的其他操作。可以与RTX进行交互的Win32的 进程数是动态的,取决于系统的配置和资源。

使用线程

CreateThread 函数可以创建一个RTSS或者Win32线程,这取决于当前进程运行在哪个环境。使用CreateThread可以固定的指明栈的大小。返回的句柄和线程ID只在CreateThread调用者的环境中有效。例如,一个Win32进程不能操作一个RTSS线程的优先级,因为此线程的句柄只在RTSS环境中有效。不过,你可以使用RTX IPC机制(例如mutex objectssemaphoresevents, 和 shared memory)在Win32和RTX进程与线程之间进行同步和通讯。

RTSS环境中的线程

RTSS线程是RTSS环境中的运行单元。一个准备运行(ready-to-run )的RTSS线程在所有Windows线程之间接受调度。一个RTSS线程会在它放弃CPU之前一直运行。当以下情况时一个线程放弃CPU:

l 等待一个同步对象

l 降低自己的优先级或提高另外一个线程的优先级

l 暂停(suspend)它自己

l 从定时器或中断处理程序中返回

l 使用参数0调用了Sleep

l 当一个时间定量设定时收到一个通知

l 被一个更高优先级中断

一个进程的初始线程有8KB大小的栈。

线程优先级

RTSS环境

RTSS环境没有直接直接的优先类别(priority classes),故所有RTSS进程的线程都会使用唯一的线程优先类别来结束对CPU的使用。一个RTSS线程有128个不同的优先级。任何优先级的线程都依照优先命令和“先进先出”命令进行运行。如果一个时间量被设为0,则线程会运行结束。如果时间量被设为其他值,一个线程会运行至指定的这个时间,然后将CPU交给拥有相同优先级的另外一个线程。RTSS调度机制执行优先级反转和顺序优先级(deferred priority)降低机制来避免优先级反转。

例如,RTX互斥锁对象支持一个1级优先级提升机制。如果一个更高优先级的线程对一个低优先级的线程拥有的互斥锁对象调用了WFSO,则互斥锁对象拥有者的优先级就被提升到和那个更高优先级的线程一样的优先级。尝试降低互斥锁对象拥有者的线程的优先级会直到此线程释放了互斥锁之后才顺序执行。

Win32环境

一个与RTX联系的Win32程序以普通优先类别启动,然而,一旦此程序调用了RtGetThreadPriorityRtSetThreadPriority或其他实时优先级函数,其优先类别就会变成实时优先类别。

表1-RTSS到Win32的线程优先级映射,显示了当RtSetThreadPriority 被一个Win32程序调用时,RTSS符号优先级命令是如何转换到一个普通Windows 2000优先级请求的。

表 1. RTSS到Win32的线程优先级映射

RTSS Symbolic Priority Name RTSS Value Windows 2000 Symbolic Priority Name for Real-Time Priority Class Win32 Value
RT_PRIORITY_MIN 0 THREAD_PRIORITY_IDLE 16
RT_PRIORITY_MIN + 1 1 THREAD_PRIORITY_LOWEST 22
RT_PRIORITY_MIN + 2 2 THREAD_PRIORITY_BELOW_NORMAL 23
RT_PRIORITY_MIN + 3 3 THREAD_PRIORITY_NORMAL 24
RT_PRIORITY_MIN + 4 4 THREAD_PRIORITY_ABOVE_NORMAL 25
RT_PRIORITY_MIN + 5...+ 126 5...126 THREAD_PRIORITY_HIGHEST 26
RT_PRIORITY_MAX 127 THREAD_PRIORITY_TIME_CRITICAL 31

表一显示,例如,RTX层面的RtSetThreadPriority(Thread, RT_PRIORITY_MIN + 1)会对应的Win32调用SetThreadPriority(Thread, THREAD_PRIORITY_LOWEST)。

从RT_PRIORITY_MIN+5 到 RT_PRIORITY_MIN+126 之间的值会将线程设置为THREAD_PRIORITY_HIGHEST,而RT_PRIORITY_MAX 则会将优先级设置成 THREAD_PRIORITY_TIME_CRITICAL。这些映射被设计为在线程优先级之间保护相近的要求。

如果一个Win32程序调用了RtGetThreadPriority,会返回调用RtSetThreadPriority指定的实时优先级。然而有一些限制。最可能困惑的一点是混合调用RtSetThreadPriority 和 SetThreadPriority(mixed)时。当使用一个双重线程句柄(a duplicated thread handle)时,函数库不一定都会理解RTSS优先级,并且为返回RT_PRIORITY_MIN+5,而不是RT_PRIORITY_MIN+6 和 RT_PRIORITY_MIN+126之间的优先级。设置和获取自己的RTSS优先级的线程(如使用GetCurrentThread来指明的线程)将会一直获得设定的RTSS优先级。

Win32程序应该为Win32线程使用Rt进行优先级调用,以在等待一个RTSS同步对象时要求不是最低的RTSS调度优先级。例如,一个拥有RTSS RT_PRIORITY_MAX优先级的Win32线程将会拥有一个互斥锁对象,而一个拥有比RT_PRIORITY_MAX优先级低的RTSS线程想要同一个互斥锁对象时就只能等待。

表2-Win32向RTSS线程优先级的映射,显示了调用Win32“设定”和“获取”线程优先级时在RTSS环境中的对应。表2的描述是表1的反转。

Table 2. Win32 to RTSS Thread Priority Mapping

Windows 2000 Symbolic Priority Name for Real-Time Priority Class Value RTSS Symbolic Priority Name Value
THREAD_PRIORITY_IDLE 16 RT_PRIORITY_MIN 0
THREAD_PRIORITY_LOWEST 22 RT_PRIORITY_MIN + 1 1
THREAD_PRIORITY_BELOW_NORMAL 23 RT_PRIORITY_MIN + 2 2
THREAD_PRIORITY_NORMAL 24 RT_PRIORITY_MIN + 3 3
THREAD_PRIORITY_ABOVE_NORMAL 25 RT_PRIORITY_MIN + 4 4
THREAD_PRIORITY_HIGHEST 26 RT_PRIORITY_MIN + 5 5
THREAD_PRIORITY_TIME_CRITICAL 31 RT_PRIORITY_MAX 127

在THREAD_PRIORITY_IDLE 和 THREAD_PRIORITY_HIGHEST之间没有额外的优先级。If you need finer grain priorities, you should use the RTSS priority spectrum instead. Just as in Win32, this value specifies a thread priority that is higher than all other priorities.

Win32环境编程考虑

一个Win32 RTX 链接的程序在启动时处在普通的优先级类别,直到调用了RtGetThreadPriorityRtSetThreadPriority, 或其他实时优先级函数,则此程序的优先级类别就变成了实时优先级类别。

这是大多数应用所期待的结果,因为它给进程赋予了最大可能的实时性能。但是,当Win32线程有GUI组件时就引起了问题。当一个处在 REALTIME_PRIORITY_CLASS 优先级的线程同Windows GUI(并链接到rtapi_win32.lib)交互时,slowdowns and lock-ups occur. 在编写拥有GUI组件的Win32程序时你可以通过首先在程序中调用:

SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS)

来避免这个问题。

提示: 如果你像上面讨论的那样设定你程序的优先级,则其GUI如果不是在最上层窗口时可能不会刷新其数据。


系统内存管理

系统内存分配

进程必须频繁地分配额外的内存以保证它们的运行。RTX内存分配机制通常会分配已经锁定的内存,以避免任何可能导致页失败的延迟机会。

内存分配API

以下API可以用来获取RTX系统内存分配服务:

RtAllocateLockedMemory从物理内存后部分配内存并锁定,然后将内存映射到进程的虚拟地址空间中。

RtFreeLockedMemory释放先前分配的锁定内存区域。

RTSS和Win32编程考虑

锁定内存通常从一个非分页内存池中分配并由Windows维护。这个内存池相当小,并在系统启动后很快就会被Windows的其他驱动和子系统造成破碎。为了避免大容量分配的失败,你应该最小化它们(大容量分配)的使用,或保证它们在系统启动很短的时间内结束。

代码例程(RTX 锁内存分配函数调用)

见Code and File Examples中RTX Locked Memory Allocation Calls Programming Example。此例子证明了RTX锁内存分配函数调用的使用。

RTX Locked Memory Allocation Calls Programming Example

The following programming example demonstrates the use of RTX locked memory allocation calls.

#include <windows.h>

#include <stdio.h>

#include <rtapi.h>

static PVOID vAddress; // virtual memory address returned by RtAllocateLockedMemory

void main(void) {

ULONG size=4096; // bytes to allocate

// Allocate memory

vAddress = RtAllocateLockedMemory(size);

if (!vAddress) {

printf("/nFailure on RtAllocateLockedMemory/t");

printf("Error=%d/n", GetLastError());

break; // if this fails - no use to continue

}

else {

printf("/nSuccess on RtAllocateLockedMemory/n");

printf("Virtual memory address = 0x%08X/n", vAddress);

// Write to the memory

*vAddress= 0;

}

// Free memory

if (!RtFreeLockedMemory(vAddress)) {

printf("/nFailure on RtFreeLockedMemory(0x%08X)./t", Address);

printf("Error Code = %d/n", GetLastError());

}

else {

printf("Success on RtFreeLockedMemory(0x%X)./n", vAddress);

}

ExitProcess(0);

}

系统内存锁定

为避免页失败,并增强关键代码处的非可预见性延迟,实时程序需要锁定在内存中的数据和代码,包括在操作系统它本身的代码和数据。

进程锁定API

RtLockProcess 锁定一个进程的全部分页段到物理内存

RtUnlockProcess 解锁一个进程先前被锁定到物理内存的虚拟地址空间的所有段

RtCommitLockProcessHeap 记录并锁定进程的堆(heap)

RtCommitLockHeap记录并锁定指定的堆(heap)

RtCommitLockStack记录并锁定进程的堆栈(stack)

RTSS环境编程考虑

默认地,RTSS环境中所有进程和内存对象都被锁定到物理内存中以避免页失败。RtLock* (Process, Heap, Stack)函数在RTSS环境中会一直以成功结束,但并没有执行实际操作。

Win32环境编程考虑

除非显式的锁定到物理内存中,所有Windows进程和服务都是分页的。在Win32环境中,调用RtLockProcess函数可以避免Win32进程引起页失败。

代码例程

Code and File Examples中的RTX Process Memory Locking Calls Programming Example

RTX Process Memory Locking Calls Programming Example

The following programming example demonstrates the use of RTX process memory locking calls.

#include <windows.h>

#include <stdio.h>

#include <rtapi.h>

void main(void) {

DWORD dwSections = RT_PLOCK_ALL;

if (!RtLockProcess( dwSections)) {

printf("/nFailure on RtLockProcess./t");

printf("Error=%d/n", RtGetLastError());

}

else {

printf("/nSuccess on RtLockProcess/n");

if (!RtUnlockProcess( dwSections)) {

printf("/nFailure on RtUnlockProcess./t");

printf("Error=%d/n", RtGetLastError());

}

else {

printf("/nSuccess on RtUnlockProcess/n");

}

}

ExitProcess(0);

}

内核锁定API

以下API可以获取RTX内核内存锁服务:

RtLockKernel 将Windows 内核的分页段锁定到物理内存中

RtUnlockKernel 将上个函数的内存解锁

RTSS环境编程考虑

默认地,RTSS环境中所有进程和内存对象都被锁定到物理内存中。

Win32环境编程考虑

相当一部分Windows操作系统组件都是分页的,包括大部分的Windows内核和Win32子系统。为了避免实时程序因内核分页失败带来的延迟,可以使用RtLockKernel函数。

Windows设备驱动程序一般不分页;其在启动时时加载并不分页。为了使驱动在系统中分页,驱动开发者必须仔细地架构其驱动并手工掌管将要分页的代码。因其复杂性,较少驱动使用此方式进行架构。

锁定Windows内核和进程减少了可用物理内存池。这对非实时系统操作是有害的。必须要有足够的内存来确保非实时操作的期待性能。更多关于非分页内存池大小,请看Microsoft Knowledge Base 或 MSDN。

代码例程

Code and File Examples中的RTX Kernel Memory Locking Calls Programming Example

RTX Kernel Memory Locking Calls Programming Example

The following programming example demonstrates the use of RTX kernel memory locking calls.

Note:  Since all RTSS processes are always locked, the function RtLockKernel() has no effect in the RTSS environment.

#include <windows.h>

#include <stdio.h>

#include <rtapi.h>

void main(void) {

DWORD dwSections = RT_KLOCK_ALL;

if (!RtLockKernel( dwSections)) {

printf("/nFailure on RtLockKernel./t");

printf("Error=%d/n", RtGetLastError());

}

else {

printf("/nSuccess on RtLockKernel/n");

if (!RtUnlockKernel( dwSections)){

printf("/nFailure on RtUnlockKernel./t");

printf("Error=%d/n", RtGetLastError());

}

else {

printf("/nSuccess on RtUnlockKernel/n");

}

}

ExitProcess(0);

}


本地内存

本地内存(Local memory)是RTX用来满足所有RTSS程序内存请求的本地内存池。从本地内存池分配内存时,RTSS程序就不需要初始化SRI(Service Request Interrupt)来从Windows请求内存。当第一个RTSS程序开始时,本地内存池就被创建,并为普通的非确定性函数提供确定性的行为,同时在Windows崩溃(蓝屏)后也会有更大的弹性和功能性。

如果默认的内存分配方式不是从本地内存池请求,RTX会在第一次使用RTSSrun /l 参数时创建本地内存池或者RTSS程序中第一次调用RtAllocateLocalMemory函数时。

设置内存池大小

在RTX Properties的Memory面板中设置本地内存池的初始大小。如果RTSS程序用尽了初始化分配的所有内存,则本地池必须从Windows请求更多的内存。附加的内存将会是初始化的大小或是请求的内存大小,取决于哪一个更大。从Windows请求内存会导致SRI动作,这是非确定性的,并且不能在关机处理函数中调用。

为了避免此情况,务必考虑好你的实时程序对内存的需求并指定可以支持它们的足够大的内存。RTX函数RtQueryLocalMemory可以检查在本地内存池中是否有足够的空余内存可供使用。这在关机处理函数中是一个有用的函数调用。

如果在RTX Properties控制面板中或者使用RTSSrun使能了本地内存池,则在RTSS程序中不管是显式还是隐式分配的内存都将从本地内存池请求分配。因此,以下API就成为确定性的,可以在关机处理函数中进行调用。

RtAllocateLockedMemory HeapFree RtCreateMutex
RtFreeLockedMemory HeapReAlloc RtOpenMutex
RtCreateSharedMemory malloc RtCreateSemaphore
RtOpenSharedMemory calloc RtOpenSemaphore
RtOpenSharedMemory realloc RtCloseHandle
HeapAlloc free InitializeCriticalSection
HeapCreate RtCreateEvent DeleteCriticalSection
HeapDestroy RtOpenEvent CreateThread*

*CreateThread –对在本地内存池创建的线程,堆栈没有保护页。


时钟和定时器

实时系统需要操作系统时序服务。操作系统必须能够保证过去时间的精确计数,在确定时间上调度线程,以及在确定周期内暂停线程。

RTX的定时器是一个隐式的线程,当定时器中止的时候RTSS会发出通知,

线程接到通知后会调用在定时器创建时指定的处理程序。定时器和系统的时钟有关,当定时器创建时,就会测量它的停止时间。一旦定时器中止,它会自动重新启动,同时处理线程会运行,处理线程的运行不会影响定时器的重新启动。

时钟服务

函数

以下为RTX时钟服务的相关函数:

RtGetClockTime 取得指定时钟的当前值

RtSetClockTime 设置指定时钟的值

RtGetClockResolution 取回指定时钟的分辨率

RtGetClockTimerPeriod 取回指定时钟的最小时钟周期RtGetRtssTimeAsFileTime取回RTSS时间的当前值

RtSetRtssTimeAsFileTime 设置RTSS时间的当前值

时钟的值以100ns的单位(ticks)被获取和设置,并被报告从1601年1月1日12:00AM以来的ticks的数量。

时钟类型

在Win32 和RTSS环境中可用的RTX时钟包括以下几种:

CLOCK_1 (alias CLOCK_SYSTEM) —CLOCK_1由实时HAL扩展提供,分辨率为1ms。Win32 和RTSS环境中的线程可以在此时钟上以1ms的增量来调度定时器。

CLOCK_2 (alias CLOCK_FASTEST) — CLOCK_2由实时HAL扩展提供,分辨率为1us。

此时钟上的定时器可以被设置为100, 200, 500, 或 1000 µs。可以通过RTX Settings控制面板来设置HAL扩展定时器。

CLOCK_3 — CLOCK_3由实时HAL扩展提供,分辨率为1us。此时钟上的定时器时期通过可编程定时器ticks的数量来计算,一个tick周期为838.095 ns。此时钟精确度为0.001ns。

注意:CLOCK_3和 CLOCK_2都基于相同的通过RTX设置面板设置的HAL扩展定时器周期,不同之外在于如何中断和以CLOCK计算的表达(见下表)。

Specified Timer Period (unit: µS) Ticks CLOCK_2 Period (unit: µS) CLOCK_3 Period (unit: 0.001 nanosecond)
100 119 100 99,733,305
200 239 200 200,304,705
500 596 500 499,504,620
1000 1193 1000 999,847,335

因为HAL扩展定时器在APIC系统上基于本地APIC定时器,而不是PIC系统中的可编程定时器(the Programmable Timer),上面所示CLOCK_3 和 CLOCK_2的区别公限于UP PIC系统。对于UP APIC和MP系统,CLOCK_3 和 CLOCK_2是一样的。

与Win32时钟的关系

RTX时钟由实时HAL扩展提供的服务进行更新。RTX时钟与实时HAL扩展定时器服务进行同步。然后,RTX时钟既不与Windows系统时钟也不与电池备份日时间时钟(the battery-backed time-of-day clock)进行同步。

RTX和Windows时钟Accuracy(只限于UP PIC系统)

略。

定时器服务

一个RTX定时器其实是一个有定时器截止时间的RTSS获取通知的隐式处理线程,并调用此定时器被创建时指定的处理函数。

定时器同系统中的时钟联系在一起——不是它的截止时间被测量——当它被创建时。(Timers are associated with a clock in the system - against which its expiration is measured - when it is created.)一个定时器从被设定之后开始计数到其截止时间。一旦定时器溢出,则它会自动进行重装载。处理线程就得到执行。处理程序的执行不影响定时器的重装载。重复周期被设为0的定时器只执行它们的处理程序一次,并称为“一次搞定”(one-shot)定时器。重复周期被设为固定值的定时器会不停的执行它们的处理程序,这称为“重复”或“周期”定时器。

API

以下为RTX定时器服务相关的API函数:

RtCreateTimer 使用指定的时钟创建一个定时器

RtDeleteTimer 删除先前创建的定时器

RtCancelTimer 取消指定定时器的截止时间

RtSetTimer 设置指定定时器的绝对(absolute)截止时间和重复周期

RtSetTimerRelative设置指定定时器的相对(relative)截止时间和重复周期

与Win32定时器的关系

RTX定时器不是同步对象,这意味着一个线程不能等待有RTX定时器处理函数(handle)的单个对象。这与Windows定时器(一个线程可以等待一个对象,或者反对一个可以接收通知的线程)正好对立。

Win32和RTSS编程考虑

如果你的程序需要通知其他线程一个定时器的截止时间,你应该在处理函数中使用合适的通知对象来触发此事件。

Sleep服务

Sleep服务可以暂停当前线程指定的一段时间。

API

Sleep 暂停当前线程指定的毫秒时间

RtSleepFt暂停当前线程指定的时间,以100ns为单位

编程考虑

RtSleepFt在一个Win32定时器线程中无法使用。定时器截止时间的一系列规定,包括定时器,等待函数和sleep函数,是为了截断指定的周期至定时器tick计数。如果此计数为0,则计数就被设为1。

代码例程

See RTX Timer and Sleep Calls Programming Example in Code and File Examples. It demonstrates the use of RTX timer and sleep calls.

RTX Timer and Sleep Calls Programming Example

The following example demonstrates the use of RTX timer and sleep calls.

#include "windows.h"

#include "stdio.h"

#include "rtapi.h"

//

// Local data.

//

LARGE_INTEGER Period; // Timer period

LARGE_INTEGER StartTime; // Start time of sampling run

ULONG TimerCounter = 0; // Counts entries to timer handler

//

//

VOID main(int argc, char **argv)

{

LARGE_INTEGER x;

HANDLE hTimer;

//

// Set default timer period to 500 micro seconds

//

Period.QuadPart = 5000;

//

// Set to the next to highest real-time priority.

//

if (!RtSetThreadPriority( GetCurrentThread(), T_PRIORITY_MAX-1))

printf("WARNING: Can't set to highest RTAPI priority./n");

//

// Setup and start the periodic timer.

//

if (!(hTimer = RtCreateTimer(

NULL, // Security - NULL is none

0, // Stack size - 0 is use default

TimerHandler, // Timer handler

NULL, // NULL context (argument to handler)

RT_PRIORITY_MAX, // Priority

CLOCK_2))) // RTX HAL Timer

{

printf("ERROR: Could not create the RTAPI timer./n");

ExitProcess(2);

}

if (!RtSetTimerRelative( hTimer, &Period, &Period))

{

printf("ERROR: Could not set and start the RTAPI timer./n");

ExitProcess(2);

}

//

// Wait for the sampling time.

//

Sleep(1000);

//

// Stop and delete the timer.

//

RtCancelTimer( hTimer, &x);

RtDeleteTimer( hTimer);

printf(" Value of number of timers counter is %d/n",TimerCounter);

ExitProcess(0);

}

//

// timer handler function

// - increment the tick counter

//

int RTFCNDCL TimerHandler(PVOID unused)

{

TimerCounter++;

return 0 ;

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实时系统RTX之理解一 的相关文章

  • 在 wampserver 2.2 上安装 php_imagick.dll PHP 扩展

    我使用的是 32 位操作系统的 Windows 7 我安装了 ImageMagick 6 8 7 Q16Link https www imagemagick org script download php windows我能够从命令行 转换
  • 415 不支持的媒体类型; Angular2 到 API

    我是 Angular 2 的新手 我面临着一个无法找到解决方案的问题 当我尝试从 Angular 2 发布到 API 时 我得到 415 不支持的媒体类型 角度2代码 onSubmit value any console log value
  • dia2dump:CoCreateInstance 失败 - HRESULT = 80040154

    我正在尝试使用 Visual Studio 2017 及其在 Windows 7 x64 上转储 PDB 的签名dia2dump https msdn microsoft com en us library b5ke49f5 aspx 我加
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • Twitter 的推文按钮有回调吗?

    有没有办法在 Twitter 的推文按钮上注册回调 我希望能够跟踪我网站上的哪些特定用户在 Twitter 上发布了链接 我无法添加 onClick 事件 因为它是跨域 iFrame 还有其他想法吗 我见过一种方法 https stacko
  • 如何在 Django Rest 框架中编写“删除”操作的测试

    我正在为 Django Rest Framework API 编写测试 我一直在测试 删除 我对 创建 的测试工作正常 这是我的测试代码 import json from django urls import reverse from re
  • Booking.com酒店管理API

    我拥有一家酒店 并在 booking com 上查看了 API 因为我想创建自己的前端界面来更新我的酒店房价 房间数 以及通过该 API 上传图片 更新酒店描述 然而 我唯一能找到的是一个 API 供联营公司以一定的价格获取特定位置的酒店等
  • webm视频转换API

    有谁知道用于将视频转换为谷歌新的 WebM 视频格式的 原型 c API 谷歌快速搜索显示 不 但是编码器示例 http www webmproject org tools vp8 sdk example simple encoder ht
  • 无法启动 Windows 服务,错误 1064

    我编写了一个在 Win10 上运行的 Windows 服务 它运行得非常好 直到我决定对其进行一些更改 我重写了一些逻辑 在调试和发布配置中进行了测试 一切都很好 然后 我使用卸载了当前版本的服务installutil exe u serv
  • Android GCM 服务器的 API 密钥

    我有点困惑我应该为 GCM 服务器使用哪个 API 密钥 在文档中它说使用 android api 密钥 这对我不起作用并且总是给出未经授权的 http developer android com google gcm gs html ht
  • Delphi中使用FindVCLWindow调用WinHelp32(WinXP Pro SP3 32bit)

    有什么问题吗 procedure TForm1 VCLHelpClick Sender TObject var Ctrl TWinControl begin Ctrl FindVCLWindow Mouse CursorPos if Ctr
  • 从 iOS 应用程序内的 Junos Pulse 获取用户凭据

    我正在通过 Junos Pulse 在 iPad 中建立 VPN 连接 以进入我组织的 Intranet 谁能告诉我是否有任何 iOS api 或 SDK 可用于获取在 iOS 应用程序内的 Junos pulse 中输入的用户凭据 Jun
  • 端点按资源 swagger 注释分组?

    我正在使用 Spring 进行 REST API 开发 我有一些 API 其中有很多端点 当我打开 swagger ui 时 它看起来很拥挤 我刚刚读过this https swagger io docs specification gro
  • 带有 OAuth2 的 YouTube API v3:更新和删除失败并出现“权限不足”错误

    我在尝试着update and delete视频使用YouTube API v3 https developers google com youtube v3 docs videos with OAuth2 用于身份验证 https dev
  • conio.h 不包含 textcolor()?

    我一直在考虑在我用 C 编写的 DOS 程序中使用颜色 有人告诉我conio h有textcolor 函数 但是当我在代码中使用它时 编译器 链接器会向我抛出错误 说我对该函数有未定义的引用 Does conio h真的有这个功能还是有人告
  • 如何使用 Win32 API 与 com 端口 (RS232) 通信

    我正在尝试使用 win32 API 与 com 端口对话 我找到了这个http www robbayer com files serial win pdf http www robbayer com files serial win pdf
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • 如何在 Windows 命令行中使用参数运行 Python 脚本

    这是我的蟒蛇hello py script def hello a b print hello and that s your sum sum a b print sum import sys if name main hello sys
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo

随机推荐

  • 嵌入式VSCode+gdbserver图形化调试环境搭建与使用

    目录 一 原理 二 环境搭建 1 VSCode设置 2 gdbserver安装 三 调试过程 一 原理 嵌入式系统中一般在 PC端运行 gdb工具 源码也是在 PC端 源码对应的可执行文件放到开发板中运行 为此我们需要在开发板中运行 gdb
  • 数据库分库分表

    一 为什么要分库分表 如果一个网站业务快速发展 那这个网站流量也会增加 数据的压力也会随之而来 比如电商系统来说双十一大促对订单数据压力很大 Tps十几万并发量 如果传统的架构 一主多从 主库容量肯定无法满足这么高的Tps 业务越来越大 单
  • Linux下Socket编程

    什么是Socket Socket接口是TCP IP网络的API Socket接口定义了许多函数或例程 程式员能够用他们来研发TCP IP网络上的应用程式 要学Internet上的TCP IP网络编程 必须理解Socket接口 Socket接
  • 七. Kubernetes Objects对象,对象状态与yaml

    目录 一 基础概念理解 二 k8s 对象中的spec与status 三 如何编写yaml 一 基础概念理解 Kubernetes Objects 官方地址 在k8s中所有操作资源实体都可以称为对象 先下图中的这些 都可以称为对象 不同对象功
  • 汇编语言随笔(10)-内中断及实验12(返回到dos的中断处理程序)

    不同类型内中断的区分 中断类型码 8086cpu中在下面4种情况下会产生内中断 1 除法错误 如之前提到的除法溢出 2 单步执行 3 执行into指令 4 执行int指令 那么当内中断发生时cpu如何来区分到底是哪种中断源呢 通过中断类型码
  • 代码随想录训练营day9

    题目一 实现strStr 力扣题目链接 题目描述 给你两个字符串 haystack 和 needle 请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标 下标从 0 开始 如果 needle 不是 haysta
  • GLSL的in、out存储限制符使用错误

    在GLSL中用in修饰的变量表示传入的数据 用out修饰的变量表示传出的数据 通过这样可以实现顶点着色器向片段着色器传递数据 但要注意这个变量的命名要相同 不相同的话 片段着色器是获取不到从顶点着色器传入的数据的 1 顶点着色器 versi
  • unity打包技巧

    打包准备 1 android 需要jdk 和android sdk 如果有使用C 的库 还需要NDK 只有将 so文件放在 Assets Plugins Android libs下 Unity才会将 so文件识别为共享库 并在打包时将之拷贝
  • 分布式事务-seata AT模式-强一致性。

    目录 1 seata原理 2 关键组件 3 seate服务端参数 4 微服务配置 5 业务流程 6 依次启动eureka seate服务器 微服务 1 seata原理 Seata 是一款开源的分布式事务解决方案 致力于提供高性能和简单易用的
  • element-ui 表格一行显示多行内容并实现多行内某一行列合并

    这是加上边框的 去掉边框后这个表格看着更明显一点 表格一行放多行内容 并让第二行进行列合并 第一行不合并
  • 详解数据结构之顺序栈的基本操作(C语言描述)

    1 栈是线性表的特例 因此栈的顺序存储其实也就是线性表顺序存储的简化 我们称之为顺序栈 线性表是采用数组来实现的 因此顺序栈也采用数组来实现 2 栈的结构定义 elementype类型根据实际情况而定 这里假设为int类型 栈的结构体定义为
  • 时间序列ARIMA滚动预测

    什么是时间序列 时间序列简单的说就是各时间点上形成的数值序列 时间序列分析就是通过观察历史数据预测未来的值 在这里需要强调一点的是 时间序列分析并不是关于时间的回归 它主要是研究自身的变化规律的 这里不考虑含外生变量的时间序列 为什么用py
  • C语言结构体struct的比较

    两个struct结构体进行比较 首先不能直接比较 struct A a b a和b相比是错误的 其次不能进行内存比较 如下 程序运行的结果会如何 void DiffStructWithMultiVar struct A a 0 struct
  • 远程连接身份验证错误,找不到加密Oracle修正(正解)

    出现问题 使用远程连接弹出一个对话框 提示 发生身份验证错误 要求的函数不受支持 方法一 win r 输入gpedit msc 找到下面路径 策略路径 计算机配置 gt 管理模板 gt 系统 gt 凭据分配 设置名称 加密 Oracle 修
  • 图像质量评估

    图像质量评估 http jingyan baidu com article cbf0e500f5505a2eab28936e html 客观评价方法 图像质量的客观评价方法是根据人眼的主观视觉系统建立数学模型 并通过具体的公式计算图像的质量
  • Java基础——集合

    首先呢 给大家讲一下集合的由来 java的思想是面向对象思想 如果想统一的管理所有的对象 就涉及到用容器来储存对象 而对象数组是可以存储对象的 但是数组有一个缺点就是长度固定 为了突破这一限制 集合就应运而生了 数组和集合的优缺点 长度 数
  • 代码随想录刷题--(链表篇)19. 删除链表的倒数第 N 个结点 ---快慢指针法

    题目链接 https leetcode cn com problems remove nth node from end of list 代码随想录链接 https programmercarl com 0019 删除链表的倒数第N个节点
  • 前端实现换肤功能

    项目背景 由于项目要求 需要前端对不同的企业用户展示不一样的颜色 也就是简单的更改肤色 本来使用前端框架会很容易解决 但是公司目前的架构不是很好 前后端分离也没有那么彻底 web工程还是搭配jsp 没办法 只好用最纯粹的css来实现换肤要求
  • 一个月拿下十几份测试岗offer的简历是什么样子的?

    一 简历模板 在应聘之前 不能不聊一聊简历 简历是职场的敲门砖 是获得offer的通行证 那样对一个初级测试工程师来说 应该如何写简历呢 可能对萌新来说 完完全全不知道怎么下手 在这里大家从0开始写 第一步你需要去找一份简历模板 可以是网络
  • 实时系统RTX之理解一

    文献来源 http wzhyblog yo2 cn articles e5 ae 9e e6 97 b6 e7 b3 bb e7 bb 9frtx e5 ae 98 e6 96 b9 e6 96 87 e6 a1 a3 e4 b8 ad e