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.

RTOS/TMS570LS1224: Call FEE functions from FreeRTOS tasks hangs.

Part Number: TMS570LS1224
Other Parts Discussed in Thread: HALCOGEN

Tool/software: TI-RTOS

Hello guys,

I am developing an application using FreeRTOS. I have about 7 tasks now with the same priority and I planned that one of them could read and save some data to EEPROM using FEE API (Flash EEPROM Emulation).

I enabled FEE in HalcoGen for this purpose.

BUT when I call some function (e.g. TI_Fee_Init()) within a FreeRTOS task, then a function call just hangs (nothing is returned, or task just crashes but nothing happens in this case).

If I call the same functions outside the FreeRTOS task (e.g. in the main function before vTaskStartScheduler() ) then everything works.

Could you please advice how to solve this issue?

Thank you for help in advance.

  • Hello Alex,

    FEE needs to be executed in supervisor mode. Can you check if your tasks are running in user mode or supervisory mode?
  • Hi, thank you for answer.

    I tried to google, but couldn't find out how to check in which mode my tasks are executed (it looks like tasks are in user mode and scheduler is in privilege mode).
    I found that I can switch to user mode by calling portSWITCH_TO_USER_MODE, actually it calls asm( " CPS #0x10"). But how to switch a processor to the supervisory mode?
    Is it possible to make this switch only for one task?

    I have found modes here: infocenter.arm.com/.../DDI0363E_cortexr4_r1p3_trm.pdf
    on page 2 14
    It says that "In User mode M[4:0] can be read. Writes to M[4:0] are ignored", so I can't set asm( " CPS #31") in the task itself.
  • Hi Alex,

    Please look in to thred 

  • Awesome, I think I've got the idea: I need to register SVC interrupt handler and execute the next code inside:

        asm(" mrs   r0, spsr");       // Get copy of Program Status Register
        asm(" bic   r0, r0, #0x1f");  // Clear mode bits
        asm(" orr   r0, r0, #0x1f");  // Set System Mode
        asm(" msr   spsr, r0");       // Write back modified SPSR

    But I am confused how to make it in my environment.

    HalcoGen shows SVC handler to "vPortSWI"

    I am having the next code now:

    os_portasm.asm

    ; SWI Handler, interface to Protected Mode Functions
    
            .def    vPortSWI
            .asmfunc
    vPortSWI
            stmfd   sp!, {r11,r12,lr}
            ldrb    r12, [lr, #-1]
            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 - Raise Priviledge
            .word   swiPortEnterCritical         ; 2 - vPortEnterCritical
            .word   swiPortExitCritical          ; 3 - vPortExitCritical
            .word   swiPortTaskUsesFPU            ; 4 - vPortTaskUsesFPU
            .word    swiPortDisableInterrupts     ; 5 - vPortDisableInterrupts
            .word    swiPortEnableInterrupts      ; 6 - vPortEnableInterrupts
            .endasmfunc

    ...

    sys_intvecs.asm

        .sect ".intvecs"
        .arm
    
    ;-------------------------------------------------------------------------------
    ; import reference for interrupt routines
    
        .ref _c_int00
        .ref vPortSWI
        .ref _dabort
        .ref phantomInterrupt
        .def resetEntry
    
    ;-------------------------------------------------------------------------------
    ; interrupt vectors
    
    resetEntry
            b   _c_int00
    undefEntry
            b   undefEntry
            b   vPortSWI
    prefetchEntry
            b   prefetchEntry
            b   _dabort
            b   phantomInterrupt
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

    I am not fimilar with the structure of this code :( could you please provide some example how to make it?

    I am very appreciate for your help!!!

  • Guys,

    Anybody, help?
  • Alex, 

    Sorry for delay, I was on vacation last week.

    I'm attaching an asm file that can be used to switch modes. 

    User can do a SVC call to switch to user or privileged mode. Mode = 0x10 for user and 0x1F for system mode

     In a header file, user needs to define function like below:

    #pragma SWI_ALIAS(swiSwitchToMode, 1)

    extern void swiSwitchToMode ( uint32 mode );

     7774.svc.asm

  • Hi,

    Sorry for the delay, had no chance to answer.

    It works, thank you a lot !!!

  • The file is inaccessible. I am having the same issue. Can you please send me the correct link of the file (7774.svc.asm). 
    Thank you. 

  • svc.c
    /*
     * svc.c
     *
     *  Created on: Nov 14, 2014
     *      Author: a0406448
     */
    
    #include "sys_common.h"
    #include "svc.h"
    
    #ifdef DEBUG
    #include <stdio.h>
    #endif
    
    extern uint32_t c_svc(uint32_t u32Param1, uint32_t u32Param2, uint32_t u32Handler);
    
    static void testReentrantSvcInThumb(uint32_t * pu32Param1, uint32_t u32Param2)
    {
    	if (0ul != u32Param2)
    	{
    		testReentrantSVC(pu32Param1 + 1, u32Param2 - 1ul); /* Call function recursively */
    
    		writePrivRegister32(pu32Param1, (uint32_t)pu32Param1);
    	}
    
    	return;
    }
    
    uint32_t c_svc(uint32_t u32Param1, uint32_t u32Param2, uint32_t u32Handler)
    {
    	uint32_t u32ReturnVal = 0ul;
    
    #ifdef DEBUG
    	printf("Called C Level SVC Handler #%u\n", u32Handler);
    #endif
    
    	switch(u32Handler)
    	{
    	case 33: /* writePrivRegister32() */
    		u32ReturnVal           = *(uint32_t *)u32Param1;
    		*(uint32_t *)u32Param1 = u32Param2;
    		break;
    
    	case 34: /* writePrivRegister8() */
    		u32ReturnVal          = (uint32_t)(*(uint8_t *)u32Param1);
    		*(uint8_t *)u32Param1 = (uint8_t)u32Param2;
    		break;
    
    	case 35: /* testReentrantSVC */
    		testReentrantSvcInThumb((uint32_t *)u32Param1, u32Param2);
    		break;
    
    	default:
    		ASSERT(0);
    		break;
    	}
    
    	return u32ReturnVal;
    }
    
    _svc.asmsvc.h

  • Thank you