Jump to content
  • 0

Zybo RAM not clearing on startup, having trouble writing to it


aytli

Question

Short version: I have reason to believe that my RAM isn't clearing on startup. It seems to retain its old value even when I reset, reprogram, or power cycle my board. I'm also having trouble writing data to arrays.

I'm working on an HDMI processor with a Zybo Z7-10 board, and I'm trying to overlay some images on my HDMI output. The images are read from an sd card on startup, and stored in the following array, where IMG_SIZE_PIXELS is 74*86*4.

static uint8_t digits[10][IMG_SIZE_PIXELS] __attribute__((aligned(0x20)));

My block diagram has a video mixer core connected between the video dma and the video output. I can write images to the layers inside the video mixer, and then enable/disable the layers to show/hide the images. This configuration worked, I was able to load my images from the sd card, display them on the output screen (below), and even change it on the fly.

Spoiler

IMAGE1.jpg.55c2fcba1da6de506aa56a802afc1010.jpg

I then declared a new array and initialized it by looping through every element and setting it to 0. I then wrote it to one of my video layers.

static uint8_t asdf[IMG_SIZE_PIXELS] __attribute__((aligned(0x20)));

for (i = 0; i < IMG_SIZE_PIXELS; i += 4)
{
    asdf[i + 0] = 0;
    asdf[i + 1] = 0;
    asdf[i + 2] = 0;
    asdf[i + 3] = 0;
}

The resulting image (below) is a noisy version of the original image, loaded from the sd card. Even when i completely disabled the sd card code, physically removed the sd card, and even power cycled the board, I can still see the old image. I expect to see a black block, since I set all the elements of the array to 0. According to the debugger, every element of this array was indeed set to 0. It seems like the old image data was written to some form of non volatile memory.

When I try running the code what reads the images from the sd card and outputs it to the screen, it seems to work fine. If I disable that code and write my own array that I've initialized to all zeros, it still outputs the old image.

Spoiler

IMAGE2.jpg.954aa6e5048b41d1de8646cdcd23a0ef.jpg

One thing I should mention is that I've greatly increased the size of my stack and heap to 0xFFFFF and 0xFFFF respectively. Although the stack and heap both live in RAM, and shouldn't write to any form of non volatile memory.

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

@aytli,

There are two behaviors you are questioning: initialization upon reset and caching. Initialization has both a hardware and a software component to it. By RAM I assume you are referring to DDR3. The content of DDR3 memories are undefined after a power-down event. It could be random data or Mona Lisa, with the latter having a negligible chance. The software component in this case is governed by the specifications of the C language referring to initialization of variables. For example:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.  If an object that has static storage duration is not initialized explicitly , then: —if it's as pointer type, it is initialized to a null pointer; —if it's an arithmetic type, it is initialized to (positive or unsigned) zero; —if it is an aggregate, every member is initialized (recursively) according to these rules; —if it is a union, the first named member is initialized (recursively) according to these rules.

Your digits variable has static storage duration so it is initialized to zero by the loader or the C runtime. According to your debugger this was implemented.

Your issues must stem from a caching behavior. You have two masters accessing the memory: processor and video DMA. The processor goes through a D-cache, while the DMA has direct access. This means that the two master's view of the memory is not the same: the DMA is not seeing what you are writing in software, because data is held in the cache instead of written out to memory. Do a D-cache flush after writing the frame buffer from software to commit the new values to the memory. The header xil_cache.h has a Xil_DCacheFlush function declared in it.

 

Link to comment
Share on other sites

I just started a project where I write images to DDR3 using software on the ARM. C code is below. SPRITES_OFFSET is 0x02100000 and is the same value used in Verilog to access the image tiles, ensure that in the .ld linker script this is outside of the range of memory used for the CPU. Xil_DCacheFlush(); is important at the end to commit the writes to DDR3 since the ARM processor has cache. We are seeing the same issue where if the ARM does not write to the frame buffer and I just display it then it will show old data but noisy even after power cycling. This is because DDR3 holds some data but corrupted even when not powered for short amount of time.

u8* pixel = SPRITES_OFFSET;

    for (major_row = 0; major_row < 29; major_row++) {
        for (major_col = 0; major_col < 23; major_col++) {
            for (minor_row = 0; minor_row < 32; minor_row++) {
                for (minor_col = 0; minor_col < 32; minor_col++) {

                    x = minor_col + 32*major_col;
                    y = minor_row + 32*major_row;

                    unsigned char r = *(unsigned char*) (rgb + (y*width*4) + (x*4));
                    unsigned char g = *(unsigned char*) (rgb + (y*width*4) + (x*4) + 1);
                    unsigned char b = *(unsigned char*) (rgb + (y*width*4) + (x*4) + 2);
                    unsigned char a = *(unsigned char*) (rgb + (y*width*4) + (x*4) + 3);

                    *(u8*)(pixel)     = (u8)r;
                    *(u8*)(pixel + 1) = (u8)g;
                    *(u8*)(pixel + 2) = (u8)b;
                    *(u8*)(pixel + 3) = (u8)a;

                    pixel += 4;
                    //xil_printf("R:%d G:%d B:%d A:%d \r\n", r,g,b,a);
                }
            }
        }
    }
    Xil_DCacheFlush();

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...