cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
stgateizo
Voyager
Voyager
765 Views
Registered: ‎10-07-2016

Malloc returns null pointer after Microblaze reset

Jump to solution

Dear Xilinx experts,

I have a Microblazesystem in my design, where the instruction code and data is stored in BRAMS as shown below.

 

stgateizo_0-1625126122145.png

The mb_reset_100 and the bus_struct_reset_100 signals are driven by a Processor System Reset IP-core, which in turn can be reset from an external input pin.

When I use this external reset signal to reset the whole system, the Microblaze starts executing the instruction code from the beginning. so far so good.
But when the following code line is executed I do not get a valid pointer, instead I get a null pointer:

InstancePtr->InstancePtr = malloc(sizeof(XClk_Wiz));

But when I load the FPGA from FLASH, or when I download the FPGA Bitfile and ELF file via Vitis over JTAG, then I get a valid pointer.

Does anybody know the reason for this behavior.

Kind regards

stgateizo

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
stgateizo
Voyager
Voyager
265 Views
Registered: ‎10-07-2016

Hello jmeador,

thank you for sending me this link. The two methods are interresting. I think Method2 is more ore less the same as the memcpy command which we have discussed in this post. In the meantime I got also an answer from Xilinx, since I have created a service request for this issue. Xilinx says, that the missing __data_load parameter in the linker script is not a bug. The __data_load parameter was added by hand in the linker script and will not be added by default when you create a new SDK or Vitis project. But when I use the linker script from the SDK project in the Vitis project, the __data_load parameter will be found, and the Vitis compiler will no longer throw an error at teh memcpy command.

So I have a solution for now, but its a bit strange that you have to dive very deeply into the linker script in order to reset the microblaze properly !

That is not very user friendly and took me a lot of time, just to properly reset the Microblaze, but we know, that is Xilinx...

Kind regards

stgateizo

View solution in original post

0 Kudos
12 Replies
joancab
Teacher
Teacher
757 Views
Registered: ‎05-11-2015

is that sizeof(XClk_Wiz) non-zero?

0 Kudos
stgateizo
Voyager
Voyager
753 Views
Registered: ‎10-07-2016

The XClk_Wiz structure looks like below:

stgateizo_0-1625127386429.png

So it is defenitely not zero...

 

0 Kudos
stgateizo
Voyager
Voyager
742 Views
Registered: ‎10-07-2016

I think it has soemthing to do with the content (instruction code, data, heap, stack) in the BRAM. When I flash the FPGA, the BRAM will be reset to zeros, before the elf file will be downloaded. But when I reset the Microblaze, the BRAM will not be reset. So all content will reamin (otherwise the instruction code would be lost). Therefore all data in the BRAM, like isntruction code, data, heap, and stack still reamins, and has probably some influence on this. The question is, how can I reset the Microblaze system properly, without loosing the instructioncode in the BRAMs?

I think I'm not the only one who want to do this?

Kind regards

stgateizo

0 Kudos
stgateizo
Voyager
Voyager
691 Views
Registered: ‎10-07-2016

One in addition,

when I search for this problem in google, I can find 2 reasons why there will be returned a null pointer.

1) Either the sizeof(XClk_Wiz) is zero, which is probably not the case, or

2) There is not enough memory, which sounds to me more logical.

I assume that the malloc function will reserve space in the heap, which is located in the BRAM. The heap size is set to 0x1000 in the linker script. But what happens if the heap is not cleared with the reset? How does the Microblaze react on such a situation? Will the Microblaze reserve space a second time when it executes the malloc function???

Kind regards

stgateizo

 

 

 

 

0 Kudos
joancab
Teacher
Teacher
659 Views
Registered: ‎05-11-2015

The second option makes sense, although I would expect a reset to also reset any allocated memory.

Could you try some command checking the allocated memory (I'm just supposing there is one) before the malloc? Then I would expect to return 0 after a 'good' reset and other number after the 'bad' reset.

PS: Because you are using Microblaze with an external, independent memory, a soft reset I think it just resets the processor stuff and I'd assume the heap size and pointers to free heap address are kept somewhere in the BRAM therefore not reset.

0 Kudos
stgateizo
Voyager
Voyager
646 Views
Registered: ‎10-07-2016

Hi joancab,

thank you for your help, but I have just found the solution for this problem. As stepehnm describes in the linked post below, you need the following memcpy command right after the Microblaze starts:

stgateizo_0-1625145802020.png

https://forums.xilinx.com/t5/Processor-System-Design-and-AXI/Microblaze-no-OS-heap-not-clean-after-reset/td-p/760996

Kind regards
stgateizo

 

joancab
Teacher
Teacher
615 Views
Registered: ‎05-11-2015

Good to know and glad you sorted it out

0 Kudos
stgateizo
Voyager
Voyager
516 Views
Registered: ‎10-07-2016

Hi joancab,

the memcpy command which I have mentoined in the previous post is only working in the SDK environment, but not with Vitis 2020.2
The parameter "__data_load" is not longer available in the linker script "lscript.ld". Therefore the memcpy command throws an compiler error, since the external declared parameter "__data_load" is unknwon, when you use Vitis.

Maybe it has to do with the way, how the linker script "lscript.d" is generated?
Does anybody know how I can overcome this issue in Vitis?

Kind regards
stgateizo

0 Kudos
joancab
Teacher
Teacher
499 Views
Registered: ‎05-11-2015

That sounds like another thread.

Being memcpy from standard C, I don't think the problem is vitis vs SDK, but more like the definitions of _data_start, etc. They may just have different names in Vitis, I would look into an SDK project to see where are these defined, with luck it's the same or a similar Vitis file.

0 Kudos
stgateizo
Voyager
Voyager
475 Views
Registered: ‎10-07-2016

Hi joancab,

Below you can see the lscript.ld generated with SDK = first picture, and lscript.ld generated with Vitis = second picture.
As you can see at the end of both scripts, the parameter "__data_load" is only defiend in the SDK linker script, and is compeltely missing in the Vitis linker script:

stgateizo_0-1625224221327.pngstgateizo_1-1625224338310.png

But maybe I could use the parameter "_end" instead? This should be the same address location or?
Well I'm not the linker script expert, but may there is somebody who knows this stuff better than I do?

Kind regards

stgateizo

 

0 Kudos
jmeador
Visitor
Visitor
358 Views
Registered: ‎07-31-2018

I just hit on this myself. The following link shows how to customize the linker script to help resolve the problem. "Method 2" shown there is  working fine so far. It did not cause the load size of the code to increase significantly in my application.

https://www.xilinx.com/support/answers/30878.html

stgateizo
Voyager
Voyager
266 Views
Registered: ‎10-07-2016

Hello jmeador,

thank you for sending me this link. The two methods are interresting. I think Method2 is more ore less the same as the memcpy command which we have discussed in this post. In the meantime I got also an answer from Xilinx, since I have created a service request for this issue. Xilinx says, that the missing __data_load parameter in the linker script is not a bug. The __data_load parameter was added by hand in the linker script and will not be added by default when you create a new SDK or Vitis project. But when I use the linker script from the SDK project in the Vitis project, the __data_load parameter will be found, and the Vitis compiler will no longer throw an error at teh memcpy command.

So I have a solution for now, but its a bit strange that you have to dive very deeply into the linker script in order to reset the microblaze properly !

That is not very user friendly and took me a lot of time, just to properly reset the Microblaze, but we know, that is Xilinx...

Kind regards

stgateizo

View solution in original post

0 Kudos