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.

NDK and 32 priority levels -- possible bug report

Hello, 

We are working on an application that uses a full range of priorities (32).

I noticed that parts of the NDK that we are using (2.24.03.35) have priority checks that are hard-coded in.

Not a big deal in the grand scheme of things, since they are easy to patch up, but here they are:

DaemonNew() has a check that prevents dchildren from running above priority 15.   The limits are directly specified in the code.  It would be nice if they were drawn from the stack configuration.

Also, please correct me if I am wrong, but it appears that on startup, the NDK assigns priorities that come from a static configuration _oscfg created in ossys.c.  This means that to really modify the stack to run at different priority ranges, one must edit osif.h and rebuild the stack.

None of this is a big deal, but I do not always fully understand the relationship between priorities specified in header files and priorities specified in system configuration using CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRI(LOW/NORM/HIGH ...)

Thank you very much for clarifications, and I apologize if these are known issues

  • Dmitry Gringauz53811 said:
    DaemonNew() has a check that prevents dchildren from running above priority 15.   The limits are directly specified in the code.  It would be nice if they were drawn from the stack configuration.

    I didn't get a chance to look at this today, but will return to it on Monday.

    Dmitry Gringauz53811 said:
    Also, please correct me if I am wrong, but it appears that on startup, the NDK assigns priorities that come from a static configuration _oscfg created in ossys.c.  This means that to really modify the stack to run at different priority ranges, one must edit osif.h and rebuild the stack.

    You don't need to modify the C code. You can configure the priorities in the XGCONF configuration (this is the *.cfg file in your app).  Have you seen that?

    Steve

  • Hi Steve,

    Yes, I did see that it should be possible to modify stack priority ranges from the .cfg file. 

    I went back to the original stack distribution over the weekend and tried this out.  Here are the entries that the GUI utility made to the .cfg file:

    Global.stackLibType = Global.MIN;
    Task.numPriorities = 32;
    Global.lowTaskPriLevel = 1;
    Global.normTaskPriLevel = 16;
    Global.highTaskPriLevel = 24;
    Global.kernTaskPriLevel = 26;
    Global.netSchedulerPri = Global.NC_PRIORITY_HIGH;
    Global.ndkThreadPri = 29;

    Unfortunately, it appears that they had no effect, at least in my configuration (I am using a separate .cfg project).  Here is what I got on debugger output when I tried running the code from a task with priority 17.  The first of the "Illegal priority call" messages came from fdOpenSession() :

    It is entirely possible that there is something not correct with my configuration.  But, as I said previously, this is not a big deal for me right now, since rebuilding the stack with new tools is very easy, and I had to do it anyway to add jumbo pbm for our application.

    My Best Regards,

    Dmitry

  • DaemonNew() has a check that prevents dchildren from running above priority 15.   The limits are directly specified in the code.  It would be nice if they were drawn from the stack configuration.

    Indeed this is a bug.  I've filed a bug report to track this issue.:

    SDOCM00120101 DaemonNew has hard coded check limiting priority to be less than 15

    Global.kernTaskPriLevel = 26;
    Global.netSchedulerPri = Global.NC_PRIORITY_HIGH;
    Global.ndkThreadPri = 29;

    One issue I see here and want to point out - the NDK thread priority should never be greater than the NDK kernel priority.  All NDK task threads should be in the range NDK low pri <= [task thread priority] <= NDK high pri < NDK kernel pri

    This could be related to the errors you are seeing, but since you're running from a task of pri 16, it seems that you shouldn't get this error.

    Can you try the following?

    1. set a break point in the task (very beginning of the task code)

    2. run to the break point

    3. open the "expressions" view in CCS and enter the global (struct) variable name "_oscfg"


    What values are you seeing for the NDK priority levels?

    The below screen shot should help you to see what I'm pointing you to.

    Steve

  • Hi Steve,

    Good to hear from you.

    Here's what I did:

    1) I reverted back to off-the-shelf NDK, 2.24.03.35

    2) I've modified the contents of my .cfg file per your recommendation above (that is, I reduced the priority of ndkThreadPri:

    Global.stackLibType = Global.MIN;

    Task.numPriorities = 32;

    Global.lowTaskPriLevel = 1;

    Global.normTaskPriLevel = 16;

    Global.highTaskPriLevel = 24;

    Global.kernTaskPriLevel = 26;

    Global.netSchedulerPri = Global.NC_PRIORITY_HIGH;

    Global.ndkThreadPri = 24;

    Program.stack = 16384;

    3) I've rebuild everything and set the breakpoint.

    Here is what I see for _oscfg contents:

    Here's how my ROV looks like:

    Now, my breakpoint is in my priority 13 task, Startup, right before fdOpenSession() is called:

    This task is spawned from NetworkOpen(), after the stack is initialized.

    Here's what I get when I step through fdOpenSession() on the console output:

    It does not appear that priority settings from the .cfg file are propagated and set in the _oscfg structure.

    Now, just grepping the code, it looks like _oscfg is declared and initialized as module-level variable in ossys.c and is extern'ed osif.h.  It also looks like there are a lot of access macros for members of _oscfg defined in osif.h.  But, besides initialization in ossys.c, which occurs during cinit, I did not notice any code, either direct or through macros, where values in this struct were changed.  I also did not notice any direct or by-name references to this structure in the generated file, app_pe66.c.  Perhaps these settings are abstracted, and I just do not know what to look for.

    Best Regards,

    Dmitry.

  • Dmitry,

    Can you please attach your *.cfg file here?

    Thanks,

    Steve
  • Dmitry,


    Thanks for attaching.  I see the problem.  The following configuration setting is preventing those priority settings from taking effect:

    Global.enableCodeGeneration = false;

    This setting causes the NDK stack thread to NOT be generated, along with the C code that applies all NDK configuration settings you may have, such as the priority ones you made.

    When you have code generation disabled, you must implement the run time C configuration code yourself to configure the stack.
      Please refer to the NDK API Guide, Appendix G, "Legacy Configuration Manager API" for details on the legacy configuration.

    I'll paste the code below that corresponds to the priority settings you want, for your convenience, though:

        /* add the configuration settings for NDK low priority task level. */
        rc = 1;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRILOW,
                     CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        /* add the configuration settings for NDK normal priority task level. */
        rc = 16;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRINORM,
                     CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        /* add the configuration settings for NDK high priority task level. */
        rc = 24;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,
                     CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        /* add the configuration settings for NDK kernel priority task level. */
        rc = 26;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIKERN,
                     CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
    

    If you have a lot of settings you want to configure, it may seem too time consuming to read and learn that whole appendix.  Instead, one trick you can do is as follows.  In short, you still use the XGCONF GUI to configure settings you want.  Then you can copy/paste the C code version of those settings.  It goes something like this:

    1. Create a new project that uses the NDK
      1. add the "var Global = xdc.useModule('ti.ndk.config.Global);" line to the config file

    2. Make sure that Global.enableCodeGeneration = true
    3. Build the app
    4. Save at the large C file that's generated, as a result of your *.cfg file as input.  This *.c file is autogenerated and will be overwritten each time you build
      1. The C file is generated in the "Debug" or "Release" sub-folder of your project
      2. For example, a project I have, has it here.  Yours should be similar, but named differently: "Debug\configPkg\package\cfg\empty_pe430X.c"
      3. if you want to inspect NDK settings, you can search for "ti.ndk.config.Global" in that C file.  That should get you close to the NDK's C code settings.
    5. Open the *.cfg file of your project
    6. Add in the priority settings/changes you made (from the earlier post you made).
    7. Rebuild
    8. Now, diff the *.c file you saved in step 4 above, with the newly generated one from step 7.
    9. The diff should clearly show you the C code that was generated as a result of the changes you made to the *.cfg file

    That's how I got the above C code for you.  It's kind of "a cheat" to save you time with figuring out the C code you need.

    Steve

    NOTE: I made several edits to clarify and provide some missing details, after the original post

  • Steve,

    Thank you for all the insight!

    Dmitry.