2

The code below is for receiving a data from the master via the socket for udp layer. There are some API supported in my project and I created a timer task for calling the task for every 2ms, 10ms and so on.

I am debugging this program on the embedded PC target in eclipse IDE using remote C/C++ application. I am calling the maketimer (alarm) inside the CreateSocket function. But how to check the timer task calling the function TASK1, TASK2 and TASK3 for every 2ms, 10ms and 100ms in the background?

#include "MAIN.h"

#define BILLION  1000000L

timer_t firstTimerID, secondTimerID, thirdTimerID;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ;

int connectedSocket, acceptSocket;
struct sockaddr_in addr;
struct sockaddr client, dest;
char buf[128];
long rc, sentbytes;
int port = 18017;


void TASK1(Task2ms_Raster)
{

    struct timespec start, stop;
    uint32 StartTime, StopTime;

    if( (StartTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 ) 
    {
        perror("clock gettime");

    }

    // return EXIT_SUCCESS;

    /* Trigger DAQ for the 2ms XCP raster. */
    if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_2msRstr( ))
    {
        ++numDaqOverload2ms;
    }

    /* Update those variables which are modified every 2ms. */
    counter32 += slope32;

    /* Trigger STIM for the 2ms XCP raster. */
    if( enableBypass2ms )
    {
        if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_2msRstr( ) )
        {
            ++numMissingDto2ms;
        }
    }
    if( (StopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) 
    {
        perror( "clock gettime" );
    }

    duration2ms = ( stop.tv_sec - start.tv_sec )
        + (double)( stop.tv_nsec - start.tv_nsec )
        / (double)BILLION;
    printf( "time difference is= %ld\n", duration2ms );
}

void TASK2(Task10ms_Raster)
{
    struct timespec start, stop;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) 
    {
        perror( "clock gettime" );
    }

    /* Trigger DAQ for the 10ms XCP raster. */
    if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_10msRstr( ))
    {
        ++numDaqOverload10ms;
    }

    /* Update those variables which are modified every 10ms. */
    counter16 += slope16;

    /* Trigger STIM for the 10ms XCP raster. */
    if( enableBypass10ms )
    {
        if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_10msRstr( ) )
        {
            ++numMissingDto10ms;
        }
    }

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) 
    {
        perror( "clock gettime" );
    }
    XCP_FN_TYPE Xcp_CmdProcessor ( );

    duration10ms = ( stop.tv_sec - start.tv_sec )
        + (double)( stop.tv_nsec - start.tv_nsec )
        / (double)BILLION;
    printf( "time difference is= %ld\n", duration10ms );
}


void TASK3(Task100ms_Raster)
{
    struct timespec start, stop;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) 
    {
        perror( "clock gettime" );

    }

    /* Trigger DAQ for the 100ms XCP raster. */
    if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_100msRstr( ))
    {
        ++numDaqOverload100ms;
    }

    /* Update those variables which are modified every 100ms. */
    counter8 += slope8;


    /* Trigger STIM for the 100ms XCP raster. */
    if( enableBypass100ms )
    {
        if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_100msRstr( ) )
        {
            ++numMissingDto100ms;
        }
    }

    if((clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) 
    {
        perror( "clock gettime" );
    }

    duration100ms = ( stop.tv_sec - start.tv_sec )
        + (double)( stop.tv_nsec - start.tv_nsec )
        / (double)BILLION;
    printf( "time difference is= %ld\n", duration100ms );
}

static void timerHandler( int sig, siginfo_t *si, void *uc )
{
    timer_t *tidp;

    tidp = si->si_value.sival_ptr;

    if ( *tidp == firstTimerID )

        TASK1(Task2ms_Raster);
    else if ( *tidp == secondTimerID )
        TASK2(Task10ms_Raster);
    else if ( *tidp == thirdTimerID )
        TASK3(Task100ms_Raster);
}

static int makeTimer( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
    struct sigevent         te;
    struct itimerspec       its;
    struct sigaction        sa;
    int                     sigNo = SIGRTMIN;

    /* Set up signal handler. */
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = timerHandler;
    sigemptyset(&sa.sa_mask);
    if (sigaction(sigNo, &sa, NULL) == -1)
    {
        perror("sigaction");
    }

    /* Set and enable alarm */
    te.sigev_notify = SIGEV_SIGNAL;
    te.sigev_signo = sigNo;
    te.sigev_value.sival_ptr = timerID;
    timer_create(CLOCK_REALTIME, &te, timerID);

    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = intervalMS * 1000000;
    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = expireMS * 1000000;
    timer_settime(*timerID, 0, &its, NULL);

    return 1;
}

int CreateSocket()
{
    if(rc!=0)
    {
        printf("socket failure code: %ld\n",rc);

        return 1;
    }

    else

    {
        printf("socket started!\n");
    }

    // Socket creation for UDP

    acceptSocket=socket(AF_INET,SOCK_DGRAM,0);

    if(acceptSocket==-1)
    {
        printf("Failure: socket creation is failed, failure code\n");

        return 1;
    }
    else
    {
        printf("Socket started!\n");
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);

    rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr));

    if(rc== -1)
    {

        printf("Failure: listen, failure code:\n");

        return 1;
    }
    else
    {
        printf("Socket an port %d \n",port);
    }


    while(rc!=-1)
    {
        rc= recvfrom(acceptSocket,buf,128,0,(struct sockaddr*)&client, sizeof(client));
        if(rc==0)
        {
            printf("Server has no connection..\n");
            break;
        }
        if(rc==-1)
        {
            printf("failure: recv, failure code\n");
            break;
        }
        XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );

        makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
        makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
        makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms

        //    buf[rc]='\0';
        //    printf("Client sendet: %s\n",buf);
        //    sprintf(buf2,"Du mich auch %s",buf);
        //    rc=sendto(connectedSocket,buf2,strlen(buf2),0);
    }

    close(acceptSocket);

    return 0;
}

int main()
{
    Xcp_Initialize();
    CreateSocket();
    return 0;
}

void XcpApp_IpTransmit( uint16 XcpPort,  Xcp_StatePtr8 pBytes, uint16 numBytes )
{
    if ((long)XcpPort==port)
    {
        sentbytes = sendto(acceptSocket,(char*)pBytes,(long)numBytes,0, (struct sockaddr*) &dest, sizeof(dest));
    }
    XcpIp_TxCallback(port,(uint16)sentbytes);
}
Clifford
  • 88,407
  • 13
  • 85
  • 165
user3252048
  • 77
  • 1
  • 12

1 Answers1

1

Read time(7) and signal(7).

BTW, your BILLION is wrong. You probably should have

#define BILLION 1.0e9

(since you are using it only in floating point expressions)

You could have three threads (read a pthreads tutorial), one for TASK1, one for TASK2, one for TASK3 (perhaps using clock_nanosleep(2)...). Or (preferably) you could have a single event loop (around e.g. a poll(2) or ppoll(2) multiplexing call....), perhaps also using timerfd_create(2) to get timer events, and also managing the sockets. See this example of poll-based event loop. You should adapt it to also use a file descriptor obtained with timerfd_create.. You could also use some event looping library like libevent or libev

Notice that 2 milliseconds is a very small delay. (How reliable do you want that to be?)

Read Advanced Linux Programming

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547