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.

Problem with HALCoGen FreeRTOS project

Other Parts Discussed in Thread: HALCOGEN

Making a HALCoGen (v.04.00.00) FreeRTOS project for RM48 microcontroller.

Got a problem with Software Timer functions (xTimerCreate()xTimerReset(),xTimerStop() etc.):
calling any of then inside a task causes a PREFETCH exception of the microcontroller.

Calling them inside main function is ok.

Parameters from FreeRTOSConfig.h

#define configUSE_TIMERS                1
#define configTIMER_TASK_PRIORITY       ( configMAX_PRIORITIES - 2 )
#define configTIMER_QUEUE_LENGTH        10
#define configTIMER_TASK_STACK_DEPTH    ( 128 )

 

The Code

#include "
#include "het.h"
#include "gio.h"
#include "FreeRTOS.h"
#include "timers.h"
#include "task.h"

void vTask1(void *pvParameters);

uint32 i = 0;

xTimerHandle xTimer1;

// Timer callback function
void vTimerFunction(xTimerHandle xTimer)
{
    // toggle port bits
    gioToggleBit(hetPORT1, i);
    i++;
    if (i>31)
        i=0;
    // restart timer
    xTimerReset(xTimer1, 0);
}

// Main function
void main(void)
{
    // configure port direction (outputs)
    gioSetDirection(hetPORT1, 0xFFFFFFFF);
    // configure port output pins initial value
    gioSetPort(hetPORT1, 0xFFFFFFFF);
    // creating task
    xTaskCreate(vTask1, (const signed char *)"TimerStart", 1024, NULL, (configMAX_PRIORITIES - 3), NULL);
    vTaskStartScheduler();
    while(1);
}

// Task function
void vTask1(void *pvParameters)
{
    // timer creation
xTimer1 = xTimerCreate((const signed char *)"Timer1", 80 / portTICK_RATE_MS, pdFALSE, (void*) 0, vTimerFunction);
// reset timer
if
(xTimer1 != NULL)
xTimerReset(xTimer1, 0);
// task self-destruction
vTaskDelete( NULL );
}

Using Assemly Step Into while calling xTimerCreate shows, that prefetch exception occures directly after uC tries to execute instruction BL xTimerCreate (look at the screenshot).

So, calling xTimerCreate causes prefetch exception.

Moving block

xTimer1 = xTimerCreate((const signed char *)"Timer1", 80 / portTICK_RATE_MS, pdFALSE, (void*) 0, vTimerFunction);
    if (xTimer1 != NULL)
        xTimerReset(xTimer1, 0);

into the main function (for example, before vTaskStartScheduler()) makes code working properly.

 

P.S. Othe FreeRTOS modules - tasks execution, queues, semaphores - work excelent. Except software timers.

The complete CCS project is attached.

What's wrong?

TimerTest.zip
  • Alexander,


    I'm working on your problem.
    Can you tell me which version of Code Composer Studio you are using?
    Also can you share the Halcogen Configuration file so I can re-create and see the configuration you are using.

  • Alexander,

    In your vTask1 you are trying to create a timer by calling xTimerCreate.
    vTask1 is executed in USER mode (no privilege) and xTimerCreate needs the CPU to be in privilege mode to execute. This is the reason you are getting an prefetch abort.

    When the code (xTimerCreate) is moved in moved inside main() it is working. The CPU is still in privilege mode.
    Once vTaskStartScheduler(); is executed, the MPU is set to protect the FLASH region holding the Kernel and a portion of the RAM used by the kernel. This is to protect the OS. The CPU is than switched to USER (no-privilege)

    Also, to my understanding, timers have to be created before starting the scheduler. (to be confirmed)

    Here is the modified main. This way it is working.

    void main(void)
    {
    /* USER CODE BEGIN (3) */
        // configure port direction (output)
        gioSetDirection(hetPORT1, 0xFFFFFFFF);
        // configure port output pins initial value
        gioSetPort(hetPORT1, 0xFFFFFFFF);

        xTimer1 = xTimerCreate((const signed char *)"Timer1", 80 / portTICK_RATE_MS, pdFALSE, (void*) 0, vTimerFunction);
        if( xTimer1 == NULL )
        {
            printf("Timer not created\n");
            /* The timer was not created. */
        }
        else
         {
             /* Start the timer.  No block time is specified, and even if one was
             it would be ignored because the RTOS scheduler has not yet been
             started. */
             if( xTimerStart( xTimer1, 0 ) != pdPASS )
             {
                 /* The timer could not be set into the Active state. */
             }
         }

        // creating task if necessary

        vTaskStartScheduler();
        while(1);
    /* USER CODE END */
    }

    Please have a try and let me know.

  • Thank you for your response.

    I use Code Composer Studio v.6.0.0.00190.

    HALCoGen project file is attached.

    Your variant of code is working, I've already tried to do like this. And I don't mind creating timers before starting the scheduler.

    But what should I do, if I need to use other Software Timer functions after starting the scheduler? Like xTimerStop, for example?

    For example, here is a modified version of sys_main.c, where timer is being created and starts counting before vTaskStartScheduler. And being stopped inside vTask1. We get the same error when calling xTimerStop - prefetch exception.

     

    #include "sys_common.h"

    #include "het.h"
    #include "gio.h"
    #include "FreeRTOS.h"
    #include "os_timer.h"
    #include "os_task.h"

    void vTask1(void *pvParameters);

    uint32 i = 0;

    xTimerHandle xTimer1;

    // Timer callback function
    void vTimerFunction(xTimerHandle xTimer)
    {

            // toggle port bits
            gioToggleBit(hetPORT1, i);
            i++;
            if (i>31)
                    i=0;

            // restart timer
            xTimerReset(xTimer1, 0);

    }

    void main(void)
    {
            // configure port direction (output)
            gioSetDirection(hetPORT1, 0xFFFFFFFF);
            // configure port output pins initial value
            gioSetPort(hetPORT1, 0xFFFFFFFF);

            // timer creation and start
            xTimer1 = xTimerCreate((const signed char *)"Timer1", 80 / portTICK_RATE_MS, pdFALSE, (void*) 0, vTimerFunction);
            if (xTimer1 != NULL)

                    xTimerStart(xTimer1, 0);

            // creating task
            xTaskCreate(vTask1, (const signed char *)"TimerStart", 1024, NULL, (configMAX_PRIORITIES - 3), NULL);

            vTaskStartScheduler();

            while(1);
    }

    void vTask1(void *pvParameters)
    {

            // stop timer
            xTimerStop(xTimer1, 0);

            // task self-destruction
            vTaskDelete( NULL );
    }

     

    If all timer functions usage inside tasks (i.e. after starting the scheduler) is prohibited, then I don't understand the purpuse of these Software Timers.

    They can not be managed during the normal program execution. Because, actually, all the code before starting a scheduler is a sort of initialization code. When one is using RTOS, all target functions are implemented after starting the scheduler.

    Timers, that can't be managed when the scheduler is already running, are senseless since they can't  be syncronized with any events inside tasks.

     

    So, what should I do to be able to Start, Reset, Stop timers after running the scheduler to make them working in combination with tasks?

    HALCoGen_TimerTest.zip
  • Alexander,

    If you look in os_timer.h there is a comment:

    /*
     * Functions beyond this part are not part of the public API and are intended
     * for use by the kernel only.
     */
    portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
    portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;

    So myy understanding is all other xTimer API should work. But if you look at the way xTimerStop is defined:

    #define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )

    It also calls xTimerGenericCommand and so need privilege.

    In your example, vTimerFunction is a callback routine and so is executed in SYSTEM mode (privilege) That is the reason why the xTimerReset() function is executed without problem.

    At that point, I will suggest to contact or post your question to FreeRtos forum.

  • Alexander,


    I did some research on FreeRtos forum and here is an interesting post.

    https://sourceforge.net/p/freertos/discussion/382005/thread/7b474ff5/

    Can you try and see if this is helpful?

  • Jean-Marc,

    used given URL and modified FreeRTOS source code in accordance with recomendation on FreeRTOS forum. Everything is working now, all timer functions are implemented successfully inside task functions and the project in general is also running well. Now going to test it longer and variously.

    Thank you very much for your help!

  • Alexander,

    Will you be able to share your modified project?
    I can send you a personal email if you don't want to make it public.

    Thanks.

  • Following FreeRTOS files were modified:

    os_mpu_wrappers.h
    os_timer.h
    os_mpu_wrappers.c

    This simple program works, but I'm going to make the same changes in my primary big project with many tasks, queues etc. I'll write to this post if I find errors while testing.

    TimerTest_Mod.rar