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.

RM46L852: FreeRTOS on RM46 - Missing function in portASM.asm file

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

Hi,

I'm trying to port FreeRTOS 10 to the RM46, based on what is provided by Halcogen.

One of the problems I'm encountering is MPU support.
To support the MPU, we need to define the following definitions in portmacro.h

- portIS_PRIVILEGED()
- portRAISE_PRIVILEGE()
- portRESET_PRIVILEGE()

Those definitions will be used in the mpu_wrappers.c. For example:

      void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */
        {
            if( portIS_PRIVILEGED() == pdFALSE )
            {
                portRAISE_PRIVILEGE();
                portMEMORY_BARRIER();

                vTaskDelete( pxTaskToDelete );
                portMEMORY_BARRIER();

                portRESET_PRIVILEGE();
                portMEMORY_BARRIER();
            }
            else
            {
                vTaskDelete( pxTaskToDelete );
            }
        }

While portRAISE_PRIVILEGE is defined in the SWI jump table, xIsPrivileged() and  vResetPrivilege() are not.

The table in question, as defined in portASM.asm

;-------------------------------------------------------------------------------
; SWI Handler, interface to Protected Mode Functions

        .def    vPortSWI
        .asmfunc
vPortSWI
        stmfd   sp!, {r11,r12,lr}
        mrs     r12, spsr
        ands    r12, r12, #0x20
        ldrbne  r12, [lr, #-2]
        ldrbeq  r12, [lr, #-4]
        ldr     r14,  table
        ldr     r12, [r14, r12, lsl #2]
        blx     r12
        ldmfd   sp!, {r11,r12,pc}^

table
        .word    jumpTable

jumpTable
        .word    swiPortYield                 ; 0 - vPortYieldProcessor
        .word   swiRaisePrivilege         ; 1 - xPortRaisePrivilege
        .word   swiPortEnterCritical         ; 2 - vPortEnterCritical
        .word   swiPortExitCritical          ; 3 - vPortExitCritical
        .word   swiPortTaskUsesFPU            ; 4 - vPortTaskUsesFPU
        .word    swiPortDisableInterrupts     ; 5 - vPortDisableInterrupts
        .word    swiPortEnableInterrupts      ; 6 - vPortEnableInterrupts
        .endasmfunc

I need help defining the assembly required to support the xIsPrivileged() and  vResetPrivilege() functions.

Is the TI compiler has a SVC of some sort? A bit like :

    #define portRAISE_PRIVILEGE()    __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );

Regards,
Gabriel

  • HI Gabriel,

    We don't have those two functions: xIsPrivileged() and vResetPrivilege(). 

  • Hi QJ,

    That was not exactly what I was hoping for, but I'm thankful for your straight-to-the-point attitude.

    In my opinion, those functions' absence prevents HalCoGen from being used with newer versions of FreeRTOS.
    If TI were to provide them, it would be possible for the community to port the kernel.

    Regards,
    Gabriel

  • Hi Gabriel,

    I understand your query. I don't knw what the xIsPrivileged() and vResetPrivilege() fo in the new version freeRTOS. In Cortex-R devices, the modes other than user mode are collectively known as Privileged modes: IRQ, FIQ, SVC, Abort, Undefine, and System. The M[4:0] of CPSR register is used to config the mode.

  • You can use the code below to get the ARM mode. 

    .def _Get_ARM_Mode

    .asmFunc

    _Get_ARM_Mode

            MRS R0, CPSR                              ;Get CPSR Value
            AND R0, R0, #0x1F                        ;Clear rest of the information
           BX LR

    .endasmfunc

    If return value (in R0) is b10000, it is in USER mode (non-privileged mode).

  • You can write your own code to restore the ARM mode for example IRQ mode, System Mode, etc:

    .def _Restore_IRQ
    .asmfunc

    _Restore_IRQ

       STMFD SP!, {R1,R2}             ;Save R1 on stack

       MRS R1, CPSR                     ;Retrieve current CPSR
       MOV R2, #0x80                     ;Need to clear bit #7 (IRQ bit)
       BIC R1, R1, R2 
       ORR R1, R1, R0                    ;Set IRQ bit as per input
       MSR CPSR_CSXF, R1          ;Write to CPSR

       LDMFD SP!, {R1,R2}             ;Pop R1 from stack
       BX LR

    .endasmfunc

    In C/C++ code, calling _Restore_IRQ(irqStatus) will restore the IRQ.