ΣSigmaStudio Ask AI Русский Log in

Can not boot BF561 from 16 bit flash

Processors & DSP rf247 Sep 12, 2017 00:00 2 replies Original on forum ↗
Thread Summary

Thread Summary

The user encountered issues with a BF561 dual-core project where the application code would not load and run from 16-bit flash at 0x20000000, despite working with a JTAG-USB ICE emulator. The problem was traced to the missing NO_INIT qualifier in the LDF files for the scratchpad memory, causing the boot kernel to hang. Adding the NO_INIT qualifier resolved the issue, allowing the application to load and run correctly from flash.
AI Generated Content
Subscribe
rf247 Question
Sep 12, 2017 00:00

This is rather long but in a nutshell I can not seem to get code for BOTH cores of the BF561 project I have to load and run from a LDR image in 16 bit flash at the traditional 0x20000000 location. Additionally, when I dial it back and simplify the objective and just try to get CoreA loaded and started that does not load and start either. I have multiple single core flash boot projects behind me but with the BF561 I can not seem to get it to load and run in either single or dual core mode.

Here are all the details

I have a BF561 dual core project that is a migration of a old fully vetted BF538 project to the dual core platform. Only purpose was to get more bandwidth since the last platform ran out of gas after stuffing one thing too many in to the older platform. The code was migrated and debugged on the BF561 EZKIT. It runs well on that platform. That code in turn was tweaked to run on the new target hardware which is virtually identical to the old hardware except the processor is BF561 rather than BF538.. I am able to load and run the resultant code on the new target hardware using a jtag - USB ICE emulator. Everything runs as expected. The PLL clock settings and the EBIU_... SDRAM settings come from the XML file as is custom when using an emulator. The code loads in to the target Cores A & B internal L1 & L2 SRAMs and in to the external SDRAM all as expected if a emulator is used. Code runs well using the emulator to load and run it.

The final step is to concatenate the 3 DXE codes in to a single LDR that can be burned in to and loaded and run from ASYNC0 address 0x2000 0000 flash. This would seem to be a "simple" process but this is where I am stalled. This process is similar to the multiple single core projects I have done in the past except instead of pre-pending the InitSDRAM code to a single core DXE it is pre-pended to CoreA + CoreB DXE's. I used the elfloader command as follows to concatenate the 3 salient DXE files to create a "single" LDR consisting of

pre-pended BF561_InitSDRAM - This is the usually-tiny assembly routine that is called by the on-chip boot Kernel prior to loading the real application code. It sets up the SDRAM register values and the PLL clock rates so that SDRAM code and data can be safely loaded. This code is loaded internal SRAM at 0xFFA00000 and run and it does its job as expected. This code is based on fully vetted prior projects and I have confidence in it because the UART diagnostics that it outputs are pretty definitive that it is doing its simple job as expected. It works exactly as it always has in past projects that are currently field deployed and sold to customers. I added diagnostic code to this to exhaustively test the SDRAM so I am pretty confident the SDRAM and clock are set properly. Plus the settings are the same as the settings from the XML file that is used when the emulator is used.

CoreA DXE. After the previous code is run the boot kernal is supposed to load the next DXE code which is the CoreA DXE. Every indicator I can gather says that the CoreA code and data is being loaded But the problem is it never runs. More on that later

CoreB DXE. After CoreA is loaded CoreB is supposed to be loaded. A LDR viewer tool I have indicates that the 3 DXE's have been concatenated in order and best I can ascertain they have the proper format. I.e. the first DXE is prepended with the magic "global header" of 0xA00000DF and each DXE is linked in the proper way. Both the LDR loader and painstaking visual inspection with a binary viewer seem to confirm that the format of the LDR is OK (but of course I can not guarantee. Hard to visually inspect reams of binary). The -nosecondstagekernel and and -NoFinalTag options in the elfloader command seem to suppress the automatic inclusion of a second stage loader (as desired) and make sure the CoreA dxe does NOT get the final tag so that CoreB can be loaded after CoreA. CoreB, the last DXE has the final tag as expected.

So the LDR image I am burning to flash looks OK to me. But its not working else I would not need help:)

The magic "the DXE concatenation command line I use looks as follows"

elfloader.exe -proc ADSP-BF561 -v -init ..\CoreA\BF561_InitSDRAM.dxe -nosecondstagekernel -NoFinalTag ..\CoreA\Release\CoreA.dxe ..\CoreB\Release\CoreB.dxe -b Flash -f binary -Width 16 -o ..\CoreA\Release\CoreAPlusCoreB.ldr

The command above is rather complicated but it looks right to me and it seems to produce the expected CoreAPlusCoreB.ldr image. Since it is hard to find explicit SUCCESSFUL examples of this sort of command I can't guarantee my command is correct. But the output sure looks correct.

So best I can discern the total InitSDRAM+CoreA+CoreB LDR is in a proper and expected format. But for some reason CoreB never seems to load and CoreA start code never gets run. What most bothers me is that the boot kernel never even jumps to the start location. I think I could debug the application if I got that far but the code load process seems to disappear in to the inscrutable black hole of the boot kernel.

At this point I am not looking for perfection. I am only looking for some sign of life so I can debug the code load.

It is as if

1. InitSDRAM is loaded and run by the boot loader as expected

2. CoreA DXE is loaded to CoreA and shared spaces as expected but never gets run

3. CoreB DXE never gets loaded OR run because CoreA must run before CoreB can run

From the outside it looks like some where during or at the end of step two above (or at the start of step three) the on-chip boot kernel goes in to some sort of "forever freeze" and that is the ball game. Since there is little to no visibility in to the boot kernel its hard to know what happened. I studied the available boot kernel assembly (found in the visualDSP 5;1;2 tools) and can see that if evil happened it could get locked in IDLE or some such horror. But exactly IF that is happening and/or what may have caused it is very difficult to diagnose.

Has anyone ever experienced this? I know of no way to step through the on chip boot loader to find where it is freezing up. If there is a error in the LDR image being able to see where it is locking up would be of immense help. When I reconnect with the emulator I can see that the CoreA program image was loaded but I have proven that it never runs because I have LED turn-on code as the first few assembly instructions of the magic 0xFFA00000 CoreA start location. I have added extended register dump diagnostics to the InitSDRAM code which always loads and runs seamlessly as expected. Nothing at that stage looks out of order. But obviously something is out of order else it would run

When I try to disassemble and/or step through the on-chip boot kernel located at 0xEF000000 the emulator misbehaves and is of no use.

I am not very much of a hardware guy but I am quite experienced in firmware including assembly. I do however have hardware geeks at my disposal if it is necessary to probe the electrons. The fact that the code runs using the emulator seems and that the initSDRAM code loads and runs from flash seems to indicate the hardware is pretty solid. I have multiple Blackfin projects behind me including writing and debugging flash boot code - load. Nothing has gotten the best of me the way the BF561 has. The target hardware seems functional as evidenced by the fact that it runs the code fine once it is loaded and run using an emulator. At this point I am running out of ideas on what to try next.

Is it possible that I need to go the Second Stage Loader route? The documentation I have read indicated that should not be necessary but after looking at the boot kernel assembly code I am not so sure. I expected to see the boot kernel use the IMDMA controller but I have not seen it. So maybe I have been trying to do something that is just not possible. I was expecting to just burn a LDR image similar to the way I have done in past projects and the boot kernel would run the initSDRAM and treat the CoreA+CoreB images as a single boot stream. So far no joy.. If anyone has any ideas I would be appreciative.

Audio Signal Processors

processors and dsp

Blackfin Embedded Processors

Processors and Microcontrollers

adsp-bf561

rf247 Reply
Sep 12, 2017 00:00

No one responded to my query (no hard feelings:). I found the problem and fixed it. Since it "just hanged" with nothing externally view-able to poke it was rather hard to diagnose. But very easy to fix once discovered once the root cause was stumbled upon.

Here is the postmortem else the effort is wasted. FIRST. I think this should be re-titled

When booting from 16 Bit flash BF561 "just hangs" in the boot kernel.

After much diagnosing the singular observation was that after running tried and true BF561_InitSDRAM code the process just "disappears" in to the boot kernel and hangs forever. The BF561_InitSDRAM code is a tiny snippet of user generated code (typically assembly only) that is used to set up the PLL and SDRAM before the bulk of the code is loaded. This code can be made as complex as you desire but typically is just a few lines of assembly to set the PLL and select EBIU_ SDRAM registers. Once that is called and runs seamlessly the unit "just hangs". Your not exactly sure it is "hung up" but what you do know for sure is your application code has not been loaded properly and not even the simplest thing you expect out of your application code is happening (I had a LED turn-on at the start address of the application code, even that never ran). No other USEFUL symptom except some of the CoreA code seems to have been loaded but never executed. Just disappears in to the black hole of the boot kernel.

After re-reading Engineer-to-Engineer Note EE-314 Rev 1 – May 15, 2007 for the hundredth time I noted on page 5:

"If booting to scratchpad memory is attempted, the processor hangs within the on-chip boot ROM"

That sounded dangerously like what I was experiencing.

Could not imagine why this would happen since the code was proven legacy code and I NEVER attempt to load-initialize scratchpad data. What changed? After a bit of forensics I discovered that the IDE WIZARD that produces LDF files for BF561 forgets to add the NO_INIT qualifier to scratchpad linker description statements. It forgot and I did not notice. In all past projects the template LDF file that is made at project creation time by the IDE wizard produces output roughly as follows

scratchpad NO_INIT

{

.......

.......

} >MEM_L1_SCRATCH

You normally get something that roughly looks like the above.

What the BF561 wizard created instead was something like

scratchpad
{
INPUT_SECTION_ALIGN(4)

....

....
} > MEM_A_L1_SCRATCH

for CoreA LDF and

scratchpad
{
INPUT_SECTION_ALIGN(4)

....

...
} > MEM_B_L1_SCRATCH

for CoreB ldf

Note that the CRITICAL NO_INIT qualifier some how got dropped. Small thing big ramification

When using the boiler plate template LDF's created for CoreA & CoreB on a BF561 the NO_INIT qualifier got lost!

This did not immediately create a nuclear melt down as the code still worked on the EZKIT and when loaded to the target with the emulator. So development continues for a long period and when its time to burn to flash your feeling pretty confident. Nobody fusses about code that is working, right? All there was was this little warning (buried in verbose output) that says "don't try to initialize scratchpad on code load".

So bottom line. If your "boot from flash" process "just hangs" in the boot kernel and all other things look OK better double check that your LDF scratchpad definitions have the NO_INIT qualifier. Even if you scrupulously never try to code-load-init your scratchpad area the linker will try to init it anyway just to see if you read the manual unless you tell it NO_INIT . .... Some things must be spelled out explicitly. Since I never have seen a Blackfin that allows code-load-init of scratchpad it would be safer just to make it illegal to even attempt to INIT scratchpad rather than "just hanging" and then giggle while you scramble to figure out what has destroyed your once working code. The result will be it will "just hang". If your lucky you will stumble on to the answer and if not you will read thousands of pages of useless stuff till the stuff you need smacks you in the face.

EZAdministrator Reply
Aug 2, 2018 00:00

This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

Thank you,
EZ Admin