Gilles, here's the test code.  The rt stats are printed in the module exit
function....

//==========================================================================
==
//
//
//==========================================================================
==
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/spi/spidev.h>
#include <native/task.h>
#include <native/timer.h>
#include <native/misc.h>
#include <native/queue.h>
#include <native/intr.h>
#include <native/cond.h>
#include <native/mutex.h>
#include <asm/uaccess.h>

MODULE_LICENSE("Dual BSD/GPL");

#define IRQDRV_NAME "irqdrv"
#define TASK_PRIO       50 /* 99-Highest RT priority */
#define TASK_MODE   0 /* No flags */
#define TASK_STKSZ  0 /* Stack size (use default one) */
#define GPIO_PIN        132
#define GPIO132_IRQ 33
#define BASEIO_CONF1            0x48000000
#define BASEIO_CONF2            0x49050000
#define BASEIO_DATA             0x49050000
#define GPIO_OE                         0x6034
#define GPIO_CLEARDATA          0x6090
#define GPIO_SETDATA            0x6094
#define GPIO_DATAIN                     0x6038
#define GPIO_SETIRQENABLE1      0x6064
#define GPIO_FALLINGDETECT      0x604C
#define GPIO132_MASK            0x00000010
#define GPIO134_MASK            0x00000040

#define DEBUG_PRINTK

static struct class *irqdrv_class;
static int irqdrv_major = 0;
static int irqdrv_devID = 0;
static RT_TASK irqdrv_taskDesc1;
static RT_INTR irqdrv_isrDesc1;
static bool irqdrv_terminated = true;
static bool irqdrv_task_finished = false;
static bool irqdrv_hi = false;
static ulong* irqdrv_map;
static RT_COND irqdrv_cond;
static RT_MUTEX irqdrv_mutex;

int irqdrv_open(struct inode *inode, struct file *filp);
int irqdrv_release(struct inode *inode, struct file *filp);
ssize_t irqdrv_read(struct file *filp, char *buf, size_t count, loff_t
*f_pos);
ssize_t irqdrv_write(struct file *filp, const char *buf, size_t count,
loff_t *f_pos);

struct file_operations irqdrv_funcs = {
    read: irqdrv_read,
    write: irqdrv_write,
    open: irqdrv_open,
    release: irqdrv_release
};
//==========================================================================
==
int irqdrv_isr(struct xnintr *intr)
{
        int retval = RT_INTR_HANDLED;
        int err;

        //rt_mutex_acquire(&irqdrv_mutex,100000000);
        if ((err = rt_cond_signal(&irqdrv_cond)) != 0)
        printk("<1>irqdrv: rt_cond_signal error: %d\n", err);

        //rt_mutex_release(&irqdrv_mutex);
        return(retval);
}
//==========================================================================
==
void irqdrv_task(void *args)
{
        while (!irqdrv_terminated)
        {
                rt_task_sleep(100000000);
                printk("<1>irqdrv: test\n");
        }
        irqdrv_task_finished = true;
}
//==========================================================================
==
void init_gpio()
{
        irqdrv_map = ioremap(BASEIO_CONF1, SZ_16K);
        if (!irqdrv_map)
        {
                printk("<1>irqdrv: ioremap failed!\n");
                return;
        }
        irqdrv_map[0x215C/4] = 0x01040104; // set gpio 132/133 to input with
no pullups (xlator causes builtin pullups to not work!)
        irqdrv_map[0x2164/4] = 0x00040004; // set gpio 136/137 to output
(used to control lvl xlator direction)
        irqdrv_map[0x2160/4] = 0x00040004; // set gpio 134/135 to output
(used for PWM output)

        iounmap(irqdrv_map);

        irqdrv_map = ioremap(BASEIO_CONF2, SZ_16K);
        if (!irqdrv_map)
        {
                printk("<1>irqdrv: ioremap failed!\n");
                return;
        }

        irqdrv_map[GPIO_OE/4] = irqdrv_map[GPIO_OE/4] | 0x00000030; // set
as input
        irqdrv_map[GPIO_OE/4] = irqdrv_map[GPIO_OE/4] & 0xFFFFFC3F; //
134,135,136,137 set as output
        irqdrv_map[GPIO_FALLINGDETECT/4] = irqdrv_map[GPIO_FALLINGDETECT/4]
| 0x00000030; // enable falling edge detect for irq generation
        irqdrv_map[GPIO_SETIRQENABLE1/4] = 0x00000030; // enable interrupt
generation
        irqdrv_map[GPIO_CLEARDATA/4] = 0x00000200; // 137 set low so B->A
for 132,133 on xlator
        irqdrv_map[GPIO_SETDATA/4] = 0x00000100; // 136 set high so A->B for
134,135 on xlator

        iounmap(irqdrv_map);
}
//==========================================================================
==
static int irqdrv_init(void) {
        int err;

    // create the device
    if ((irqdrv_major = register_chrdev(irqdrv_major, IRQDRV_NAME,
&irqdrv_funcs)) < 0)
    {
        printk("<l>irqdrv: register_chrdev error: %i\n", irqdrv_major);
        return irqdrv_major;
    }
    irqdrv_class = class_create(THIS_MODULE, IRQDRV_NAME);
    device_create(irqdrv_class, NULL, MKDEV(irqdrv_major, irqdrv_devID),
NULL, IRQDRV_NAME "%d", irqdrv_devID);

    init_gpio();

    irqdrv_map = ioremap(BASEIO_DATA, SZ_16K);
        if (!irqdrv_map)
        {
                printk("<1>irqdrv: ioremap failed!\n");
                irqdrv_terminated = true;;
        }

        if ((err = rt_mutex_create(&irqdrv_mutex,"irqdrv_mutex")) != 0)
    {
        printk("<1>irqdrv: rt_cond_create error: %d\n", err);
        return err;
    }

        if ((err = rt_cond_create(&irqdrv_cond,"irqdrv_cond")) != 0)
    {
        printk("<1>irqdrv: rt_cond_create error: %d\n", err);
        return err;
    }

    int irq = gpio_to_irq(GPIO_PIN);
    if ((err = rt_intr_create(&irqdrv_isrDesc1, "irqdrv_isr", irq,
irqdrv_isr, NULL, 0)) != 0)
    {
        printk("<1>irqdrv: rt_intr_create error: %d\n", err);
        return err;
    }

    if ((err = rt_intr_enable(&irqdrv_isrDesc1)) != 0)
    {
        printk("<1>irqdrv: rt_intr_enable error: %d\n", err);
        return err;
    }

    // start the RT task
    if ((err =
rt_task_create(&irqdrv_taskDesc1,"irqdrvTask",TASK_STKSZ,TASK_PRIO,0)) == 0)
    {
        irqdrv_terminated = false;
        rt_task_start(&irqdrv_taskDesc1,&irqdrv_task,NULL);
    }
    else
    {
        printk("<1>irqdrv: rt_task_create error: %i\n", err);
        return err;
    }
    return 0;
}
//==========================================================================
==
int irqdrv_open(struct inode *inode, struct file *filp) {
#ifdef DEBUG_PRINTK
    printk("<1>irqdrv: open!\n");
#endif
    return 0;
}
//==========================================================================
==
ssize_t irqdrv_read(struct file *filp, char *buf, size_t count, loff_t
*f_pos) {
#ifdef DEBUG_PRINTK
        printk("<1>irqdrv: read!\n");
#endif
    return 0;
}
//==========================================================================
==
ssize_t irqdrv_write(struct file *filp, const char *buf, size_t count,
loff_t *f_pos) {
#ifdef DEBUG_PRINTK
        printk("<1>irqdrv: write!\n");
#endif
    return 0;
}
//==========================================================================
==
int irqdrv_release(struct inode *inode, struct file *filp) {
    return 0;
}
//==========================================================================
==
static void irqdrv_exit(void) {

    RT_TASK_INFO info;
    rt_task_inquire(&irqdrv_taskDesc1, &info);
    printk("<1>irqdrv: BASEPRIOR: %d  CURPRIOR: %d  EXECTIME: %ld  MODESW:
%d  CTXSW:
%d",info.bprio,info.cprio,info.exectime,info.modeswitches,info.ctxswitches);

    irqdrv_terminated = true;
    while (!irqdrv_task_finished) rt_task_sleep(500000);

    rt_intr_delete(&irqdrv_isrDesc1);
    rt_task_delete(&irqdrv_taskDesc1);
    rt_cond_delete(&irqdrv_cond);
    rt_mutex_delete(&irqdrv_mutex);
        iounmap(irqdrv_map);

    device_destroy(irqdrv_class, MKDEV(irqdrv_major, irqdrv_devID));
    class_destroy(irqdrv_class);
    unregister_chrdev(irqdrv_major, IRQDRV_NAME);
}
//==========================================================================
==
module_init(irqdrv_init);
module_exit(irqdrv_exit);





 

-----Original Message-----
From: Gilles Chanteperdrix [mailto:[email protected]] 
Sent: Friday, December 30, 2011 4:23 AM
To: Terry Fryar
Cc: [email protected]
Subject: Re: [Xenomai-help] Mode switches??

On 12/30/2011 01:01 AM, Gilles Chanteperdrix wrote:
> On 12/29/2011 10:43 PM, Terry Fryar wrote:
>> Using 2.6.0, I am have trouble understanding the results of the
>> rt_task_info() call?
>>  
>> Have a very simple kernel module that fires off an ISR routine and a 
>> xenomai task.  The IRQ is not firing for these tests, so it's not doing
anything.
>> Here's the xenomai rt task created using rt_create_task():
>>  
>> void irqdrv_task(void *args)
>> {
>>     while (!irqdrv_terminated)
>>      {
>>           rt_task_sleep(10000000);
>>      }
>> }
>>  
>> So, in the driver "exit" code, right before I delete this task I do a
>> rt_task_info() and I see no context switches and very little exec 
>> time for this task.  However, it's showing 1,000,000 mode switches in 
>> just 5 or 10 seconds of exec time??
>>  
>> The info.modeswitches is the number of times the task switches 
>> between primary and secondary mode, yes??  Why in the world are there 
>> so many for a small task doing nothing but call a xenomai function, 
>> and in a kernel driver to boot!!
>>  
>> Am I missing something here....shouldn't mode switches be zero???  
>> I'm not calling any linux kernel functions...it shouldn't have switched
ever??
> 
> mode switches do not exist for kernel-space tasks. So, reading the 
> modeswitch member of the task info structure for a kernel space task 
> does not really make sense. Which is why probably nobody else noticed 
> (that, and the fact that the native API in kernel-space is not very 
> much in use, these days).
> 
the mode switches count should still be zero. Could you show us the full
test code?

-- 
                                                                Gilles.


_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to