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.

No CAN ISR in HW_ISR example

Other Parts Discussed in Thread: SYSBIOS

 Alan DeMars posted RE: Sysbios Hwi in BIOS forum.

Mark,

Please open a new Forum thread for this issue.

Having said that, I suspect that the problem you're having is that you're application is being interrupted to death because ALL or SEVERAL of the interrupts you created are enabled and pending.

Just prior to calling the user's ISR, the interrupt dispatcher re-enables global interrupts.

If another interrupt is pending, it will be serviced immediately, preventing the ISR code from being arrived at.

On the way to servicing the pre-empting interrupt, the dispatcher will again re-enable global interrupts just before calling the ISR code. etc, etc...

By default, when interrupts are created, they are also enabled.

The Hwi parameter that controls whether an interrupt is automatically enabled when created is 'enableInt' and it is true by default.

If you want only ONE of your CAN interrupts enabled when created, set this parameter to 'false' in your config script for all Hwi's except the one you're interested in.

Alan

 

Hi Alan

When I try my code I transmit 1 packet to the 28335 only so I should get just one ISR. I also comment out the call to

PWMInit() ;  /// this enables  pwm interrupts

when I run my code just to be safe I will remove all the HWI's I have in the GUI and leave only the CAN RX mailbox and rerun the example

 

I dont think its being overidden by IRQS as setting a bkpt in any ISR I never get there 

 

 

  • Mark,

    Have you seen this FAQ page?

    http://processors.wiki.ti.com/index.php/SYS/BIOS_for_the_28x

    Steve

  • Hi Steve

    I have several questions about this page the below statement

    Alternately, you can use the 28x-specific versions of the run-time APIs and static configuration settings provided by the ti.sysbios.family.c28.Hwi module. These include some additional features for 28x only. To use this module, include the following in your code:

    C code: #include <ti/sysbios/family/c28/Hwi.h>
    Configuration script: var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');

    I dont see the your supplied pwm.c including any header file and it works???????

     Explain this please it confuses me. Do I need c code to accomplish what I want  OR can I use .cfg and use no code?

    I am beginning to suspect that I have expectation of the  GUI that dont exist I also supspect my .cfg is NOT getting saved correctly

    This being said I want a simple .cfg that will attach PIE  vec 101 here is what I have pasted from within CCS of idle.cfg

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
    var Boot = xdc.useModule('ti.catalog.c2800.init.Boot');

    /*
     * Use SysMin for output (System_printf() and error messages) and
     * minimize the output buffer size to save data space.
     */
    System.SupportProxy = SysMin;
    SysMin.bufSize = 80;

    /*
     * Create a LoggerBuf and make it the default logger for all modules.
     */
    var LoggerBufParams = new LoggerBuf.Params();
    LoggerBufParams.numEntries = 16;
    var logger0 = LoggerBuf.create(LoggerBufParams);
    Defaults.common$.logger = logger0;

    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    /*
     * Minimize size of the system stack.  System stack usage by the app
     * can be reviewed with ROV in the module view for ti.sysbios.knl.Task.
     */
    Program.stack = 512;

    /*
     * Program.argSize sets the size of the .args section.
     * The examples don't use command line args so argSize is set to 0.
     */
    Program.argSize = 0x0;

    /*
     * Uncomment this line to globally disable Asserts.
     * All modules inherit the default from the 'Defaults' module.  You
     * can override these defaults on a per-module basis using Module.common$.
     * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
     */

    /*
     * Uncomment this line to keep module names from being loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
    Defaults.common$.namedModule = false;
     */

    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 4;       

    /*
     * Uncomment this line to disable the Error print function.  
     * We lose error information when this is disabled since the errors are
     * not printed.  Disabling the raiseHook will save some code space if
     * your app is not using System_printf() since the Error_print() function
     * calls System_printf().
    Error.raiseHook = null;
     */

    /*
     * Uncomment this line to keep Error, Assert, and Log strings from being
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
    Text.isLoaded = false;
     */

    /*
     * Uncomment this line to disable the output of characters by SysMin
     * when the program exits.  SysMin writes characters to a circular buffer.
     * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
     */

    /*
     * Application specific configuration
     */
     
    /*
     * Disable unused BIOS features to minimize footprint.
     * This example does not use Swis, Tasks, or Clocks.
     */
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.swiEnabled = false;
    BIOS.taskEnabled = false;
    BIOS.clockEnabled = false;

    /* Minimize system heap size */
    BIOS.heapSize = 0x0;

    /*
     * In this example, runtime support functions that need
     * a lock are NOT called from multiple threads that can
     * pre-empt each other.
     *
     * Use the simplest lock function available.
     */
    BIOS.rtsGateType = BIOS.NoLocking;

    /* Add a background idle function */
    var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    Idle.addFunc("&myIdleFxn");

    /*
     * Build a custom BIOS library.  The custom library will be smaller than the
     * pre-built "instrumented" (default) and "non-instrumented" libraries.
     *
     * The BIOS.logsEnabled parameter specifies whether the Logging is enabled
     * within BIOS for this custom build.  These logs are used by the RTA and
     * UIA analysis tools.
     *
     * The BIOS.assertsEnabled parameter specifies whether BIOS code will
     * include Assert() checks.  Setting this parameter to 'false' will generate
     * smaller and faster code, but having asserts enabled is recommended for
     * early development as the Assert() checks will catch lots of programming
     * errors (invalid parameters, etc.)
     */
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = false;
    BIOS.assertsEnabled = true;
    Boot.pllOSCCLK = 25;
    BIOS.cpuFreq.lo = 75000000;
    Boot.pllcrDIV = 6;
    Boot.configurePll = false;

    var hwi1Params = new Hwi.Params();
    hwi1Params.instance.name = "hwi1";
    hwi1Params.arg = null;
    Program.global.hwi1 = Hwi.create(101, "&CAN_LowPriorityISR", h

  • Hwi_create returns NULL for this as well

    Void main()
    {

        Hwi_Params hwiParams;
        Hwi_Handle myHwi;
        Error_Block eb;
        /*
         * Print "Hello world" to a log buffer.
         */
        DeviceInit();   // Hardware and Peripheral Initialization

        Log_info0("Hello world\n");
    //    PWMInit() ;
        Log_info0("PWMs initialized\n");

        Error_init(&eb);

        Hwi_Params_init(&hwiParams);

        hwiParams.arg = 101;
        hwiParams.enableAck = 1;
    //    hwiParams.maskSetting = Hwi.MaskingOption_BITMASK;
        hwiParams.disableMask = 0x0;
        hwiParams.restoreMask = 0x0;
        hwiParams.enableInt = 0;

        myHwi = Hwi_create(101,CAN_LowPriorityISR,&hwiParams,&eb);
        if(myHwi == NULL)
        {
            while(1);
        }
        Hwi_enableInterrupt(101);

  • Hi mark lazarewicz1,

    Which version of SYS/BIOS are you using?  CCS version?

    If you haven't already, you may want to have a look at the SYS/BIOS Getting Started Guide and User's Guide.  You can find them via CCS help:

    Also, have you seen the C28x PIE example that comes with SYS/BIOS?  You can import this example into your workspace by selecting the CCS menu Project->New CCS Project.  Then Select the PIE example.  Below screen should help.

    Steve

  • This example seems to generate two interrupts then stops generating interrupts. is this by design?

  • Yes.  The example is meant to show you how to handle peripheral interrupts, and that's accomplished by manually setting bits in both the IER and IFR registers.

    In a "real world" use case, these interrupts would come from one or more actual peripherals.

    Steve

  • Yes but why is  task myTaskFxn only executed once?

  • Once a Task function exits, the task will enter the terminated state and is essentially done.  Usually this is prevented by using a loop of sorts within a Task function.  However, since the code of myTaskFxn doesn't have a loop, the function posts the PIE interrupts, and then returns (and in result, ending the Task).

    If you wanted to change that behavior, you could add a while loop around the code that posts the PIE interrupts, possibly with a Task_sleep() call as well, and then you would see the interrupts posted more than one time (with each iteration of the loop).

    Steve

  • Thanks Steve

    I set up PIE Vector 101 dynamically and used this example as a starting point

    I have my CAN Rx PIE IRQ working you can close this issue after explaining

    below question please

    In parting I need to understand the period that SYSBIOS scheduler runs at and how that is configured. typically an RTOS

    has a timer set at 10 mS. is this the case with SYSBIOS? which timer is used on 28335 and where is the scheduler code? I need to validate this

    code i dont see the caller of TaskSupport_asm.s28 in my call stack

  • Hello again Mark,

    The scheduler is invoked as needed.

    It is given energy whenever any API modifies the state of the Task or Swi ready queues in order to guarantee this rule: "At any given time, the highest priority thread that is ready to run is running".

    APIs such as Semaphore_pend() and Semaphore_post() will usually invoke the scheduler inline.

    When Semaphore_post() is called from within a Hwi or Swi, the invocation of the task scheduler is delayed until all Hwis and Swis have been serviced and the CPU is about to return to the task thread that was originally pre-empted to determine if it is still the highest priority ready task and adjust the return behavior accordingly.

    The common task scheduling C code can be found in the Task_schedule() function within Task.c.

    The task scheduler invokes the target/device specific ti_sysbios_family_c28_TaskSupport_swap() register context saving/restoring API by means of a proxy-delegate binding in the implementation of the Task_SupportProxy_swap() function.

    Regarding timer usage and tick period, the default Clock module tick period is 1ms (1000us). This period is configurable by setting the Clock.tickPeriod parameter in the config script

    By default, the Clock module statically configures Timer 0 of 28x timers to provide the 1ms interrupt. The choice of which timer is used is controlled by the Clock.timerId configuration parameter.

    Alan

  • Thanks Alan and Steve for the excellant support!

    I wont even ask what a proxy-delegate binding is (-: