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/MSP432P401R: Clock_start() within Task Causing RTOS to Abort

Part Number: MSP432P401R

Tool/software: TI-RTOS

Let me preface by saying that I am new to using the TI-RTOS, so the mistake might be something obvious.

The issue itself, is that TSK_read_accelerometer() is only running once then it terminates.

I have edited MSP_EXP432P401R.c, MSP_EXP432P401R.h, and Board.h to add support for ADC Channels 11, 13, and 14 to be able to use the accelerometer on the Booster Pack.

This is the task itself. SEMHDL_update_accel is posted by a clock module. That code will also be posted below.

Void TSK_read_accelerometer()
{
    while(1) {
        // wait for resource to be available
        Semaphore_pend(SEMHDL_update_accel, BIOS_WAIT_FOREVER);

        // disable all other interrupt sources; Hwi_disable() also disables tasks and Swis
       // UInt key = Hwi_disable();

        // update accel prev
        accel_prev = accel_current;

        // update accel_current
        accel_current.z = ADC_read_z_axis();
        accel_current.y =  ADC_read_y_axis();
        accel_current.x = ADC_read_x_axis();

        // update accel max values
        if (accel_current.z > accel_max.z)
            accel_max.z = accel_current.z;

        if (accel_current.y > accel_max.y)
            accel_max.y = accel_current.y;

        if (accel_current.x > accel_max.x)
            accel_max.x = accel_current.x;

        // Check for fall detection
        if ( (accel_current.z > accel_prev.z - 3000) ||
             (accel_current.z < accel_prev.x + 3000) ||
             (accel_current.z > 15000))               {
            Clock_start(CLK_HDL_enable_buzzer);
        }

        System_printf("X: %d\t", accel_current.x);
        System_printf("Y: %d\t", accel_current.y);
        System_printf("Z: %d\n", accel_current.z);
        System_flush();
    }
    // re-enable Hwi's, Swi's, and tasks
  //  Hwi_restore(key);
}

Here is the clock module code. It is periodic.

Void CLK_TSK_read_accelerometer()
{
    Semaphore_post(SEMHDL_update_accel);
}

Here is a sample that reads a single ADC channel. It is very similar to the driver example.

uint16_t ADC_read_z_axis()
{
    ADC_Handle   adc;
    ADC_Params   params;
    uint16_t adc_val;
    int_fast16_t res;

    ADC_Params_init(&params);
   adc = ADC_open(Board_ADC11, &params);
/*
   if (adc == NULL) {
       System_abort("Error initializing ADC channel z\n");
   }
   else {
       System_printf("ADC channel z initialized\n");
   }
*/
   res = ADC_convert(adc, &adc_val);
   if (res == ADC_STATUS_ERROR) {
       adc_val = 0;
   }

   ADC_close(adc);
   return adc_val;
}

Here is the console output. It prints the ADC values only a single time.

System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
X: 10986 Y: 10947 Z: 14886
FSR = 0x0000
HFSR = 0x40000000
DFSR = 0x00000001
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...

Update: I found out that the issue is Clock_start(CLK_HDL_enable_buzzer); being called within my task. Why would this be causing these issues?

Update 2: I reread the user guide. The clock module runs as a Swi, and according to the documentation only a Hwi or Swi can post another Swi. I'm essentially posting a Swi from a Task.

Here's my entire project code: Project5_Peters.zip

  • Hello Drue,
    I will need to discuss with my colleagues. TI-RTOS is bundled with the SimpleLink SDK, so I am a little unsure of the software configuration you are using.

    For you reference here is the SDK and an ADC example:

    www.ti.com/.../software.html

    www.ti.com/.../SIMPLELINK-MSP432-SDK

    dev.ti.com/.../

    dev.ti.com/.../

    Regards,
    Chris
  • I was basing my example off of the example found in the Resource Explorer.

    I've included a screenshot showing where the configuration is. The main issue with this thread has been solved. I added the explanation under update 2

    There is something weird going on with the ADC, though. I get different results using the RTOS ADC driver than I do manual configuration through the normal SDK, but that might be for a separate thread. The reference voltage for both is set at 2.5V.

    Edit: I actually just dived into the source code and edited the ADCMSP432.c file. Everything is working like it should be.

    One last question before I close this. How do I submit a feature request? I wrote a function that allows me port map a single pin. It might be a good addition to DriverLib. It allows you to port map pins on the same port from multiple places. For instance, on this board, the RGB LED is P2.0 - P2.2, and the buzzer is P2.7. I wrote drivers for each, but ran into an issue because of the port mapping. So, I wrote a function that allows port mapping of a single pin.

    Anyway, I know that's for a separate thread, and wanted to know where I might post that as a possible feature.

  • Hi Drue,

    First, I'd recommend you use SimpleLink MSP432P4 SDK instead of TI-RTOS for MSP430. The latter product has MSP432P4 support, but all ongoing development in TI for the MSP432P4 is with the SimpleLink SDK.

    Having said that, I expect you are getting a blown stack. Can you take a look at this page to see techniques to debug the issue: training.ti.com/debugging-common-application-issues-ti-rtos

    Todd
  • Also, I saw that you are using grlib. I did not look at the project too much, but a common problem with grlib is that it is not thread-safe. Are you making grlib calls from more than one task? If so, you'll need to add some mutual exclusion. To avoid this, we generally recommend making all the grlib calls from a single task.

    Todd
  • I just relooked and saw how to create it from SimpleLink SDK... The Resource Explorer has changed several times.
    This is a homework assignment, but I'll definitely change for our next project. I had to manually configure dependencies to use the MSP430 version. That probably would have made things much simpler.

    Also, are you sure it's a blown stack?

    When the error originally popped up, I checked my stack sizes. My code is running flawlessly since I've changed my code.

    I've made a lot of changes since the original post.

    This was my reasoning:
    Clock_start() is being called within a task.
    Clock_start() posts a swi.
    This post is within a task.
    Error is because I'm posting a swi from within a task.

  • GRLIB is contained to a single task.

    I'm using a semaphore and some flags for updating. 

    Void TSK_update_LCD()
    {
        while (1) {
            // wait for SEMHDL_update_LCD to be posted from button press
            Semaphore_pend(SEMHDL_update_LCD, BIOS_WAIT_FOREVER);
            
            // wait for disp_flags to be available
            Semaphore_pend(SEMHDL_disp_flags, BIOS_WAIT_FOREVER);
    
            if (disp_flags.disp_accel_max) {
                draw_accel_max();
                disp_flags.disp_accel_max = 0;
            }
    
            if (disp_flags.disp_accel_curr) {
                draw_accel_curr();
                disp_flags.disp_accel_curr = 0;
            }
    
            if (disp_flags.disp_temp) {
                draw_temp();
                disp_flags.disp_temp = 0;
            }
            Semaphore_post(SEMHDL_disp_flags);
        }
    }

    Here is an example of a function being called within:

    void draw_temp()
    {
        // declared static because there's no use in waiting for reallocation if this runs all the time
        static char disp_str[10];
        
        Semaphore_pend(SEMHDL_update_temp, BIOS_WAIT_FOREVER);
        
        // write temp to disp_str
        sprintf(disp_str, "%.2f", temperature);
        
        // set temperatue style for display
        set_temp_style();
        
        Graphics_drawStringCentered(&g_sContext, (int8_t *)disp_str,   5, 64, 40, OPAQUE_TEXT);
        
        // go back to default style
        set_default_style();
    
        Semaphore_post(SEMHDL_update_temp);
    }

  • Did you check the System stack (ROV->Hwi->Module or BIOS->Scan for Errors)? Swi's run on the system stack.
    I'm not sure what you meant when you said "Clock_start() posts a swi.". Calling Clock_start or Swi_post from a Clock function is fine. Calling Clock_start or Swi_post from a Task is fine also.
  • I did at the time and no errors were reported. The code has since been fixed. The updated code is at in files project5.c and project5.h.

    I can create a test case if you would like that. It's been consistent.

    Could you explain why calling Clock_start or Swi_post is fine? I've included a screenshot from the user's guide that seems to contradict. I'm just trying to understand everything going on.

    Page 68 of:  .

  • Hi Drue,

    Sorry, I was out of the office on vacation.

    The paragraph you attached is stating that if a ISR calls Swi_post, it must be a ISR managed by the SYS/BIOS dispatcher. It cannot be a zero-latency (non-managed) ISR.

    The best place to look is the Context calling tables in the SYS/BIOS API reference. For example, here is the Swi_post valid calling contexts

    Todd

**Attention** This is a public forum