This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Non-Zero Initialization of GSRAM by CPU2

Other Parts Discussed in Thread: C2000WARE

Hello,

Apologies, I don't know if this is a device problem or CCS problem. I'm using controlCARD for F2837xD.

The problem is that I cannot reliably non-zero initialise variables in GSRAM from CPU2.

 

I have:

  • Declared a non-zero initialized variable in CPU2 in a COFF project. I have no choice but to use COFF due to the use of Vector CANape with CCP. It’s a long story.
  • Linked it to GSRAM2.

 

After clicking Restart (required a few times for some reason) and then reaching main(), the variable is often not initialized in CPU2. It’s as though pinit does not work. Occasionally I have seen it work.

 

 If anybody has any ideas, I'd be grateful.

Some specific questions:

 

Question 1)

Is it possible in theory to have non-zero initialized variables in the CPU2 project located in GSRAM?

 

Question 2)

If not, it all makes sense. If so, pinit runs before main() in CPU2 so how is it possible that CPU2 has write access to GSRAM in order to initialise at this time?

Thank you.

  • Non-Zero-Init.zip

    PFA my demo project exhibiting the problem. Variable 'counter_GSRAM_cpu2' won't initialise correctly.

  • After setting a watchpoint for data write to 'counter_GSRAM_cpu2' I can see that the initialisation routine in CPU2 does not have ownership of GSRAM2 which probably explains why initialisation fails.

  • Kier,

    You are correct, the CPU2 must have ownership of the GSxRAM in order to write/initialize it.  I've C/P the below from the TRM, that gives details on the semaphore/register that CPU1 would need to set to give CPU2 this access.

    The RAM Init is governed by the same semaphore, but you could initialize with CPU1 before passing ownership over.

    Best,
    Matthew

  • Thank you. That's certainly true for user code but my broader point is that the boot code does not work in CPU2 for RAM initialisation in GSRAM. In other words I think it's a bug, at least in its COFF form. If it's not a bug I think it's nuts that CPU2 can't initialise its own globals correctly in boot code supplied by TI.

    I'd like a statement from the boot code authors whether that is a recognised limitation, an oversight or agreement that it is a bug and when it might be fixed please.

  • Kier,

    Let me loop in the Boot code authors for comment.

    Best,

    Matthew

  • Many thanks Matthew.

    BTW, I don't think this issue is confined to COFF. I tested with EABI output and the issue remains.

  • i reviewed the boot flow and i don't see anything wrong with boot initialization of GS RAM. 

    The initialization is handled by CPU1 boot code and then CPU2 is released from reset.

    So now if you allocate GS RAM to cpu2 it should work as expected. I don't have enough background to comment on pinit at this point.

  • Let's simplify the question.

    Is it possible for CPU2 to non-zero initialise a variable located in GSRAM?

    It sounds like you are saying it is not possible. Have I understood you correctly?

  • Kier,

    I had some additional discussions on this, and will attempt to clarify.

    In a standalone/production scenario this is the flow that will happen once the device is released from reset:

    • CPU1 boots  (CPU2 is held in reset)
    • CPU1 Initializes the device, including memory assignments, pin assignments, etc (in your case this is where CPU2 now is granted ownership of the GSRAMs in question)
    • CPU1 releases CPU2 from reset
      • Note: during debug you could create a project that does just this and nothing else to get CPU2 going
      • CPU1, in a system, most likely waits here for CPU2 to say “I’ve booted”
    • CPU2 boots, initializes its memory
    • CPU2, in a system, probably does something to tell CPU1 it is up and going – interrupt or sets a flag, IPC message or something similar

    I think the confusion might be in a debug environment, since you connect to the individual core to load code, you would still need to connect/execute some code on CPU1(per  above) before loading your code to CPU2.

    You should see the above demonstrated in our dual code examples in C2000 ware ex: C:\ti\c2000\C2000Ware_4_01_00_00\device_support\f2837xd\examples\dual\dma_transfer_shared_peripheral or others.

    To answer your last question directly, CPU2 can't init GSRAM until CPU1 assigns ownership.  In a standalone system this is not an issue since CPU2 is held in reset until CPU1 releases it(and has allocated memory/peripherals to it).  In a debug environment this will have to be done manually by executing some code on CPU1 before loading code to CPU2.

    Let me know if this clears things up.

    Best,

    Matthew

  • Matthew,

    Thanks for the explanation. I think that's certainly making the cause of the issue clearer. It's good to know that it's probably going to be OK in standalone mode. However, I don't think I'm any closer to solving the problem in the debug use-case. If I can't reliably create the same initial conditions as standalone use-case then that is not a very good debug environment.

    The attached project is also a dual led blinky project taken from the C2000Ware examples. All I've done in addition to the example is:

    - Declare and initialise a non-zero variable in CPU2 and located it in GSRAM2.

    - Given CPU2 write access to GSRAM2 after Device_Init() in CPU1 and before CPU2 Boot (in standalone mode).

    - Increment counter_GSRAM_cpu2 every 0.5s.

    I tried and failed to work out a CPU1/CPU2 Reset/Restart etc. sequence to follow that you have described in order to initialise GSRAM2 from CPU2.

    I'd be very grateful if you could please download the project and let me the know the correct sequence of button pushes.

  • I think I managed to fix this issue after studying the aforementioned sequence:

    Step 1) Disable Auto Run* in CPU2 debugger configurations.

    *This is enabled by default and runs to main() without waiting for CPU1 to transfer memory ownership. This is the root cause of this problem.

    Step 2) Add an empty function in CPU1 inserted after memory ownership is transferred to CPU2.

    Step 3) Select empty function as Auto Run symbol in CPU1:

    Now at Reset/Restart, CPU2 has not run boot code (including cinit) but CPU1 runs to a point where GSRAM2 write permission for CPU2 has been granted:

    Step 4) Clicking 'Resume' now runs user code in CPU1 and begins boot in CPU2 where the boot code is guaranteed to be able to write to GSRAM2.

    If there's an easier way to do that I'm open to ideas but at least now I get robust initial conditions when using the debugger.

  • Kier,

    Glad you were able to progress with this.  That's a great point on the auto-run feature that is enabled by default in CCS and issues it will cause for this scenario.  I often forget about those hidden options myself.  Let me see if others have any other suggestions as well.

    Best,

    Matthew

  • Hi Kier,

    Thanks for the explanation. I think that's certainly making the cause of the issue clearer. It's good to know that it's probably going to be OK in standalone mode. However, I don't think I'm any closer to solving the problem in the debug use-case. If I can't reliably create the same initial conditions as standalone use-case then that is not a very good debug environment.

    You should be able to create the standalone condition with debugger connected. What you need to do for that is after issuing reset on CPU1, click on "Run" (or resume) instead of restart. Also before clicking on run set the EMAULTION BOOT mode correctly on CPU1 (refer TRM for detail) so that it jumps to flash. 

    In general, one should avoid shared RAM for stack on CPU2 because of the issue you are facing. User can use M0/M1 or LSx RAM for that. If user has to use the it then they need to have IPC handshake between CPU1 and CPU2 to make sure CPU2 code does not access resources before CPU1 allocate it to CPU2. In this case unfortunately this has to go in F2837xD_CodeStartBranch.asm file and need to be written in assembly because these are accessed in init function called in this .asm file. 

    Hope this helps..

    Regards,

    Vivek Singh  

  • Hi Vivek,

    Thank you, I'll try that out and come back if it doesn't work.