vxWorks로 개발한 이후에 Stand-alone 으로 시스템을 구동시키고자 할때 쓰이는 방법을 소개하고자 한다.
흔히 사용하는 방법으로는 vxWorks의 커널 프로젝트에서 usrAppInit.c 함수에 사용자의 Entry-point를 적으면 된다.
하지만, 이 방법을 사용하고자 하려면 사용자의 이미지가 vxWorks 커널에 포함되어야 하는 단점이 존재한다.
목표로하는 Stand-alone 시스템은 사용자이미지를 .out 의 형태로 유저 플래쉬에 저장하며 커널 로드시 해당 라이브러리를 동적으로 로딩하고, Entry-point의 심볼을 동적으로 찾아 수행하도록 하는데 있다.
볼드체로 된 부분이 추가된 부분이다. define 문으로 동작형태를 구분하고 있다.
- /* 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를 구동하는 함수이다.
- #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 심볼로 수정해야하는 상황이 발생할 수 있다.
- 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에서 해당 키워드를 넣는 방법은 이곳을 참고하기 바란다.
이 글은 스프링노트에서 작성되었습니다.