Question

Interrupts are handled in the kernel mode but to handle interrupt in rt linux they are saying that :

I need to write code using RTLinux in kernel space and with kernel modules. With QNX, you can't write kernel modules (the kernel is not open) and you have real-time in user-space.

my question : How to write a code in kernel space ?? what is exactly mean by that ?? where should i modify the kernel ??

someone Please suggest some ideas.

udp code :

 int CreateSocket()
 {
     socklen_t len;

   // 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("Oh dear, something went wrong with bind()! %s\n", strerror(errno));

   return 1;

 }

 else

 {

   printf("Socket an port %d \n",port);
 }


   while(rc!=-1)
   {
     len = sizeof(client);
     rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len);

     //I am calculating the time here
     InterruptTime = GetTimeStamp();
     measurements[17] = InterruptTime;

     if(rc==0)
     {
       printf("Server has no connection..\n");
       break;
     }
     if(rc==-1)
     {
         printf("Oh dear, something went wrong with read()! %s\n", strerror(errno));
       break;
     }

     XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );


   }

   close(acceptSocket);
   return 1;
   }

int main()
{
CreateSocket();

while(1)
{
     TASK1(Task2ms_Raster);
     TASK2(Task10ms_Raster);
     TASK3(Task100ms_Raster);
}
Was it helpful?

Solution

Unlike QNX the Linux kernel is open source software. Which means that you can modify and change it in whatever ways you desire. You grab the sources from http://kernel.org (preferrably you use Git to clone into a local repository), make your modifications, additions, etc. compile the think and boot your computer with it.

Note that Linux since version 2.6 also offers realtime scheduling, which might be sufficient.

Update code example

For the time raster task execution I suggest the following:

#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE   500

#include <sched.h>  /* for sched_setsched */
#include <unistd.h> /* for usleep */
#include <time.h>   /* for clock_gettime */
#include <string.h> /* for memset */

#define MS_to_US(x) ((x)*1000)

useconds_t delta_t_us(struct timespec const *a, struct timespec const *b)
{
    time_t const delta_sec  = b->tv_sec  - a->tv_sec;
    long   const delta_nsec = b->tv_nsec - a->tv_nsec;

    /* this might actually overflow for "long" time intervalls"
     * should be safe for a delta_t < 2ms though */
    return delta_sec * 1000000 + delta_nsec / 1000;
}

void rastertask()
{
    struct sched_param sparm;
    memset(&sparm, 0, sizeof(sparm));
    sparm.sched_priority = 10; /* 0 = lowest, 99 = highest */

    sched_setscheduler(
        0 /* pid, 0 ==> this process */,
        SCHED_RR /* policy */,
        &sparm);

    unsigned int n_loop;
    for(n_loop=0;;n_loop++) {
        struct timespec ts_start, ts_end;
        clock_gettime(CLOCK_MONOTONIC, &ts_start);

        TASK1(); /* gets called every 2ms */
        if( (n_loop % 5) == 0) {
            TASK2(); /* get called every 5 * 2ms = 10ms */
        }
        if( (n_loop % 50) == 0) {
            TASK2(); /* get called every 50 * 2ms = 100ms */
        }

        if( (n_loop % 250) == 0 ) {
            /* reset loop counter when smallest common
             * multiple of timing grid has been reached */
            n_loop = 0;
        }

        clock_gettime(CLOCK_MONOTONIC, &ts_end);
        useconds_t const tasks_execution_time = delta_t_us(&ts_start, &ts_end);

        if( tasks_execution_time >= MS_to_US(2) ) {
            /* report an error that tasks took longer than 2ms to execute */
        }

        /* wait for 2ms - task_execution_time so that tasks get called in
         * a close 2ms timing grid */
        usleep( MS_to_US(2) - tasks_execution_time );
    }
}

Please note that the process requires either CAP_SYS_NICE privileges (prior to Linux 2.6.12) or sufficient RLIMIT_RTPRIO resource limits to be able to set its priority.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top