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.

When to use @ModuleStartup

Other Parts Discussed in Thread: SYSBIOS

Hi,

I've been developing several projects for the C6472 DSP using XDC 3.22.04.46 and SYSBIOS 6.32.05.54.  Periodically, one or more of our applications will not run to main() after loading the executable through CCS via XDS100v1.  I've stepped into the application from _c_int00 and normally what happens is the DSP gets stuck looping in the XDC module startup functions somewhere.  In autoinit.c, it never returns from the call to xdc_runtime_Startup_Exec__E().  We are using several RTSC modules that we produced and I'm wondering if we need to initialize some variables in addition to what happens in our .xs files.  Is there a requirement for initializing variables in a Module_startup function?  How do we know what needs initialization? For example, is there a difference between a simple Int type and a module handle?

We are explicitly creating our modules statically in the .cfg file.  Is the Module_startup function only called for dynamically created instances?

Thanks,

Nick

  • Note: This might also be a problem with the link options we're using and how we're building our project.  I switched from -c (ROM MODEL) to -cr (RAM MODEL) and saw this happen at one point. 

    If we build our RTSC modules separate from our executable, is there a specific way to link the RTSC libraries so that initialization will occur correctly?

  • As a second addendum, is there a special requirement if our RTSC module interacts with IPC in some way? I just saw this in Module Primer 7:

    "In practice, most modules do not require @ModuleStartup; on the other hand, those modules that do interact directly with underlying peripherals (device drivers, timer managers, and so forth) would require a call during program startup to initialize hardware."

    One of our modules calls MessageQ functions.  Do we need to define a startup function to check that MessageQ is initialized?

  • Nick,

    Module_startup is called whenever a module gets used via xdc.useModule().  Any module that is used by the app should get an xdc.useModule() in the .cfg file.
    So to answer your question.  No, Module_startup function is not called for only dynamically created instances but for all instances of xdc.useModule().

    Module startup is there for initializing the module's state that might be used by other modules.  There's no requirement to having this function.
    Yes, there is a difference between a Int type and a module handle but I'm not sure what you are trying to get at with this question.

    Could you please attach your executable here?

    Judah

  • Nick,

    Why did you switch from ROM MODEL to RAM MODEL?  ROM module will use runtime init.  RAM means you need a special loader that will do the init for you.

    Judah

     

  • Nick,

    If you depend on MessageQ, then simply make sure you do a xdc.useModule() of MessageQ in your module.
    If you had a Module startup function which uses MessageQ then you would wait on Messageq's Module startup to complete first.
    Many of the BIOS/IPC modules have examples of Module Startup and the full source code is there for you to see.

    Judah

  • Ok, I am looking at the MessageQ_Module_startup function as an example.  I am a bit confused because MessageQ_Module_startup waits on NameServer_Module_startupDone() but doesn't make calls to that module's functions in its own Module_startup function.  It does make calls in Instance_init() however, so I assume that is the reason for checking if NameServer is started. 

    I will switch back to ROM model linking and give that a try.  I know that one of the applications I am currently debugging did NOT work with ROM or RAM model, but switching to RAM model allowed me to step further into autoinit.c before the DSP went off to la la land.  I am using a demo board with the POST bootloader; I had thought that the bootloader performs the "special loader" functions that you mentioned.

    "Module startup is there for initializing the module's state that might be used by other modules."  --> Does this mean that other modules reference different initialized values than are set by processing the .xs file? 

    Can you email me your contact info for the executable?

  • Nick,

    Yes, you are correct in respect to the MessageQ using NameServer especially since MessageQ creates some NameServer instances statically.

    Typically, most module state variables are init'ed in the .xs file, but there are times when it needs or can only be done during runtime.

    If you don't want to post your executable on here, what you can do is add me as a "friend" then you can privately share your executables.

    Judah

  • I sent you a shared message.

    Nick

  • Nick,

    What version of BIOS are you using?  Also Can I see your config script?
    I think this might be a problem that has been solved from older versions of BIOS.

    I tried out your executable.  I am also seeing it jump out to the weeds.

    I don't know what is exactly causing this, but I know that the jump happends on address:  0x002b49b6

    In addr:  0x002b49b0 its loading B3 from the StackPointer[2] which points to 0xf06f40 which contains value 0x72444427.

    I see that System_Module_startup__F is calling atexit().

    Judah

  • Judah,

    I'm using SYSBIOS 6.32.05.54.  I was seeing the same behavior that you described.  It looks like something about the Startup module is not being configured properly.  The program branches to an invalid address when looping on Startup_sfxnTab function pointers in the Startup_startMods function. 

    I'm using these options in my package.bld file:

    Pkg.attrs.copts = '-g -mv64+'

    Pkg.attrs.lopts = ' -l core0_linker.cmd' + ' --issue_remarks' +  ' --reread_libs -c';

    Pkg.attrs.defs = '-D_INCLUDE_NIMU_CODE -D_C6472_ -DBIOS_TYPES';

    My linker file is as follows:

    -a

    SECTIONS
    {
       .text:_c_int00: ALIGN 1024

    }

    Could this behavior be caused by building libraries and/or RTSC modules with different options (e.g. debug vs release profile) than my final executable?

  • I've recompiled the underlying libraries that my executable uses, making sure that I had -g and debug profile set.  The executable still fails in about the same place (some of the registers have changed and PC addresses).  It seems like the Startup function for the System module is erroneously getting executed twice and the DSP branches to an invalid PC on the second call.  This is what my dissassembly looks like when the branch is about to occur:

    A3 appear to be a valid address of Startup_sfxnTab but the LDW instruction uses A10 as an index with respect to A3.  As far as I understand, A10 should have a 5-bit maximum value when using pointer indexing. Therefore, whatever function was called previously seems like it didn't correctly restore A10. 

  • Nick,

    I've forwarded this thread to another person who I think might know what's going on.

    Judah

  • Ok, this is getting ridiculous.  I thought I had figured out a solution to this issue by statically creating a 32K HeapMem region in SL2RAM and setting that as the default Program heap.  (I had a theory based on my .cfg file that the runtime Startup functions for my XDC modules were causing a memory overflow or something like that.)  My code ran properly for one or two debug sessions.  Then, I disconnected my demo board and restarted CCS to make sure it really was working.  After loading the same executable, the DSP jumped into the weeds in the Startup_startMods() function again.  I don't know if some combination of breakpoints solved it temporarily or what. 

    This is very frustrating because I do not know how to control the XDC module init functions associated with the Startup module; it seems they are set by the build tools when building my executable and processing the .cfg file.    My executable fails before reaching main() and (it appears) while attempting to initialize the System or SysMin module.  I'm guessing I've got something incorrect in my .cfg file, but I've compared it to several examples and don't see anything wrong.  This is what prompted my question about properly initializing custom RTSC modules with @ModuleStartup.  Then, I began wondering if the problem was related to something more general like running out of memory; however, increasing memory for the default heap didn't seem to make a difference in the long run.

  • Is there any chance that your C stack is too small and that you're simply overflowing the stack into objects that are being initialized within the module startup functions?

    Try increasing the Program.stack value and see if the problem goes away.

    Alan

  • Hi Alan,

    I think you're on to something there.  I have been playing with memory locations/sizes all morning and I think I found a good combination.  I added the .systemHeap memory section to my .cfg file.  Previously I was creating Program.global.heap with a sectionName = null.  A portion of my .cfg file is below:

    // Create global heap memory
    Program.sectMap[".systemHeap"] = new Program.SectionSpec();
    Program.sectMap[".systemHeap"].loadSegment = "LL2RAM";
    var instti_sysbios_heaps_HeapMem0Params0 = new ti_sysbios_heaps_HeapMem.Params();
    instti_sysbios_heaps_HeapMem0Params0.sectionName = ".systemHeap";
    instti_sysbios_heaps_HeapMem0Params0.size = 0x8000;
    Program.global.heap = ti_sysbios_heaps_HeapMem.create(instti_sysbios_heaps_HeapMem0Params0);
    xdc_runtime_Memory.defaultHeapInstance = Program.global.heap;
    Program.heap = 0x8000;
    Program.stack = 0x1000;


    Program.stack was increased from 0x800 to 0x1000 also.  Is there a good way to get an estimated size for the Program.stack value? Previously 0x800 was large enough before adding some modules to our .cfg file.

    Thanks and apologies for rambling from my initial question,

    Nick

  • Once the program reaches a task, you can halt it using CCS and look at the Task module's ROV module view.

    The "hwiStackPeak" value will be how deep that C stack has been.

    You can then work back from there.

    Alan