Difference between revisions of "Circbuf"

From ElphelWiki
Jump to: navigation, search
Line 22: Line 22:
  
 
The buffer is circular, so before 0 there is 0x4b7fff - last long word in the buffer). In this example FPGA compressed frame starting from the very beginning of the circbuf, bit stream is 0x378fe bytes long (as written in the 0x00de47 - OR-ed with 0xff000000) and it ends in the long word 0xde3f : "cc 03 0b d3 ... 1c 0e f4 6a 3b 00"
 
The buffer is circular, so before 0 there is 0x4b7fff - last long word in the buffer). In this example FPGA compressed frame starting from the very beginning of the circbuf, bit stream is 0x378fe bytes long (as written in the 0x00de47 - OR-ed with 0xff000000) and it ends in the long word 0xde3f : "cc 03 0b d3 ... 1c 0e f4 6a 3b 00"
 +
 +
Timestamp - seconds=0x46ff4a82 and microseconds=000303bd are stored in the 0xde45 and 0xde46 - right before the bitstream length.
 +
Internal Etrax DMA ponter (circbuf write pointer) is now equal 0xde50 so the next frame will be acquired starting from that word. Data in the range 0xde48..0xde4f is garbage (you can see remnants from the other frame acquired starting from the same address 0x0 - "46ff4a81  000a1930  ff037929"). Actually FPGA already had sent 32 bytes (8 long words) of zeros - they are now in the ETRAX DMA buffer and will be written to 0xde48..0xde4f as soon as FPGA will start sending the next frame from address 0xde50. So the 32-byte spare area ''after'' (address-wise) the frame (it is used to make sure that all the current frame data, including timestamp+length is actually written to the system memory when the frame is finished without explicit flushing of the DMA buffer) can not be used, but it is possible to use it ''preceding'' the frame, and this is what is now implemented in the firmware of the 353 camera.
 +
 +
The interrupt service routine [http://elphel.cvs.sourceforge.net/elphel/elphel353-2.10/os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/cc353.c?view=markup arch/cris/arch-v32/drivers/elphel/cc353.c::camSeq_interrupt] is responsible for
 +
*updating software pointer (JPEG_wp) after each new frame is compressed to match the location where next frame bitstream will be output,
 +
*copying the bitstream length before the frame itself (no simplify traversing frames) - it is now at 0x4b7fff (copied from 0xde4f lower 24 bits)
 +
*writing 2 of the 0xff bytes just before the length as a marker of valid frame header (incoming compressed bitstream data will never have 2 0xffs, and the microsecond high byte, that might be written at that location is always 0)
 +
*filling in the 26 byte remaining area right before the last frame acquired - it is now safe until the whole buffer will be filled with image data. In the example above it starts at 0x4b7ff8.
 +
 +
This area is used to store essential data related to particular frame acquisitio
 +
*filling in the 8 word area right before the last frame acquired - it is now safe until the whole buffer will be filled with image data. In the example above it is 0x4b7ff8-0x4b7fff

Revision as of 10:12, 30 September 2007

Overview

Elphel cameras use FPGA to compress images and video, the compressed frames are transferred from the FPGA to the system memory through pseudo-DMA channel implemented in the CPU (Axis Etrax FS). It is "pseudo" as physically the data still goes (over the system bus) from the FPGA to the CPU chip, buffered there in small chunks and then sent to the system memory. Overall on average it takes 5 bus cycles (100MHz clock) to transfer one 32-bit word (4 bytes) of data from the FPGA to the system memory - 80MB/sec. There are hardware provisions in the model 353 to support new feature of ETRAX FS (not available in earlier ETRAX 100LX used in Elphel earlier models 303,313,323 and 333 cameras) - allowing external device (FPGA in our case) to become the bus master. That can allow to increase the data rate to virtually full 400MB/sec (in large bursts), but no FPGA code is yet developed to support this mode.

Circular buffer in Elphel 353 camera

The compressed frames are stored in a large circular buffer, it is done similar in the previous cameras and with other compressor (Ogg Theora) but the following description applies to the current state of the firmware (7.1.0.1) of the model 353 camera with JPEG compressor (Theora branch is not ported yet as of September 2007). Currently buffer size - CCAM_DMA_SIZE is ~19MB as defined in include/asm-cris/elphel/c313a.h).

All DMA transfers are 32-bytes aligned (32 bytes is a size of the internal DMA buffer in Etrax), and the data received from the FPGA contains JPEG-encode bit stream -- everything between SOF and EOF tags, no header, all 0xff data bytes escaped by appropriate 0x00 codes as required by the standard, so no 2 0xff bytes can appear together - this fact is used to find out if the data in the circular buffer was overwritten by the newer image frames.

When FPGA outputs the whole frame (it does not know the frame size in advance, only after compression is over) it adds 12 more bytes (3 long words), aligning them to the end of the 32-byte chunk, adding zeros before the data if needed. The last 4 bytes contain a 24-bit byte length of the JPEG data with the high byte set to 0xff. 8 bytes before (2 long words) have timestamp of the frame exposure start - seconds from epoch and microseconds.

The following listing has a sample of the buffer data (generated by the /usr/local/bin/test_mmap:

4b7ff8:  000000a4  06000800  016c0120  0a3946c1  01ab010a  40404040  ffff0000  000378fe
000000: {d30b03cc} 8af1dc34  a5875e77  9d4cf334  204db683  b1533cc7  c59f949e  36b1af45
000008:  90e20102  5e9ad7f1  f68cd273  130a1dc5  7e50641c  41bd14ef  140720c5  73c0e02e
...
00de38:  20a50766  4e433fc9  7614f51c  087bd2e4  988ee64e  cdf41ca0  6af40e1c  0000003b
00de40:  00000000  00000000  00000000  00000000  00000000  46ff4a82  000303bd <ff0378fe>
00de48:  f6285e9f  aeacb0a5  00000000  00000000  00000000  46ff4a81  000a1930  ff037929
00de50: [00000000] 00000000  00000000  00000000  00000000  00000000  00000000  00000000

The buffer is circular, so before 0 there is 0x4b7fff - last long word in the buffer). In this example FPGA compressed frame starting from the very beginning of the circbuf, bit stream is 0x378fe bytes long (as written in the 0x00de47 - OR-ed with 0xff000000) and it ends in the long word 0xde3f : "cc 03 0b d3 ... 1c 0e f4 6a 3b 00"

Timestamp - seconds=0x46ff4a82 and microseconds=000303bd are stored in the 0xde45 and 0xde46 - right before the bitstream length. Internal Etrax DMA ponter (circbuf write pointer) is now equal 0xde50 so the next frame will be acquired starting from that word. Data in the range 0xde48..0xde4f is garbage (you can see remnants from the other frame acquired starting from the same address 0x0 - "46ff4a81 000a1930 ff037929"). Actually FPGA already had sent 32 bytes (8 long words) of zeros - they are now in the ETRAX DMA buffer and will be written to 0xde48..0xde4f as soon as FPGA will start sending the next frame from address 0xde50. So the 32-byte spare area after (address-wise) the frame (it is used to make sure that all the current frame data, including timestamp+length is actually written to the system memory when the frame is finished without explicit flushing of the DMA buffer) can not be used, but it is possible to use it preceding the frame, and this is what is now implemented in the firmware of the 353 camera.

The interrupt service routine arch/cris/arch-v32/drivers/elphel/cc353.c::camSeq_interrupt is responsible for

  • updating software pointer (JPEG_wp) after each new frame is compressed to match the location where next frame bitstream will be output,
  • copying the bitstream length before the frame itself (no simplify traversing frames) - it is now at 0x4b7fff (copied from 0xde4f lower 24 bits)
  • writing 2 of the 0xff bytes just before the length as a marker of valid frame header (incoming compressed bitstream data will never have 2 0xffs, and the microsecond high byte, that might be written at that location is always 0)
  • filling in the 26 byte remaining area right before the last frame acquired - it is now safe until the whole buffer will be filled with image data. In the example above it starts at 0x4b7ff8.
This area is used to store essential data related to particular frame acquisitio
  • filling in the 8 word area right before the last frame acquired - it is now safe until the whole buffer will be filled with image data. In the example above it is 0x4b7ff8-0x4b7fff