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.

TMS570LC4357: FreeRTOS demo hang

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

I created a simple demo using the FreeRtos profile for HalCogen and compiled it using CC8.3.0. 

The entirety of the code is here:

/** @file HL_sys_main.c 
*   @brief Application main file
*   @date 07-July-2017
*   @version 04.07.00
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* 
* Copyright (C) 2009-2016 Texas Instruments Incorporated - www.ti.com  
* 
* 
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/* USER CODE BEGIN (0) */
#include <stdio.h>
#include <FreeRTOS.h>
#include <os_task.h>
#include <os_queue.h>
#include <assert.h>
#include <HL_gio.h>
/* USER CODE END */

/* Include Files */

#include "HL_sys_common.h"

/* USER CODE BEGIN (1) */
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */

static QueueHandle_t tickQueue = NULL;
static uint32 LEDState = 0;

static void tickTask( void *pvParameters ) {

    uint32_t val;
    gioSetBit(gioPORTB,6,1);

    for( ;; )
    {
        /* Wait until something arrives in the queue - this task will block
        indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
        FreeRTOSConfig.h. */
        xQueueReceive( tickQueue, &val, portMAX_DELAY );
        gioSetBit(gioPORTB,7,LEDState);
        LEDState = 1 - LEDState;
//        printf("Val: %d\n",val);
    }
}


/* USER CODE END */

uint8	emacAddress[6U] = 	{0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
uint32 	emacPhyAddress	=	1U;

int main(void)
{
/* USER CODE BEGIN (3) */

    gioInit();

    printf("Startup!\n");

    tickQueue = xQueueCreate( 10, sizeof( unsigned long ) );

    assert(tickQueue);

    BaseType_t stat = xTaskCreate( tickTask,                   /* The function that implements the task. */
                "ticker",                                   /* The text name assigned to the task - for debug only as it is not used by the kernel. */
                configMINIMAL_STACK_SIZE,               /* The size of the stack to allocate to the task. */
                0, /* The parameter passed to the task - just to check the functionality. */
                tskIDLE_PRIORITY + 1 ,        /* The priority assigned to the task. */
                NULL );                                 /* The task handle is not required, so NULL is passed. */

    assert(stat == pdPASS);

    vTaskStartScheduler();
/* USER CODE END */

    return 0;
}


/* USER CODE BEGIN (4) */

uint32_t count = 0;
uint32_t divider = 10;

void vApplicationTickHook( void ) {
    count++;
    if (count % divider == 0) {
        xQueueSendFromISR( tickQueue, (void*)count, NULL );
    }
}
/* USER CODE END */

The example runs for about 24 hours then hangs. Breaking into the execution brings me here:

resetEntry
        b   _c_int00
undefEntry
        b   undefEntry
        b   vPortSWI
prefetchEntry
        b   prefetchEntry
dataEntry
        b   dataEntry
        b   phantomInterrupt
        ldr pc,[pc,#-0x1b0]
        ldr pc,[pc,#-0x1b0]

    
;-------------------------------------------------------------------------------

The debugger highlights the "b dataEntry" line.

I set the tick rate on the OS config tab to 100Hz.

Any idea why this is happening?

  • Hello

    The CPU takes the data abort if data is read from or written to a protected or faulty memory location. This could be because of:

    –The memory location is not implemented
    –The memory location is read or write only in privileged mode (when processor is in User mode)
    –The memory location is read or write protected by the MPU
    –If an error is detected in the data by the ECC checking logic
    Data aborts can be precise or imprecise
    Please check the CP15 register to find the source of the data abort. The Data Fault Status Register (DFSR) holds status information regarding the source of the last data abort.
  • DFSR shows 0x00000000. DFAR is 0x00400006.
  • Is there a way to recover the stack?
  • The vApplicationTickHook() runs periodically from the timer ISR, once every tick, and it has higher priority than your task tickTask. The code looks ok to me.

    My question is that what happens if the Queue is empty when you try to copy the queue data to your buffer &val in your tickTask.

    The DFSR shows that abort address is at 0x0040_0006 which is out of our flash range. The TMS570LC43x has 4MB flash from 0x0 to 0x3F_FFFF.
  • tickTask() will only wake up without a message if it times out. In that event, val should be left unmodified.

    I am using an out-of-the-box HacCoGen FreeRTOS configuration for this, so someone at TI is maintaining a FreeRTOS port. Is it possible to communicate with the person or team directly? This looks like an issue with the port.

  • Hi Timothy
    To be accurate, my understanding is that the Halcogen FreeRTOS configuration was something that we had enabled a few years back (~3-4 years back), the developer is no longer with the team and we are not proactively maintain FreeRTOS port.
    Recently we have seen an uptick in queries and potential issues with the port - and we will evaluate if in coming quarters we need to do a refresh etc.
    For now, I would recommend continuing to work with QJ to see if he can help you work through the issues you are facing.
    Sorry for the inconvenience and frustration - there is likely room for improvement on FreeRTOS/Halcogen support in the longer run.

    Regards
    Mukul
  • Thank you - we are evaluating the R5/FreeRtos combination for some Smallsat/Cubesat projects, so it would be nice to have a stable configuration. Not sure how to proceed at the point since it seems like it could be FreeRtos internals that I'm not familiar with.

  • Hi Timothy,

    My apologies for late response. I reviewed your code again and noticed that your code xQueueSendFromISR( tickQueue, (void*)count, NULL ); will not be able to send the value of count to the queue.

    Please change the code to:
    xQueueSendFromISR( tickQueue, (void*)&count, NULL );

    If there are another ISR that is going to access tickQueue, the critical section may be needed for reading the queue.

    portENTERCRITICAL();
    ....
    portEXITCRITICAL();
  • Hello,

    The problem is caused by your code:
    xQueueSendFromISR( tickQueue, (void*)count, NULL );

    This function sends data at address (void*)count to the Queue. When the value of count is larger than 0x3FFFFF, (void*)count reads the data from an unimplemented memory. --> –The memory location is not implemented (my response on May 1st, May 17).

    Using (void*)&count will solve your problem.
  • Wow! Computer Science 101 goof on my part! Let me try it.
  • That was it! Thanks for spotting it.