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/TI-RTOS-MCU: Is there a recommended method for running unit tests on sys/bios-enabled code?

Part Number: TI-RTOS-MCU
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Team,  I have a customer with a TI-RTOS question using Tiva, looking at adding unit tests to their codebase. Much of their modules include some sort of sysbios include (<ti/sysbios/knl/Clock.h> and <ti/sysbios/knl/Semaphore.h> are fairly common). Because of this, The customer is having a lot of trouble building unit tests since all these includes heavily utilize xdc. Is there a recommended method for running unit tests on sysbios-enabled code?

"It only looks like I have a couple of options:

  1. Create new, fake headers / conditionally compile all xdc headers out of unit tests (lots of work)
  2. Target xdc tools for the host OS (x86 Linux, not even sure if this is possible)

We’re not actually trying to build sysbios for our host, instead we would need to stub/fake key functions where necessary. As far as I know, there isn’t anything that we can already leverage for unit testing, but I wanted to check and see if you’re aware of how other projects are handling this / if there’s a standard way of unit testing projects that utilize TI-RTOS."

  • Not TI-RTOS but I can tell you what I use for unit testing C

    Googletest for the test framework and FFF (Fake Free Functions) for the mocks. Reasonably straightforward and FFF makes the mocks easy to write. Hardware registers (if needed) are easily emulated with global variables in a stub file.

    We set it up so that each module has a matching subdirectory and test file. Make ensures the tests are automatically run if the module changes and errors are generated if the test files are missing. Tests are run before compilation is allowed.

    Robert
  • We used to support Linux and Windows for an XDC target. It still might be present (I'd need to dig in a little for make sure) but we do not support it with TI-RTOS (e.g. SYS/BIOS) code anymore. There was simply not enough interest to warrant supporting it.
  • ToddMullanix said:
    There was simply not enough interest to warrant supporting it.

    Yet - "such interest" (or lack thereof) is unlikely to remain static - and arrives right here - right now.

    Are all such "decisions" cast in stone?      And - might such "interest lack" point towards, (pardon) "Non-Vendor specific implementations" - sure to secure, "far higher interest" due to their (substantially) larger user base & "breadth of service?"

  • Nothing is ever cast in stone, but unless an edict from high in our management chain came down, there are no plans in the future to support this.
  • Surely - none of this - "your fault/doing."     That said - the "pitfalls" of any "Vendor-Locked" implementation - are (very) well displayed...

  • Just to provide an illustration of the mocking I use for TIVAWare. This is from a test setup

    FAKE_VOID_FUNC2(GPIOPinTypeGPIOOutput,uint32_t, uint8_t);
    FAKE_VOID_FUNC2(GPIOPinTypeADC,uint32_t, uint8_t);
    
    FAKE_VOID_FUNC3(GPIOPinWrite,uint32_t, uint8_t, uint8_t);
    FAKE_VALUE_FUNC1(bool, SysCtlPeripheralReady,uint32_t);
    
    #define RESET_FFF() {    RESET_FAKE(SysCtlPeripheralEnable); \
        RESET_FAKE(GPIOPinTypeGPIOOutput); \
        RESET_FAKE(GPIOPinTypeADC); \
        RESET_FAKE(GPIOPinWrite); \
        FFF_RESET_HISTORY();}
    

    The calling history of each of the functions defined via this mock interface can be checked. For example to check if a specific peripheral was enabled by the code I add this check to the test

    	// Utility function to check if peripheral has been enabled. 
    bool CheckPeripheralEnabled(uint32_t periph, int line)
    {
        bool ioport_configured;
    
    	// Make sure history is stored
        EXPECT_LT(SysCtlPeripheralEnable_fake.call_count,
        	SysCtlPeripheralEnable_fake.arg_history_len) << 
    	"Too many SysCtlPeripheralEnable to analyze -- Line " << line;
    
        ioport_configured = FALSE;
        for( int i=0; i < SysCtlPeripheralEnable_fake.call_count; i++){
             if(SysCtlPeripheralEnable_fake.arg0_history[i]==periph){
                  ioport_configured = TRUE;
    	      }
             }
        return ioport_configured;     
    }
    
    

    And the check itself

        EXPECT_TRUE(CheckPeripheralEnabled(SYSCTL_PERIPH_ADC0, line)) << "SYSCTL_PERIPH_ADC0 not enabled -- Line " << line;
    

    Straightforward and you don't need to depend on the supplier to provide you with test functions to match your environment.

    Robert