mailarchive of the ptxdist mailing list
 help / color / mirror / Atom feed
* [ptxdist] Patch Kernet with preempt_rt patch
@ 2013-03-26 13:40 "Breixo López García"
  2013-03-26 13:52 ` Bernhard Walle
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: "Breixo López García" @ 2013-03-26 13:40 UTC (permalink / raw)
  To: ptxdist

[-- Attachment #1: Type: text/html, Size: 923 bytes --]

[-- Attachment #2: Type: text/plain, Size: 48 bytes --]

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ptxdist] Patch Kernet with preempt_rt patch
  2013-03-26 13:40 [ptxdist] Patch Kernet with preempt_rt patch "Breixo López García"
@ 2013-03-26 13:52 ` Bernhard Walle
  2013-03-26 14:02 ` "Breixo López García"
  2013-03-26 23:56 ` Robert Schwebel
  2 siblings, 0 replies; 7+ messages in thread
From: Bernhard Walle @ 2013-03-26 13:52 UTC (permalink / raw)
  To: ptxdist

Hi,

* "Breixo López García" <Breixo.Lopez@gmx.de> [2013-03-26 14:40]:
>     
>    I will patch the kernel for phyCPRE-AM335x with PREEMPT kernel 3.2, for
>    this I use ptxdist. the patch from the kernel comes from
>    [1]https://www.kernel.org/pub/linux/kernel/projects/rt/3.2/.
>     
>    I have been following
>    [2]http://www.mail-archive.com/ptxdist@pengutronix.de/msg03324.html and I
>    put the uncompresed packaged in the .../patches/linux-3.2. But then when I
>    compile the kernel the PREEMPT_RT option cannot be selected. What I am
>    overlooking in the process

What's the output of

 % ptxdist print PTXCONF_KERNEL_VERSION

Do you have a patches/linux-3.2/series file? What's the contents of that
series file?


Regards,
Bernhard

PS: Please disable HTML mails.

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ptxdist] Patch Kernet with preempt_rt patch
  2013-03-26 13:40 [ptxdist] Patch Kernet with preempt_rt patch "Breixo López García"
  2013-03-26 13:52 ` Bernhard Walle
@ 2013-03-26 14:02 ` "Breixo López García"
  2013-03-26 23:56 ` Robert Schwebel
  2 siblings, 0 replies; 7+ messages in thread
From: "Breixo López García" @ 2013-03-26 14:02 UTC (permalink / raw)
  To: ptxdist

[-- Attachment #1: Type: text/html, Size: 2100 bytes --]

[-- Attachment #2: Type: text/plain, Size: 48 bytes --]

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ptxdist] Patch Kernet with preempt_rt patch
  2013-03-26 13:40 [ptxdist] Patch Kernet with preempt_rt patch "Breixo López García"
  2013-03-26 13:52 ` Bernhard Walle
  2013-03-26 14:02 ` "Breixo López García"
@ 2013-03-26 23:56 ` Robert Schwebel
  2013-03-27  7:24   ` Tim Sander
  2 siblings, 1 reply; 7+ messages in thread
From: Robert Schwebel @ 2013-03-26 23:56 UTC (permalink / raw)
  To: ptxdist

On Tue, Mar 26, 2013 at 02:40:01PM +0100, "Breixo López García" wrote:
> I will patch the kernel for phyCPRE-AM335x with PREEMPT kernel 3.2, for this I
> use ptxdist. the patch from the kernel comes from https://www.kernel.org/pub/
> linux/kernel/projects/rt/3.2/.

Note that AM335x is in the meantime relatively well supported in 3.8,
and we have 3.8-rt since a few days. Our first tests this week show
pretty good realtime results so far.

Do you have a special reason why you want to use this prehistoric
kernel?

rsc
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ptxdist] Patch Kernet with preempt_rt patch
  2013-03-26 23:56 ` Robert Schwebel
@ 2013-03-27  7:24   ` Tim Sander
  2013-03-27  8:13     ` Robert Schwebel
  0 siblings, 1 reply; 7+ messages in thread
From: Tim Sander @ 2013-03-27  7:24 UTC (permalink / raw)
  To: ptxdist

Hi
Am Mittwoch, 27. März 2013, 00:56:16 schrieb Robert Schwebel:
> On Tue, Mar 26, 2013 at 02:40:01PM +0100, "Breixo López García" wrote:
> > I will patch the kernel for phyCPRE-AM335x with PREEMPT kernel 3.2, for
> > this I use ptxdist. the patch from the kernel comes from
> > https://www.kernel.org/pub/ linux/kernel/projects/rt/3.2/.
There is a complete repository for the beaglebone from me with some arago 
patches merged: https://gitorious.org/ptxdist-beaglebone/ptxdist-beaglebone
> Note that AM335x is in the meantime relatively well supported in 3.8,
> and we have 3.8-rt since a few days. Our first tests this week show
> pretty good realtime results so far.
I have tested with 3.2.32-rt51 and when floodpinging the latency in a kernel 
driver(! not even usermode) was in the range of milliseconds? Have you tested 
flood pinging with the newer kernel? 
> Do you have a special reason why you want to use this prehistoric
> kernel?
Well, the Ti Arago project is still on this kernel? But at least they are 
mainlining... Also i just tested a newer kernel on the beaglebone and it just 
switched itself off on booting? So would you mind sharing your kernelconfig, 
probably i was missing a driver for the power sequencer?

Best regards
Tim

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ptxdist] Patch Kernet with preempt_rt patch
  2013-03-27  7:24   ` Tim Sander
@ 2013-03-27  8:13     ` Robert Schwebel
  2013-03-28  8:31       ` [ptxdist] am335x latency Tim Sander
  0 siblings, 1 reply; 7+ messages in thread
From: Robert Schwebel @ 2013-03-27  8:13 UTC (permalink / raw)
  To: ptxdist

On Wed, Mar 27, 2013 at 08:24:21AM +0100, Tim Sander wrote:
> I have tested with 3.2.32-rt51 and when floodpinging the latency in a
> kernel driver(! not even usermode) was in the range of milliseconds?
> Have you tested flood pinging with the newer kernel?

We just got it running yesterday, more tests will come.

rsc
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ptxdist] am335x latency
  2013-03-27  8:13     ` Robert Schwebel
@ 2013-03-28  8:31       ` Tim Sander
  0 siblings, 0 replies; 7+ messages in thread
From: Tim Sander @ 2013-03-28  8:31 UTC (permalink / raw)
  To: ptxdist

[-- Attachment #1: Type: text/plain, Size: 856 bytes --]

Hi

Am Mittwoch, 27. März 2013, 09:13:00 schrieb Robert Schwebel:
> On Wed, Mar 27, 2013 at 08:24:21AM +0100, Tim Sander wrote:
> > I have tested with 3.2.32-rt51 and when floodpinging the latency in a
> > kernel driver(! not even usermode) was in the range of milliseconds?
> > Have you tested flood pinging with the newer kernel?
> 
> We just got it running yesterday, more tests will come.
I have tested the interrupt latency in kernel with a module which is attached. 
This uses the am335x timers to measure the latency into usermode and after 
interrupt. The code is attached. Just compile the module and start up the 
usermode helper which prints out the measured latencies.

Could you possibly send me the kernelconfig of the 3.6 rt setup? I would like 
to test the new rt kernel but somehow my kconfig is borked.

Best regards
Tim

[-- Attachment #2: firq.c --]
[-- Type: text/x-csrc, Size: 13371 bytes --]

/*
 * FIRQ interrupt latency test
 *
 * 2010 (C) Tim Sander <tim.sander@hbm.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License Version
 * 2 as published by the Free Software Foundation.
 *
 */

#define DEBUG

#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/io.h>
#include <linux/version.h>
#include <mach/hardware.h>
#include <plat/dmtimer.h>

#define DRV_NAME	"firq"

#define TIMER_RELOAD			0xffffffff-10000000u
#define FIRQ_DEVICES			(2)
#define FIRQ_FIFO_SIZE			64
#define IOMEM_BASE				0x48044000
#define IOMEM_LEN				0xFFFF+1


struct firq_priv;

struct irq_stat {
	unsigned int min;
	unsigned int max;
	unsigned int avg;
};

struct firq_misc {
	int			minor;
	atomic_t		free;
	struct firq_priv		*priv;
};

struct firq_priv {
	struct omap_dm_timer	*timer;
	int	 					irq;
	struct platform_device	*pdev;
    struct kfifo			fifos[FIRQ_DEVICES];
    wait_queue_head_t		wqs[FIRQ_DEVICES];
	struct firq_misc		misc[FIRQ_DEVICES];
	struct irq_stat			irqstat;
	struct irq_stat			userstat;
	struct task_struct 		*wakeupTask;
	int 					maxlatency;
};

void init_irq_statistics(struct irq_stat *irq) {
	irq->min=0xffffffff;
	irq->max=0;
	irq->avg=1;
}

void update_irq_statistics(unsigned int tval,unsigned int rval,struct irq_stat *irq) {
	unsigned int real = tval - rval;
	if(real>irq->max) irq->max=real;
	if(real<irq->min) irq->min=real;
	irq->avg=(irq->avg*7+real)>>3;
}

static struct firq_priv	*current_instance;

static inline int firq_get_device_no(struct firq_priv *priv, struct firq_misc *misc)
{
	return misc - priv->misc;
}

static int firq_misc_get(struct firq_priv *priv, struct inode *inode, struct firq_misc **ret_misc)
{
	struct firq_misc *misc;
	int minor = iminor(inode);
	int i;

	dev_dbg(&priv->pdev->dev, "%s: minor: %d\n", __func__, minor);

	for (i = 0; i < ARRAY_SIZE(priv->misc); i++) {
		misc = &priv->misc[i];

		dev_dbg(&priv->pdev->dev, "%s: misc->minor: %d, free %d\n", __func__, misc->minor, atomic_read(&misc->free));

		if (misc->minor == minor) {
			if (!atomic_sub_and_test(1, &misc->free)) {
				atomic_inc(&misc->free);
				return -EBUSY;
			}

			dev_dbg(&priv->pdev->dev, "%s: using device #%d\n", __func__, i);

			*ret_misc = misc;
			return 0;
		}
	}

	return -ENODEV;
}

static int firq_misc_put(struct firq_priv *priv, struct firq_misc *misc)
{
	atomic_inc(&misc->free);

	return 0;
}

static int firq_open(struct inode *inode, struct file *file)
{
	struct firq_priv *priv = current_instance;
	struct firq_misc *misc;
	int err;

	err = firq_misc_get(priv, inode, &misc);
	if (err)
		return err;

	file->private_data = misc;

	//initialize iomem mapping here
	return 0;
}

static int firq_release(struct inode *inode, struct file *file)
{
	struct firq_misc *misc = file->private_data;
	struct firq_priv *priv = misc->priv;

	firq_misc_put(priv, misc);
	//free io

	return 0;
}

static ssize_t firq_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
	unsigned long retval;
    //unsigned lenout;
	struct firq_misc *misc = file->private_data;
	struct firq_priv *priv = misc->priv;
	//int device_number = firq_get_device_no(priv, misc);

	priv->wakeupTask=current;
	set_current_state(TASK_INTERRUPTIBLE);
	schedule();

	update_irq_statistics(ioread32(((void*)priv->timer->io_base)+0x3C),ioread32(((void*)priv->timer->io_base)+0x40),&(priv->userstat));
	retval=copy_to_user(buf,&priv->irqstat,sizeof(priv->irqstat));
	__set_current_state(TASK_RUNNING);

	return retval;
}

static ssize_t firq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	struct firq_misc *misc = file->private_data;
	struct firq_priv *priv = misc->priv;
	int res;
	unsigned int maxlatency;
	char inbuffer[10];
    res=copy_from_user(inbuffer,buf,count<10?count:10);
	if(res) {
		return res;
	}
	inbuffer[9]=0;
	if(strncmp("clear",inbuffer,5)==0) {
		init_irq_statistics(&(priv->userstat));
		init_irq_statistics(&(priv->irqstat));
	} else {
		sscanf(inbuffer,"%u",&maxlatency);
		dev_info(&priv->pdev->dev,"maxlatency:%i\n",maxlatency);
		priv->maxlatency=maxlatency;
		tracing_on();
	}
	return count;
}

static unsigned int firq_poll(struct file *file,poll_table *wait) {
	/*
	struct firq_misc *misc = file->private_data;
	struct firq_priv *priv = misc->priv;
	unsigned int mask=0;
	int device_number = firq_get_device_no(priv, misc);
	dev_dbg(&priv->pdev->dev, "%s: using device #%d poll_wait\n", __func__, device_number);
	poll_wait(file,&priv->wqs[device_number],wait);
	if(kfifo_len(&priv->fifos[device_number])) { //we have data available for reading
		mask |= POLLIN |POLLRDNORM; 
	}
	if((FIRQ_FIFO_SIZE/2-ioread32(&priv->fpga->regsGeneral.fifoCpuToMspCount))>0) { //we have space in input buffer
		mask |= POLLOUT |POLLWRNORM;                                   //for writing
	}
	return mask;
	*/
	return 0;
}

static int firq_mmap(struct file *file, struct vm_area_struct *vma) {
	int size=vma->vm_end-vma->vm_start;
	if(size>IOMEM_LEN) {
		return -EINVAL;
	}
	vma->vm_flags |= VM_IO |VM_RESERVED;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	if(remap_pfn_range(vma, vma->vm_start, IOMEM_BASE>>PAGE_SHIFT, size, vma->vm_page_prot)) {
		printk(KERN_INFO "firq: mmap of timer registers failed.");
		return -EAGAIN;
	};
	return 0;
}

static irqreturn_t firq_irq_handler(int irq,void *data) {
	struct firq_priv *priv = data;
	unsigned int tval,rval;
	//clear interrupt flag
	iowrite32(0x2,priv->timer->io_base+0x28);
	tval=ioread32(((void*)priv->timer->io_base)+0x3C);
	rval=ioread32(((void*)priv->timer->io_base)+0x40);
	update_irq_statistics(tval,rval,&(priv->irqstat));
	if(priv->maxlatency<(tval-rval)) {
		tracing_off();
		priv->maxlatency=0;
	}
	if(current_instance->wakeupTask) wake_up_process(current_instance->wakeupTask);

	return IRQ_HANDLED;
}

static struct file_operations firq_fops = {
	.owner		= THIS_MODULE,
	.open		= firq_open,
	.release	= firq_release,
	.read		= firq_read,
	.write		= firq_write,
	//.poll		= firq_poll,
	.mmap		= firq_mmap,
};

static struct file_operations firq_latency_fops = {
	.open		= firq_open,
	.release	= firq_release,
	.write		= firq_write,
};

static struct miscdevice firq_miscdev[] = {
	{
		.minor	= MISC_DYNAMIC_MINOR,
		.name	= "firq",
		.fops	= &firq_fops,
	},
	{
		.minor	= MISC_DYNAMIC_MINOR,
		.name	= "firqlatency",
		.fops	= &firq_latency_fops,
	},
};

static int firq_probe_cdev(struct platform_device *pdev)
{
	struct firq_priv *priv = platform_get_drvdata(pdev);
	int i=0, err,have_misc=0;
	dev_info(&pdev->dev, "nr of devices: %i",ARRAY_SIZE(firq_miscdev));
	for (i = 0; i < ARRAY_SIZE(firq_miscdev); i++) { 
		init_waitqueue_head(&priv->wqs[i]);
		err = misc_register(&firq_miscdev[i]);
		if (err) goto exit_unregister;
		have_misc=1;

		priv->misc[i].minor = firq_miscdev[i].minor;
		priv->misc[i].priv = priv;
		atomic_set(&priv->misc[i].free, 1);

		dev_info(&pdev->dev, "registered %s with minor %d\n", firq_miscdev[i].name, firq_miscdev[i].minor);
   		err=kfifo_alloc(&priv->fifos[i],FIRQ_FIFO_SIZE,GFP_KERNEL); 
		if(err) goto exit_unregister;
		have_misc=0;

	}

	return 0;

 exit_unregister:
	printk("ERROR IN CDEV\n");
	for (i--; i >= 0; i--) {
		kfifo_free(&priv->fifos[i]);
		if(have_misc) misc_deregister(&firq_miscdev[i]);
		have_misc=1;
	}

	return err;
}

static int firq_probe(struct platform_device *pdev)
{
	struct firq_priv *priv;
	struct resource *res;
	void __iomem *base;
	int err, irq;
	char *cm_per;
	
	dev_info(&pdev->dev, "%s\n", __func__);
	if (current_instance)
		return -EBUSY;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	
	if (!res) {
		dev_info(&pdev->dev, "%s probe failed on resource register.\n", __func__);
		err = -ENODEV;
		goto exit;
	}

	/* requesting region collides with fpga driver, but we want both drivers access the same region
	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		pr_err("firq driver request region failed");
		err = -EBUSY;
		goto exit;
	}
	*/

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		dev_err(&pdev->dev, "%s error: failed to map memory",__func__);
		err = -ENOMEM;
		goto exit;
	}

	priv = kzalloc(sizeof(struct firq_priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "%s error: failed to allocate memory",__func__);
		err = -ENOMEM;
		goto exit_iounmap;
	}
	init_irq_statistics(&(priv->irqstat));
	init_irq_statistics(&(priv->userstat));
	priv->wakeupTask=NULL;

	platform_set_drvdata(pdev, priv);
	priv->pdev = pdev;

	current_instance = priv;
	
	//get clock module peripheral registers
	cm_per = ioremap(0x44E00000,1024);
	if(cm_per) {
		dev_info(&priv->pdev->dev,"switch mux to high speed clock timer 4\n");
		iowrite32(1,cm_per+0x10); //enable high speed clock on timer 4
		iounmap(cm_per);
	}
	//priv->timer = omap_dm_timer_request();
	priv->timer = omap_dm_timer_request_specific(4);
	if(priv->timer==0) goto exit_free;
	irq = omap_dm_timer_get_irq(priv->timer);
	omap_dm_timer_set_int_enable(priv->timer,OMAP_TIMER_INT_OVERFLOW);
	omap_dm_timer_enable(priv->timer);
	//omap_dm_timer_set_source(priv->timer,OMAP_TIMER_SRC_SYS_CLK); //does not work?
	//omap_dm_timer_set_source(priv->timer,OMAP_TIMER_SRC_32_KHZ);
	omap_dm_timer_set_pwm(priv->timer,1,0,OMAP_TIMER_TRIGGER_OVERFLOW);
	omap_dm_timer_set_prescaler(priv->timer,0);
	omap_dm_timer_set_load_start(priv->timer,1,TIMER_RELOAD);
	iowrite32(0x2,((void*)priv->timer->io_base)+0x2c);
	dev_info(&priv->pdev->dev,"iobase: %x\n",(unsigned int)priv->timer->io_base);
	dev_info(&priv->pdev->dev,"func_base: %x\n",(unsigned int)priv->timer->func_base);
	dev_info(&priv->pdev->dev,"irqstatus raw: %x\n",ioread32(((void*)priv->timer->io_base)+0x24));
	dev_info(&priv->pdev->dev,"irqstatus: %x\n",ioread32(((void*)priv->timer->io_base)+0x28));
	dev_info(&priv->pdev->dev,"irqenable: %x\n",ioread32(((void*)priv->timer->io_base)+0x2c));
	dev_info(&priv->pdev->dev,"timer status: %x\n",ioread32(((void*)priv->timer->io_base)+0x18));
	dev_info(&priv->pdev->dev,"timer control: %x\n",ioread32(((void*)priv->timer->io_base)+0x38));
	dev_info(&priv->pdev->dev,"timer count: %x\n",ioread32(((void*)priv->timer->io_base)+0x3C));
	dev_info(&priv->pdev->dev,"timer load: %x\n",ioread32(((void*)priv->timer->io_base)+0x40));

	priv->irq = irq;
	if(request_irq(irq,firq_irq_handler,IRQF_SHARED|IRQF_TRIGGER_LOW,"firq-timer",current_instance)) {
		dev_err(&pdev->dev, "error: failed to allocate interrupt.");
		err = - ENODEV;
		goto exit_timer;
	}
	
	//enable_irq(irq);
	err = firq_probe_cdev(pdev);
	if (err) goto exit_irq;

	return 0;
 exit_irq:
	free_irq(irq,pdev);
 exit_timer:
	omap_dm_timer_free(priv->timer);
 exit_free:
	kfree(priv);
 exit_iounmap:
	iounmap(base);
	/*
 exit_release:
	release_mem_region(res->start, resource_size(res));
	*/
 exit:
	return err;
}

static void firq_remove_cdev(struct platform_device *pdev)
{
	int i=0;

	for (i = ARRAY_SIZE(firq_miscdev) - 1; i >= 0; i--)
		misc_deregister(&firq_miscdev[i]);
}

static int firq_remove(struct platform_device *pdev)
{
	struct firq_priv *priv = platform_get_drvdata(pdev);
	struct resource *res;

	disable_irq(priv->irq);
	firq_remove_cdev(pdev);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	//release_mem_region(res->start, resource_size(res));

	current_instance = NULL;

	kfree(priv);

	return 0;
}

static struct platform_driver firq_driver = {
	.probe		= firq_probe,
	.remove		= firq_remove,
	.driver.name	= DRV_NAME,
};


/* this should go into the board file - START - */

static struct resource firq_resources[] = {
	{
		.start	= IOMEM_BASE,
		.end	= IOMEM_BASE + IOMEM_LEN - 1,
		.flags	= IORESOURCE_MEM,
	},
};

/* not needed in board file */
static void firq_plat_release(struct device *dev)
{
	dev_info(dev, "%s\n", __func__);
}

static struct platform_device firq_device = {
	.name		= DRV_NAME,
	.id		= -1,
	.resource	= firq_resources,
	.num_resources	= ARRAY_SIZE(firq_resources),
	.dev.release	= firq_plat_release,
};

static int firq_device_register(void)
{
	return platform_device_register(&firq_device);
}

/* not needed in board file */
static void firq_device_unregister(void)
{
	platform_device_unregister(&firq_device);
}

/* this should go into the board file - END - */


static int __init firq_init(void)
{
	int err;

	pr_info("%s driver loaded\n", DRV_NAME);

	err = firq_device_register();
	if (err)
		goto exit;

	err = platform_driver_register(&firq_driver);
	if (err) {
		dev_info(NULL,"%s platform register failed\n",DRV_NAME);
		goto exit_unregister;
	}


	return 0;
 exit_unregister:
	firq_device_unregister();
 exit:
	return err;
}

static void __exit firq_exit(void)
{
	firq_device_unregister();
	platform_driver_unregister(&firq_driver);
	pr_info("%s driver removed\n", DRV_NAME);
}

module_init(firq_init);
module_exit(firq_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("firq serial driver");
MODULE_AUTHOR("Tim Sander");
MODULE_ALIAS("devname:firq");
MODULE_ALIAS("platform:firq");

[-- Attachment #3: firqreader.c --]
[-- Type: text/x-csrc, Size: 2681 bytes --]

#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h>

#define MMAP_LEN	1024
#define FPGA_DEV "/dev/firq"

struct irq_tstat {
	unsigned int min;
	unsigned int max;
	unsigned int avg;
};
//global variables for thread
pthread_mutex_t slowThreadMutex;
int finish=0;
int firq_dev;
void *mmap_base;
struct irq_tstat is;
struct irq_tstat tstat;

void outputStat(const char *mode,struct irq_tstat val) {
	float tcl = .00000004000000000000;
	printf("%s min:%.9f max:%.9f avg:%.9f\n",mode,val.min*tcl,val.max*tcl,val.avg*tcl);
}

void sighandler(int signum) {
	finish=1;
}

static void *rtthread(void *arg) {
	while(!finish) {
		read(firq_dev,&is,sizeof(is));
		unsigned int counter = *((unsigned int*)(mmap_base+0x3C));
		unsigned int reload = *((unsigned int*)(mmap_base+0x40));
		unsigned diff = counter - reload;
		if(tstat.min>diff) tstat.min=diff;
		if(tstat.max<diff) tstat.max=diff;
		tstat.avg = (tstat.avg+diff)>>1;
		pthread_mutex_unlock(&slowThreadMutex);
	}
}

int main(int argc,char* argv[]) {
	pthread_mutexattr_t mutexattr;
	pthread_attr_t rtattr;
	pthread_t tid;
	struct sched_param params;
	struct sigaction action;
	unsigned char c;
	unsigned short s;
	unsigned int   w;
	int address;
	char access;
	char *endptr;
	int res;
	int i;
	struct sched_param param;
	tstat.min=0xffffffff;
	tstat.max=0;
	tstat.avg=1;
	printf("threaded version:1\n");

	firq_dev=open(FPGA_DEV,O_RDWR);
	if(firq_dev==-1) {
		perror(FPGA_DEV);
		exit(1);
	};
	mmap_base=mmap(0,MMAP_LEN,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_LOCKED,firq_dev,0);
	if((int)mmap_base==-1) {
		perror("mmap");
		exit(2);
	}
	for(i=0;i<20;i++) {
		action.sa_handler=sighandler;
		sigaction(i,&action,NULL);
	}
	pthread_mutexattr_init (&mutexattr);
	//pthread_mutexattr_setprotocol (&mutexattr, PTHREAD_PRIO_NONE);
	pthread_mutex_init(&slowThreadMutex,&mutexattr);
	pthread_attr_init(&rtattr);
	pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO);
	params.sched_priority = 98;
	pthread_attr_setschedparam(&rtattr, &params);
	pthread_create(&tid,&rtattr,rtthread,NULL);
	/*
	param.sched_priority=98;
	if(sched_setscheduler(0,SCHED_FIFO,&param) == -1) {
		perror("MeasThread::run(), sched_setscheduler");
		exit(-1);
	}
	*/
	
	while(!finish) {
		pthread_mutex_lock(&slowThreadMutex);
		outputStat("rusermode",tstat);
		outputStat("rirq     ",is);
		printf("usermode  min:%u max:%u avg:%u\n",tstat.min,tstat.max,tstat.avg);
		printf("irq       min:%u max:%u avg:%u\n",is.min,is.max,is.avg);
	}
	res=munmap(mmap_base,MMAP_LEN);
	close(firq_dev);
   return 0;
}

[-- Attachment #4: Type: text/plain, Size: 48 bytes --]

-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-03-28  8:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-26 13:40 [ptxdist] Patch Kernet with preempt_rt patch "Breixo López García"
2013-03-26 13:52 ` Bernhard Walle
2013-03-26 14:02 ` "Breixo López García"
2013-03-26 23:56 ` Robert Schwebel
2013-03-27  7:24   ` Tim Sander
2013-03-27  8:13     ` Robert Schwebel
2013-03-28  8:31       ` [ptxdist] am335x latency Tim Sander

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox