We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
---------------------------------------------------------------------------------------------- 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. :(
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.
Thank you very much for your quick response.
RE: Indeed, I use IMG_WIDTH, IMG_HEIGHT, PRO_IMG_WIDTH and PRO_IMG_HEIGHT these four defined names, but they are defined as the same value which is 120 in my program. In other words, the two dimensions of the 2-D array are fixed and exactly the same (120).
RE: U're right, I indeed use JLINK to step into my function and check the passing parameters, and only to find that the address is fixed to 0x00000000.
Again, thank you for your quick response, hope that I can get your further guidance.
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.
RE: I am sure that the assembly language translated by KEIL stored the address of the image-buffer's address to register R0 and R1, and I do know it will take many instructions before entering / leaving a sub-function. I just cannot understand how could my function not be able to fetch the passing parameters. Really wish to get answers and lessons from you.
Michael Zhou
but they are defined as the same value which is 120 in my program. Not only are they currently the same value, they have to stay that way forever, or your program would fail even more spectacularly than it already does. So what do you think you can possibly gain by having 4 different names for the same number? At least 2 of those 4 serve no discernible purpose other than making your program harder to understand for everybody who ever has to work with it, most importantly yourself.
I already changed the declaration, now these three arrays are defined clearly with the dimension 120, and of course, the 2-d array parameter process function is also changed:
Process(uint8_t Array_1[][120], Array_2[][120])
However, the function still cannot fetch the array I passed to it.
Can you help to guide me the possible problems? I will continue to dig this weird phenomenon.
Thanks.
I think you have entirely missed the point there!
That's possibly more of a maintenance nightmare than the original!
Sorry for my mis-typing, the process function is described as below:
Process(uint8_t Array_1[][PRO_IMG_HEIGHT], uint8_t Array_2[][PRO_IMG_HEIGHT])
So you still have multiple #defines for the same same value?
No, now I am only using one defined name which is PRO_IMG_WIDTH, but the problem still exists.
Can you explain the possibilities that may cause this problem?
Should be PRO_IMG_HEIGHT which is defined as 120, sorry for my mistyping since my brain is in chaos now.
Post a minimal complete program that can be built to reproduce your issue.
Thank you very much for your response, I will go to lab tomorrow to set up a simple test code, and if the problem re-occurred, I will let you know.
Michael