This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Pass 2-D array to a function is invalid

----------------------------------------------------------------------------------------------
It is really a strange problem and I wish that I could describe my problem clearly in order to get assistance.

I am using STM32F407VG (RAM: 128K without 64K CCM) to develop a vision-based project using a camera sensor, and I create three 2-D arrays(120x120) in one C source file (SRC_A.c):

uint8_t Image_Buffer_1[IMG_WIDTH][IMG_HEIGHT];
uint8_t Image_Buffer_2[IMG_WIDTH][IMG_HEIGHT];
uint8_t Image_Buffer_3[IMG_WIDTH][IMG_HEIGHT];

And in SRC_A.h, I define both IMG_WIDTH and IMG_HEIGHT as 120.

I need to process two of these buffers in another function: Process(uint8_t Array_1[][PRO_IMG_WIDTH], uint8_t Array_2[][PRO_IMG_HEIGHT])
which is located in SRC_B.c, similarly, I also define PRO_IMG_WIDTH and PRO_IMG_HEIGHT as 120, meanwhile, in SRC_A.h, I "externed" these three buffers and call function "Process" in the main function (MAIN.c) like this:

Process( Image_Buffer_1, Image_Buffer_2 );

The result was abnormal, so I used JLINK Hardware Simulator to debug only to find that the array cannot be passed to this function which is funny because the assembly language clearly shows that the address of these two buffers are moved to register R0 and R1 before "BX Process", but when I traced into this function and watch the function's parameters "Array_1" and "Array_2", they owned the same wrong address : "0x00000000".

I really don't know why, but I changed the definition of these three arrays without length definition like this:

uint8_t Image_Buffer_1[120][120];
uint8_t Image_Buffer_2[120][120];
uint8_t Image_Buffer_3[120][120];

And it worked! Though the problem was solved, but I still couldn't understand, I hope that I can get support in KEIL forum.

----------------------------------------------------------------------------------------------

Another problem happened just now. In order to clarify the firmware architecture, I want to separate the lowest hardware driver and upper applications, so I moved some application functions which are previously located in IMAGE data acquiring driver (via DCMI interface, using DMA Double Buffer Mode to fill image data to three buffers I mentioned above) to another application file which is relevant to data process. And another weird problem occurred: Previously I used USART DMA to transfer the content of the Image_Buffer_1 or 2 or 3, and I can get one complete frame, however, after these functions moved, I got a misplaced image (90% is OK while the other 10% which should be in the left of 90% but now in the right of 90% .. :( ).

It drove me into crazy, so I defined all these three buffers in another way:

uint8_t Image_Buffer_n[120][120] __attribute__((aligned(8)));

And it worked, the image is complete without misplacement again! But the old problem occurred once again! 2D array could not be passed to the function "Process(uint8_t Array_1[][PRO_IMG_WIDTH], uint8_t Array_2[][PRO_IMG_HEIGHT])" I mentioned above.

I've no choice but to keep the worked version of my firmware, really need the assistance and guidance from specialists of KEIL. :(

Parents
  • So you have not just two, but three independently defined names (IMG_HEIGHT, PRO_IMG_WIDTH and PRO_IMG_HEIGHT) for the size of the second dimension of your 2D array, yet your program just blindly assumes that all these are the same value. Do you really think that's wise?

    Process(uint8_t Array_1[][PRO_IMG_WIDTH], uint8_t Array_2[][PRO_IMG_HEIGHT])
    

    How do you expect that to work? The same dimension of the same image can hardly be width one time, and height the second, or can it?

    but when I traced into this function and watch the function's parameters "Array_1" and "Array_2", they owned the same wrong address : "0x00000000".

    That may mean a lot less than you fear. You'll have to step into that function for a bit before you can reliably conclude that it doesn't manage to fetch its parameters. Function entry / exit sequences take a couple of instructions.

Reply
  • So you have not just two, but three independently defined names (IMG_HEIGHT, PRO_IMG_WIDTH and PRO_IMG_HEIGHT) for the size of the second dimension of your 2D array, yet your program just blindly assumes that all these are the same value. Do you really think that's wise?

    Process(uint8_t Array_1[][PRO_IMG_WIDTH], uint8_t Array_2[][PRO_IMG_HEIGHT])
    

    How do you expect that to work? The same dimension of the same image can hardly be width one time, and height the second, or can it?

    but when I traced into this function and watch the function's parameters "Array_1" and "Array_2", they owned the same wrong address : "0x00000000".

    That may mean a lot less than you fear. You'll have to step into that function for a bit before you can reliably conclude that it doesn't manage to fetch its parameters. Function entry / exit sequences take a couple of instructions.

Children