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/LAUNCHXL-F28379D: Is driverlib compatible with SYS/BIOS?

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software: TI-RTOS

Hello,

I wrote my own I2C library for non-BIOS projects. Now I would like to write a BIOS version. I made a project and I added driverlib headers. I added driverlib sources and include paths to the project too. Project compiles but when I put in my code any function from driverlib application crashes.

So, here is my question - is there any way to use driverlib in SYS/BIOS projects?

BR,

Dawid.

  • Hi Dawid,

    They are compatible. Can you tell me more about the crash you're seeing? Are you getting an error message?

    Whitney
  • Hi Whitney,

    I can't see "red error" but after pushing "play" button my application immadiately stops. I solved that issue in the meantime - I realised that I added "Interrupt_initVectorTable();" line. I read that this is forbidden while using RTOS. Now, I have another issue.

    I would like to use I2C so I created Hwi (INT8.1 has 88 number) and I put 88 as interrupt number. Should I do anything else to enable this interrupt in rtos?

    Here is my code:

    #include <xdc/std.h>
    #include <xdc/runtime/Log.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Swi.h>
    
    #include "driverlib.h"
    #include "device.h"
    #include "i2c_library.h"
    
    #define SLAVE_ADDRESS               0x20
    
    I2C_Master_t I2cMaster;
    
    // Global functions
    void I2C_lib_init(uint32_t I2C_BASE, I2C_Master_t *i2c)
    {
        *i2c = InitializeFunctionPointers();
    
        // zapisanie w strukturze adresu używanego modułu I2C
        i2c->I2C_BASE = I2CA_BASE;
    
        // Must put I2C into reset before configuring it
        I2C_disableModule(I2C_BASE);
    
        // I2C configuration.
        I2C_initMaster(I2C_BASE, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_50);
        I2C_setBitCount(I2C_BASE, I2C_BITCOUNT_8);
        I2C_setEmulationMode(I2C_BASE, I2C_EMULATION_FREE_RUN);
    
        // Enable stop condition and register-access-ready interrupts
        I2C_enableInterrupt(I2C_BASE,   I2C_INT_STOP_CONDITION |
                                        I2C_INT_REG_ACCESS_RDY |
                                        I2C_INT_RX_DATA_RDY |
                                        I2C_INT_TX_DATA_RDY |
                                        I2C_INT_NO_ACK
                                        );
    
        // FIFO configuration
        I2C_enableFIFO(I2C_BASE);
        //I2C_clearInterruptStatus(I2C_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
    
        // Configuration complete. Enable the module.
        I2C_enableModule(I2C_BASE);
    }
    
    
    /*
     *  ======== main ========
     */
    Int main()
    {
        GPIO_setPinConfig(GPIO_104_SDAA);
        GPIO_setPadConfig(104, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(104, GPIO_QUAL_ASYNC);
        GPIO_setPinConfig(GPIO_105_SCLA);
        GPIO_setPadConfig(105, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(105, GPIO_QUAL_ASYNC);
    
        Interrupt_initModule();
        // Interrupt_initVectorTable();
        I2C_lib_init(I2CA_BASE, &I2cMaster);
        //Interrupt_enable(INT_I2CA);
    
        /*
         * Print "Hello world" to a log buffer. 
         */
        Log_info0("Hello world\n");
    
        /* 
         * Start BIOS
         * Perform a few final initializations and then
         * fall into a loop that continually calls the
         * installed Idle functions.
         */
        BIOS_start();    /* does not return */
        return(0);
    }
    
    /*
     *  ======== myIdleFxn ========
     *  Background idle function that is called repeatedly 
     *  from within BIOS_start() thread.
     */
    Void myIdleFxn(Void) 
    {
        uint8_t data[] = {0x0F, 0x1F, 0x2F, 0x3F, 0x4F};
        if(I2cMaster.status == I2CM_STATUS_READY)
            if(!I2C_getStopConditionStatus(I2CA_BASE))
                I2C_lib_MasterWriteRead(&I2cMaster, SLAVE_ADDRESS, data, 0, 5);
    }
    
    Void I2caISR()
    {
        I2C_lib_InterruptHandler(&I2cMaster);
    }
    

    I am not sure if I can use functions like: Device_init(); Device_initGPIO(); or Interrupt_enable(INT_I2CA); in RTOS.

    I can see in my scope that nothing is happening on I2C lines so I think I am making I2C config wrong. So how should I do it properly in RTOS?

    BR,
    Dawid.

  • You still will need parts of Device_init(). The SYS/BIOS Boot module can configure the system clock for you, but it won't enable the peripheral clocks. Either call Device_enableAllPeripherals() or call SysCtl_enablePeripheral() for the specific peripherals you're using. SYS/BIOS doesn't configure any GPIOs, so Device_initGPIO() is fine to call as is.

    The Hwi module should take care of initializing the vector table and enabling the interrupts you're using in the PIE and CPU, so you shouldn't have to call the Interrupt module functions.

    processors.wiki.ti.com/.../BIOS_for_the_28x

    Whitney
  • Whitney,

    according to your previous message I made some changes in my code. Here it is:

    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);
        Device_enableAllPeripherals();
        Device_initGPIO();
        GPIO_setPinConfig(GPIO_104_SDAA);
        GPIO_setPadConfig(104, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(104, GPIO_QUAL_ASYNC);
        GPIO_setPinConfig(GPIO_105_SCLA);
        GPIO_setPadConfig(105, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(105, GPIO_QUAL_ASYNC);
    
        Interrupt_initModule();
        I2C_lib_init(I2CA_BASE, &I2cMaster);
        Interrupt_enable(INT_I2CA);

    Now I2C fires and interrupt handler fires to, but here is my log from console:

    [C28xx_CPU1] Tick Count = 1
    ackOverflow: ISR stack overflow.
    xdc.runtime.Error.raise: terminating execution


    Auto Acknowledge in BIOS config is checked. I checked BIOS config and I can see this:

    I am not sure if that clock frequency is correct. In non-BIOS projects my frequency clock was always 200 MHz. It is possible that ackOverflow: ISR stack overflow is caused by bad CPU clock settings?

    BR,

    Dawid.

  • I don't think that the clock frequency would cause a stack overflow. On that page that you've posted a screenshot above, try increasing the "System (Hwi and Swi) stack size" field and see if that helps. You can use ROV in the CCS Debug session (it's under Tools > ROV Classic for me--might depend on what version you're using) to check on your stack usage. Select Hwi from the modules list and click the Module tab for stack info.

    But you are correct that SYS/BIOS has configured your SYSCLK to run at a different speed than the C2000Ware code. You can adjust that in the Boot module.

    Whitney

  • Whitney,

    thank you very much for sending me Clock Configuration. It's working fine.

    I increased stack size and I was watching hwi stack peak with different configurations for a while. I noticed that when I am using System_printf() and System_flush() stack peak is much bigger. It's bigger than 300. Now, when I comment out system_printf and system_flush stack peak it's smaller than default 256, but it's still high I think:

    I think it's a big number. What do you think about that?

    BR,
    Dawid.

  • Printf functions tend to use quite a bit of stack, so that doesn't surprise me. I don't think the numbers you're seeing are worryingly large either though. Do you have a couple function calls in your Hwis? You could try stepping through your code and watching the stack in the memory browser to try to see where it's coming from if you're concerned.

    Whitney
  • My Hwi looks like this:

    Void I2caISR()
    {
        I2C_lib_InterruptHandler(&I2cMaster);
    }

    where I2C_lib_InterruptHandler is:

    void I2C_lib_InterruptHandler(I2C_Master_t *i2c)
    {
        I2C_InterruptSource intSource = i2c->GetInterruptSource(i2c->I2C_BASE);//I2C_getInterruptSource(i2c->I2C_BASE);
    
        switch(intSource)
        {
            case I2C_INTSRC_TX_DATA_RDY:
                I2C_lib_MasterWriteHandler(i2c);
                break;
            case I2C_INTSRC_RX_DATA_RDY:
                I2C_lib_MasterReadHandler(i2c);
                break;
            case I2C_INTSRC_REG_ACCESS_RDY:
                I2C_lib_MasterRegAccessReadyHandler(i2c);
                break;
            case I2C_INTSRC_NO_ACK:
                I2C_lib_MasterNoAckHandler(i2c);
                break;
            case I2C_INTSRC_STOP_CONDITION:
                I2C_lib_MasterStopConditionHandler(i2c);
                break;
        }
    }

    What do you think? Is it a good approach in rtos or should I fire Swi to handle this interrupt?

    I look in the Memory Browser and I can see this:

  • That seems fine. Whether or not is should be changed to a Swi is typically a matter of what your other Hwis' priorities are and which ones need to be able to interrupt each other.

    Whitney
  • Whitney,

    I understand. Thank you very much for your help, you really helped me a lot. Now I have got a good point to explore BIOS further.

    BR,

    Dawid.