FreeRtos Harmony V3 Linker Error

Hi,

I am trying to migrate a harmony v3 project from pic32mk1024mcf064 to pic32mk1024mcm064.

Project with pic32mk1024mcf064 worked ok, before update mplabx, xc32 compiler and harmony.

After some changes i got stuck in this linker error:

c:\microchip\xc32\v3.01\bin\bin\gcc\pic32mx\8.3.1\..\..\..\..\bin/pic32m-ld.exe: build/default/production/_ext/951553261/port_asm.o: in function `vPortTickInterruptHandler':
C:\Users\02373893983\Desktop\MPLAB Programas\freeRTOS-LVGL-12-10-2021\firmware\PIC32MK.X/../src/third_party/rtos/FreeRTOS/Source/portable/MPLAB/PIC32MK/port_asm.S:108: multiple definition of `__vector_dispatch_4'; build/default/production/_ext/1171490990/interrupts.o:c:/users/02373893983/desktop/mplab programas/freertos-lvgl-12-10-2021/firmware/src/config/default/interrupts.c:(.vector_4+0x0): first defined here
c:\microchip\xc32\v3.01\bin\bin\gcc\pic32mx\8.3.1\..\..\..\..\bin/pic32m-ld.exe: build/default/production/_ext/951553261/port_asm.o: in function `vPortYieldISR':
C:\Users\02373893983\Desktop\MPLAB Programas\freeRTOS-LVGL-12-10-2021\firmware\PIC32MK.X/../src/third_party/rtos/FreeRTOS/Source/portable/MPLAB/PIC32MK/port_asm.S:159: multiple definition of `__vector_dispatch_1'; build/default/production/_ext/1171490990/interrupts.o:c:/users/02373893983/desktop/mplab programas/freertos-lvgl-12-10-2021/firmware/src/config/default/interrupts.c:(.vector_1+0x0): first defined here
c:\microchip\xc32\v3.01\bin\bin\gcc\pic32mx\8.3.1\..\..\..\..\bin/pic32m-ld.exe: Link terminated due to previous error(s).

Info: Loading file: ./..\src\config\default\p32MK1024MCM064.ld
collect2.exe: error: ld returned 255 exit status
make[2]: *** [dist/default/production/PIC32MK.X.production.hex] Error 255
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 31s)

Thank’s for the help.

It is hard to say more than the linker error is already telling you - the FreeRTOS kernel code is defining an interrupt that is already defined in default/interrupts.c. You need to keep the kernel’s implementation - so have a look at your old project to see how that removed the default implementation from interrupts.c - how that is done is going to be tools specific, rather than FreeRTOS specific - maybe there is a build time option, or interrupts.c needs to be edited, or whatever.

I don’t know if harmony generated the code wrongly or what.
After i commented the “New code” below, the code compiled.
I just need to test in the hardware now.

File: interrupts.c

Old code:

// *****************************************************************************

#include "definitions.h"

// *****************************************************************************
// *****************************************************************************
// Section: System Interrupt Vector Functions
// *****************************************************************************
// *****************************************************************************

void CORE_TIMER_InterruptHandler( void );  // Prototype function.


/* All the handlers are defined here.  Each will call its PLIB-specific function. */
void __ISR(_CORE_TIMER_VECTOR, ipl1SOFT) CORE_TIMER_Handler (void)
{
    CORE_TIMER_InterruptHandler();
}

/*******************************************************************************
 End of File
*/

New code:

// *****************************************************************************

#include "interrupts.h"
#include "definitions.h"


// *****************************************************************************
// *****************************************************************************
// Section: System Interrupt Vector Functions
// *****************************************************************************
// *****************************************************************************


void CORE_TIMER_InterruptHandler( void );



/* All the handlers are defined here.  Each will call its PLIB-specific function. */
void __ISR(_CORE_TIMER_VECTOR, ipl1SRS) CORE_TIMER_Handler (void)
{
    CORE_TIMER_InterruptHandler();
}

/*
void __ISR(_CORE_SOFTWARE_0_VECTOR, ipl1SRS) CORE_SOFTWARE_0_Handler (void)
{
}

void __ISR(_TIMER_1_VECTOR, ipl1SRS) TIMER_1_Handler (void)
{
}
*/

/*******************************************************************************
 End of File
*/

The hardware without FreeRtos are working.

But the function “void vApplicationTickHook( void )” is not being called.

I think timer1 are not running, i dont know yet.

#define configUSE_TICK_HOOK 1

Hi,

I decided to create a very simple project from scratch using harmony v3.
I only add freertos module to test.
The harmony v3 is generating a strange code that generates the bug of the title of this question.

The function “void vApplicationTickHook( void )” are called ok.
When i comment out the code inside “void vApplicationTickHook( void )” and enable the code( my_led_toggle(); ) inside task “loxa” the program crash.

If in debug mode step by step the code dont crash.
If in debug mode full running the code crash, only when i enable the code( my_led_toggle(); ) inside task “loxa” .

freertos_hooks.c file harmony v3 generated.

#define my_led_toggle() ( LATAINV = _LATA_LATA7_MASK )

void vApplicationTickHook( void )
{
    /* This function will be called by each tick interrupt if
    configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
    added here, but the tick hook is called from an interrupt context, so
    code must not attempt to block, and only the interrupt safe FreeRTOS API
    functions can be used (those that end in FromISR()). */
   
    static uint32_t c = 0;

    c++;
    if( c == 1000 )
    {
        c = 0;
        my_led_toggle();
    }    
}

main.c file.

#include <proc/p32mk1024mcm064.h>
#include <stdint.h>
#include "definitions.h"  // SYS function prototypes 

#include "third_party/rtos/FreeRTOS/Source/include/FreeRTOS.h"
#include "task.h"

#define my_led_toggle() ( LATAINV = _LATA_LATA7_MASK )

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

void loxa( void* pvParameters )
{
    while(1)
    {
        my_led_toggle();
        
        vTaskDelay( 250 );
    }    
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

int main( void )
{   
    SYS_Initialize( NULL );  // Initialize all modules    

//////////////////////////////////////////////////////////////////////////////// 
   
    while(1)
    {         
        TickType_t tempo = 250;        
                
        xTaskCreate(    loxa,
                        "func1Test",
                        512,  // words(4 bytes). 512 words * 4 = 2048 bytes.
                        &tempo,  
                        1,
                        (TaskHandle_t*) NULL       
                    );
        
        vTaskStartScheduler();    
    }   
}

https://www.microchip.com/forums/m1187881.aspx

Some suggestion on why in debug mode step by step the freertos dont crash and in debug mode running the freertos crash.

Hi,

Any suggestion ?

Hi,

I’m sending a link to download the project for anyone interested in testing it.

Thank’s.

You may find interrupts are disabled when step debugging - so the issue could be in an ISR if it only works when step debugging.

Now i’m debugging again.

The task only runs once and FreeRtos doesn’t return anymore.

It feels like it gets stuck in a loop inside FreeRtos.

What have you done to try and debug this? “If feels like it gets stuck in a loop” - what do you actually see it doing if you break on the debugger. Have you read through https://freertos.org/FAQHelp.html

Now i put one i/o output in “vApplicationTickHook”:

void vApplicationTickHook( void )
{
    /* This function will be called by each tick interrupt if
    configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
    added here, but the tick hook is called from an interrupt context, so
    code must not attempt to block, and only the interrupt safe FreeRTOS API
    functions can be used (those that end in FromISR()). */
    
    static int c = 0;
    
    c++;
    if( c == 1000 )
    {
        c = 0;
        my_led_toggle_pin_1();
    } 
}

And another i/o output in task “loxa”:
main file too.

void loxa( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );
    
    while(1)
    {
        my_led_toggle_pin_2();
        
        vTaskDelay( xDelay );
    }    
}

main file:

int main( void )
{   
    SYS_Initialize( NULL );
    
//////////////////////////////////////////////////////////////////////////////// 
   
    TickType_t tempo = 500;        
                
    xTaskCreate( loxa,
                 "func1Test",
                 512,    // words(4 bytes). 512 words * 4 = 2048 bytes.
                 &tempo,  
                 1,
                 (TaskHandle_t*) NULL       
               );
                
    vTaskStartScheduler();
}

As the tick of FreeRtos is set at 1000Hz, the “vApplicationTickHook” is toggling the i/o every 1 second and are OK.

The task “loxa” is toggling the i/o at 75 kHz and are not ok.
The correct one would be to toggle the i/o every 500 ms.

I’m measuring with an oscilloscope.

I think that the problem is a microchip FreeRtos port bug for PIC32MK1024MCM064
Or
I think that the problem is a microchip Mplab harmony 3 generating a bad configured code for PIC32MK1024MCM064.

The PIC32MK1024MCM064 has a MIPS32 core.

It looks like you are calling vTaskDelay(1), and expecting that to delay for exactly 1 tick interrupt each time - but when you only have a granularity of 1 the actual time you delay will depend on how far through the tick interrupt you are when the delay period starts - it will delay up to the next tick as there are no fractions of a tick. So if you ask for a delay of 1 immediately after the last tick you will get nearly a whole tick period, if you ask for a delay of 1 immediately before a tick you will get a small fraction of a tick period.

Actually, this is the usual main() stack fallacy: You pass a pointer into the startup stack as the parameter to your stack function. It’s been discussed here many many times that this won’t work because FreeRTOS will reuse the startup stack when the scheduler starts. Change the declaration of tempo in main() to static and see if that changes anything in the behavior you see.

Hi @RAc,

xDelay inside task “loxa” is static.

With another chip(pic32mk1024mcf064) and other tools versions, the project worked in the same way.

Now i turned on my hardware and the led that indicate tick time dont blink.

I went to debug and now it’s generating an exception.

If i comment the “my_led_toggle_pin_2();” inside task “loxa” the tick time led blink( ie: program run).

I am lost.

_excep_addr

_excep_code

Now the problem is here: “vTaskStartScheduler();”

Specifically here: file port.c

/* Kick off the highest priority task that has been created so far.
Its stack location is loaded into uxSavedTaskStackPointer. */

uxSavedTaskStackPointer = *( UBaseType_t * ) pxCurrentTCB;
vPortStartFirstTask();

Hi @RAc,

I tested like this.
Same problem.
The task “loxa” is toggling the i/o at 75 kHz and are not ok.

"
As the tick of FreeRtos is set at 1000Hz, the “vApplicationTickHook” is toggling the i/o every 1 second and are OK.

The task “loxa” is toggling the i/o at 75 kHz and are not ok.
The correct one would be to toggle the i/o every 500 ms.

I’m measuring with an oscilloscope.
"

void loxa( void* pvParameters )
{
    /*
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );
    */
    
    while(1)
    {
        my_led_toggle_pin_2();
        
        vTaskDelay( 500 );
    }    
}