Hi Everyone,

As it is one of my pet subjects, I'd like to say that I think it is
great that there has been a port of the rt_mem_mgr to RTL (remember, you
don't have to use it if you don't want it, even in RTAI it is an option
in the Rules.make file).  I'd like to also see that this code becomes
common for RTL/RTAI (the difference hidden by macros or somthing
similar).

I have attached rt_compat.h that comes with RTAI, which is a very simple
set of macros, that shows how easy it is to find an equivlalent call for
RTL/RTAI.  The only thing that is a little complicated is the
task_create stuff.  Anyhow, the idea is not to say that this is *the*
solution, just to plant the idea that it may not be so difficult to find
a mechanism that will let us all benefit from optional modules that can
be easily used for both RTL and RTAI.  For my part I try to write/port
apps that can work with both (the latest R2D2 and kgdb+kmod do) and also
David Schleef does the same with rtnet and COMEDI.   I think that this
approach is helpful to users, without forcing the maintainers of RTL or
RTAI to do something that they don't agree with.

Regards, Stuart



Karim Yaghmour wrote:
> 
> This is very interesting indeed.
> 
> I won't claim to be an expert on the rt_mem_mgr stuff, I guess Pierre would
> have to take care of this one. Maybe the RTL guys could help you out too
> for the verification and provide ftp space for this. But I can't speak
> for anyone. Just hope the pointers help out.
> 
> If nothing else, this gives a brief outline of the changes necessary to
> port something between RTAI and RTL and vice-versa, which could be useful.
> 
> Best regards
> 
> Karim
> 
> Joel Vallier wrote:
> >
> > I've done the porting to RTL 3.0 of the RTAI Dynamic Memory Manager
> > (rt_mem_mgr) distributed with RTAI-1.5.
> >
> > It works for me, but I'd like that some RTL experts verify that all is Ok.
> >
> > Here is a list of main changes for the porting:
> > ---------------------------------------------------------------------------------
> > flags = rt_spin_lock_irqsave(&rt_mem_lock);                             // RTAI
> > rtl_spin_lock_irqsave(&rtl_dmm_lock, flags);                            // RTL3.0
> > ---------------------------------------------------------------------------------
> > rt_spin_unlock_irqrestore(flags, &rt_mem_lock);                         // RTAI
> > rtl_spin_unlock_irqrestore(&rtl_dmm_lock, flags);                       // RTL3.0
> > ---------------------------------------------------------------------------------
> > alloc_sysrq.srq = rt_request_srq(0, rt_alloc_sysrq_handler, 0)          // RTAI
> > alloc_sysrq.srq = rtl_get_soft_irq (rtl_alloc_sysrq_handler, "rtl_dmm") // RTL3.0
> > ---------------------------------------------------------------------------------
> > rt_pend_linux_srq(alloc_sysrq.srq);                                     // RTAI
> > rtl_global_pend_irq(alloc_sysrq.srq);                                   // RTL3.0
> > ---------------------------------------------------------------------------------
> > void rt_alloc_sysrq_handler(void)                                       // RTAI
> > void rtl_alloc_sysrq_handler(int irq, void *dev_id, struct pt_regs *p)  // RTL3.0
> > ---------------------------------------------------------------------------------
> > kmalloc(granularity, GFP_KERNEL)                                        // RTAI
> > kmalloc(granularity, GFP_ATOMIC)                                        // RTL3.0
> > ---------------------------------------------------------------------------------
> >
> > I can make source public if you give me a FTP server.
> >
> > Regards,
> >
> > Joel
> >
> > Karim Yaghmour wrote:
> > >
> > > You can dynamically allocate memory in real-time using the rt_mem_mgr
> > > stuff in RTAI.
> > >
> > > Cheers
> > >
> > > Karim
> > >
> > > [EMAIL PROTECTED] wrote:
> > > >
> > > > I remember seeing many discussions on the list about memory allocation,
> > > > but i am failing to find them now.
> > > >  I remember that you can only do memory allocation in initmodule. Is
> > > > this right?  I would like to allocate a few
> > > > kbytes either in a fifo handler or a real time thread.  Is this ok?
> > > > eric
////////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 2000 Zentropic Computing LLC
//
//  Authors:            Stuart Hughes
//  Contact:            [EMAIL PROTECTED]
//  Original date:      April 13th 2000
//  Ident:              @(#)$Id: rt_compat.h,v 1.8 2000/07/27 13:40:54 seh Exp $
//  Description:        RTL/RTAI common api header
//  License: You are free to copy this header file without restriction
//
////////////////////////////////////////////////////////////////////////////////

#ifndef RTL_RTAI_H

#ifndef FREQ 
#warning "FREQ not defined, defaulting FREQ to 1000 Hz"
#define FREQ            1000
#endif
#define BASE_PER        (NSECS_PER_SEC/FREQ)
#define NSECS_PER_SEC   1000000000

typedef void *(* VP_FP)();
typedef void  (* V_FP_V  )(void);
typedef void  (* V_FP_I  )(int);

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <asm/io.h>

#if CONFIG_RTL
#    include <rt/rtl.h>
#    include <rt/rtl_fifo.h>
#    include <rt/rtl_sched.h>
#    include <rt/posix/pthread.h>
#    define TASK_STR              pthread_t
#    define get_time_ns           gethrtime
#    define rt_task_wait_period   pthread_wait_np
#    define rt_task_suspend(x)    pthread_suspend_np(*x)
#    define rt_task_resume(x)     pthread_wakeup_np(*x)
#    define rt_get_time_ns        get_time_ns
#    define rtl_task_make_periodic(task_ptr, when_ns, period_ns)        \
        pthread_make_periodic_np(*task_ptr, when_ns, period_ns)
#    define rt_task_del(task_ptr)                                       \
        pthread_delete_np(*task_ptr)
#    define rt_timer_stop()
#    define rt_mount()
#    define rt_unmount()
#    define rt_set_oneshot_mode rtl_set_oneshot_mode
#    define rt_linux_use_fpu()
#else
#    include <rt/rtai.h>
#    include <rt/rtai_sched.h>
#    include <rt/rtai_fifos.h>
#    define TASK_STR              RT_TASK
#    define rtf_create(num, size) rtf_create_using_bh(num, size, 0)
#    define get_time_ns           rt_get_cpu_time_ns
#    define rtl_schedule()
#    define rtl_task_make_periodic(task_ptr, when_ns, period_ns)        \
        rt_task_make_periodic(task_ptr,                                 \
                                nano2count(when_ns),                    \
                                nano2count(period_ns))
#    define     rt_task_del(task_ptr)                                   \
        do {    rt_task_suspend(task_ptr);                              \
                rt_task_delete(task_ptr);       } while(0)
#    define     rt_timer_stop()                                         \
        do {    stop_rt_timer();                                        \
                rt_busy_sleep(10000000);             } while(0)
#    define rt_mount   rt_mount_rtai
#    define rt_unmount rt_umount_rtai
#endif

struct task_data {
    TASK_STR task;
    VP_FP func;
    int arg;
    int stack_size;
    int priority;
    int period;
    int uses_fpu;
    int one_shot;
    V_FP_V sig_han;
    long long period_ns;
    long long when_ns;
};

////////////////////////////////////////////////////////////////
// task creation wrapper
///////////////////////////////////////////////////////////////
static inline int rt_task_create( struct task_data *t)
{
#if CONFIG_RTL

    struct sched_param p;
    pthread_create(     &t->task,
                        NULL,
                        t->func,
                        (void *)t->arg
                );
    if(t->uses_fpu) {
        pthread_setfp_np(t->task, 1);
    }
    p.sched_priority = 100 - t->priority;
    pthread_setschedparam(t->task, SCHED_FIFO, &p);

    if(t->period == 0) {
        return 0;
    }

#else                                   // RTAI

    static int timer_started = 0;


    if( timer_started == 0) {
        // start timer, this defaults to periodic mode
        if (t->one_shot)
            rt_set_oneshot_mode();
        start_rt_timer(nano2count(BASE_PER));
        timer_started   = 1;
    }

    rt_task_init(       &t->task,
                        (V_FP_I)t->func,
                        t->arg,
                        t->stack_size,
                        t->priority,
                        t->uses_fpu,
                        t->sig_han
                );

    if(t->period == 0) {
        return 0;
    }
    if(t->uses_fpu) {
        rt_linux_use_fpu(1);
    }

#endif

    t->when_ns          = rt_get_time_ns() + 1 * NSECS_PER_SEC;
    t->period_ns        = (long long)t->period * BASE_PER;
    rtl_task_make_periodic( &t->task, t->when_ns, t->period_ns);

    return 0;
}



#endif

Reply via email to