Compilation/Linker Issues in Running the Demo Example for FreeRTOS/Demo/RL78_RL78G13_Promo_Board_IAR directory

Hello All,

I am also stuck in porting the FreeRTOS on RL78 Renesas MCU. I am using IAR version 4.2 and FreeRTOS 10.3.1 . Initially my demo code was for R5F100LEA(RL78_RL78G13_Promo_Board_IAR). I had the below lines which were giving the error in in “port87.asm” file.

COMMON INTVEC:CODE:ROOT(1)
ORG configTICK_VECTOR
DW vPortTickISR

COMMON INTVEC:CODE:ROOT(1)
ORG 126
DW vPortYield

Afterwards I have changed the above instructions to the below.

ASEGN .intvec:CODE:ROOT,56
DATA16
DC16 vPortTickISR

ASEGN .intvec:CODE:ROOT,126
DATA16
DC16 vPortYield

Now again errors are coming mentioned below.

Error[Li005]: no definition for “vRegTestError” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\RegTest.o]
Error[Li005]: no definition for “usCriticalNesting” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\portasm.o]
Error[Li005]: no definition for “pxCurrentTCB” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\portasm.o]
Error[Li005]: no definition for “xTaskIncrementTick” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\portasm.o]
Error[Li005]: no definition for “vTaskSwitchContext” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\portasm.o]
Error[Li005]: no definition for “_vRegTest1” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\main.o]
Error[Li005]: no definition for “_vRegTest2” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\main.o]
Error[Li005]: no definition for “_vPortStartFirstTask” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\port.o]
Error[Li005]: no definition for “_vTaskDelayUntil” [referenced from C:\Users\Anmol Arora\FreeRTOSv10.3.1\FreeRTOSv10.3.1\FreeRTOS\Demo\
RL78_RL78G13_Promo_Board_IAR\Debug\Obj\blocktim.o]
Error[Lp011]: section placement failed
unable to complete “place at” directives with a total estimated minimum size of 0x7c bytes in <[0x4-0x37]> (total space 0x34).
Error[Lp015]: section placement failure: overcommitted content in [0x4-0x37]
Error while running Linker

The above errors are saying that the mentioned variables(vRegTestError) are undefined portasm.o . When I am opening this file “portasm.o”, its not written in C, its an output of compiler file. Please tell how can I remove these errors.

Best Regards
Anmol Arora

I think there is an incompatibility in the output format used by the IAR compiler since the RL78 port was created. You have already fixed up one piece of assembly, and I think there are addition changes required.

I would however recommend you spend some time learning how the C compilation process works. The linker (after compilation) is telling you there is an object file generate from a source file that contains a reference it can’t find. The compiler generates the object .o files from the source files, and in the case of portasm.o the source file is an assembly file, not a C file. Likewise regtest is also an assembly file. So it looks like the method of importing and exporting symbols from assembly files is different with your version of the compiler.

Hello,

the issues seem to be famous because many threads are found as followings. But unfortunately every thread doesn’t show all steps to succeed building the project. So, I’d like to try to fix the issues and post the result regardless of success or fail. If it is succeeded then I’d like to post a pull request. (As of today, nobody posted a pull request regarding to the issues.)

https://www.freertos.org/FreeRTOS_Support_Forum_Archive/March_2016/freertos_Unable_to_compile_FreeRTOSV9.0.0rc1_with_IAR_2.20_5fbce14dj.html

http://www.openrtos.net/FreeRTOS_Support_Forum_Archive/November_2016/freertos_Assembler_Build_Errors_in_FreeRTOS_Demo_using_RL78_IAR_EW_v7.4_15bfb02dj.html

https://sourceforge.net/p/freertos/bugs/172/

https://renesasrulz.com/rl78/f/the-rl78-forum/6145/freertos-compilation-in-iar-for-rl78

https://renesasrulz.com/rl78/f/the-rl78-forum/7122/freertos-on-rl78-g14-with-iar-2-21-1-demo

https://renesasrulz.com/rl78/f/the-rl78-forum/8967/freertos-demo-on-rl78-with-iar-2-21-1-is-not-compiling

https://renesasrulz.com/rl78/f/the-rl78-forum/9585/freertos-porting-on-iar-3-10

Best regards,
NoMaY

Hello,

Now I understand that it is wrong to use ‘ASEGN .intvec:CODE:ROOT,XX<newline>DATA16’ instead of ‘COMMON INTVEC:CODE:ROOT(1)<newline>ORG XX’ if the segment is the interrupt vector table area. And I understand that it is correct to define one more label such as ___interrupt_0xXX: at the start address of ISR.

This is original code: (configTICK_VECTOR is 0x38.)

; Install the interrupt handlers

    COMMON INTVEC:CODE:ROOT(1)
    ORG configTICK_VECTOR
    DW vPortTickISR

The following modification is wrong:

; Install the interrupt handlers

    ASEGN .intvec:CODE:ROOT,0x38
    DATA16
    DC16 _vPortTickISR

Above code causes the following linker errors because the interrupt vector table is already placed at address 0x4-0x7F but above new absolute segment starts at address 0x38 therefore these two areas overlap:

Error[Lp011]: section placement failed 
    unable to complete "place at" directives with a total estimated minimum size of 0x7c bytes in <[0x4-0x37]> (total space 0x34). 
Error[Lp015]: section placement failure: overcommitted content in [0x4-0x37] 

The following modification is correct:

PUBLIC    _vPortTickISR
PUBLIC    ___interrupt_0x38    <---- HERE

 RSEG CODE:CODE
_vPortTickISR:
___interrupt_0x38:    <---- HERE
portSAVE_CONTEXT               ; Save the context of the current task.
call    _xTaskIncrementTick    ; Call the timer tick function.
cmpw    ax, #0x00
skz
call    _vTaskSwitchContext    ; Call the scheduler to select the next task.
portRESTORE_CONTEXT            ; Restore the context of the next task to run.
reti

; Install the interrupt handlers

;    Nothing to do.    <---- HERE

MAP file shows that ___interrupt_0xXXs are pre-difined weak code labels and ___interrupt_tab_0xXXs are pre-difined global data labels:

___interrupt_0x00         0x4839         Code  Gb  cstartup.o [3]
___interrupt_0x04         0x48e1   0x13  Code  Wk  default_handler.o [3]
...
___interrupt_0x36         0x48e1   0x13  Code  Wk  default_handler.o [3]
___interrupt_0x38         0x49f2         Code  Gb  portasm.o [1]
___interrupt_0x3A         0x48e1   0x13  Code  Wk  default_handler.o [3]
...
___interrupt_0x7C         0x48e1   0x13  Code  Wk  default_handler.o [3]
___interrupt_0x7E         0x49aa         Code  Gb  portasm.o [1]
___interrupt_tab_0x00        0x0         Data  Gb  interrupt_vector.o [3]
___interrupt_tab_0x04        0x4         Data  Gb  interrupt_vector.o [3]
...
___interrupt_tab_0x36       0x36         Data  Gb  interrupt_vector.o [3]
___interrupt_tab_0x38       0x38         Data  Gb  interrupt_vector.o [3]
___interrupt_tab_0x3A       0x3a         Data  Gb  interrupt_vector.o [3]
...
___interrupt_tab_0x7C       0x7c         Data  Gb  interrupt_vector.o [3]
___interrupt_tab_0x7E       0x7e         Data  Gb  interrupt_vector.o [3]

Now I can build the project on my desktop with other modifications and I’m thinking how to check the modification because I don’t have RL78/G13 Promotion Board.

Other modifications:

Source/portable/IAR/RL78/{portasm.s87, ISR_Support.h}

  • Define ___interrupt_0x7E: at the start address of __vPortYield:.
  • Add ‘_’ at the beginning of PUBLIC symbols and EXTERN symbols.

Demo/RL78_RL78G13_Promo_Board_IAR/RegTest.s87

  • Add ‘_’ at the beginning of PUBLIC symbols and EXTERN symbols.

Demo/RL78_RL78G13_Promo_Board_IAR/FreeRTOSConfig.h

  • Change the following definision. (Probably one of demo common source file was changed after this demo was created.)
    #define INCLUDE_vTaskDelayUntil 0 ----> 1

Best regards,
NoMaY

Hello,

Now I understand that the following method is no longer available due to the incompatible change of ioreg definition header files because (at least the latest version of EWRL78) ICCRL78’s header files have neither ‘#define RTCEN XXXX’ nor ‘#define TMKAEN XXXX’. So, I’ll consider something to fix it.

port.c

static void prvSetupTimerInterrupt( void )
{
    const uint16_t usClockHz = 15000UL; /* Internal clock. */
    const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;

    /* Use the internal 15K clock. */
    OSMC = ( uint8_t ) 0x16;

    #ifdef RTCEN    <---- HERE
        {
            /* Supply the interval timer clock. */
            RTCEN = ( uint8_t ) 1U;

            /* Disable INTIT interrupt. */
            ITMK = ( uint8_t ) 1;

            /* Disable ITMC operation. */
            ITMC = ( uint8_t ) 0x0000;

            /* Clear INIT interrupt. */
            ITIF = ( uint8_t ) 0;

            /* Set interval and enable interrupt operation. */
            ITMC = usCompareMatch | 0x8000U;

            /* Enable INTIT interrupt. */
            ITMK = ( uint8_t ) 0;
        }
    #endif /* ifdef RTCEN */

    #ifdef TMKAEN    <---- HERE
        {
            /* Supply the interval timer clock. */
            TMKAEN = ( uint8_t ) 1U;

            /* Disable INTIT interrupt. */
            TMKAMK = ( uint8_t ) 1;

            /* Disable ITMC operation. */
            ITMC = ( uint8_t ) 0x0000;

            /* Clear INIT interrupt. */
            TMKAIF = ( uint8_t ) 0;

            /* Set interval and enable interrupt operation. */
            ITMC = usCompareMatch | 0x8000U;

            /* Enable INTIT interrupt. */
            TMKAMK = ( uint8_t ) 0;
        }
    #endif /* ifdef TMKAEN */
}

By the way, the avobe code seems to be the following code. (mistake of +/-, not so important.)

WRONG:

const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;

CORRECT:

const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) - 1UL;

Hello,

Now I understand that RL78_RL78G13_Promo_Board_IAR’s RegTest.s87 is no longer correct maybe due to the change of assembly language syntax of ‘Bcond’ instructions. At least the latest version of EWRL78, ‘Bcond’ instructions need -2 offset as follows.

No longer correct:

MOVW    AX, BC
CMPW    AX, #0x3344
BZ      +5            <---- HERE
BR      vRegTestError   
MOVW    AX, DE
CMPW    AX, #0x5566
BZ      +5            <---- HERE
BR      vRegTestError   
MOVW    AX, HL  
CMPW    AX, #0x7788
BZ      +5            <---- HERE
BR      vRegTestError
MOV     A, CS
CMP     A, #0x01
BZ      +5            <---- HERE
BR      vRegTestError

Correct:

MOVW    AX, BC
CMPW    AX, #0x3344
BZ      +5-2            <---- HERE
BR      _vRegTestError  
MOVW    AX, DE
CMPW    AX, #0x5566
BZ      +5-2            <---- HERE
BR      _vRegTestError  
MOVW    AX, HL  
CMPW    AX, #0x7788
BZ      +5-2            <---- HERE
BR      _vRegTestError
MOV     A, CS
CMP     A, #0x01
BZ      +5-2            <---- HERE
BR      _vRegTestError

Hello,

Now I understand that the 16bit ticks mode needs the following definition (at least the latest version of EWRL78) for RTOSDemo working. (This definition had been known already for CC-RL and GNURL78 in the Japanese user forum for Renesas development tools.) Maybe only early versions of EWRL78 were able to build RTODemo working without this definition. Fortunately another RTOSDemo (in the RL78_multiple_IAR directory) which is built by the latest EWRL78 now becomes working with RL78/G14 Fast Prototyping Board on my desktop. I think that all updated source files will be posted in a week.

FreeRTOSConfig.h

#if (configUSE_16_BIT_TICKS == 1)
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( uint32_t ) ( xTimeInMs ) * ( uint32_t ) configTICK_RATE_HZ ) / ( uint32_t ) 1000 ) )
#endif 

By the way, the past issue of RTCEN and TMKAEN is fixed as follows:

port.c

#if INTIT_vect == 0x38
    {
        ...omit...
    }
#endif /* if INTIT_vect == 0x38 */

#if INTIT_vect == 0x3C
    {
        ...omit...
    }
#endif /* if INTIT_vect == 0x3C */

portasm.s87

#if INTIT_vect == 0x38

    #define ___interrupt_TICK_VECTOR ___interrupt_0x38

#endif

#if INTIT_vect == 0x3C

    #define ___interrupt_TICK_VECTOR ___interrupt_0x3C

#endif

#ifndef ___interrupt_TICK_VECTOR

    #error Neither vector 0x38 nor vector 0x3C is available for the tick interrupt.

#endif

`

PUBLIC ___interrupt_TICK_VECTOR

`

_vPortTickISR:
___interrupt_TICK_VECTOR: