All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] PCI Framegrabber real-time driver
@ 2006-01-11 18:55 Rodrigo Rosenfeld Rosas
  2006-01-11 19:48 ` Jan Kiszka
  0 siblings, 1 reply; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-11 18:55 UTC (permalink / raw)
  To: xenomai

Hi,

I developed a v4l2 driver for my PCI framegrabber and I need to use it in my
real-time applications. I think I need to write a new one with real-time
constrainments. But I'm not sure of which API would be the best one for this
kind of driver.

I know about existence of RTDM, but I'm not sure if it is the best choice...

Let me explain how the driver works. It initializes the board with some PCI
writes on startup. It's passed to the kernel the parameter "mem=510M"
reserving 2Mb for use with the framegrabber through DMA access. I need a
continuous physic memory area and I can't get it through kmalloc or similar
functions. I map this memory in my programs in user space. So, I basically
need to write and read from PCI registers in the drive. But I don't know if
it should be better to develop the driver using some existing API or not
because I didn't find any API that applies to framegrabbers like v4l does on
Linux domain...

Please, what do you suggest about the design of my driver?

Thanks,

Rodrigo.

	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 18:55 [Xenomai-help] PCI Framegrabber real-time driver Rodrigo Rosenfeld Rosas
@ 2006-01-11 19:48 ` Jan Kiszka
  2006-01-11 21:21   ` Rodrigo Rosenfeld Rosas
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2006-01-11 19:48 UTC (permalink / raw)
  To: Rodrigo Rosenfeld Rosas; +Cc: xenomai

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

Rodrigo Rosenfeld Rosas wrote:
> Hi,
> 
> I developed a v4l2 driver for my PCI framegrabber and I need to use it in my
> real-time applications. I think I need to write a new one with real-time
> constrainments. But I'm not sure of which API would be the best one for this
> kind of driver.
> 
> I know about existence of RTDM, but I'm not sure if it is the best choice...
> 
> Let me explain how the driver works. It initializes the board with some PCI
> writes on startup. It's passed to the kernel the parameter "mem=510M"
> reserving 2Mb for use with the framegrabber through DMA access. I need a

I guess "510M" does not stand for 510 MB... ;)

> continuous physic memory area and I can't get it through kmalloc or similar
> functions. I map this memory in my programs in user space. So, I basically
> need to write and read from PCI registers in the drive. But I don't know if
> it should be better to develop the driver using some existing API or not
> because I didn't find any API that applies to framegrabbers like v4l does on
> Linux domain...

There is no such thing like video4RTDM (yet), that's true.

> 
> Please, what do you suggest about the design of my driver?
> 

Well, if you already have a working driver for standard Linux, I would
suggest the following:

Split up your driver in the (non-real-time) initialisation work where
you may use all the useful driver APIs Linux provides you (BTW, how do
you obtain this continuous memory block?) and a (real-time) runtime part
where only RTDM functions can be used.

Then register a RTDM device, likely some misc device with a nice unique
name and an instance number postfix, and with open, close, and ioctl
handlers. The init stuff, or parts of it, would be moved to the open_nrt
(note the "_nrt") handler, cleanup to close_nrt. Likely the parameters
that can be passed via rt_dev_open (or plain "open" in the posix skin)
are not sufficient to configure your device instance. E.g. you may want
to pass up or down some userspace buffer addresses. Therefore, register
an ioctl_nrt handler which deals with specific setup-IOCTLs. On the
other hand, all the synchronisation, buffer flipping, etc. you need to
perform during runtime from your hard-real-time task has to be
implemented in an ioctl_rt (note: "_rt") handler.

As there is no magic involved in the rt-part of RTDM - all
synchronisation mechanisms are standard -, porting the existing semantic
of your driver over the RTDM API should cause no real problem. But I
don't know your driver design and its usage, so feel free to point out
potential issues you see.

If you like to have a look at a rather simple reference code with all
the described features included (just without direct hardware acesss),
check out ksrc/drivers/benchmark/ in the latest Xenomai SVN.

And if you think the final API design for your framegrabbing hardware
looks common enough to cover other framegrabbing hardware as well, you
are warmly welcome to post the concept so that we can discuss making
this THE real-time framegrabbing device profile (officially reserving an
RTDM ID and name, including the API header in the Xenomai code base,
etc.). That could mean your application suddenly becomes portable over
other hardware - something like video4RTDM...

Jan

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]

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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 19:48 ` Jan Kiszka
@ 2006-01-11 21:21   ` Rodrigo Rosenfeld Rosas
  2006-01-11 22:23     ` Gilles Chanteperdrix
  2006-01-11 22:31     ` Jan Kiszka
  0 siblings, 2 replies; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-11 21:21 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

Hi Jan, thank you for replying (I was really guessing that your answer would 
be the first ;) ).

I'll comment along the message.

>> Hi,
>>
>> ...
>> Let me explain how the driver works. It initializes the board with some
>> PCI writes on startup. It's passed to the kernel the parameter "mem=510M"
>> reserving 2Mb for use with the framegrabber through DMA access. I need a
>
>I guess "510M" does not stand for 510 MB... ;)

Sorry, why not? This is taken from Documentation/kernel-parameters.txt:
mem=nn[KMG]     [KNL,BOOT] Force usage of a specific amount of memory
                       Amount of memory to be used when the kernel is not able
                       to see the whole system memory or for test.
                       [IA-32] Use together with memmap= to avoid physical
                       address space collisions. Without memmap= PCI devices
                       could be placed at addresses belonging to unused RAM.

>> continuous physic memory area and I can't get it through kmalloc or
>> similar functions. I map this memory in my programs in user space. So, I
>> basically need to write and read from PCI registers in the drive. But I
>> don't know if it should be better to develop the driver using some
>> existing API or not because I didn't find any API that applies to
>> framegrabbers like v4l does on Linux domain...
>
>There is no such thing like video4RTDM (yet), that's true.

:(

>> Please, what do you suggest about the design of my driver?
>
>Well, if you already have a working driver for standard Linux, I would
>suggest the following:
>
>Split up your driver in the (non-real-time) initialisation work where
>you may use all the useful driver APIs Linux provides you (BTW, how do
>you obtain this continuous memory block?) and a (real-time) runtime part
>where only RTDM functions can be used.

Actually, the great advantage of V4L(2) API is for user space programmers to 
have a common API. There is too few advantages the API provides for 
initialization (actually, the API does no hardware initialization, it only 
register the devices to be used by userspace programs). So, the 
initialization API is useless without the runtime API.

The memory is obtained passing the kernel the parameter "mem=510M". So, the 
kernel won't use the last 2 Mb. I know it is not an elegant solution but it's 
pretty simple and I can't imagine another one... For using this memory in the 
driver there are two options:
 - The user pass the address to be used by DMA through a module parameter.
 - if no address was specified, try to use the last address with the "dma = 
virt_to_phys(high_memory);". Of course, this is dangerous if another driver 
uses the same method and is already using that memory. But I know that in my 
system this is the only driver that uses that memory.

>Then register a RTDM device, likely some misc device with a nice unique
>name and an instance number postfix, and with open, close, and ioctl
>handlers.
I think that in that cases a mmap handler is very useful too.

>The init stuff, or parts of it, would be moved to the open_nrt 
>(note the "_nrt") handler, cleanup to close_nrt. Likely the parameters
>that can be passed via rt_dev_open (or plain "open" in the posix skin)
>are not sufficient to configure your device instance. E.g. you may want
>to pass up or down some userspace buffer addresses. Therefore, register
>an ioctl_nrt handler which deals with specific setup-IOCTLs. On the
>other hand, all the synchronisation, buffer flipping, etc. you need to
>perform during runtime from your hard-real-time task has to be
>implemented in an ioctl_rt (note: "_rt") handler.
>
>As there is no magic involved in the rt-part of RTDM - all
>synchronisation mechanisms are standard -, porting the existing semantic
>of your driver over the RTDM API should cause no real problem. But I
>don't know your driver design and its usage, so feel free to point out
>potential issues you see.

Well, there is only one thing I can see at the moment. I would need to rewrite 
the interrupt part to use a real-time interrupt routine instead of the PCI 
interrupt method, am I right?

>If you like to have a look at a rather simple reference code with all
>the described features included (just without direct hardware acesss),
>check out ksrc/drivers/benchmark/ in the latest Xenomai SVN.
Thank you, I'll check them...

>And if you think the final API design for your framegrabbing hardware
>looks common enough to cover other framegrabbing hardware as well, you
>are warmly welcome to post the concept so that we can discuss making
>this THE real-time framegrabbing device profile (officially reserving an
>RTDM ID and name, including the API header in the Xenomai code base,
>etc.). That could mean your application suddenly becomes portable over
>other hardware - something like video4RTDM...

Unfortunatelly, I think I won't have time at this moment to suggest a common 
API for all framegrabbers because I'm bad on time. I have no more than 6 
months to finish my work on college and I have a lot of other things to 
implement and some articles to write... But, I might have some time in 
future...

Thank you,

Rodrigo.

	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 21:21   ` Rodrigo Rosenfeld Rosas
@ 2006-01-11 22:23     ` Gilles Chanteperdrix
  2006-01-12 19:47       ` Rodrigo Rosenfeld Rosas
  2006-01-11 22:31     ` Jan Kiszka
  1 sibling, 1 reply; 13+ messages in thread
From: Gilles Chanteperdrix @ 2006-01-11 22:23 UTC (permalink / raw)
  To: Rodrigo Rosenfeld Rosas; +Cc: xenomai

Rodrigo Rosenfeld Rosas wrote:
 > The memory is obtained passing the kernel the parameter "mem=510M". So, the 
 > kernel won't use the last 2 Mb. I know it is not an elegant solution but it's 
 > pretty simple and I can't imagine another one...

Another one, suggested in "Linux devices drivers", chapter 8, is to
allocate your memory at boot time with one of the alloc_bootmem
functions. Of course, in order to call these functions, a small part of
your driver need to run in the kernel itself.

For more details, see:
http://lwn.net/Kernel/LDD3/

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 21:21   ` Rodrigo Rosenfeld Rosas
  2006-01-11 22:23     ` Gilles Chanteperdrix
@ 2006-01-11 22:31     ` Jan Kiszka
       [not found]       ` <1137032878.43c5beae139f5@domain.hid>
  2006-01-13 14:24       ` Rodrigo Rosenfeld Rosas
  1 sibling, 2 replies; 13+ messages in thread
From: Jan Kiszka @ 2006-01-11 22:31 UTC (permalink / raw)
  To: Rodrigo Rosenfeld Rosas; +Cc: xenomai

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

Rodrigo Rosenfeld Rosas wrote:
> Hi Jan, thank you for replying (I was really guessing that your answer would 
> be the first ;) ).

How did you? ;)

> 
> I'll comment along the message.
> 
> 
>>>Hi,
>>>
>>>...
>>>Let me explain how the driver works. It initializes the board with some
>>>PCI writes on startup. It's passed to the kernel the parameter "mem=510M"
>>>reserving 2Mb for use with the framegrabber through DMA access. I need a
>>
>>I guess "510M" does not stand for 510 MB... ;)
> 
> 
> Sorry, why not? This is taken from Documentation/kernel-parameters.txt:
> mem=nn[KMG]     [KNL,BOOT] Force usage of a specific amount of memory
>                        Amount of memory to be used when the kernel is not able
>                        to see the whole system memory or for test.
>                        [IA-32] Use together with memmap= to avoid physical
>                        address space collisions. Without memmap= PCI devices
>                        could be placed at addresses belonging to unused RAM.
> 

Argh, I confused something here.

Yes, this is a way to obtain this continous memory. The other, more
organised way is via the old bigphysarea patch. It's still being update
even for 2.6 (http://pv105234.reshsg.uci.edu/~jfeise/Downloads/zr36120).
Anyway, as long as you are alone with this requirement on your system,
this is the simpler way to go.

> 
>>>continuous physic memory area and I can't get it through kmalloc or
>>>similar functions. I map this memory in my programs in user space. So, I
>>>basically need to write and read from PCI registers in the drive. But I
>>>don't know if it should be better to develop the driver using some
>>>existing API or not because I didn't find any API that applies to
>>>framegrabbers like v4l does on Linux domain...
>>
>>There is no such thing like video4RTDM (yet), that's true.
> 
> 
> :(
> 
> 
>>>Please, what do you suggest about the design of my driver?
>>
>>Well, if you already have a working driver for standard Linux, I would
>>suggest the following:
>>
>>Split up your driver in the (non-real-time) initialisation work where
>>you may use all the useful driver APIs Linux provides you (BTW, how do
>>you obtain this continuous memory block?) and a (real-time) runtime part
>>where only RTDM functions can be used.
> 
> 
> Actually, the great advantage of V4L(2) API is for user space programmers to 
> have a common API. There is too few advantages the API provides for 
> initialization (actually, the API does no hardware initialization, it only 
> register the devices to be used by userspace programs). So, the 
> initialization API is useless without the runtime API.
> 
> The memory is obtained passing the kernel the parameter "mem=510M". So, the 
> kernel won't use the last 2 Mb. I know it is not an elegant solution but it's 
> pretty simple and I can't imagine another one... For using this memory in the 
> driver there are two options:
>  - The user pass the address to be used by DMA through a module parameter.
>  - if no address was specified, try to use the last address with the "dma = 
> virt_to_phys(high_memory);". Of course, this is dangerous if another driver 
> uses the same method and is already using that memory. But I know that in my 
> system this is the only driver that uses that memory.
> 
>>Then register a RTDM device, likely some misc device with a nice unique
>>name and an instance number postfix, and with open, close, and ioctl
>>handlers.
> 
> I think that in that cases a mmap handler is very useful too.
> 

Maybe, maybe not. The mmap interface, especially its current low-end
side on Linux, contains a lot dynamics and tight relations to the
mm-subsystem to use it directly in hard-RT contexts. So far I think it
would be overkill to define this interface just to pass some user memory
region to a RTDM driver. I rather vote for specialised new interfaces in
this cases, typically based on IOCTLs.

See, touching the mm in hard RT code is at least "tricky". You drag a
lot of external compexity into your RT subdomain without real need. It
simply that you then have to take much more code into account to gain
certainty if your system is actually deterministic. Tight mm-relation is
e.g. one reason why userspace locking services (futexes) are even on
PREEMPT_RT still fishy regarding hard-RT - but this is a different topic.

> 
>>The init stuff, or parts of it, would be moved to the open_nrt 
>>(note the "_nrt") handler, cleanup to close_nrt. Likely the parameters
>>that can be passed via rt_dev_open (or plain "open" in the posix skin)
>>are not sufficient to configure your device instance. E.g. you may want
>>to pass up or down some userspace buffer addresses. Therefore, register
>>an ioctl_nrt handler which deals with specific setup-IOCTLs. On the
>>other hand, all the synchronisation, buffer flipping, etc. you need to
>>perform during runtime from your hard-real-time task has to be
>>implemented in an ioctl_rt (note: "_rt") handler.
>>
>>As there is no magic involved in the rt-part of RTDM - all
>>synchronisation mechanisms are standard -, porting the existing semantic
>>of your driver over the RTDM API should cause no real problem. But I
>>don't know your driver design and its usage, so feel free to point out
>>potential issues you see.
> 
> 
> Well, there is only one thing I can see at the moment. I would need to rewrite 
> the interrupt part to use a real-time interrupt routine instead of the PCI 
> interrupt method, am I right?
> 

Don't know. Maybe you could sketch the data flow of a typical frame
capturing cycle. Does the application trigger it by polling and then
blocks until the result arrived? Or is the update continously going on?
How does an application know if a frame is up-to-date, is currently
being updated, or whatever? Sorry, I never worked with such hardware
before and only have a rough idea of it.

> 
>>If you like to have a look at a rather simple reference code with all
>>the described features included (just without direct hardware acesss),
>>check out ksrc/drivers/benchmark/ in the latest Xenomai SVN.
> 
> Thank you, I'll check them...
> 
> 
>>And if you think the final API design for your framegrabbing hardware
>>looks common enough to cover other framegrabbing hardware as well, you
>>are warmly welcome to post the concept so that we can discuss making
>>this THE real-time framegrabbing device profile (officially reserving an
>>RTDM ID and name, including the API header in the Xenomai code base,
>>etc.). That could mean your application suddenly becomes portable over
>>other hardware - something like video4RTDM...
> 
> 
> Unfortunatelly, I think I won't have time at this moment to suggest a common 
> API for all framegrabbers because I'm bad on time. I have no more than 6 
> months to finish my work on college and I have a lot of other things to 
> implement and some articles to write... But, I might have some time in 
> future...

Nevermind, this discussion can already collect interesting aspects and
new ideas. Maybe others, e.g. from the (RT-)FireWire framegrabbing side
will pick this once up.

Jan

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]

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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
       [not found]       ` <1137032878.43c5beae139f5@domain.hid>
@ 2006-01-12  9:29         ` Jan Kiszka
  0 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2006-01-12  9:29 UTC (permalink / raw)
  To: vdkeybus; +Cc: xenomai

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

vdkeybus wrote:
>> Argh, I confused something here.
>>
>> Yes, this is a way to obtain this continous memory. The other, more
>> organised way is via the old bigphysarea patch. It's still being
>> update
>> even for 2.6
>> (http://pv105234.reshsg.uci.edu/~jfeise/Downloads/zr36120).
>> Anyway, as long as you are alone with this requirement on your
>> system,
>> this is the simpler way to go.
> 
>>>>> continuous physic memory area and I can't get it through kmalloc
> 
> I did a quick check and I could easily allocate a 2MB contiguous, 
> aligned buffer on my system using the following calls. (See DMA-
> mapping.txt in your kernel Documentation folder):
> 
> struct pci_dev *p;
> 
> ...
> 
> pci_set_master(p);
> pci_set_consistent_dma_mask(p, DMA_32BIT_MASK);
> pci_alloc_consistent(p, 2097152, &phys_ptr);

I think this depends on how long your system already ran, how much of
the physical memory had already been allocated and how it was released
again, probably causing heavy fragmentation. But if you have, say, 512
MB and only require that 2 MB, the probability to get obtain this block
during system startup is quite high. So it's best to place he request in
the driver's module init routine.

> 
> ...
> 
> You can also get the irq line number here from p->irq . Use this for 
> rtdm_irq_request().
> 
>>>>> Please, what do you suggest about the design of my driver?
> 
> 1. Use RTDM and write a kernel module. It allows you to write a 
> specific test program on it, which you can reuse later on every 
> occasion where you need to know whether the driver or the program 
> contains causes a problem. You can also shut an RTDM driver down 
> manually if your RT program ever bails out 'ungracefully'. 

More precisely, you can try to kill stalled RT file descriptors by
writing their number to /proc/xenomai/rtdm/open_fildes. Depends on the
driver if this works, i.e. its closure handler has to support the
enforced cleanup from every device state.

> 
> 2. Use 2 framebuffers and implement a ping-pong buffer, so that the 
> grabber may fill in a second buffer while you're using the contents of 
> number one. Avoid copying of the data.
> 
> 3. Remember to use the PCI DMA API. It is the easiest way to guarantee 
> that CPU L1/2 caching is not going to fool you some day. You do not 
> want to mess yourself with MTRR and friends (?) on the CPU. (Something 
> I think may be a serious issue when using tricks like the ones 
> mentioned earlier.)
> 
> 4. Use portable functions to access your PCI card, such as read[b/w/l]
> () and write[b/w/l](). Don't do *(unsigned int *)ptr = val. Where 
> needed, use memory write barriers such as wmb(), to avoid instruction 
> reordering by the compiler. 
> 
> 5. Don't catch interrupts that weren't meant for you. If your ISR gets 
> called, check some status register of your card to see if it was the 
> cause of the interrupt. If so, finish with return(RTDM_IRQ_ENABLE). 
> Otherwise, return(RTDM_IRQ_PROPAGATE), so other handlers may catch it 
> (and reset the possibly shared IRQ line, which is never going to be 
> deasserted otherwise (== stuck)).

Currently, RTDM_IRQ_PROPAGATE tells the RT-IRQ subsystem to forward
unhandled IRQs to the Linux domain. If you have to do this as there is
an IRQ sharing between a RT and a non-RT device, you are generally
doomed anyway. The non-RT device can then easily break the determinism
of the RT subsystem. We should rework this flag or at least its
documentation soon when RTDM will be extended (slightly) to support
RT-IRQ sharing (which is RT-safe by design).

> 
> (Anyone, feel free to comment on these lines.)
> 
> BTW, when specifying mem=510M, how would you access the range 510-512 
> without causing a segmentation fault ?
> 
>>> Well, there is only one thing I can see at the moment. I would need
>> to rewrite 
>>> the interrupt part to use a real-time interrupt routine instead of
>> the PCI 
>>> interrupt method, am I right?
> 
> I think you are. I have used an RTDM event (rtdm_event_t) to signal the 
> blocking read function that a frame has arrived.
> 
> Also see the 16550A RTDM driver example to see how events are used to 
> accomplish this.
> 

Yep, another example, just "a bit" more complicated than xeno_timerbench.

> 
> Jeroen.
> 
> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
> 

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 22:23     ` Gilles Chanteperdrix
@ 2006-01-12 19:47       ` Rodrigo Rosenfeld Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-12 19:47 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

Gilles Chanteperdrix escreveu:

>Rodrigo Rosenfeld Rosas wrote:
> > The memory is obtained passing the kernel the parameter "mem=510M". So, the 
> > kernel won't use the last 2 Mb. I know it is not an elegant solution but it's 
> > pretty simple and I can't imagine another one...
>
>Another one, suggested in "Linux devices drivers", chapter 8, is to
>allocate your memory at boot time with one of the alloc_bootmem
>functions. Of course, in order to call these functions, a small part of
>your driver need to run in the kernel itself.
>
>For more details, see:
>http://lwn.net/Kernel/LDD3/
>  
>
Yes, I knew about that, but the it was not an option at the time. I can 
not show the source code of the driver due to a contract or else I 
wouldn't have the specifications. So, if I need to use the driver in 
other places I will have to build a module and distribute only the 
module. I'm still thinking in other solutions but it is easier to ask 
the user to pass the kernel the mem parameter...

But thank you anyway!

Rodrigo.


	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-11 22:31     ` Jan Kiszka
       [not found]       ` <1137032878.43c5beae139f5@domain.hid>
@ 2006-01-13 14:24       ` Rodrigo Rosenfeld Rosas
  2006-01-13 19:57         ` Jan Kiszka
  1 sibling, 1 reply; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-13 14:24 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

>Yes, this is a way to obtain this continous memory. The other, more
>organised way is via the old bigphysarea patch. It's still being update
>even for 2.6 (http://pv105234.reshsg.uci.edu/~jfeise/Downloads/zr36120).
>Anyway, as long as you are alone with this requirement on your system,
>this is the simpler way to go.

I really want to avoid every unnecessary patch to the kernel, so I prefer on 
not depending in other patches then ipipe. And the initial idea was to provide 
the (non-rt) driver to normal users that have the DT3153 framegrabber in 
binary module. I will not do that, but we asked the specifications and told 
them we would send them the final source code for them to distribute the 
module drivers but there is no obligation... The only requirement is that we 
can not redistribute the specifications...

>> I think that in that cases a mmap handler is very useful too.
>
>Maybe, maybe not. The mmap interface, especially its current low-end
>side on Linux, contains a lot dynamics and tight relations to the
>mm-subsystem to use it directly in hard-RT contexts. So far I think it
>would be overkill to define this interface just to pass some user memory
>region to a RTDM driver. I rather vote for specialised new interfaces in
>this cases, typically based on IOCTLs.

The problem with IOCTLs and read/write interfaces is that I need to copy the 
large memory block each time I need a frame... But I could also ask for the 
physical memory address with an IOCTL and use the /dev/mem device for reading 
the memory. But the device is not real-time... How could I share this memory 
with userspace RT-programs in a deterministic way? Of course I would need 
some syncronization method like mutex or another one to avoid begin a new 
capture while the user is reading the memory... But it is not a problem since 
most RT-applications do not need to share the framegrabber. So they should 
ask for a frame, use it, and then ask for another one... I know there are 
ways to avoid waiting for the frame to be acquired doing a continuous capture 
and stopping it when the user needs to read the memory... I'm not concerned 
with this design for now...

>See, touching the mm in hard RT code is at least "tricky". You drag a
>lot of external compexity into your RT subdomain without real need. It
>simply that you then have to take much more code into account to gain
>certainty if your system is actually deterministic. Tight mm-relation is
>e.g. one reason why userspace locking services (futexes) are even on
>PREEMPT_RT still fishy regarding hard-RT - but this is a different topic.

I can't understand why sharing that memory should be so complex...

>> Well, there is only one thing I can see at the moment. I would need to
>> rewrite the interrupt part to use a real-time interrupt routine instead of
>> the PCI interrupt method, am I right?
>
>Don't know. Maybe you could sketch the data flow of a typical frame
>capturing cycle. Does the application trigger it by polling and then
>blocks until the result arrived?

An interrupt can occur when a frame capture finishes. Unless I set the board 
to not generate interrupts...

>Or is the update continously going on? 
It can be set to syncronous or asyncronous mode...

>How does an application know if a frame is up-to-date, is currently
>being updated, or whatever? Sorry, I never worked with such hardware
>before and only have a rough idea of it.
By reading the registers in the PCI board the driver can get the acquire 
status (capturing, finished, etc).

Well, let me explain what my problem is. I'm developing a framework for 
developing rt applications for mobile robots. OROCOS seemed too complex for 
me... For testing the framework I built a simple robot with an optical 
encoder on the weels. I developed an odometry system based on the encoder 
sensors that worked well. I would like to write an application that does 
position and speed control by using the images taken by the framegrabber and 
compare the result with the odometry system for making a conceptual proof of 
my framework for my master-thesis work.

I'd like to thank for all support you, Jeroen and Gilles are giving me.

Rodrigo.


	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
@ 2006-01-13 15:11 Rodrigo Rosenfeld Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-13 15:11 UTC (permalink / raw)
  Cc: xenomai

>> >>>continuous physic memory area and I can't get it through kmalloc
>
>I did a quick check and I could easily allocate a 2MB contiguous,
>aligned buffer on my system using the following calls. (See DMA-
>mapping.txt in your kernel Documentation folder):
>
>struct pci_dev *p;
>
>...
>
>pci_set_master(p);
>pci_set_consistent_dma_mask(p, DMA_32BIT_MASK);
>pci_alloc_consistent(p, 2097152, &phys_ptr);
>
>...

I'll take a look on this approach, but I think that the other is more robust
because this one can fail if it does not find an contiguous block of 2Mb
(actually I'm using about 1,2M on my driver for now...) due to memory
fragmentation... I remember I tried this way some time before when I had
256Mb but could only alloc 512kb of contiguous memory (7 was the maximum
order I could get)... It seemed to me that the kernel has changed since
there. It was not possible to get an order superior to 8 and now I think the
default maximum is order 11... (PAGE_SIZE<<order) I think page size is 4kb
for x86.

>You can also get the irq line number here from p->irq . Use this for
>rtdm_irq_request().
>
>> >>>Please, what do you suggest about the design of my driver?
>
>1. Use RTDM and write a kernel module. It allows you to write a
>specific test program on it, which you can reuse later on every
>occasion where you need to know whether the driver or the program
>contains causes a problem. You can also shut an RTDM driver down
>manually if your RT program ever bails out 'ungracefully'.

Ok, I'm new to RTDM but I think I'll end up using it...

>2. Use 2 framebuffers and implement a ping-pong buffer, so that the
>grabber may fill in a second buffer while you're using the contents of
>number one. Avoid copying of the data.

There is an option, but it would increase the complexity of both the driver
and user code because the user should know what memory is in the turn... And
that is not the only way to avoid copying the data. I can run the acquires on
asyncronous way. The advantage of the ping-pong buffer is that I wouldn't
need to wait for a frame capture to complete (the board can do 30fps [frames
per second]) depending on how I design the driver... I'll think better on
this approach.

>3. Remember to use the PCI DMA API. It is the easiest way to guarantee
>that CPU L1/2 caching is not going to fool you some day. You do not
>want to mess yourself with MTRR and friends (?) on the CPU. (Something
>I think may be a serious issue when using tricks like the ones
>mentioned earlier.)

You are talking about specifying the mem option (is it the trick you
 mention)? Well I need to read more about this topic before discussing it
 with you. I do not know how this caching works nor MTRR...

>4. Use portable functions to access your PCI card, such as read[b/w/l]
>() and write[b/w/l]().

Yes, I already use them.

>Don't do *(unsigned int *)ptr = val. Where
>needed, use memory write barriers such as wmb(), to avoid instruction
>reordering by the compiler.

I forgot this when first designed my driver but I'll take a better look on
this. Do you know about what situations could take the code to be executed in
a different order? I mean, reads and writes to PCI registers could be done in
a different order then I've told to the driver?

>5. Don't catch interrupts that weren't meant for you. If your ISR gets
>called, check some status register of your card to see if it was the
>cause of the interrupt. If so, finish with return(RTDM_IRQ_ENABLE).
>Otherwise, return(RTDM_IRQ_PROPAGATE), so other handlers may catch it
>(and reset the possibly shared IRQ line, which is never going to be
>deasserted otherwise (== stuck)).

I think it is dangerous to share the interrupt with other non-rt drivers. If
the non-rt driver disables the interrupt for a while, the hard rt-driver will
give wrong result. Unless it was possible to not allow the interrupt to be
disabled by non-rt drivers, it is too dangerous to share the interrupt line.

>BTW, when specifying mem=510M, how would you access the range 510-512
>without causing a segmentation fault ?

Why should it cause a segmentation fault? The mem=510M parameter only informs
the kernel to not use that memory but it allows manual use of that memory by
a module or so. But kmalloc  won't alloc that memory.

Thank you Jeroen, you helped me a lot.

Best regards,
Rodrigo.

	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-13 14:24       ` Rodrigo Rosenfeld Rosas
@ 2006-01-13 19:57         ` Jan Kiszka
  2006-01-13 21:53           ` Rodrigo Rosenfeld Rosas
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2006-01-13 19:57 UTC (permalink / raw)
  To: Rodrigo Rosenfeld Rosas; +Cc: xenomai

Rodrigo Rosenfeld Rosas wrote:
>> Yes, this is a way to obtain this continous memory. The other, more
>> organised way is via the old bigphysarea patch. It's still being update
>> even for 2.6 (http://pv105234.reshsg.uci.edu/~jfeise/Downloads/zr36120).
>> Anyway, as long as you are alone with this requirement on your system,
>> this is the simpler way to go.
> 
> I really want to avoid every unnecessary patch to the kernel, so I prefer on 
> not depending in other patches then ipipe. And the initial idea was to provide 
> the (non-rt) driver to normal users that have the DT3153 framegrabber in 
> binary module. I will not do that, but we asked the specifications and told 
> them we would send them the final source code for them to distribute the 
> module drivers but there is no obligation... The only requirement is that we 
> can not redistribute the specifications...
> 
>>> I think that in that cases a mmap handler is very useful too.
>> Maybe, maybe not. The mmap interface, especially its current low-end
>> side on Linux, contains a lot dynamics and tight relations to the
>> mm-subsystem to use it directly in hard-RT contexts. So far I think it
>> would be overkill to define this interface just to pass some user memory
>> region to a RTDM driver. I rather vote for specialised new interfaces in
>> this cases, typically based on IOCTLs.
> 
> The problem with IOCTLs and read/write interfaces is that I need to copy the 
> large memory block each time I need a frame... But I could also ask for the 
> physical memory address with an IOCTL and use the /dev/mem device for reading 
> the memory. But the device is not real-time... How could I share this memory 
> with userspace RT-programs in a deterministic way? Of course I would need 

Set up the memory mapping between kernel and user space during (non-rt)
initialisation. This means that you have to create some mapping from the
physical block into the user space address range. I think
remap_pfn_range() or io_remap_page_range() should do this after mapping
the physical memory into the address space of the kernel (ioremap()).
But I suggest LDD3 on this topic as a better reference.

> some syncronization method like mutex or another one to avoid begin a new 
> capture while the user is reading the memory... But it is not a problem since 
> most RT-applications do not need to share the framegrabber. So they should 
> ask for a frame, use it, and then ask for another one... I know there are 
> ways to avoid waiting for the frame to be acquired doing a continuous capture 
> and stopping it when the user needs to read the memory... I'm not concerned 
> with this design for now...
> 
>> See, touching the mm in hard RT code is at least "tricky". You drag a
>> lot of external compexity into your RT subdomain without real need. It
>> simply that you then have to take much more code into account to gain
>> certainty if your system is actually deterministic. Tight mm-relation is
>> e.g. one reason why userspace locking services (futexes) are even on
>> PREEMPT_RT still fishy regarding hard-RT - but this is a different topic.
> 
> I can't understand why sharing that memory should be so complex...

As long as it's static, it's trivial. But as soon as you have to
synchronise with potential changes of your process' mm, it starts to
cause problems. Again, the concept of setting up the mapping during
non-rt init of your driver and then using it in RT context is safe.

> 
>>> Well, there is only one thing I can see at the moment. I would need to
>>> rewrite the interrupt part to use a real-time interrupt routine instead of
>>> the PCI interrupt method, am I right?
>> Don't know. Maybe you could sketch the data flow of a typical frame
>> capturing cycle. Does the application trigger it by polling and then
>> blocks until the result arrived?
> 
> An interrupt can occur when a frame capture finishes. Unless I set the board 
> to not generate interrupts...
> 
>> Or is the update continously going on? 
> It can be set to syncronous or asyncronous mode...
> 
>> How does an application know if a frame is up-to-date, is currently
>> being updated, or whatever? Sorry, I never worked with such hardware
>> before and only have a rough idea of it.
> By reading the registers in the PCI board the driver can get the acquire 
> status (capturing, finished, etc).

... and single this event by unblocking some potentially waiting user
space, which was blocked in some related IOCTL of your driver. So, as
Jeroen suggested as well, let the user register two or more exchange
buffers, set up a shared memory region, and provide in IOCTL interface
to inform the user about updates.

> 
> Well, let me explain what my problem is. I'm developing a framework for 
> developing rt applications for mobile robots. OROCOS seemed too complex for 

Welcome to the club - we are working on the same topic at my institute.

> me... For testing the framework I built a simple robot with an optical 
> encoder on the weels. I developed an odometry system based on the encoder 
> sensors that worked well. I would like to write an application that does 
> position and speed control by using the images taken by the framegrabber and 
> compare the result with the odometry system for making a conceptual proof of 
> my framework for my master-thesis work.

Sounds very interesting. Would be interesting to hear, when this works,
what precision can be achieved with your hardware.

> 
> I'd like to thank for all support you, Jeroen and Gilles are giving me.
> 
> Rodrigo.
> 
> 

Jan


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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-13 19:57         ` Jan Kiszka
@ 2006-01-13 21:53           ` Rodrigo Rosenfeld Rosas
  2006-01-13 22:29             ` Jan Kiszka
  0 siblings, 1 reply; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-13 21:53 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

>> How could I
>> share this memory with userspace RT-programs in a deterministic way?
>Set up the memory mapping between kernel and user space during (non-rt)
>initialisation. This means that you have to create some mapping from the
>physical block into the user space address range. I think
>remap_pfn_range() or io_remap_page_range() should do this after mapping
>the physical memory into the address space of the kernel (ioremap()).
>But I suggest LDD3 on this topic as a better reference.

Of course. You are right. I will only need this at initialization so I 
shouldn't bore about that.

>> I can't understand why sharing that memory should be so complex...
>
>As long as it's static, it's trivial. But as soon as you have to
>synchronise with potential changes of your process' mm, it starts to
>cause problems. Again, the concept of setting up the mapping during
>non-rt init of your driver and then using it in RT context is safe.

Right.

>> By reading the registers in the PCI board the driver can get the acquire
>> status (capturing, finished, etc).
>
>... and single this event by unblocking some potentially waiting user
>space, which was blocked in some related IOCTL of your driver.

Sorry, I didn't understand this phrase... My ioctl's never block...

>So, as Jeroen suggested as well, let the user register two or more exchange
>buffers, set up a shared memory region, and provide in IOCTL interface
>to inform the user about updates.

Do you mean by using polling or by a more efficient mechanism? I mean, how can 
I use an IOCTL interface like a condition variable?

>> Well, let me explain what my problem is. I'm developing a framework for
>> developing rt applications for mobile robots. OROCOS seemed too complex
>> for
>
>Welcome to the club - we are working on the same topic at my institute.

:)

>> me... For testing the framework I built a simple robot with an optical
>> encoder on the weels. I developed an odometry system based on the encoder
>> sensors that worked well. I would like to write an application that does
>> position and speed control by using the images taken by the framegrabber
>> and compare the result with the odometry system for making a conceptual
>> proof of my framework for my master-thesis work.
>
>Sounds very interesting. Would be interesting to hear, when this works,
>what precision can be achieved with your hardware.

I'll let you know when I finish it -- if I finish! ;)

Best regards,

Rodrigo.

	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-13 21:53           ` Rodrigo Rosenfeld Rosas
@ 2006-01-13 22:29             ` Jan Kiszka
  2006-01-17 14:33               ` Rodrigo Rosenfeld Rosas
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2006-01-13 22:29 UTC (permalink / raw)
  To: Rodrigo Rosenfeld Rosas; +Cc: xenomai

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

Rodrigo Rosenfeld Rosas wrote:
>>> How could I
>>> share this memory with userspace RT-programs in a deterministic way?
>> Set up the memory mapping between kernel and user space during (non-rt)
>> initialisation. This means that you have to create some mapping from the
>> physical block into the user space address range. I think
>> remap_pfn_range() or io_remap_page_range() should do this after mapping
>> the physical memory into the address space of the kernel (ioremap()).
>> But I suggest LDD3 on this topic as a better reference.
> 
> Of course. You are right. I will only need this at initialization so I 
> shouldn't bore about that.
> 
>>> I can't understand why sharing that memory should be so complex...
>> As long as it's static, it's trivial. But as soon as you have to
>> synchronise with potential changes of your process' mm, it starts to
>> cause problems. Again, the concept of setting up the mapping during
>> non-rt init of your driver and then using it in RT context is safe.
> 
> Right.
> 
>>> By reading the registers in the PCI board the driver can get the acquire
>>> status (capturing, finished, etc).
>> ... and single this event by unblocking some potentially waiting user
>> space, which was blocked in some related IOCTL of your driver.
> 

Bah, once again:

"... and *signal* this event by unblocking some potentially waiting user
space *task*, which was blocked in a related IOCTL of your driver."

> Sorry, I didn't understand this phrase... My ioctl's never block...

In case you want synchronous frame access, you can create an IOCTL that
blocks until the hardware signals the arrival of a new one via an IRQ.
Of course, if you design an asynchronous interface, your IOCTL(s) may
only be used to switch the current buffer.

> 
>> So, as Jeroen suggested as well, let the user register two or more exchange
>> buffers, set up a shared memory region, and provide in IOCTL interface
>> to inform the user about updates.
> 
> Do you mean by using polling or by a more efficient mechanism? I mean, how can 
> I use an IOCTL interface like a condition variable?

By using one of RTDM's services in your driver's IOCTL handler,
typically either a semaphore or an event. See the Xenomai API doc for
details - and have a look at the existing drivers...

> 
>>> Well, let me explain what my problem is. I'm developing a framework for
>>> developing rt applications for mobile robots. OROCOS seemed too complex
>>> for
>> Welcome to the club - we are working on the same topic at my institute.
> 
> :)
> 
>>> me... For testing the framework I built a simple robot with an optical
>>> encoder on the weels. I developed an odometry system based on the encoder
>>> sensors that worked well. I would like to write an application that does
>>> position and speed control by using the images taken by the framegrabber
>>> and compare the result with the odometry system for making a conceptual
>>> proof of my framework for my master-thesis work.
>> Sounds very interesting. Would be interesting to hear, when this works,
>> what precision can be achieved with your hardware.
> 
> I'll let you know when I finish it -- if I finish! ;)

That's just a question of (re-)defining the goal when necessary. :)

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

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

* Re: [Xenomai-help] PCI Framegrabber real-time driver
  2006-01-13 22:29             ` Jan Kiszka
@ 2006-01-17 14:33               ` Rodrigo Rosenfeld Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Rodrigo Rosenfeld Rosas @ 2006-01-17 14:33 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

>>... how can I use an IOCTL interface like a condition variable?
>
>By using one of RTDM's services in your driver's IOCTL handler,
>typically either a semaphore or an event. See the Xenomai API doc for
>details - and have a look at the existing drivers...

Thank you. I'll take a better look on RTDM.

>> ... I'll let you know when I finish it -- if I finish! ;)
>
>That's just a question of (re-)defining the goal when necessary. :)

Maybe you're right, but I don't think my advisor will agree :)

I think now it's time to put in practice what we've been discussing. When I 
get some results we return to this topic. Now, I'm concerned about how to use 
C++ on the framework. I mean, how can I allocate memory in a time bounded way 
in the robot and sensor classes with C++? I know I can't use libstdc++ and 
took a look at xeno-- but I didn't like the idea of using exceptions instead 
of returning some value, except for the new operator. It seems to me that it 
becomes too dificult to estimate the time between the exception is thrown to 
the time it is catched, as stated in EC++ 
(http://www.caravan.net/ec2plus/rationale.html).

Any ideas are welcome.

Thank you,

Rodrigo.

P.S: I couldn't send this message yesterday due to a break in the Internet 
system here.

	

	
		
_______________________________________________________ 
Yahoo! doce lar. Faça do Yahoo! sua homepage. 
http://br.yahoo.com/homepageset.html 




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

end of thread, other threads:[~2006-01-17 14:33 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-11 18:55 [Xenomai-help] PCI Framegrabber real-time driver Rodrigo Rosenfeld Rosas
2006-01-11 19:48 ` Jan Kiszka
2006-01-11 21:21   ` Rodrigo Rosenfeld Rosas
2006-01-11 22:23     ` Gilles Chanteperdrix
2006-01-12 19:47       ` Rodrigo Rosenfeld Rosas
2006-01-11 22:31     ` Jan Kiszka
     [not found]       ` <1137032878.43c5beae139f5@domain.hid>
2006-01-12  9:29         ` Jan Kiszka
2006-01-13 14:24       ` Rodrigo Rosenfeld Rosas
2006-01-13 19:57         ` Jan Kiszka
2006-01-13 21:53           ` Rodrigo Rosenfeld Rosas
2006-01-13 22:29             ` Jan Kiszka
2006-01-17 14:33               ` Rodrigo Rosenfeld Rosas
  -- strict thread matches above, loose matches on Subject: below --
2006-01-13 15:11 Rodrigo Rosenfeld Rosas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.