如何编写rt-linux的内核模式?

时间:2014-03-26 15:20:35

标签: c linux linux-kernel kernel real-time

中断在内核模式下处理,但是为了处理rt linux中的中断,他们说:

我需要在内核空间和内核模块中使用RTLinux编写代码。使用QNX,您无法编写内核模块(内核未打开),您可以在用户空间中实时使用。

我的问题: 如何在内核空间中编写代码? 究竟是什么意思? 我应该在哪里修改内核??

有人请提出一些想法。

udp代码:

 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);
}

1 个答案:

答案 0 :(得分:3)

与QNX不同,Linux内核是开源软件。这意味着您可以以任何您想要的方式修改和更改它。您从http://kernel.org获取源代码(最好使用Git克隆到本地存储库中),进行修改,添加等等。编译思考并使用它启动计算机。

请注意,从版本2.6开始的Linux也提供实时调度,这可能就足够了。

更新代码示例

对于光栅任务执行的时间,我建议如下:

#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 );
    }
}

请注意,该过程需要CAP_SYS_NICE权限(在Linux 2.6.12之前)或足够的RLIMIT_RTPRIO资源限制才能设置其优先级。