본문 바로가기

OS/vxworks

vxWorks Standalone 시스템 구축

vxWorks로 개발한 이후에 Stand-alone 으로 시스템을 구동시키고자 할때 쓰이는 방법을 소개하고자 한다.

흔히 사용하는 방법으로는 vxWorks의 커널 프로젝트에서 usrAppInit.c 함수에 사용자의 Entry-point를 적으면 된다.

하지만, 이 방법을 사용하고자 하려면 사용자의 이미지가 vxWorks 커널에 포함되어야 하는 단점이 존재한다.

 

목표로하는 Stand-alone 시스템은 사용자이미지를 .out 의 형태로 유저 플래쉬에 저장하며 커널 로드시 해당 라이브러리를 동적으로 로딩하고, Entry-point의 심볼을 동적으로 찾아 수행하도록 하는데 있다.

볼드체로 된 부분이 추가된 부분이다. define 문으로 동작형태를 구분하고 있다.

 

  1. /* usrAppInit.c - stub application initialization routine */

    /* Copyright (c) 1998,2006 Wind River Systems, Inc.
     *
     * The right to copy, distribute, modify or otherwise make use
     * of this software may be licensed only pursuant to the terms
     * of an applicable Wind River license agreement.
     */

    /*
    modification history
    --------------------
    01b,16mar06,jmt  Add header file to find USER_APPL_INIT define
    01a,02jun98,ms   written
    */

    /*
    DESCRIPTION
    Initialize user application code.
    */

    #include <vxWorks.h>
    #if defined(PRJ_BUILD)
    #include "prjParams.h"
    #include "taskLib.h"
    #endif /* defined PRJ_BUILD */

    #define IDLC_STAND_ALONE_MODE    0

    extern void IDLC_Loader();

    /******************************************************************************
    *
    * usrAppInit - initialize the users application
    */

    /*extern int vxmain(int, char**);*/

    void usrAppInit (void)
        {
    #ifdef    USER_APPL_INIT
        USER_APPL_INIT;        /* for backwards compatibility */
    #endif

        /* add application specific code here */
        selectInit();
    #ifdef    IDLC_STAND_ALONE_MODE
        IDLC_Loader();
    #endif

        }

 

다음은 유저 라이브러리를 동적으로 로드처리하는 부분과 Entry-point를 구동하는 함수이다.

 

  1. #include "vxWorks.h"
    #include "ioLib.h"
    #include "loadLib.h"
    #include "moduleLib.h"
    #include "stdlib.h"

    #define    IDLC_ENTRY_POINT    "vxmain"

    extern SYMTAB_ID    sysSymTbl;    /* target system symbol table */

    void IDLC_Loader()
    {
        char symbolName[20] = {0};
        char symAdrs[5] = {0};
        int iAdrs = 0;
        SYM_TYPE symType;
       
        ld(1, 1, "/tffs0/IDLC_DKM_Modules.out");
       
        sprintf(symbolName, "vxmain");
       
        if ( ERROR == symFindByName(sysSymTbl, symbolName, (char **)&symAdrs, &symType) )       
        {
            printf("Failed to load %s.\n", symbolName);
            return;
        }
       
        memcpy((char *)&iAdrs, symAdrs, sizeof(iAdrs));
       
        printf("Start %s...\n", symbolName);
       
        if ( taskSpawn("tIdlcMain", 150, VX_FP_TASK, 50000, (FUNCPTR)iAdrs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR )
        {
            printf("Error at Start IDLC Main\n");
            return;
        }
    }

 

※ 주의해야할 사항 : 위의 예제에서는 Entry-point의 경우 C 심볼형식을 가지고 있으며, 만약 Entry-point 함수가 C++로 작성되어 있다면 extern "C" 키워드로 C 심볼로 수정해야하는 상황이 발생할 수 있다.

 

  1. extern "C" {

    int vxmain(int argc, char* argv[]) {
        int status = 0;
        if(OXF::initialize())
            {
                CIDLC_DKM_Builder * p_CIDLC_DKM_Builder;
                p_CIDLC_DKM_Builder = new CIDLC_DKM_Builder;
                p_CIDLC_DKM_Builder->startBehavior();
                //#[ configuration IDLC_DKM::Workbench
                //#]
                OXF::start();
                delete p_CIDLC_DKM_Builder;
                status = 0;
            }
        else
            {
                status = 1;
            }
        return status;
    }

    }

 

IBM Rhapsody에서 해당 키워드를 넣는 방법은 이곳을 참고하기 바란다.

 

이 글은 스프링노트에서 작성되었습니다.