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.

RTOS/66AK2H12: NC_NetStart() and task prioritties

Part Number: 66AK2H12

Tool/software: TI-RTOS

XDCtools 3.32, SYS/BIOS 6.46, CCS 7.4, PDK 4.0.7, NDK 2.25

I'm not sure how to phrase my query but I've got an ARM build roughly using the PDK NDK emac example as a starting point. It is a TCP application with three servers set to run along with a multitude of other tasks. Depending upon what level I set various task priorities to, the NC_NetStart() NetIP callback will get called once when the network is added and then immediately called again with the network removed. I am using a fixed IP. In other words, my callback for NetIP is as in the example; static void NetworkIPAddr(IPN IPAddr, uint IfIdx, uint fAdd). That function gets called twice with fAdd as true and than again with it as false.

The above happens as I raise the task priorities of some of my other tasks. I have the network stack task itself at 12, the server tasks at 7 (set from DaemonNew()). If I keep other tasks lower, say 5, everything works as expected.

Note that there is no connection begin establish during the above sequence. I am simple starting the ARM executable under CCS debug and seeing the NetIP call back getting called twice (it printf()s "Network Added" or Network Removed").

Is/are there some task priority rule(s) that I am not aware of in regard to setting the levels with NC_NetStart() or the network task? What would cause the network to be removed after being added?

Mike

  • The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Hi,

    Can you provide a screenshot of RTOS ROV view of tasks for the failure case and working case?

    Regards, Eric
  • Hi Eric. Sure I'll post below. Thank you for the quick look at this.

    Working case:

    and non working:

    I hadn't looked at this task view before in investigating this question. I can see that in the non working case the network task and daemon task are gone. Certainly a problem. What is strange is that I am trying to set the networkStack task priority set to 12 (as can be seen in the code snippet from main() at top of the screen shot) yet it is showing as 2 in the ROV display (working case). Also, the xmt_task_stub_()s and rcv_task_stub_()s; in the working case I've programmed them to be 7. To create the non working case I programmed them to be 11 yet they are shown in the ROV as 9.

    Mike

  • Hi Mike,

    What is the code of your networkStack thread doing? Is this the code that's running the NDK stack?

    In particular, I'm asking because I also see that the "normal" NDK stack thread is also in the ROV view, shown as terminated (ti_ndk_config_Global_stackThread).

    This isn't necessarily an issue, you may have configured the stack to use your own custom stack thread, which could explain this.

    Can you please attach your application's configuration file (*.cfg file)?

    Also, in the same ROV tool, can you check the module called SysMin? In there, there is a buffer that contains (unflushed) print output. Can you check the contents of the SysMin buffer for any messages?

    Steve
  • Almost forgot. Priorities in the NDK are important to get right. Have you seen the section of the NDK documentation that discusses thread priorities?

    If not, I would highly recommend reviewing that. You can find it in the NDK install (should be located in your SDK installation):

    - ndk_2_25_00_09\docs\spru523j.pdf

    - section "3.1.2 Global Scheduling Configuration"

    - section "3.3 Creating a Task"

    - a highlight: "Setting a [NDK sockets] thread to a higher priority than the NDK's high-priority thread level may disrupt the system and cause unpredictable behavior if the thread calls any stack-related functions"

    - section "4.2.2 Scheduling Options"

    - section "4.2.3 Scheduler Thread Priority"

    Steve
  • Steve,

    Thanks for looking at this. networkStack() just calls Network_stack() which is more or less exactly lifted from the NIMU_emacExample_EVMK2H_armBiosExampleProject example. But now that you asked and had me focus on that call, I see one of the very first things it does is:     rc = NC_SystemOpen(NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT);

    So that probably explains why the priority is 2 and not what I am trying to set it to in main()'s taskcreate().

    The ti_ndk_config_Global_stackThread shows as terminated for both the case where everything is working as well as the case in the failure as you can see in the screen shots.

    The cfg file is:

    var Program = xdc.useModule('xdc.cfg.Program');
    var cfgArgs = Program.build.cfgArgs;
    var RB = (cfgArgs.profile == "release" ? true : false);
    
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    var IHeap = xdc.useModule('xdc.runtime.IHeap');
    var GateHwi = xdc.useModule('ti.sysbios.gates.GateHwi');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Timer = xdc.useModule('ti.sysbios.hal.Timer');
    //var Event = xdc.useModule('ti.sysbios.knl.Event');
    var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Log = xdc.useModule('xdc.runtime.Log');
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    //var Text = xdc.useModule('xdc.runtime.Text');
    var Assert = xdc.useModule('xdc.runtime.Assert');
    var Error = xdc.useModule('xdc.runtime.Error');
    var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
    
    //Task.defaultStackSize = 4096 * 4;
    Task.defaultStackSize = 8192 * 16;
    Task.deleteTerminatedTasks = true;
    
    // BIOS Setup
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.libType = (RB ? BIOS.LibType_NonInstrumented : BIOS.LibType_Instrumented);
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.heapSize = 0x200000;
    
    Program.argSize = 100;  // Minimum Size
    Program.stack = 0x1000;
    
    SysMin.bufSize = 0x1000;
    SysMin.flushAtExit = false;
    System.SupportProxy = SysMin;
    
    //Clock.timerId = -1;
    
    // Heap
    /*var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var heapMemParams = new HeapMem.Params();
    heapMemParams.size = 0x80000;
    
    var Memory = xdc.useModule('xdc.runtime.Memory');
    Memory.defaultHeapInstance = HeapMem.create(heapMemParams);*/
    
    // IPC Configuration
    xdc.useModule('ti.sdo.ipc.MessageQ');
    
    Program.global.procName = "HOST";
    xdc.loadCapsule("../shared/ipc.cfg.xs");
    
    // Select IPC libraries
    var Build = xdc.useModule('ti.sdo.ipc.Build');
    Build.libType = (RB ? Build.LibType_NonInstrumented : Build.LibType_Debug);
    Build.assertsEnabled = (RB ? false : true);
    Build.logsEnabled = (RB ? false : true);
    
    // Set default diags mask
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    
    Defaults.common$.diags_ENTRY = Diags.ALWAYS_OFF;
    Defaults.common$.diags_EXIT = Diags.ALWAYS_OFF;
    Defaults.common$.diags_LIFECYCLE = Diags.ALWAYS_OFF;
    Defaults.common$.diags_INTERNAL = (RB ? Diags.ALWAYS_OFF : Diags.ALWAYS_ON);
    Defaults.common$.diags_ASSERT = (RB ? Diags.ALWAYS_OFF : Diags.ALWAYS_ON);
    Defaults.common$.diags_STATUS = Diags.RUNTIME_ON;
    Defaults.common$.diags_USER1 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_USER2 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_USER3 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_USER4 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_USER5 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_USER6 = Diags.ALWAYS_OFF;
    Defaults.common$.diags_INFO = Diags.ALWAYS_OFF;
    Defaults.common$.diags_ANALYSIS = Diags.ALWAYS_OFF;
    
    // Override diags mask for selected modules
    xdc.useModule('xdc.runtime.Main');
    Diags.setMaskMeta(
        "xdc.runtime.Main",
        Diags.ENTRY | Diags.EXIT | Diags.INFO,
        Diags.RUNTIME_ON
    );
    
    var Registry = xdc.useModule('xdc.runtime.Registry');
    Registry.common$.diags_ENTRY = Diags.RUNTIME_OFF;
    Registry.common$.diags_EXIT = Diags.RUNTIME_OFF;
    Registry.common$.diags_INFO = Diags.RUNTIME_OFF;
    Registry.common$.diags_ANALYSIS = Diags.RUNTIME_OFF;
    Registry.common$.diags_USER1 = Diags.RUNTIME_OFF;
    
    // Create logger instance
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var loggerBufP = new LoggerBuf.Params();
    loggerBufP.numEntries = 256;  /* 256 entries = 8 KB of memory */
    loggerBufP.bufType = LoggerBuf.BufType_FIXED;
    
    var appLogger = LoggerBuf.create(loggerBufP);
    appLogger.instance.name = "AppLog_arm0";
    Defaults.common$.logger = appLogger;
    
    // Network Stack 
    BIOS.taskEnabled = true;
    
    xdc.loadCapsule("../network/network.cfg.xs");
    
    /* Default idle stack is 131072! */
    Task.idleTaskStackSize = 4096;

    And the ../network/netwqork.cfg.xs is:

    //////////////////////////////////////////////////////////////////////
    // Include this section to add network support
    //////////////////////////////////////////////////////////////////////
    
    // Load the CSL packagage
    var csl = xdc.loadPackage('ti.csl');
    csl.Settings.deviceType = "k2h"
    
    // Load the OSAL package
    var Osal = xdc.useModule('ti.osal.Settings');
    Osal.osType = "tirtos";
    
    // Load the CPPI package
    var Cppi = xdc.loadPackage('ti.drv.cppi');
    
    // Load the QMSS package
    var Qmss = xdc.loadPackage('ti.drv.qmss');
    
    // Load the PA package
    var Pa = xdc.useModule('ti.drv.pa.Settings');
    Pa.deviceType = "k2h";
    
    var Nimu = xdc.loadPackage('ti.transport.ndk.nimu');
    Nimu.Settings.socType = "k2h";
    
    // Use this load to configure NDK 2.2 and above using RTSC. In previous versions of
    // the NDK RTSC configuration was not supported and you should comment this out.
    
    var Ndk = xdc.loadPackage('ti.ndk.config');
    var Global = xdc.useModule('ti.ndk.config.Global');
    Global.enableCodeGeneration = false;
    
    var Cache = xdc.useModule('ti.sysbios.family.arm.a15.Cache');
    Cache.enableCache = true;
    
    var Mmu = xdc.useModule('ti.sysbios.family.arm.a15.Mmu');
    // Enable the MMU (Required for L1/L2 data caching)
    Mmu.enableMMU = true;
    
    // descriptor attribute structure
    var peripheralAttrs = new Mmu.DescriptorAttrs();
    Mmu.initDescAttrsMeta(peripheralAttrs);
    peripheralAttrs.type = Mmu.DescriptorType_BLOCK;  // BLOCK descriptor
    peripheralAttrs.noExecute = true;                 // not executable
    peripheralAttrs.accPerm = 0;                      // read/write at PL1
    peripheralAttrs.attrIndx = 1;                     // MAIR0 Byte1 describes
    // memory attributes for
    // Define the base address of the 2 MB page
    // the peripheral resides in.
    var peripheralBaseAddrs = [
        { base: 0x02620000, size: 0x00001000 },  // bootcfg
        { base: 0x0bc00000, size: 0x00100000 },  // MSMC config
        { base: 0x02000000, size: 0x00100000 },  // NETCP memory
        { base: 0x02a00000, size: 0x00100000 },  // QMSS config memory
        { base: 0x23A00000, size: 0x00100000 },  // QMSS Data memory
        { base: 0x02901000, size: 0x00002000 },  // SRIO pkt dma config memory
        { base: 0x01f14000, size: 0x00007000 },  // AIF pkt dma config memory
        { base: 0x021F0200, size: 0x00000600 },  // FFTC 0 pkt dma config memory
        { base: 0x021F0a00, size: 0x00000600 },  // FFTC 4 pkt dma config memory
        { base: 0x021F1200, size: 0x00000600 },  // FFTC 5 pkt dma config memory
        { base: 0x021F4200, size: 0x00000600 },  // FFTC 1 pkt dma config memory
        { base: 0x021F8200, size: 0x00000600 },  // FFTC 2 pkt dma config memory
        { base: 0x021FC200, size: 0x00000600 },  // FFTC 3 pkt dma config memory
        { base: 0x02554000, size: 0x00009000 },  // BCP pkt dma config memory
        { base: 0x30000000, size: 0x04000000 },  // emif 16 space: nand flash TRC
        { base: 0x21000a00, size: 0x00000100 },  // emif config 
    ];
    
    // Configure the corresponding MMU page descriptor accordingly
    for (var i = 0; i < peripheralBaseAddrs.length; i++) {
        for (var j = 0; j < peripheralBaseAddrs[i].size; j += 0x200000) {
            var addr = peripheralBaseAddrs[i].base + j;
            Mmu.setSecondLevelDescMeta(addr, addr, peripheralAttrs);
        }
    }
    
    // Reconfigure DDR to use coherent address
    Mmu.initDescAttrsMeta(peripheralAttrs);
    
    peripheralAttrs.type = Mmu.DescriptorType_BLOCK;
    peripheralAttrs.shareable = 2;            // outer-shareable (3=inner, 0=none)
    peripheralAttrs.accPerm = 1;              // read/write at any privelege level
    peripheralAttrs.attrIndx = 2;             // normal cacheable (0=no cache, 1=strict order)
    
    for (var vaddr = 0x80000000, paddr = 0x800000000; vaddr < 0x100000000; vaddr += 0x200000, paddr += 0x200000) {
        Mmu.setSecondLevelDescMeta(vaddr, paddr, peripheralAttrs);
    }
    
    // Add MSMC as coherent
    for (var addr = 0x0c000000; addr < 0x0c600000; addr += 0x200000) {
        Mmu.setSecondLevelDescMeta(addr, addr, peripheralAttrs);
    }
    

    I'll set up the test again and check in SysMin for any messages. And review the NDK documentation sections you suggested in you next post. But maybe now that I see the stack is getting set to NC_PRIORITY_LOW that might explain the problem.

    I'll post again after I get some reading and testing.

    Cheers,
    Mike

  • Steve,

    I've read the sections in the NDK guide but still don't have insight as to why I am having the problem.

    I now see that the only valid priorities to NC_SystemOpen() are NC_PRIORITY_LOW and NC_PRIORITY_HIGH although I don't understand why that is.

    I set the priority to use NC_PRIORITY_HIGH (which I see using the debugger gets set to a value 8). Running with that level my application works with the xmt/rcv tasks set to use priority level 7. I have no messages in ROV SysMin OutputBuffer and I see in ROV Task the network priority level is 8 (networkStack) and all other tasks are set at levels programmed. See Working case screen capture pasted ewarlier in this thread).

    But if xmt/rcv tasks are set to level 11 I again get the same non working failure behavior.

    I get the following output on the CCS console (these messages are printf() from the nimu I beleive and from the same static void NetworkIPAddr(IPN IPAddr, uint IfIdx, uint fAdd) used in the emacNimu example):

    [arm_A15_0] QMSS successfully initialized
    CPPI successfully initialized
    PA successfully initialized

    TCP/IP Stack

    Network_stack: using local IP
    Network Added: IF-1:10.10.70.50
    Network Removed: IF-1:10.10.70.50
    Network_stack: exiting

     

    You asked that I look at ROV SysMin. It shows a bunch of entries now. There are around 10 of these paired entries:

    00020.508 llExit: Illegal call to llExit()
    00020.508 llEnter: Illegal priority call to llEnter()

    and a final entry:

    00023.001 mmFree: Double Free

    The ROV Task listing no longer has an entry for networkStack() and the priorities of the xmt/rcv tasks are showing 9, not the level 11 set in the taskCreate calls.

    Some additional notes:

    • This is all running on ARM0.
    • No network pings or client connections are taking place during these test. I am simply starting the application under the CCS debugger after a power off/on reset of the EVM.
    • Concerning rcv and xmt tasks. There are three pairs each intended to provide a different TCP service to a client. Only one client will be connected at a time. Both rcv and xmt do fdOpenSession() so that they can use the connected socket and can use pipe(). The xmt tasks block on SemaphorePend() waiting for the appication to generate data. The rcv tasks block on a fdPoll() waiting for a signal that a connection has been established or data to arrive on a connected socket. (The connection established signalling happens via the network daemons setup on NetStart callback setup in NC_NetStart()).
    • The application here will be generating a lot of data that needs to be moved out via TCP stream. So the goal here is to configure the network and xmt/rcv task priorities to achieve the maximum throughput.
  • Mike Dannhardt said:
    You asked that I look at ROV SysMin. It shows a bunch of entries now. There are around 10 of these paired entries:

    00020.508 llExit: Illegal call to llExit()
    00020.508 llEnter: Illegal priority call to llEnter()

    Those errors are come from functions in the ndk_<version>\packages\ti\ndk\os\task.c source file. Can you set a breakpoint on the line in llEnter which reports "llEnter: Illegal priority call to llEnter()" and the line in llExit which reports the "llExit: Illegal call to llExit()" to see:

    a) If these errors occur before "Network_stack: exiting" has appeared on the CCS console.

    b) What is the call leading to these errors.

    00004.001 llEnter: Illegal priority call to llEnter() - Round II suggests these errors can be caused by the application task priorities being too high.

  • Hi Mike,

    It sounds like your RX and TX task priorities may be too high (I see that Chester is also suspecting this).

    The task priority of a task thread that does NDK socket operations should never be higher than the NDK stack thread itself. Looks like this is the case for your app when things aren't working.

    In general, the NDK thread priorities should have the following relationship:

    OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < OS_TASKPRIKERN  

    (assuming the defaults, gives us this: 3 < 5 < 7 < 9)

    Can you try readjusting your priorities such that the above holds true? I'd recommend leaving in a gap between priority levels, as can be seen with the default vaues.

    Steve

  • Hi Steve and Chester.

    I thought that there were 16 thread priority levels as the default and this is what is show in XGCONFIG for numPriorities. I'd really like to be able to use that full range of granuality.

    Is there a reason that NC_SystemOpen() is restricted to NC_PRIORITY_LOW and NC_PRIORITY_HIGH? (NC_PRIORITY_LOW and NC_PRIORITY_HIGH are levels 2 and 8 respectably on my system as viewed under debug).

    Where does NC_PRIORITY_LOW and NC_PRIORITY_HIGH fit into: OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < OS_TASKPRIKERN  

    How do I check what the OS_TASKPRIKERN level is?

    "The task priority of a task thread that does NDK socket operations should never be higher than the NDK stack thread itself."
    Thanks for that guidenance.

    "Looks like this is the case for your app when things aren't working."
    Well that isn't exactly what I am seeing. Originally I had NC_PRIORITY_LOW (2) and the socket threads at 7 and this ~seemed~ to work fine. Does the above relationship only include socket operations and the stack, i.e, other task priorities not using network functionality can be set with higher priority and not break network operation?

    Chester I've not gotten to do te debug you asked about yet but will get to it tomorrow I think.

    Thank you both for your help.

  • Mike Dannhardt said:
    Is there a reason that NC_SystemOpen() is restricted to NC_PRIORITY_LOW and NC_PRIORITY_HIGH? (NC_PRIORITY_LOW and NC_PRIORITY_HIGH are levels 2 and 8 respectably on my system as viewed under debug).

    Where does NC_PRIORITY_LOW and NC_PRIORITY_HIGH fit into: OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < OS_TASKPRIKERN 

    These two options affect how the NDK network scheduler works and interacts with other (NDK) task threads. Please refer to these specific sections for more info:

    4.2.3 Scheduler Thread Priority

    “The scheduler priority (relative to network application thread priority) affects how network applications can

    be programmed. For example, when running the scheduler in low priority, a network application cannot

    poll for data by continuously calling recv() in a non-blocking fashion. This is because if the application

    thread never blocks, the network scheduler thread never runs, and incoming packets are never processed

    by the NDK.”

    and

    4.2.2 Scheduling Options

     

    Mike Dannhardt said:
    How do I check what the OS_TASKPRIKERN level is?

    You should be able to see this in XGCONF, under the NDK's Global module. Here's a screen shot highlighting it in my CCS view:

    Mike Dannhardt said:
    Originally I had NC_PRIORITY_LOW (2) and the socket threads at 7 and this ~seemed~ to work fine. Does the above relationship only include socket operations and the stack, i.e, other task priorities not using network functionality can be set with higher priority and not break network operation?

    Yes, the NDK priorities and kernel mode are designed to keep the stack and related NDK/network/sockets task threads synchronized. The above mentioned priority relationship applies to NDK task threads only; your other non-network related threads can have their own priorities.

    Steve

  • Forgot a couple of things ...

    Mike Dannhardt said:
    I thought that there were 16 thread priority levels as the default and this is what is show in XGCONFIG for numPriorities. I'd really like to be able to use that full range of granuality.

    Yes, there are, that is the full range of priorities defined in SYS/BIOS. You have access to all of those, however the NDK picks certain levels (from within that same range) and assigns them to be its "low/norm/high/kern" priorities.

    Your non network tasks can use any of the available priorities, choosing whatever makes sense for your app. It's just the NDK stuff that needs to follow the aforementioned rules.

    I would recommend putting your NDK priorities for "low/norm/high/kern" back to the defaults that you can see in that screen shot I posted above. Then also change your scheduler priority to NC_PRIORITY_HIGH and see how things work for you with that.

    If it works well, then you can modify the NDK priorities for "low/norm/high/kern", just as long as you maintain the relationship OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < OS_TASKPRIKERN

    Steve

  • I'm sorry but I am getting frustrated. Here is a capture of the closest thing I can find in my XGCONF. 

    I do not have a Global under outline but do under the Available Products and it matches your screen shot. I can not make any changes here as you can see. They are all greyed out.

    Further, as I mentioned earlier in this thread, the NC_SystemOpen() will only accept NC_PRIORITY_LOW or NC_PRIORITY_HIGH. And those resolve to values 2 and 8. I haven't to my knowledge changed the assigned values anywhere. I attached my cfg files earlier in this thread.

    Your responses mention OS_TASK priorities and I am trying to understand how those relate to NC priorities.

    The bottom line is still that NC_SystemOpen() will only accept NC_PRIORITY_LOW (2) or NC_PRIORITY_HIGH (8) and you indicate that any socket functions must be lower than those. The choke point in this system will be moving the produced data off the SBC via Etherenet and hence needs to be of the highest priority yet is limited to 1/2 the highest priority available. So in setting priorities for all the other data production tasks that feed into the transmit tasks must now be under that. And the suggestion of having 2 levels between task further reduces the granuality of the selections.

    Is there a reason why the network stack is limited to the maximum of NC_PRIORITY_HIGH, 8?

  • Hi Mike,

    I'm sorry you're getting frustrated! Not what we want!

    Is it possible that you are trying a different configuration file than before? As you mention, the Global module isn't present in the outline view which would indicate that it's not being used in your XGCONF *.cfg file. But, I see in your previous post that it was there, in the file "../network/netwqork.cfg.xs":

    var Global = xdc.useModule('ti.ndk.config.Global');

    In any case, can you try click dragging the Global module from the available view into your outline view? Once it's in the outline, you should be able to edit those fields.

    Steve
  • Mike,

    What's the status with this?

    Todd
  • Hi Todd. Sorry I've not tried dragging the Global setting over but still have to resolve this issue as I need the stack running at a higher priority level. I never changed the levels from their defaults so I don't understand why the high is 8. It is confusing why there is a configuration setting yet the values are still setting via code. It seems like it would have been much simpler just to allow users to assign the numeric values that they want to use in their systems but I must be missing something.

    Thank you for following up but please hold this open for a few more days at least.
    Mike
  • Mike,

    I re-reviewed the *.cfg files you attached and see a setting that may be related to your frustrations:

    Global.enableCodeGeneration = false;

    With the above set to false, most of the settings you make in the XGCONF GUI *will not* take effect.

    Related to this, can you please post the C code of the Task thread called "networkStack"?

    This will give me some more insight into what I'm suspecting with your app.

    Steve
  • Hi Todd. Thanks for continueing to look into this for me.

    That setting; Global.enableCodeGeneration = false; (along with others relating to the network) came directly from the PDK example NIMU_emacExample_EVMK2H_armBiosExampleProject.

    Here is my code for networkStack. Basically it again is more or less the same, I think, as is in the example.

    Int Network_init(void)
    {
        NIMU_QMSS_CFG_T     qmss_cfg;
        NIMU_CPPI_CFG_T     cppi_cfg;
    
    #ifdef __ARM_ARCH_7A__
        Uint32 privid;
        Uint32 index;
        Mmu_DescriptorAttrs attrs;
    
        CSL_MsmcRegs *msmc = (CSL_MsmcRegs *) CSL_MSMC_CFG_REGS;
        extern char ti_sysbios_family_arm_a15_Mmu_Module_State_0_secondLevelTableBuf_1__A;
        uint32_t addr = (uint32_t) &ti_sysbios_family_arm_a15_Mmu_Module_State_0_secondLevelTableBuf_1__A;
    
        Mmu_initDescAttrs(&attrs);
    
        attrs.type = Mmu_DescriptorType_TABLE;
        attrs.shareable = 0; // non-shareable
        attrs.accPerm = 1;   // read/write at any privelege level
        attrs.attrIndx = 0;  // Use MAIR0 Register Byte 3 for
                             // determining the memory attributes
                             // for each MMU entry
    
        // Update the first level table's MMU entry for 0x80000000 with the new attributes.
        Mmu_setFirstLevelDesc((Ptr) 0x40000000, (UInt64)addr, &attrs);
    
        // Set up SES & SMS to make all masters coherent
        for (privid = 0; privid < 16; privid++)
        {
            for (index = 0; index < 8; index++)
            {
                uint32_t ses_mpaxh = msmc->SES_MPAX_PER_PRIVID[privid].SES[index].MPAXH;
                uint32_t sms_mpaxh = msmc->SMS_MPAX_PER_PRIVID[privid].SMS[index].MPAXH;
    
                if (CSL_FEXT(ses_mpaxh, MSMC_SES_MPAXH_0_SEGSZ) != 0)
                {
                    // Clear the "US" bit to make coherent.  This is at 0x80.
                    ses_mpaxh &= ~0x80;
                    msmc->SES_MPAX_PER_PRIVID[privid].SES[index].MPAXH = ses_mpaxh;
                }
    
                if (CSL_FEXT(sms_mpaxh, MSMC_SMS_MPAXH_0_SEGSZ) != 0)
                {
                    // Clear the "US" bit to make coherent.  This is at 0x80.
                    sms_mpaxh &= ~0x80;
                    msmc->SMS_MPAX_PER_PRIVID[privid].SMS[index].MPAXH = sms_mpaxh;
                }
            }
        }
    #endif
    
        /* Initialize the components required to run this application:
         *  (1) QMSS
         *  (2) CPPI
         *  (3) Packet Accelerator
         */
    
        qmss_cfg.master_core = 1;
        qmss_cfg.max_num_desc = MAX_NUM_DESC;
        qmss_cfg.desc_size = MAX_DESC_SIZE;
        qmss_cfg.mem_region = Qmss_MemRegion_MEMORY_REGION0;
    
        if (NIMU_initQmss(&qmss_cfg) != 0)
        {
            platform_write("Failed to initialize the QMSS subsystem \n");
    
            NC_SystemClose();
            return 0;
        }
        else
        {
            platform_write("QMSS successfully initialized \n");
        }
    
        cppi_cfg.master_core = 1;
        cppi_cfg.dma_num = Cppi_CpDma_PASS_CPDMA;
        cppi_cfg.num_tx_queues = NUM_PA_TX_QUEUES;
        cppi_cfg.num_rx_channels = NUM_PA_RX_CHANNELS;
    
        if (NIMU_initCppi(&cppi_cfg) != 0)
        {
            platform_write("Failed to initialize CPPI subsystem \n");
            NC_SystemClose();
            return 0;
        }
        else
        {
            platform_write("CPPI successfully initialized \n");
        }
    
        if (NIMU_initPass() != 0)
        {
            platform_write("Failed to initialize the Packet Accelerator \n");
            NC_SystemClose();
            return 0;
        }
        else
        {
            platform_write("PA successfully initialized \n");
        }
    
        return 0;
    }
    
    
    void networkStack(UArg arg0, UArg arg1)
    {
        Network_stack();
    }
    
    int Network_stack(void)
    {
        int     rc;
        HANDLE  hCfg;
        
        Network_init();
    
        // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!!
        rc = NC_SystemOpen(NET_STACK_TASK_PRIORITY, NC_OPMODE_INTERRUPT);
    
        if (rc)
        {
            platform_write("NC_SystemOpen Failed (%d)\n", rc);
            for (;;);
        }
    
        // Print the banner
        platform_write(banner);
    
        // Create a new configuration
        hCfg = CfgNew();
    
        if (!hCfg)
        {
            platform_write("Unable to create configuration\n");
            NC_SystemClose();
            return 0;        
        }
    
        // Do not show debug messages less than WARNINGS
        rc = DBG_WARN;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        // Setup the TCP and UDP buffer sizes (8192 is the default)
        rc = SOCKTCP_TXBUF_SZ;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // TCP Receive buffer size (copy mode)
        rc = 8192;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // TCP Receive limit (non-copy mode)
        rc = 8192;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // UDP Receive limit
        rc = 8192;
        CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        rc = 4096; // increase stack size
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKBOOT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        hCfg_  = hCfg;
    
        // Boot the system using this configuration and keep booting until the function returns 0. 
        // This allows for a "reboot" command.
        do
        {
            rc = NC_NetStart(hCfg, NetworkOpen, NetworkClose, NetworkIPAddr);
        } while (rc > 0);
    
        // Delete Configuration
        CfgFree(hCfg);
    
        platform_write("Network_stack: exiting\n");
        NC_SystemClose();
    
        return 0;
    }

    And these defines:

    #define NET_STACK_TASK_PRIORITY NC_PRIORITY_HIGH
    #define SOCKTCP_TXBUF_SZ  (16*32768)

    Thanks,
    Mike

  • Sorry - Thanks Steve! (and Todd). Also note, it is the call to NC_SystemOpen() that when I stepped into it, did a hard check to make sure the only valid priorities are hi and low:

        if( Priority != NC_PRIORITY_LOW &&  Priority != NC_PRIORITY_HIGH )
            return(NC_OPEN_ILLEGAL_PRIORITY);

  • Hi Mike,

    OK, here's what I think you should do. I think you should configure the NDK stack via the C code of your Network_stack() function.

    As I mentioned before, the examples you have started with are all set to essentially disable the configuration GUI (i.e. XGCONF). So, everything you've been trying so far (via the GUI) hasn't even had an effect.

    I'd like for you to retry what I wrote previously, but this time in a different way:

    Steven Connell said:

    I would recommend putting your NDK priorities for "low/norm/high/kern" back to the defaults that you can see in that screen shot I posted above. Then also change your scheduler priority to NC_PRIORITY_HIGH and see how things work for you with that.

    If it works well, then you can modify the NDK priorities for "low/norm/high/kern", just as long as you maintain the relationship OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < OS_TASKPRIKERN

    This time, you can do this by adding the following C code to your Network_stack() function (also see attached for the full updated version of that code):

    // use the below macros to rebuild app with updated NDK priorities

    #define MY_NDKPRI_LOW  3
    #define MY_NDKPRI_NORM 5
    #define MY_NDKPRI_HIGH 7
    #define MY_NDKPRI_KERN 9

    #define NET_STACK_TASK_PRIORITY NC_PRIORITY_HIGH


    int Network_stack(void)
    {

    ...

        rc = NC_SystemOpen(NET_STACK_TASK_PRIORITY, NC_OPMODE_INTERRUPT);

    ...

        rc = 4096; // increase stack size
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKBOOT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);

        /* *********************************************************************** */

        /* add the configuration settings for NDK low priority task level. */
        rc = MY_NDKPRI_LOW;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRILOW,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        /* add the configuration settings for NDK normal priority task level. */
        rc = MY_NDKPRI_NORM;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRINORM,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        /* add the configuration settings for NDK high priority task level. */
        rc = MY_NDKPRI_HIGH;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        rc = MY_NDKPRI_KERN;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIKERN,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
        
        /* *********************************************************************** */

        hCfg_  = hCfg;

        // Boot the system using this configuration and keep booting until the function returns 0.
        // This allows for a "reboot" command.
        do
        {
            rc = NC_NetStart(hCfg, NetworkOpen, NetworkClose, NetworkIPAddr);
        } while (rc > 0);

    ...

    }

    Then, create your network application threads using these priorities:

    // network stack thread:
    ...
    ndkStackTskParams.priority = MY_NDKPRI_NORM;
    if (Task_create(networkStack, &ndkStackTskParams, &eb) != NULL) {
    ...

    // TX task
    ...
    tskParams.priority = MY_NDKPRI_NORM;
    Task_create(txTask, &xmt_task_stub_, &eb);

    // RX task
    ...
    tskParams.priority = MY_NDKPRI_NORM;
    Task_create(rxTask, &rcv_task_stub_, &eb);

    // repeat for other network task threads

    Please give that a try using the default priority values in the macros above. Then, if that seems to be working, you can then play around with the priorities (again, being sure to keep them in relative alignment).

    Steve

  • Here's that file attachment:

    config.c
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 5 
    #define MY_NDKPRI_HIGH 7
    #define MY_NDKPRI_KERN 9
    
    int Network_stack(void)
    {
        int     rc;
        HANDLE  hCfg;
        
        Network_init();
    
        // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!!
        rc = NC_SystemOpen(NET_STACK_TASK_PRIORITY, NC_OPMODE_INTERRUPT);
    
        if (rc)
        {
            platform_write("NC_SystemOpen Failed (%d)\n", rc);
            for (;;);
        }
    
        // Print the banner
        platform_write(banner);
    
        // Create a new configuration
        hCfg = CfgNew();
    
        if (!hCfg)
        {
            platform_write("Unable to create configuration\n");
            NC_SystemClose();
            return 0;        
        }
    
        // Do not show debug messages less than WARNINGS
        rc = DBG_WARN;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        // Setup the TCP and UDP buffer sizes (8192 is the default)
        rc = SOCKTCP_TXBUF_SZ;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // TCP Receive buffer size (copy mode)
        rc = 8192;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // TCP Receive limit (non-copy mode)
        rc = 8192;
        CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT,
                    CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );
    
        // UDP Receive limit
        rc = 8192;
        CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        rc = 4096; // increase stack size
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKBOOT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);
    
        /* *********************************************************************** */
    
        /* add the configuration settings for NDK low priority task level. */
        rc = MY_NDKPRI_LOW;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRILOW,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
    
        /* add the configuration settings for NDK normal priority task level. */
        rc = MY_NDKPRI_NORM;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRINORM,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
    
        /* add the configuration settings for NDK high priority task level. */
        rc = MY_NDKPRI_HIGH;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
    
        rc = MY_NDKPRI_KERN;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIKERN,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
        
        /* *********************************************************************** */
    
        hCfg_  = hCfg;
    
        // Boot the system using this configuration and keep booting until the function returns 0. 
        // This allows for a "reboot" command.
        do
        {
            rc = NC_NetStart(hCfg, NetworkOpen, NetworkClose, NetworkIPAddr);
        } while (rc > 0);
    
        // Delete Configuration
        CfgFree(hCfg);
    
        platform_write("Network_stack: exiting\n");
        NC_SystemClose();
    
        return 0;
    }
    
    // network stack thread:
    ...
    ndkStackTskParams.priority = MY_NDKPRI_NORM;
    if (Task_create(networkStack, &ndkStackTskParams, &eb) != NULL) {
    ...
    
    // TX task
    ...
    tskParams.priority = MY_NDKPRI_NORM;
    Task_create(txTask, &xmt_task_stub_, &eb);
    
    // RX task
    ...
    tskParams.priority = MY_NDKPRI_NORM;
    Task_create(rxTask, &rcv_task_stub_, &eb);
    
    // repeat for other network task threads
    

  • I made the changes you suggested.

    The problem still remains in that NC_SystemOpen() will only accept two priorities; either NC_PRIORITY_LOW or NC_PRIORITY_HIGH.

    In the NDK User Guide for NC_SystemOpen() it says; "Two calling arguments, Priority and OpMode,
    indicate how the scheduler should execute." and the NDK API Reference Guide says: "Priority is set to either NC_PRIORITY_LOW or NC_PRIORITY_HIGH, and determines the scheduler task's priority relative to other networking tasks in the system."

    I find NC_PRIORITY_LOW and NC_PRIORITY_HIGH defined in netctrl.h as:

    #define NC_PRIORITY_LOW OS_SCHEDULER_LOWPRI
    #define NC_PRIORITY_HIGH OS_SCHEDULER_HIGHPRI

    and in osif.h I have:

    #define OS_SCHEDULER_HIGHPRI (_oscfg.TaskPriKern-1)
    #define OS_SCHEDULER_LOWPRI (_oscfg.TaskPriLow-1)

    In my debugger I see _oscfg.TaskPriKern has a value 9 and _oscfg.TaskPriLow a value of 3 hence the only priorities I can pass to NC_SystemOpen() are 2 or 8.

    So even with the changes you suggest, it doesn't appear possible to increase the priority of networking tasks. Or am I missing something?

    Another note/comment: It doesn't seem to matter what priority is used in creating network stack thread:

    ndkStackTskParams.priority = MY_NDKPRI_NORM;
    if (Task_create(networkStack, &ndkStackTskParams, &eb) != NULL

    because the task seems to end up at the priority passed in NC_SystemOpen()

    Tests:
    #1
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 5
    #define MY_NDKPRI_HIGH 7
    #define MY_NDKPRI_KERN 9
    and my socket tasks at 7
    Resukt -> everything works.

    #2
    Change my socket tasks to 8.
    Result -> everything appears to work.

    #3
    Change my socket tasks to 9.
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 7
    #define MY_NDKPRI_HIGH 9
    #define MY_NDKPRI_KERN 11
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()


    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 9
    #define MY_NDKPRI_HIGH 11
    #define MY_NDKPRI_KERN 13
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    Mike

  • Mike,

    OK, let me walk through all of this and hopefully it will help clarify things up:

    Mike Dannhardt said:
    #2
    Change my socket tasks to 8.
    Result -> everything appears to work.

    This is not recommended. The highest priority you should set an NDK sockets task to is OS_TASKPRIHIGH

    In this case, OS_TASKPRHIGH == MY_NDKPRI_HIGH == 7, so 8 is in violation of this.

    Mike Dannhardt said:
    #3
    Change my socket tasks to 9.
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    Same reason above applies here.

    You're seeing that illegal call message because in this case, you have set your NDK task to have priority == OS_TASKPRIKERN (also not allowed). When you make a socket call, e.g. send(), early on it calls llEnter() to enter kernel mode. The first thing llEnter() does is check to see if you're already in kernel mode (i.e. if your priority is already OS_TASKPRIKERN). That's the case here, so it prints the error message.

    Mike Dannhardt said:

    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 7
    #define MY_NDKPRI_HIGH 9
    #define MY_NDKPRI_KERN 11
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()


    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 9
    #define MY_NDKPRI_HIGH 11
    #define MY_NDKPRI_KERN 13
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    Hmm ... I would expect these both to work. I'll have to try to reproduce this one and get back to you.

    Mike Dannhardt said:
    So even with the changes you suggest, it doesn't appear possible to increase the priority of networking tasks. Or am I missing something?

    Can you clarify a bit on this?

    What other task threads do you want your networking threads to have priority over?

    Do you want your networking threads (I'm guessing xmt_task_stub, rcv_task_stub) to have higher priority over your non-NDK task threads?

    If that is the case, would something like this work? (using the default working priority values, use something in the middle):

    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 5
    #define MY_OTHER_TASK_PRI 6 // set your other, non networking threads to use this pri
    #define MY_NDKPRI_HIGH 7 // set your xmt & rcv tasks to have this pri
    #define MY_NDKPRI_KERN 9

    With the above, your TX/RX tasks will run at the highest (NDK) priority, which will also be higher than your other non-NDK threads in the system.

    Mike Dannhardt said:
    The problem still remains in that NC_SystemOpen() will only accept two priorities; either NC_PRIORITY_LOW or NC_PRIORITY_HIGH.

    In the NDK User Guide for NC_SystemOpen() it says; "Two calling arguments, Priority and OpMode,
    indicate how the scheduler should execute." and the NDK API Reference Guide says: "Priority is set to either NC_PRIORITY_LOW or NC_PRIORITY_HIGH, and determines the scheduler task's priority relative to other networking tasks in the system."

    I find NC_PRIORITY_LOW and NC_PRIORITY_HIGH defined in netctrl.h as:

    #define NC_PRIORITY_LOW OS_SCHEDULER_LOWPRI
    #define NC_PRIORITY_HIGH OS_SCHEDULER_HIGHPRI

    and in osif.h I have:

    #define OS_SCHEDULER_HIGHPRI (_oscfg.TaskPriKern-1)
    #define OS_SCHEDULER_LOWPRI (_oscfg.TaskPriLow-1)

    Yes, there are only 2 scheduler priorities - high and low relative to all other NDK task threads. The values of these are not meant to be (directly) configurable. Since all NDK application threads should be running at a priority level in the set {OS_TASKPRILOW, OS_TASKPRINORM, OS_TASKPRIHIGH}, they are computed to ensure that the scheduler is either lower or higher than any of these 3 priorities.

    So, we can say:

    • NC_PRIORITY_LOW means: "run the NDK scheduler at a priority that is lower than any other *NDK* application thread in the system."
    • NC_PRIORITY_HIGH means: "run the NDK scheduler at a priority that is higher than any other *NDK* application thread in the system.

    Also, just to be sure in case you missed it, let me again point you to the following section in the NDK User's Guide (you could easily have missed this section because you wouldn't it when searching the doc for "NC_PRIORITY_HIGH" for example):

    3.2.2 Scheduling Options

    That section explains the different permutations of NC priority levels and polling vs interrupt mode.

    Hope this helps.

    Steve

  • Case 1, 2 and 3 were as I expected and understood. I included them to try and give a full picture.
    Case 4 and (woops) 4 are what I did not understand, thought would work and want to work.

    You ask me to clarify _ I want to raise the network related priority tasks higher so that I can set other tasks with lower priorities to a fuller range. I don't want to have to set all other tasks to the same level, say 6. I'd like to be able to prioritize those yet they all will still be under the networking. If networking is stuck at 9 I don't have a full range to work with. Basically I don't have the full 15 levels I thought I'd have.
  • Steven,
    Did my clarification make sense? I want to raise MY_NDKPRI_KERN above 9. Can I make it 15? 13?
    Mike
  • Mike,

    This issue fell through the cracks. I took another look at your priority settings and I think I understand why things weren't working in the scenarios you tried.

    In general, I think I should have more accurately stated the relationship between priorities like this:

        NC_PRIORITY_LOW < OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < NC_PRIORITY_HIGH < OS_TASKPRIKERN  

    But, the problems you've encountered are not your fault (they're mainly due to a known issue, more on that soon).

    The values NC_PRIORITY_LOW/HIGH are supposed to adjust automatically based on the values of OS_TAKSPRIKERN and OS_TAKSPRILOW, in order to maintain the above mentioned priority value relationship, as you have discovered previously:

    #define NC_PRIORITY_LOW             OS_SCHEDULER_LOWPRI
    #define NC_PRIORITY_HIGH            OS_SCHEDULER_HIGHPRI

    #define OS_SCHEDULER_HIGHPRI    (_oscfg.TaskPriKern-1) // TaskPriKern == OS_TASKPRIKERN


    #define OS_SCHEDULER_LOWPRI     (_oscfg.TaskPriLow-1) // TaskPriLow == OS_TASKPRILOW

    So, when you change/configure the

    The problem is that at the time that NC_SystemOpen() runs, the configuration settings you have, have not taken effect yet. What this means is, for example, the setting you have like the following, will not be applied until after NC_SystemOpen() runs:

    The end result is that the default values of NC_PRIORITY_LOW and NC_PRIORITY_HIGH are what's being used when NC_SystemOpen runs.

    This issue is described in the following outstanding bug report:

    NDK-19 NDK configuration values do not apply in NC_SystemOpen

    Having said that, let me give you some analysis of the different scenarios you tried:

    Mike Dannhardt said:
    Tests:
    #1
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 5
    #define MY_NDKPRI_HIGH 7
    #define MY_NDKPRI_KERN 9
    and my socket tasks at 7
    Resukt -> everything works.

    All is good here as you're using the default values. The priority relationship is maintained here as:

     NC_PRIORITY_LOW < 3 < 5 < 7 < NC_PRIORITY_HIGH < 9
    
                               ^
                            skt task

    where:

    • NC_PRIORITY_LOW = 2
    • NC_PRIORITY_HIGH = 8

    Mike Dannhardt said:
    #2
    Change my socket tasks to 8.
    Result -> everything appears to work.

    Here we have:

        NC_PRIORITY_LOW < 3 < 5 < 7 < NC_PRIORITY_HIGH < 9
                                             ^
                                          skt task

    This works, but is actually an illegal priority for your socket task.


    (it's set to NC_PRIORITY_HIGH, same as stack thread pri, which is an illegal pri for skt task. You should set the priority of the socket task to be OS_TASKPRILOW, OS_TASKPRINORM or OS_TASKPRIHIGH). It should be OS_TASKPRILOW, OS_TASKPRINORM or OS_TASKPRIHIGH

        ----> solution: change socket task pri to one of the legal values of OS_TASKPRILOW, OS_TASKPRINORM or OS_TASKPRIHIGH.

    Mike Dannhardt said:
    #3
    Change my socket tasks to 9.
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    Here we have:

        NC_PRIORITY_LOW < 3 < 5 < 7 < NC_PRIORITY_HIGH < 9
                                                         ^
                                                      skt task

        analysis: illegal pri for skt task (it's set to KERN pri). It should be OS_TASKPRILOW, OS_TASKPRINORM or OS_TASKPRIHIGH

        solution: change socket task pri to OS_TASKPRILOW, OS_TASKPRINORM or OS_TASKPRIHIGH.

    Mike Dannhardt said:
    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 7
    #define MY_NDKPRI_HIGH 9
    #define MY_NDKPRI_KERN 11
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

     

    The issues here are due to the aforementioned bug. Due to this bug, the NC priorities are still:

    • NC_PRIORITY_LOW = 2
    • NC_PRIORITY_HIGH = 8

    So we have:

       NC_PRIORITY_LOW < 3 < 7 < NC_PRIORITY_HIGH < 9 < 11
    
                                                    ^
                                                 skt task
    
    
    

    Analysis: this is due to NC_PRIORITY_HIGH staying at priority 8. Therefore,
              NC_PRIORITY_HIGH is no longer in between  OS_TASKPRIHIGH and OS_TASKPRIKERN pri

    Mike Dannhardt said:
    #4
    #define MY_NDKPRI_LOW 3
    #define MY_NDKPRI_NORM 9
    #define MY_NDKPRI_HIGH 11
    #define MY_NDKPRI_KERN 13
    and my socket tasks at 9
    Result -> Fail with output:
    Network_stack: exiting
    00027.004 llEnter: Illegal priority call to llEnter()

    In this case, your socket task has been changed to have a legal priority of OS_TASKPRINORM. But, the issues here are again due to the aforementioned bug. Due to this bug, the NC priorities are still:

    • NC_PRIORITY_LOW = 2
    • NC_PRIORITY_HIGH = 8

    So we have:

        NC_PRIORITY_LOW < 3 < 9 < NC_PRIORITY_HIGH < 11 < 13
    
                              ^
                           skt task



    The bad news is, regarding the latter 2 cases that are due to  the bug, it looks like you're stuck until this issue is fixed.

  • Mike,

    Good news! I've figured out a work around for you regarding this issue. It's a bit of a hack, but if you're careful and update the code just as I'm about to show you, then you should be OK.

    Since the macros NC_PRIORITY_LOW, NC_PRIORITY_HIGH are really just getting the values of the _oscfg struct:

    #define NC_PRIORITY_LOW             OS_SCHEDULER_LOWPRI
    #define NC_PRIORITY_HIGH            OS_SCHEDULER_HIGHPRI
    
    #define OS_SCHEDULER_HIGHPRI    (_oscfg.TaskPriKern-1) // TaskPriKern == OS_TASKPRIKERN
    
    
    #define OS_SCHEDULER_LOWPRI     (_oscfg.TaskPriLow-1) // TaskPriLow == OS_TASKPRILOW

    And since that struct is later updated with the configuration parameters set by the application, we can directly write to that struct, as it is a global - as long as we write the exact same values as the application code will configure it to be anyway.

    This last part is pretty important, as we could end up with priority values that are out of sync. To ensure this consistency, I'm using the #define macros to do this workaround that we used in previous discussions. The values here are taken from your "test case #4 (the first #4)" from your previous response in this thread:

    #define MY_NDKPRI_LOW  4
    #define MY_NDKPRI_NORM 7
    #define MY_NDKPRI_HIGH 9
    #define MY_NDKPRI_KERN 11
    

    Now, to keep things consistent, we must use the above for the workaround, AND make sure to also use them in the config code to actually change the priority values:

    int Network_stack(void)
    {
        int     rc;
        HANDLE  hCfg;
        
        Network_init();

        // **********************
        // workaround for NDK-19:
        // manually update the OS configuration struct ahead of time:
        // **********************
        _oscfg.TaskPriLow = MY_NDKPRI_LOW;
        _oscfg.TaskPriKern = MY_NDKPRI_KERN;

        // test print the values:
        DbgPrintf(DBG_INFO, "steveStackThread: after: NC_PRIORITY_LOW = %d, NC_PRIORITY_HIGH = %d", NC_PRIORITY_LOW, NC_PRIORITY_HIGH);

        // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!!
        rc = NC_SystemOpen(NET_STACK_TASK_PRIORITY, NC_OPMODE_INTERRUPT);

        if (rc)
        {
            platform_write("NC_SystemOpen Failed (%d)\n", rc);
            for (;;);
        }

        // Print the banner
        platform_write(banner);

        // Create a new configuration
        hCfg = CfgNew();

        ...

        // **********************
        // workaround for NDK-19:
        // configure the priorities with the same value:
        // **********************
        /* add the configuration settings for NDK low priority task level. */
        rc = MY_NDKPRI_LOW;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRILOW,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        /* add the configuration settings for NDK normal priority task level. */
        rc = MY_NDKPRI_NORM;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRINORM,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        /* add the configuration settings for NDK high priority task level. */
        rc = MY_NDKPRI_HIGH;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

        rc = MY_NDKPRI_KERN;
        CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIKERN,
                     CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
        

    With the above changes, you should be able to run the NDK with the priorities configured in the macros.

    Steve

  • Steve,

    Thank you. Your work around NDK-19 seems to work for me.  Also your clarification

    In general, I think I should have more accurately stated the relationship between priorities like this:

       NC_PRIORITY_LOW < OS_TASKPRILOW < OS_TASKPRINORM < OS_TASKPRIHIGH < NC_PRIORITY_HIGH < OS_TASKPRIKERN  

    is much clearer. Hopefully the documentation can get updated or at least others can find this  info within this long thread.

    Regards,
    Mike