C语言中的多个源文件

C语言中的多个源文件,c,C,我目前正在开发一个实现多个C源文件的程序。这是我做的第一个项目,有很多问题。很抱歉最近的问题,但我真的很感谢你的帮助 我有一个带有main函数的主源文件。在这个主函数中,我有一个调用“高级”函数的操作循环,这些函数本质上是子例程。例如,我有一个名为ReadInputs()的函数,它位于“ReadInputs.c”中。我严格出于组织目的将其分解 我有几个问题: 我听说将头文件与每个源文件相关联是一种很好的做法。因此,我可以有一个名为“ReadInputs.h”的文件,其中包含在“ReadInput

我目前正在开发一个实现多个C源文件的程序。这是我做的第一个项目,有很多问题。很抱歉最近的问题,但我真的很感谢你的帮助

我有一个带有main函数的主源文件。在这个主函数中,我有一个调用“高级”函数的操作循环,这些函数本质上是子例程。例如,我有一个名为ReadInputs()的函数,它位于“ReadInputs.c”中。我严格出于组织目的将其分解

我有几个问题:

我听说将头文件与每个源文件相关联是一种很好的做法。因此,我可以有一个名为“ReadInputs.h”的文件,其中包含在“ReadInputs.c”中找到的ReadInputs()函数的原型。我的第一个问题是,有必要有这样一个简单的小头文件吗?到目前为止,“ReadInputs.h”只包含一个原型。是否可以将此原型包含在整个头文件中?在我的例子中,我有一个标题为“Definitions.h”的总头文件,其中包括原型ReadInputs

问题2:因为我想在每个源文件之间共享变量,所以我使用以下方法:

我在'main.c'中声明了一个名为Var的变量。在'Definitions.h'头文件中,我声明了一个extern Var。在每个其他源文件中,我包含Definitions.h。我相信这将允许全球共享变量。这是正确的假设吗


对不起,这是文字墙。感谢您的帮助

对于第一个问题,是的,这种情况经常发生

例如,考虑一组实现平衡树的文件,用不同的C源文件进行插入、删除查找等。这通常用于更好的构建过程,例如,如果您只更改了

insert
文件,则只需重新编译该文件

但是,您希望代码的用户只需要包含一个
btree.h
,因此您只需将所有函数原型(以及其他内容)都包含在其中

因此,你最终会得到如下结果:

btree.h            - public stuff
btree_priv.h       - private stuff
btreeInsert.c      - individual functions
btreeDelete.c
btreeFind.c
btreeRebalance.c
btreeIterate.c
btree_priv.h
文件在用户头
btree.h
的上方和之外保存了足够的信息,以允许各自源文件中的各个函数了解彼此和“隐藏”数据结构

然后,您通常会将所有已编译的“单个函数”对象文件打包到一个库中,然后分发库和公共头文件

第二个问题也是,但有一点需要注意。
extern
将显式声明变量,以便其他翻译单元(源文件)知道它。但这是(例如)在文件级别将其声明为非静态的行为,这将使它在链接时对您链接的所有文件可见

  • 原型、结构等应在头文件中。这是一种良好的做法,行业遵循这一规则。随着代码库的增加,您将添加不同的函数,您的头文件也将增加,所以您不必担心这一点

  • 是的,你是对的

  • 一次一个,由顶级makefile调用 这就是使用“@”行的地方。
    --文件:Main\u Scheduler.c
    /**
    @文件Main_Scheduler.c
    @简介包含控制“已删除”的功能
    @作家理查德·威廉姆斯
    @日期2012年6月27日
    */
    /*应用于此文件的SIRT问题:
    SIRT问题-
    */
    /**********************包含的文件**********************************************************************************/
    #包括
    #包括
    #包括//用于system()和itoa()实用程序
    #包括//用于va_list()等
    #包括//字符串处理实用程序
    #include//信号量处理实用程序
    #包含//标志位的符号定义
    #include//包含系统调用中使用的数据类型的定义
    #包括//类型定义(即结构sockaddr\u in)
    #包括//权限位和open()的符号定义
    #包括//ipc接口实用程序
    #包含//共享内存实用程序
    #包括//INADR\U ANY等
    #包含//用于访问errno和相关函数
    #包括//定义真、假、布尔
    #包括//time()和相关函数的原型
    //包含通用数据类型定义
    #包括“./GOT4_类型.h”
    //包含打开和关闭的数据定义
    #包括“./CdsDefines.h”
    //包含进程间通信的原型
    #包括“./Common\u进程间通信.h”
    //包含UDP实用程序函数的原型
    #包括“./Common_UDP_Utilities.h”
    //包含配置操作的原型和枚举
    #包括“./CommonConfiguration.h”
    //包含用于写入CDS日志文件的原型
    #包括“./commonwritecdlog.h”
    //包含处理stderr文件的原型
    #包括“./CommonDateFunctions.h”
    //包含看门狗操作的原型和枚举
    #包括“Main_Scheduler_Watchdog.h”
    //包含命令操作的原型和枚举
    #包括“Main_Scheduler_Command.h”
    //包含此文件中全局可见函数和数据类型的原型
    #包括“Main_Scheduler.h”
    /********************文件静态函数*******************************************************/
    静态枚举enumReturnStatus主调度程序启动任务(INT32任务选择器);
    静态枚举enumReturnStatus主调度程序停止任务(INT32 taskSelector);
    静态枚举枚举返回状态主调度器任务初始化(无效);
    静态枚举enumReturnStatus主调度器配置初始化(BOOL bFirstTime);
    #定义dMAX\U IPC\U有效负载(256)
    #定义最大系统长度(256)
    /********************全局变量*************************************************************************************/
    /********************文件静态变量*************************************************/
    静态BOOL-ActiveTaskTable[eMaxTasks]={FALSE};
    //用于格式化要写入IPC的消息的有效负载
    //stati
    
    three files are included below
    first the top level makefile
    then the bottom level makefile
    then an example source file
    
    Note: the makefiles are using 'sed' for
          the creation of the dependency files
          however, the gcc compiler has 
          appropriate parameters that
          can make the operation much simplier
    
    in general, the way to use this is:
    -- in the top level directory
       make -f makefile -dDEBUG > make.out
       then examine the file make.out to search for any compile/link errors
    
    Note: I do not know why some lines are being displayed in large/bold font
    
    --- file: makefile.mak
    SHELL = /bin/sh
    
    
    #  note: this makefile.mak needs to be run from the ./src directory
    # of the GOT4 directory tree
    
    
    SRC := $(wildcard *.c)
    OBJ := $(SRC:.c=.o)
    DEP := $(SRC:.c=.d)
    INC := $(SRC:.c=.h)
    
    
    MAKE    :=  /usr/bin/make
    
    CC      :=  /usr/bin/gcc
    
    CP      :=  cp
    
    MV      :=  mv
    
    LDFLAGS :=  -L/usr/local/lib -L/usr/lib -L/lib
    
    DEBUG   :=  -ggdb3
    
    CCFLAGS :=  $(DEBUG) -Wall -W
    
    #CPPFLAGS += =MD
    
    LIBS    :=  -lssl -ldl -lrt -lz -lc -lm
    
    
    
    .PHONY: AllDirectories
    # the following statement needs to be edited as 
    # subdirectories are added/deleted/re-named
    #AllDirectories := \
    #    Command_Configuration \
    #    Communication \
    #    Main_Scheduler \
    #    Retrieve_CDS_Log \
    #    Retrieve_EventRecorder_Log \
    #    Retrieve_GPS \
    #    Retrieve_QES_Alarm_Log \
    #    Retrieve_QES_RealTime \
    #    Write_CDS_Log
    
    AllDirectories :=  \
        Main_Scheduler \
        Communication  \
        Retrieve_GPS   \
        Test_Communication_Dev 
    
    
    
    .PHONY: all
    #all: $(OBJ) $(AllDirectories)
    #   $(foreach d,$(AllDirectories), \
    #    ( cd $d && $(MAKE) -f makefile.mak name=Tsk_$d all ); )
    
    all: $(OBJ) $(AllDirectories)
        $(foreach d,$(AllDirectories), \
        ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all ); )
    
    
    
    #
    # create dependancy files
    #
    %.d: %.c
        # 
        # ========= START $< TO $@ =========
        $(CC) -M $(CPPFLAGS) $< > $@.$$$$;                      \
        sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;     \
        rm -f $@.$$$$
        # ========= END $< TO $@ =========
    
    
    
    #
    # compile the .c file into .o files using the compiler flags
    #
    %.o: %.c %.d 
        # 
        # ========= START $< TO $@ =========
        $(CC) $(CCFLAGS) -c $< -o $@ -I. 
        # ========= END $< TO $@ =========
        # 
    
    
    
    .PHONY: clean
    #clean: $(AllDirectories)
    #   # ========== start clean activities ==========
    #   rm -f *.o
    #   rm -f $(name).map
    #   rm -f $(name)
    #   rm -f *.d
    #   $(foreach d,$(AllDirectories), \
    #    ( cd $d && $(MAKE) -f makefile.mak clean ); )
    #   # ========== end clean activities ==========
    
    clean: $(AllDirectories)
        # ========== start clean activities ==========
        rm -f *.o
        rm -f $(name).map
        rm -f $(name)
        rm -f *.d
        rm -f ../bin/Tsk_*
        $(foreach d,$(AllDirectories), \
        ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean ); )
        # ========== end clean activities ==========
    
    
    
    .PHONY: install
    #install: $(AllDirectories)
    #   # ========== start install activities ==========
    #   $(foreach d,$(AllDirectories), \
    #    ( cd $d && $(MAKE) -f makefile.mak clean ); )
    #   # ========== end install activities ==========
    
    install: $(AllDirectories)
        # ========== start install activities ==========
        $(foreach d,$(AllDirectories), \
        ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install ); )
        # ========== end install activities ==========
    
    
    
    # include the contents of all the .d files
    # note: the .d files contain:
    # <filename>.o:<filename>.c plus all the dependancies for that file 
    # I.E. the #include'd header files
    # wrap with ifneg... so will not rebuild *.d files when goal is 'clean'
    #
    ifneq "$(MAKECMDGOALS)" "clean"
    -include $(DEP)
    endif
    
    then the makefile (located in the top level directory)
    that creates each of the sub directory executables
    
    -- file: makefile.bot
    SHELL = /bin/sh
    
    
    BINDIR  :=  /home/user/bin
    
    
    .PHONY: all
    all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot
    
    
    #
    # macro of all *.c files 
    # (NOTE:
    # (the following 'wildcard' will pick up ALL .c files
    # (like FileHeader.c and FunctionHeader.c 
    # (which should not be part of the build
    # (so be sure no unwanted .c files in directory
    # (or change the extension
    #
    SRC := $(wildcard *.c)
    OBJ := $(SRC:.c=.o)
    DEP := $(SRC:.c=.d)
    INC := $(SRC:.c=.h)
    
    
    COMMON_OBJ := $(wildcard ../*.o)
    #COMMON_SRC := $(wildcard ../*.c)
    #COMMON_OBJ := $(COMMON_SRC:.c=.o)
    #COMMON_DEP := $(COMMON_SRC:.c=.d)
    #COMMON_INC := $(COMMON_SRC:.c=.h)
    
    MAKE    :=  /usr/bin/make
    
    CC      :=  /usr/bin/gcc
    
    CP      :=  cp
    
    MV      := mv
    
    LDFLAGS :=  -L/usr/local/lib
    
    DEBUG   :=  -ggdb3
    
    CCFLAGS :=  $(DEBUG) -Wall -W
    
    #CPPFLAGS += =MD
    
    #LIBS    :=  -lidn -lssl -ldl -lrt -lz -lc -lm
    LIBS    :=   -lssl -ldl -lrt -lz -lc -lm
    
    
    
    #
    # link the .o files into the executable 
    # using the linker flags
    # -- explicit rule
    #
    $(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot
        #
        # ======= $(name) Link Start =========
        $(CC) $(LDFLAGS) -o $@ $(OBJ) $(COMMON_OBJ) $(LIBS)
        # ======= $(name) Link Done ==========
        #
    
    
    
    # note:
    # using MV rather than CP results in all executables being re-made everytime
    $(BINDIR)/$(name): $(name)
        #
        # ======= $(name) Copy Start =========
        sudo $(CP) $(name) $(BINDIR)/.
        # ======= $(name) Copy Done ==========
        #
    
    
    
    #
    #create dependancy files -- inference rule
    # list makefile.mak as dependancy so changing makfile forces rebuild
    #
    %.d: %.c 
        # 
        # ========= START $< TO $@ =========
        $(CC) -M $(CPPFLAGS) $< > $@.$$$$;                      \
        sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;     \
        rm -f $@.$$$$
        # ========= END $< TO $@ =========
    
    
    
    # 
    # compile the .c file into .o files using the compiler flags
    # -- inference rule
    #
    %.o: %.c %.d 
        # 
        # ========= START $< TO $@ =========
        $(CC) $(CCFLAGS) -c $< -o $@ -I. 
        # ========= END $< TO $@ =========
        # 
    
    
    
    .PHONY: clean
    clean: 
        # ========== CLEANING UP ==========
        rm -f *.o
        rm -f $(name).map
        rm -f $(name)
        rm -f *.d
        # ========== DONE ==========
    
    
    
    .PHONY: install
    install: all
    
    # include the contents of all the .d files
    # note: the .d files contain:
    # <filename>.o:<filename>.c plus all the dependancies for that .c file 
    # I.E. the #include'd header files
    # wrap with ifneg... so will not rebuild *.d files when goal is 'clean'
    #
    ifneq "$(MAKECMDGOALS)" "clean"
    -include $(DEP)
    endif
    
    and finally, a typical file, showing the many local and system headers used
    note: although the usage was trivial in this file, 
          the doxygen documentation utility
          was used in the process of automatic document creation
    
    -- file: Main_Scheduler.c
    /**
        @file   Main_Scheduler.c
        @brief  contains functions to control 'deleted'
        @author Richard Williams
        @date   June 27, 2012
    */
    
    
    /*  SIRT issues applied to this file:
        SIRT issue ### -
    
    */
    
    
    /* *************** Included files ************************************* */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>    // for system() and itoa() utilities
    #include <stdarg.h>    // for va_list(), etc
    #include <string.h>    // string handling utilities
    #include <semaphore.h> // semaphores handling utilities
    
    #include <fcntl.h>     // symbolic definitions for flags bits
    #include <sys/types.h> // contains definitions of data types used in system calls
    #include <sys/socket.h>// type definitions (I.E. struct sockaddr_in)
    #include <sys/stat.h>  // symbolic definitions for permission bits and open()
    #include <sys/ipc.h>   // ipc interface utilities
    
    #include <sys/shm.h>   // shared memory utilities
    #include <arpa/inet.h> // defines INADDR_ANY, etc
    
    #include <errno.h>     // for accessing errno and related functions
    #include <stdbool.h>   // define true, false, bool
    #include <time.h>      // prototypes for time() and related functions
    
    
        // contains common data type definitions
    #include "../GOT4_Types.h"
    
        // contains data definitions for ON and OFF
    #include "../CdsDefines.h"
    
        // contains prototypes for Interprocess Communication
    #include "../Common_Interprocess_Communication.h"
    
        // contains prototypes for UDP utility functions
    #include "../Common_UDP_Utilities.h"
    
        // contains prototypes and enums for configuration operations
    #include "../CommonConfiguration.h"
    
        // contains prototypes for writing to CDS Log file
    #include "../CommonWriteCdsLog.h"
    
        // contains prototypes for handling stderr files
    #include "../CommonDateFunctions.h"
    
        // contains prototypes and enums for watchdog operations
    #include "Main_Scheduler_Watchdog.h"
    
        // contains prototypes and enums for command operations
    #include "Main_Scheduler_Command.h"
    
        //contains prototypes for globally visible functions and data types in this file
    #include "Main_Scheduler.h"
    
    
    
    /* *************** File static functions ****************************** */
    static enum enumReturnStatus Main_Scheduler_StartTask( INT32 taskSelector );
    static enum enumReturnStatus Main_Scheduler_StopTask ( INT32 taskSelector );
    
    static enum enumReturnStatus Main_Scheduler_Task__Initialize( void );
    static enum enumReturnStatus Main_Scheduler_Config__Initialize( BOOL bFirstTime );
    
    
    
    #define dMAX_IPC_PAYLOAD ( 256 )
    #define dMAX_SYSTEM_BUF_LENGTH ( 256 )
    
    /* *************** Global Variables *********************************** */
    
    
    
    /* *************** File Static Variables ****************************** */
    static BOOL   ActiveTaskTable[ eMaxTasks ] = { FALSE };
    
    
    // used to format the payload of messages to write to IPC
    //static char   inITC_payload[ dMAX_IPC_PAYLOAD ];
    static char   outITC_payload[ dMAX_IPC_PAYLOAD ];
    
    // used for executing commands in shell
    static char   systemCommand[dMAX_SYSTEM_BUF_LENGTH] = {0x00};
    
    
    // used to enable kicking the hardware watchdog
    static BOOL   flgWatchdogKick = TRUE;
    
    
    
    /* *************** Code *********************************************** */
    
    
    
    /**
      @fn INT32 main(INT32 argc, char *argv[])
      @brief -
      @param [in] argc -
      @param [in] argv -
      @return INT32 -
    
      :
    
     */
    INT32 main( INT32 argc __attribute__ ((unused)), char* argv[] )
    {
        enum enumReturnStatus returnStatus;
    
        INT32  taskSelector; // loop counter
        INT32  CommandValue; // command to send to sub task
    
        struct structWriteIPC WriteIPC;
    
        struct timespec       timeout;  // timeout for interprocess communication call
        unsigned              priority; // message priority for sending messages, 5 is low, 10 is high
    
        char  *pBaseName =    gnu_basename( argv[ 0 ]); // get name of this file
    
        remove_all_IPC();  // Only done from Main Scheduler, clears out all external (OS) interprocess buffers
    
        Initialize_IPC();
        itc_payload_size_init();
    
        set_TaskSelector( eTask_Main_Scheduler );
    
        set_pTask_NameString( eTask_Main_Scheduler, pBaseName );
    
        // select initial file to receive stderr messages
        CommonDateFunctions_stderr( pBaseName );
    
        // initialize the logging subsystem, indicating not owner of resource
        CommonWriteCdsLog__Initialize();
    
        if( atexit( release_CommonConfiguration ) )
        { // then setting exit function failed
    
            CommonWriteCdsLog( eLL_Critical,
                get_pFormatString( eFormat_CFFL_string_string ),
                __FILE__, __LINE__,
                "LibFunc:atexit()",
                strerror(errno) );
    
            system( "sync; sync;" );
            exit( EXIT_FAILURE);
        }
    
    
        /*
         * ***************************************************************
         * implied else (atexit() successful)
         *****************************************************************
         */
    
    
        // read .config file and initialize database
        Main_Scheduler_Config__Initialize( TRUE ); // true=first time
    
        returnStatus = Main_Scheduler_Task__Initialize();
    
    
        // pass tracking message to CDS log file
        CommonWriteCdsLog( eLL_Info,
            get_pFormatString( eFormat_IFFL_string ),
            __FILE__, __LINE__,
            "Entering main execution loop" );
    
    
        /*
        *********************************************************************
        * main operating loop starts here
        * *******************************************************************
        */
    
    
        flgWatchdogKick = true;
        while( flgWatchdogKick )
        {
            // step to next stderr file at midnight, otherwise do nothing
            CommonDateFunctions_stderr( pBaseName );
    
            // 11 kick the CPU watchdog
            Main_Scheduler_wd_kick();
    
    
    
            // 12) kick the external watchdog
            //todo:
    
            for( taskSelector=1; // step by main_scheduler task=(0)
                 taskSelector<eMaxTasks ;
                 taskSelector++ )
            {
    
                if( !ActiveTaskTable[  taskSelector ] )
                { // then selected task not configured to run
    
                    continue; // step to next itteration of inner loop
                }
    
    
                /*
                 *********************************************************************
                 * implied else, task-of-interest ready to run
                 * *******************************************************************
                 */
    
    
                // throttle execution rate of sub tasks
                step_Interval_counter( taskSelector );
    
                if( is_Interval_expired( taskSelector) )
                { // then, kick related task
    
                    reset_Interval_counter( taskSelector );
    
                    // note: get_Task_command() handles all errors
                    CommandValue = get_Task_command( taskSelector );
    
    
                    if( eTask_Retrieve_GPS == taskSelector )
                    {
    
                        CommandValue = eTaskCommand_GetGPSreport; // periodic event
                    }
    
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> ATTEMPTING TO KICK cmd#:%d TASK# %d\n", __FILE__, CommandValue, taskSelector );
    fflush( stdout );
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> task:%d, command;%d\n\n", __FILE__, taskSelector, CommandValue );
    fflush( stdout );
    
                    memset( outITC_payload, 0x00, sizeof(outITC_payload) );
                    ((struct structITC_Command*)outITC_payload)->ITC_Receiver = taskSelector;
                    ((struct structITC_Command*)outITC_payload)->ITC_Command  = CommandValue;
    
                    WriteIPC.TaskSelector    = taskSelector;
                    WriteIPC.ITC_MsgType     = eITC_MsgType_Command;
                    WriteIPC.ITC_PayLoadSize = 2*sizeof(INT32);
                    WriteIPC.pITC_Payload    = outITC_payload;
    
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> calling write_ITC_Record_To_IPC() with taskSelector:%d\n\n", __FILE__, taskSelector );
    fflush( stdout );
    
    
                    clock_gettime(CLOCK_REALTIME, &timeout);   // gets current time
                    timeout.tv_sec +=  1;                      // adds one second to current time for timeout
                    priority        = 10;
                    returnStatus    = write_ITC_Record_To_IPC( &WriteIPC, &timeout, priority );
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> returned from write_ITC_Record_To_IPC()\n\n", __FILE__ );
    fflush(  stdout );
    
                    if( eRS_Success == returnStatus )
                    { // then. write successful
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> SUCCESFULLY SENT MSG TO TASK#%d\n", __FILE__, taskSelector );
    fflush(  stdout );
    
                        // overwrite command so not executed again.
                        set_Task_command( taskSelector, eTaskCommand_DoNothing );
                    }
    else
    {
    fprintf( stdout,"DEBUG:File:%s\n\t--> FAILED TO SEND MSG TO TASK#%d   error is:%d\n", __FILE__, taskSelector, returnStatus );
    fflush(  stdout );
    }
                } // endif( is interval expired )
            } // end for( each task )
    
            // wait a second before going through the above again
            sleep(1);
    
    
            // 16) get any new commands
            // rkw: comment until ready to receive commands from CommandConfiguration task
            // Main_Scheduler_Command();
        } // end while( flgWatchdogKick )
    
    
        CommonWriteCdsLog( eLL_Info,
            get_pFormatString( eFormat_IFFL_Exiting_Status ),
            __func__, __FILE__, EXIT_SUCCESS );
    
        return( EXIT_SUCCESS );
    } // end main()
    
    
    
    static enum enumReturnStatus Main_Scheduler_StartTask( INT32 taskSelector )
    {
        char *pTask_NameString;
        int   systemReturn;
    
    
        if( is_taskSelector_Valid( taskSelector) )
        {
    
            // note: task_nameString is setup during call to Main_Scheduler_Config__Initialize()
            pTask_NameString = get_pTask_NameString( taskSelector );
    
            if( NULL != pTask_NameString )
            { // then get_pTask_NameString successful
    
                memset( systemCommand, 0x00, sizeof(systemCommand) );
    
                // set the command string
                // set to run in background so will get execution back
                sprintf( systemCommand, "%sTsk_%s &", dEXECUTION_DIR, pTask_NameString );
    
                // pass tracking message to CDS log file
                CommonWriteCdsLog( eLL_Critical, // Critical to assure will be written to log file
                    get_pFormatString( eFormat_CFFL_string ),
                    __FILE__, __LINE__,
                    systemCommand );
    
    fprintf( stdout,"DEBUG:File:%s\n\t--> starting subsytem: %s\n", __FILE__, systemCommand );
    fflush( stdout );
    
                // run the command ( which starts the task )
                systemReturn = system( systemCommand );
    
                if (( 0 != systemReturn ) )
                {
                    CommonWriteCdsLog( eLL_Critical,
                        get_pFormatString( eFormat_CFFL_digit_string ),
                        __FILE__, __LINE__, systemReturn,
                        "system() call failed." );
    
                    system( "killall Tsk*" );
                    system("sync;sync;");
                    exit( EXIT_FAILURE );
                }
    
                return( eRS_Success ); // indicate operation successful
            }
    
            //else
            //{ // else, get_pTask_NameString() failed
              // which means the task is not configured in the .config file
    
            //    CommonWriteCdsLog( eLL_Error,
            //        get_pFormatString( eFormat_EFFL_digit_string ),
            //        __FILE__, __LINE__,
            //        taskSelector,
            //        "=taskSelector: Function:get_pTask_NameString() failed" );
            //} // endif( got task name string )
        }
    
        else
        { // else, bad parameter
    
            CommonWriteCdsLog( eLL_Error,
                get_pFormatString( eFormat_EFFL_digit_string ),
                __FILE__, __LINE__,
                taskSelector,
                "=taskSelector: Parameter out of range" );
        }
    
        return( eRS_Failure ); // indicate error occurred
    } // end Main_Scheduler_StartTask()
    
    
    
    static enum enumReturnStatus Main_Scheduler_StopTask ( INT32 taskSelector )
    {
        char systemCommand[ 256 ];
        char *pTask_NameString;
    
    
    
        if( is_taskSelector_Valid( taskSelector ) )
        {
            memset( systemCommand, 0x00, sizeof(systemCommand) );
            pTask_NameString = get_pTask_NameString( taskSelector );
    
            if( NULL != pTask_NameString )
            { // then, get_pTask_NameString successful
    
                sprintf( systemCommand, "killall %sTsk_%s", dEXECUTION_DIR, pTask_NameString );
    
                // pass tracking message to CDS log file
                CommonWriteCdsLog( eLL_Critical,
                    get_pFormatString( eFormat_CFFL_string ),
                    __FILE__, __LINE__,
                    systemCommand );
    
                // run the command, which kills the task
                system( systemCommand );
    
                return( eRS_Success ); // indicate success
            }
        }
    
        else
        { // else, bad parameter
    
            CommonWriteCdsLog( eLL_Error,
                get_pFormatString( eFormat_EFFL_digit_string ),
                __FILE__, __LINE__,
                taskSelector,
                "=taskSelector: Parameter out of range" );
        }
    
    
        return( eRS_Failure ); // indicate problem occurred
    } // end Main_Scheduler_StopTask()
    
    
    
    static enum enumReturnStatus Main_Scheduler_Config__Initialize( BOOL bFirstTime )
    {
        enum enumReturnStatus returnStatus = eRS_Success;
    
    
        // Note: check for first time avoids trying to 'free() un-initialized char pointers
        if( !bFirstTime )
        {
            release_CommonConfiguration();
        }
    
        clear_CommonConfiguration();
    
        acquire_CommonConfiguration( eDivision_Main_Scheduler );
    
        return( returnStatus );
    } // end Main_Scheduler_Config__Initialize()
    
    
    
    static enum enumReturnStatus Main_Scheduler_Task__Initialize( void )
    {
        enum enumReturnStatus returnStatus = eRS_Success;
    
        INT32 taskSelector;
    
    
    
        // 2) reset the IOC card
        memset( systemCommand, 0x00, sizeof(systemCommand) );
        strcat( systemCommand, "/usr/bin/diag_client -s 172.20.100.17:23 'reset'" );
        //rkw for testing system( systemCommand );
    
    
    
        // 3) reset the DIO card
        memset( systemCommand, 0x00, sizeof(systemCommand) );
        strcat( systemCommand, "/usr/bin/diag_client -s 172.20.100.18:23 'reset'" );
        //rkw for testing system( systemCommand );
    
    
    
        /*
        *********************************************************************
        * start task execution
        * *******************************************************************
        */
    
    
        // pass tracking message to CDS log file
        CommonWriteCdsLog( eLL_Info,
            get_pFormatString( eFormat_IFFL_string ),
            __FILE__, __LINE__,
            "kill any running Task" );
    
        for( taskSelector=1; // task 0 is Main_Scheduler (I.E. this task)
             eMaxTasks > taskSelector;
             taskSelector++ )
        {
            Main_Scheduler_StopTask( taskSelector );
        }
    
    
        // pass tracking message to CDS log file
        CommonWriteCdsLog( eLL_Info,
            get_pFormatString( eFormat_IFFL_string ),
            __FILE__, __LINE__,
            "Entered: Start Task Execution Loop" );
    
        for( taskSelector=1; // task 0 is Main_Scheduler (I.E. this task)
             eMaxTasks > taskSelector;
             taskSelector++ )
        {
    
            returnStatus = Main_Scheduler_StartTask( taskSelector );
    
            if( eRS_Success == returnStatus )
            {
                ActiveTaskTable[ taskSelector ] = TRUE;
            }
    
            else
            { // else, task not configured
    
                ActiveTaskTable[ taskSelector ] = FALSE;
            }
        } // end for( each possible task )
    
    
    
    
        /*
        *********************************************************************
        * initialization loop
        * *******************************************************************
        */
    
    
        // 8) set task initializer command for each task
    
        for( taskSelector=1; // step by Main_Scheduler task=0
             taskSelector>=eMaxTasks;
             taskSelector++ );
        {
    
            set_Task_command( taskSelector, eTaskCommand_Initialize );
        } // end for( each task to initialize )
    
    
    
        /*
        *********************************************************************
        * initialze CPU card and external watchdog operations
        * *******************************************************************
        */
    
    
        // 9) initialize the CPU watchdog
        Main_Scheduler_wd_init();
        Main_Scheduler_wd_enable();
    
        // 9.1 set kickWatchdog flag to indicate watchdog is to be kicked
        flgWatchdogKick = TRUE;
    
    
        // 10) initialize throttle timers
        // pass tracking message to CDS log file
        CommonWriteCdsLog( eLL_Info,
            get_pFormatString( eFormat_IFFL_string ),
            __FILE__, __LINE__,
            "resetting all timers" );
    
        for( taskSelector=0;
             taskSelector<eMaxTasks ;
             taskSelector++ )
        {
    
            reset_Interval_counter( taskSelector );
        }
    
        return( returnStatus );
    } // end Main_Scheduler_Task__Initialize()
    
    
    
    /* ******************************************************************** **
    ** End of source file: Main_Scheduler.c
    ** ******************************************************************** */
    
    
    I know the above examples contain the information that you need
    for your project.  
    But it may be a bit difficult  to decyper without knowing 
    the makefile syntax and builtin calls