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.

RM48L952: prefetch abort when calling pvPortMalloc() from within a FreeRTOS task

Part Number: RM48L952
Other Parts Discussed in Thread: HALCOGEN

Hello,

I have a Hercules RM48 HDK devboard.  I created a HALCoGen FreeRTOS project for it.  I did not change any HALCoGen default settings.  Then I added code to create 1 task, followed by code to enable the scheduler (vTaskStartScheduler).  The task code simply implements a while (1) loop toggling an LED every second.  This code works and the LED flashes at the expected rate.   

In the task code, I then added a call to pvPortMalloc(20 bytes) prior to entering the while (1) loop.  When the code runs it aborts with a prefetch error.  As soon as I step into pvPortMalloc() with the debugger the prefetch occurs.

Note that calls to pvPortmalloc() succeed when called from the startup code (outside of the task, before calling xTaskCreate).

Can anyone shed some light on this?  I zipped up the entire CCS project including my changes (see apptest.c) for your inspection.4380.halcogen_48L952.zip

Thank you,

Keith

  • Hello Keith,

    When a prefetch abort occurs, the CPU marks the prefetched instruction as invalid, and all the p-aborts are precise abort. Please check the value in the link register (r14_pabt) to determine which instruction generated the abort.

    You can also use the CP15_Instruction_Fault_address register (CCS-->registers-->CP15) to determine which instruction causes the abort:

  • QJ,

    The prefetch abort shows:

    R14_PABT = 0x4EA0

    CP15 INST FAULT Status = 0xD

    CP15 AUX INST FAULT Status = 0x00400000

    CP15 INST FAULT Address = 0x4E9C.  This is the address of pvPortMalloc(), a valid address.

    In the debugger I set a BP for vTestTask().  Then I asm step into pvPortMalloc.  It immediately generates the abort. 

    Can you try to replicate using the zip file I provided?  I am totally stuck at this point.

    Note that my os_portmacro.h  defines portUSING_MPU_WRAPPERS = 1, and that xTaskCreate is calling MPU_xTaskCreate.  And xTaskCreate is able to call pvPortmalloc successfully. 

    I also noticed that in my startup code (apptest.c) that when my task is created, in MPU_xTaskCreate, xRunningPrivileged = 15 before prvRaisePrivilege is called.  ie, swiRaisePrivilege shows that the caller was not in user mode before calling xTaskCreate.  I think this is expected?

    thanks,

    Keith

  • More info: Here is the asm code:

    pvPortMalloc():
    00004e9c: E92D4000 stmdb sp!, {lr}
    00004ea0: E24DD014 sub sp, sp, #0x14
    00004ea4: E58D0000 str r0, [sp]
    149 void *pvReturn = NULL;
    00004ea8: E3A0C000 mov r12, #0
    00004eac: E58DC010 str r12, [sp, #0x10

    Just before stepping into pvPortMalloc, the SP = 0x08001218, a valid stack address.
  • QJ,
    One more data point: when I create the task in Supervisor mode (task priority = 0..15| portPRIVILEGE_BIT) then the pvPortMalloc code runs Ok within the task, and the task can malloc memory Ok. This raises a new question: if User mode tasks can't call pvPortMalloc , what memory allocation routine should be used? I also tried calling malloc(), which is defined in rtsv7R4_T_le_v3D16_eabi.lib, but that function causes a data abort and does not return.

    thanks,
  • Hello Keith,

    The fault status is 0x0D, Which means it is permission fault:

    The memory region (xMemory Region) for the task can not be accessed in user mode.