PCI DMA

I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

  2. In task A, start a capture, using the physical address from (1) and the
    index of a buffer to provide an address to receive the DMA.

  3. In task B, map the buffer area using the physical address from (1) into
    the task address space, using /dev/shmem/Physical.

  4. When an image is captured in a buffer, task A sends the buffer index to
    B, which then uses it to index into the memory map from (3) to get at the
    image data.

Does this sound like it would work? Is there a better way?

Thanks,

Kevin

“Kevin Miller” <kevin.miller@transcore.com> wrote in message
news:cdhhl3$pur$1@inn.qnx.com

I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

  2. In task A, start a capture, using the physical address from (1) and the
    index of a buffer to provide an address to receive the DMA.

  3. In task B, map the buffer area using the physical address from (1) into
    the task address space, using /dev/shmem/Physical.

  4. When an image is captured in a buffer, task A sends the buffer index to
    B, which then uses it to index into the memory map from (3) to get at the
    image data.

Does this sound like it would work? Is there a better way?

Sounds good to me.

Thanks,

Kevin

Kevin Miller <kevin.miller@transcore.com> wrote:

I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

Do you need physically contiguous buffers?

Take a look at /etc/readme/technotes/shmem.txt.

qnx_segment_alloc_flags() is the recommended way to get DMA safe
buffers.

qnx_segment_info() is used to get the physical address of the segment.

mmap() is used to get a virtual pointer to that memory inside your
process.


  1. In task A, start a capture, using the physical address from (1) and the
    index of a buffer to provide an address to receive the DMA.

  2. In task B, map the buffer area using the physical address from (1) into
    the task address space, using /dev/shmem/Physical.

  3. When an image is captured in a buffer, task A sends the buffer index to
    B, which then uses it to index into the memory map from (3) to get at the
    image data.

Does this sound like it would work? Is there a better way?

Yup, sounds quite reasonable.

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com

Thanks for the replies. qnx_segment_raw_alloc() is documented to return
contiguous memory, so I think I’m covered there. I have yet to receive the
full hardware specs from the manufacturer, so there may be other limitations
on the memory that I will have to satsify. This is a good start, though.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:cdjd0c$a2i$1@inn.qnx.com

Kevin Miller <> kevin.miller@transcore.com> > wrote:
I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

Do you need physically contiguous buffers?

Take a look at /etc/readme/technotes/shmem.txt.

qnx_segment_alloc_flags() is the recommended way to get DMA safe
buffers.

qnx_segment_info() is used to get the physical address of the segment.

mmap() is used to get a virtual pointer to that memory inside your
process.


2) In task A, start a capture, using the physical address from (1) and
the
index of a buffer to provide an address to receive the DMA.

  1. In task B, map the buffer area using the physical address from (1)
    into
    the task address space, using /dev/shmem/Physical.

  2. When an image is captured in a buffer, task A sends the buffer index
    to
    B, which then uses it to index into the memory map from (3) to get at
    the
    image data.

Does this sound like it would work? Is there a better way?

Yup, sounds quite reasonable.

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com

Kevin Miller wrote:

Thanks for the replies. qnx_segment_raw_alloc() is documented to return
contiguous memory, so I think I’m covered there. I have yet to receive the
full hardware specs from the manufacturer, so there may be other limitations
on the memory that I will have to satsify. This is a good start, though.

If your process dies holding this memory, it is not returned to the
system when allocated via qnx_segment_raw_alloc() - buyer beware!


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>

“Adam Mallory” <amallory@qnx.com> wrote in message
news:cdjn1c$hp1$1@inn.qnx.com

Kevin Miller wrote:
Thanks for the replies. qnx_segment_raw_alloc() is documented to return
contiguous memory, so I think I’m covered there. I have yet to receive
the
full hardware specs from the manufacturer, so there may be other
limitations
on the memory that I will have to satsify. This is a good start, though.

If your process dies holding this memory, it is not returned to the system
when allocated via qnx_segment_raw_alloc() - buyer beware!

And for ISA device it doesn’t ensure memory is located below 16M


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net

Mario Charest wrote:

And for ISA device it doesn’t ensure memory is located below 16M

Sure, but this is for PCI DMA.


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>

An interesting aspect of the PCI controller on this board is that it has an
MMU in addition to a DMA controller. You can allocate a bunch of 64k buffers
in virtual memory, remembering their physical addresses in the MMU. The DMA
controller can then be set to do virtual-to-physical address translation on
the fly, with no further intervention by the CPU. I don’t plan on using this
feature, since QNX makes easy to use straight physical memory, but it’s kind
of a neat thing nonetheless.

“Kevin Miller” <kevin.miller@transcore.com> wrote in message
news:cdhhl3$pur$1@inn.qnx.com

I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

  2. In task A, start a capture, using the physical address from (1) and the
    index of a buffer to provide an address to receive the DMA.

  3. In task B, map the buffer area using the physical address from (1) into
    the task address space, using /dev/shmem/Physical.

  4. When an image is captured in a buffer, task A sends the buffer index to
    B, which then uses it to index into the memory map from (3) to get at the
    image data.

Does this sound like it would work? Is there a better way?

Thanks,

Kevin

Kevin Miller <kevin.miller@transcore.com> wrote:

Thanks for the replies. qnx_segment_raw_alloc() is documented to return
contiguous memory, so I think I’m covered there. I have yet to receive the
full hardware specs from the manufacturer, so there may be other limitations
on the memory that I will have to satsify. This is a good start, though.

I would avoid that one – as Adam said, it never returns the memory to the
OS free pool. This means, if you’re debugging and the programming crashes,
you’ve burnt that memory. Will force you to reboot to get it back – not
a fun thing.

I’d recommend going with qnx_segment_alloc_flags().

-David


“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:cdjd0c$a2i$> 1@inn.qnx.com> …
Kevin Miller <> kevin.miller@transcore.com> > wrote:
I have a PCI image capture card, and I want to use its DMA controller to
transfer the images into memory. This is what I thought I would try:

  1. qnx_segment_raw_alloc() the memory for an array of buffers, about 5
    mbytes total.

Do you need physically contiguous buffers?

Take a look at /etc/readme/technotes/shmem.txt.

qnx_segment_alloc_flags() is the recommended way to get DMA safe
buffers.

qnx_segment_info() is used to get the physical address of the segment.

mmap() is used to get a virtual pointer to that memory inside your
process.


2) In task A, start a capture, using the physical address from (1) and
the
index of a buffer to provide an address to receive the DMA.

  1. In task B, map the buffer area using the physical address from (1)
    into
    the task address space, using /dev/shmem/Physical.

  2. When an image is captured in a buffer, task A sends the buffer index
    to
    B, which then uses it to index into the memory map from (3) to get at
    the
    image data.

Does this sound like it would work? Is there a better way?

Yup, sounds quite reasonable.

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com


Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com