RTX理解12

文献来源: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_14.html

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

本文档包括以下内容:


在VS中运行一个RTSS映像

To specify the Configuration Properties settings:

1.   From the Configurations drop-down menu, select RTSSRelease.

2.   From the Project menu, choose Properties to open the Property pages dialog box, and then choose the Configuration Properties,  Debugging node. 项目属性 -> 调试

3.    In the Command field, type in RTSSrun.exe. Include the full path, for example: 在 “命令”中输入Rtssrun的路径

C:/Program Files/Ardence/RTX/bin/rtssrun.exe

4.   In the Command Arguments field, enter the path to your .rtss image. For example: 在“命令参数”中输入要运行的rtss映像路径

C:/Program Files/Microsoft Visual Studio/MyProjects/Example/RTSSRelease/Example.rtss

  1. Click OK to save the settings.

要运行RTSS映像:

From the Debug menu, choose Start without Debugging.       “调试”-> “开始执行(Ctrl + F5)”


生成和注册RTDLL

生成RTDLL的方法与生成rtss的方法相同。

使用RTSSrun来注册生成的RTDLL。


编码技术

  • 使用RTX动态链接库
  • 使用C运行时库函数
  • 加载rtapi_w32.dll
  • 使用浮点数
  • 使用MMX 和SSE
  • 编写RTSS设备驱动
  • C++ 和结构化异常捕获
  • 饥饿管理
  • 用关机处理程序测试RTX程序

1. 使用RTX动态链接库

本节包括以下内容:

  • Descriptions of the two types of real-time DLLs (RTSS DLL and RTDLL)
  • C Runtime Libraries: Programming Considerations for DLLs
  • References to RTSS DLL and RTDLL code examples关于RTSS DLL和RTDLL

    RTSS DLL

    RTSS DLL其实并不是DLL,而是一个可以导出供其他RTSS进程使用的RTSS程序。它们共同一个地址空间。可以在启动时加载,也可以从C/C++编写的Windows程序中调用(e.g., System("RTSSrun LibName.rtss")。尽管与RTSS程序类似,但是其入口点为Main,并被编译链接之后产生一个可以供其他RTSS程序调用的导出函数库。一般地,一个RTSS DLL的Main将会简单地产生一个SuspendThread调用。RTSS DLL允许你在一个调用的程序中用名字引用函数,但是加载时比较麻烦,因为其他RTSS程序使用它们时不会自动加载和卸载它们。

    RTDLL

    RTDLL是可以通过调用LoadLibrary和FreeLibrary动态地加载和卸载的RTSS对象。当引用它们的最后一个进程中止时会自动从内存中卸载。RTDLL不应被静态的加载或延迟加载(delay loaded)。因为RTDLL不需要链接到一个显式的导出库,而是提供一种方便的、弹性的运行时动态适应方法。

    C Runtime Libraries: Programming Considerations for DLLs C运行时库:DLL的编程考虑

    本小节讨论当你设计一个将要与RTX提供的C运行库(RTXlibc.lib or RTXlibcmt.lib)进行链接的RTSS DLL或RTDLL时,需要一直进行考虑的问题。

    MS的C运行库初始化代码假定全局变量有进程范围,比如,会为每一个使用库的进程分配一个所有C运行库的全局变量和结构体的拷贝。但是,在RTSS DLL和RTDLL中不是这样。

    RTSS DLL

    因为RTSS DLL是一些被链接成产生一个导出库的RTSS进程,也因为它们在关机之前不会从内存被卸载,所以,初始化时产生的全局结构体会在使用RTSS DLL的进程的存活周期内一直保留。

    提示:被多个进程使用的RTSS DLL中的少部分C运行时函数会带来不安全因素。

    你不应使用的函数有:fprintf(), getenv(), perror(), printf(), vsprintf(), and wprintf()。因为这些函数信赖于每个进程的全局变量,它们会产生可能导致系统重启的结果。注意这里的“被多个进程使用”意思是在系统启动和关闭时被多于一个的进程在任何时刻使用,包括同一个RTSS映像、在一系列里使用同一个RTSS PID运行两次。

    RTDLLs

    RTDLL不是RTSS进程;他们是可以动态加载和卸载的RTSS对象。因为一个RTDLL产生的对象通常属于调用它的进程,当此进程中止时它们也就被随之销毁。另一方面,C运行库初始化时产生用来内存分配的堆(heaps),这些堆会一直保留到初始加载RTDLL的进程中止之时。因为C运行库函数的行为只在一个RTDLL里可靠,这个RTDLL是多个进程通过有严格限制的LoadLibrary, FreeLibrary 函数调用的。 建议永远不要注册通过C运行库链接得到的RTDLLit,这可以通过  RTSSrun 的 /s 开关来实现。

    RTSS DLL 和 RTDLL 代码例程

    1. RTSS DLL Code Example

    This programming example demonstrates a simple RTSS DLL that exports one function, toggle(), which toggles the state of the PC speaker. A timer is used to control the frequency with which toggle() is called in order to generate a tone with a constant pitch. This example is shown in five parts:

    1. Simple dll.c program
    2. Definition file (dll.def)
    3. Simple program which imports toggle() from dll.rtss
    4. Makefile used to link dll.c
    5. Win32 program to start the DLL and the application that uses it

    RTSS DLL Part 1: dll.c


    #include "windows.h"

    #include "rtapi.h"

    #define SPEAKER_PORT ((PUCHAR)0x61) // Port IO address for speaker

    #define GATE_BIT 0x02

    //

    // MAIN - just suspend the main thread for this process until its

    // use as a DLL is finished and the process is terminated.

    //

    int main(int argc, char **argv)

    {

    SuspendThread( GetCurrentThread());

    return 0;

    }

    //

    // The exported DLL function.

    //

    VOID declspec(dllexport) Toggle(VOID)

    {

    UCHAR i;

    i = RtReadPortUchar( SPEAKER_PORT); // Read PIT PORTB register

    i ^=GATE_BIT; // Change GATE bit

    RtWritePortUchar( SPEAKER_PORT, i); // Write it to PIT PORTB

    }



    RTSS DLL Part 2: dll.def


    LIBRARY DLL.RTSS

    DESCRIPTION 'DLL RTSS'

    EXPORTS

    Toggle



    RTSS DLL Part 3: dll-test.c


    #include "windows.h"

    #include "stdio.h"

    #include "rtapi.h"

    #define NO_ERRORS 0

    #define ERROR_OCCURRED -1

    //

    // External function prototype.

    //

    VOID _stdcall Toggle(VOID);

    //

    // Timer handler -- call the "Toggle" function.

    int RTFCNDCL TimerHandler(PVOID unused)

    {

    Toggle(); // Call the DLL exported function

    return NO_ERROR;

    }

    //

    // MAIN -- start the timer and wait 10 seconds.

    //

    int main(int argc,char *argv[])

    {

    LARGE_INTEGER time;

    HANDLE hTimer;

    ULONG stackSize = 0;

    int waitTime = 10000; //10 seconds

    //

    // Setup and start the periodic timer.

    //

    if (!(hTimer = RtCreateTimer(

    NULL, // Security - NULL is none

    stackSize, // Stack size - 0 is use default

    TimerHandler, // Timer handler

    NULL, // NULL context (argument to handler)

    RT_PRIORITY_MAX, // Priority

    CLOCK_FASTEST))) // Always use fastest available clock

    {

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

    return (ERROR_OCCURED);

    }

    time.QuadPart = 10000; // 1 milliscond interval

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

    {

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

    return (ERROR_OCCURED);

    }

    //

    // Wait for 10 seconds.

    //

    Sleep(waitTime);

    //

    // Stop and delete the timer.

    //

    if (!RtDeleteTimer( hTimer))

    {

    printf("ERROR: Could not Delete timer./n");

    return (ERROR_OCCURED);

    }

    return (NO_ERRORS);

    }



    RTSS DLL Part 4: dll.mak


    NODEBUG = 1

    !include <rtx.mak>

    all: dll.rtss dll-test.rtss RunTest.exe

    dll.rtss: dll.obj

    lib -nodefaultlib -machine:$(CPU) -out:dll.lib -def:dll.def dll.obj

    link $(rtsslflags) -out:dll.rtss dll.exp dll.obj $(rtsslibs)

    del dll.exp

    dll-test.rtss: dll.lib dll-test.obj

    link $(rtsslflags) -out:$*.rtss $*.obj dll.lib $(rtsslibs)

    clean:

    -del *.rtss

    -del *.obj

    -del *.exe

    -del dll.lib



    RTSS DLL Part 5: runtest.c


    #include "windows.h"

    #include "stdio.h"

    #define NO_ERRORS 0

    #define ERROR_OCCURRED -1

    //

    // Standard function to run a utility.

    //

    LONG RunUtility( PCHAR lpCmd )

    {

    STARTUPINFO sinfo;

    PROCESS_INFORMATION pinfo;

    LONG exitCode = 0;

    //

    // Initialize startup info to all zeros.

    //

    ZeroMemory(&sinfo, sizeof(sinfo));

    sinfo.cb=sizeof(sinfo);

    //

    // Create the process to run the utility.

    //

    if (CreateProcess(NULL, lpCmd, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)==FALSE)

    {

    return (exitCode-1);

    }

    //

    // Wait for the utility to complete.

    //

    WaitForSingleObject( pinfo.hProcess, INFINITE);

    //

    // Get the exit code (RTSSrun returns the process slot) and close handles.

    //

    GetExitCodeProcess( pinfo.hProcess, &exitCode);

    CloseHandle( pinfo.hThread);

    CloseHandle( pinfo.hProcess);

    return exitCode;

    }

    //

    // MAIN.

    //

    int main( int argc, char *argv[])

    {

    LONG dllPid, testPid;

    char buf[50];

    int sleepTime = 5000;

    LONG exitCode = 0;

    //

    // Load the RTSS DLL first.

    //

    dllPid = RunUtility("RTSSrun dll.rtss");

    if (dllPid<=exitCode)

    {

    printf("DLL failed to load./n");

    return (ERROR_OCCURED);

    }

    //

    // Now run the test program.

    //

    testPid = RunUtility("RTSSrun dll-test.rtss");

    if (testPid<=exitCode)

    {

    printf("DLL-TEST failed to run,/n");

    return (ERROR_OCCURED);

    }

    // Sleep for 5 seconds and then terminate program and dll.

    Sleep(sleepTime);

    sprintf( buf, "RTSSkill %d", testPid);

    RunUtility( buf);

    sprintf( buf, "RTSSkill %d", dllPid);

    RunUtility( buf);

    return NO_ERROR;

    }


    2. RTDLL Code Example

    This example implements the same functionality as the RTSS DLL example above using an RTDLL to provide the toggle() function. It is shown in four parts:

    1. Simple RTDLL program source code
    2. Simple RTSS application which loads the RTDLL and calls an exported subroutine
    3. Makefile used to create the RTSS application and RTDLL
    4. RTSSrun command used to register the RTDLL

    RTDLL Part 1: sampleRtdll.c


    #include "windows.h"

    #include "rtapi.h"

    #define SPEAKER_PORT ((PUCHAR)0x61) //Port IO address for speaker

    #define GATE_BIT 0x02

    //exported Rtdll Function

    __declspec ( dllexport )

    int _stdcall Toggle(int argc, char* argv[])

    {

    UCHAR i;

    // Read PIT PORTB register

    i = RtReadPortUchar( SPEAKER_PORT);

    // Check GATE bit

    i^= GATE_BIT;

    // Write it to PIT PORTB

    RtWritePortUchar( SPEAKER_PORT, i);

    return 0;

    }

    //DllMain must Explicitly return True

    BOOL WINAPI _stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)

    {

    return TRUE;

    }



    RTDLL Part 2: usingRtdll.c


    #include <windows.h>

    #include <stdio.h>

    #include <rtapi.h>

    #define NO_ERRORS 0

    #define ERROR_OCCURRED -1

    #define SPEAKER_PORT ((PUCHAR)0x61) //Port IO address for speaker

    FARPROC FunctionPtr = NULL;

    int RTFCNDCL TimerHandler(PVOID unused)

    {

    //call Function Toggle

    FunctionPtr(0, NULL);

    return NO_ERRORS;

    }

    /*** MAIN ****/

    int main(int argc, char* argv[])

    {

    HANDLE hLibModule = NULL;

    HANDLE hTimer = NULL;

    LARGE_INTEGER time;

    LPCSTR lpLibFileName = "sampleRtdll.dll";

    LPCSTR lpProcName = "_Toggle@8";

    ULONG sleepTime = 10000;

    //*********** Sample Code: usingRtdll ***********//

    //load Library sampleRtdll

    hLibModule = LoadLibrary(lpLibFileName);

    //check if loadLibrary returned correctly

    if(hLibModule==NULL)

    {

    //error caused by loading a corrupt or unregistered Rtdll

    RtPrintf("UsingRtdll: ERROR: LoadLibrary() failed. Get last Error = %d/n",GetLastError());

    RtPrintf("%s maybe corrupt or not registered with RTSS/n", lpLibFileName);

    return (ERROR_OCCURED);

    }

    //Get function from Rtdll

    FunctionPtr = GetProcAddress(hLibModule, lpProcName);

    //check if function was found

    if(FunctionPtr == NULL)

    {

    //error caused by nonexistent function name

    RtPrintf("UsingRtdll: Error: GetProcAddress() failed. Get Last Error = %d/n",GetLastError());

    RtPrintf("The Function %s does not exist/n", lpProcName);

    //free library before exit

    FreeLibrary(hLibModule);

    return (ERROR_OCCURED);

    }

    //Enable so Win32 can use PortIO

    if (! RtEnablePortIo(SPEAKER_PORT, 1))

    {

    printf("UsingRtdll: Error: Could not enable Port IO/n");

    FreeLibrary(hLibModule);

    return (ERROR_OCCURED);

    }

    // Setup and start the periodic timer.

    hTimer = RtCreateTimer(NULL, 0, TimerHandler, NULL, RT_PRIORITY_MAX,CLOCK_FASTEST);

    //check if timer was created

    if(hTimer == NULL)

    {

    RtPrintf("UsingRtdll: ERROR: RtCreateTimer failed. Get Last Error = %d/n",GetLastError());

    //free library before exit

    FreeLibrary(hLibModule);

    return (ERROR_OCCURED);

    }

    time.QuadPart = 10000; // 1 milliscond interval

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

    {

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

    //free library before exit

    FreeLibrary(hLibModule);

    return (ERROR_OCCURED);

    }

    // Wait for 10 seconds.

    Sleep(sleepTime);

    // Stop and delete the timer.

    if(!RtDeleteTimer(hTimer))

    {

    RtPrintf("UsingRtdll: ERROR: RtDeleteTimer failed. Get Last Error = %d./nGetLastError());

    //free library before exit

    FreeLibrary(hLibModule);

    return (ERROR_OCCURED);

    }

    //free the Library before exiting Process

    if(!FreeLibrary(hLibModule))

    {

    //error caused by an invalid Library handle

    RtPrintf("UsingRtdll: Error: FreeLibrary() failed. Get Last Error = %d/n",GetLastError());

    return (ERROR_OCCURED);

    }

    //the end

    return (NO_ERRORS);

    }


    RTDLL Part 3: rtdll.mak


    NODEBUG = 1

    RTSS_CRT = 1

    !include <rtx.mak>

    all: sampleRtdll.rtdll usingRtdll.rtss /

    sampleRtdll.dll usingRtdll.exe

    clean:

    -del *.rtdll

    -del *.lib

    -del *.obj

    -del *.exp

    -del *.dll

    -del *.exe



    RTDLL Part 4: Register the rtdll


    C:/> RTSSRun /dll sampleRtdll
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值