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.
I'm trying to run freertos onto my custom RM48 board and have followed the TI recommend instructions for doing so. However, I get my prefetch Abort error when I create an OS task. Specifically, I get the prefetch Abort immediately after executing this line highlighted below.
; Start the first task by restoring its context.
public vPortStartFirstTask
vPortStartFirstTask
cps #0x13
portRESTORE_CONTEXT
When I step into this macro it seems to manipulates registers normally until at some point my registers look like this:
When I exit the portRESTORE_CONTEXT macro my registers look like this:
From here the next instruction is the prefetch abort. How do I go about finding out what causes the abort?
My link file looks like this:
/*----------------------------------------------------------------------------*/
define memory mem with size = 4G;
define region VECTORS = mem:[from 0x00000000 size 0x00000020];
define region KERNEL = mem:[from 0x00000020 size 0x00008000];
define region FLASH = mem:[from 0x00008020 size 0x00177FE0]
| mem:[from 0x00180000 size 0x00180000];
define region STACK = mem:[from 0x08000000 size 0x00002500];
define region KRAM = mem:[from 0x08002500 size 0x00000800];
define region RAM = mem:[from (0x08002500+0x00000800) size (0x0003F800 - 0x00000800)];
define block HEAP with size = 0x800, alignment = 8{ };
initialize by copy {readwrite};
do not initialize {section .noinit};
place in VECTORS {readonly section .intvecs};
place in KERNEL {readonly section .kernelTEXT};
place in FLASH {readonly};
place in RAM {readwrite section .kernelHEAP};
place in KRAM {readwrite section .kernelBSS};
place in RAM {readwrite};
place in RAM {block HEAP};
/*----------------------------------------------------------------------------*/
Thanks for the reply. The 0x0D3C address is loaded into LR before the call to portRESTOR_CONTEXT. The instruction at that address is the last instruction in the vPortSWI label that I've bolded.
;-------------------------------------------------------------------------------
; SWI Handler, interface to Protected Mode Functions
public vPortSWI
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
dcd jumpTable
jumpTable
dcd swiPortYield ; 0 - vPortYieldProcessor
dcd swiRaisePrivilege ; 1 - Raise Priviledge
dcd swiPortEnterCritical ; 2 - vPortEnterCritical
dcd swiPortExitCritical ; 3 - vPortExitCritical
dcd swiPortTaskUsesFPU ; 4 - vPortTaskUsesFPU
dcd swiPortDisableInterrupts ; 5 - vPortDisableInterrupts
dcd swiPortEnableInterrupts ; 6 - vPortEnableInterrupts
Thanks. The IFAR contains the same invalid address in the LR (see below) so I'm not sure what to make of that. Is the DFSR indicating that this is a "Synchronous Parity/ECC Error"
This project worked fine on bare-metal so I think it's something that adding FreeRTOS introduced. Could this be related to how the MPU is set up? I'm using the default MPU settings in FreeRTOS shown below.
In the prvSetupDefaultMPU( void ) function below the flash size is defined as 4MB and SRAM is 512K but the RM48 has 3MB flash and 256K RAM. Is it OK to use this function as-is? I tried changing the sizes to the match the 3MB and 256K but that didn't fix my prefetch abort error.
/*----------------------------------------------------------------------------*/
define memory mem with size = 4G;
define region VECTORS = mem:[from 0x00000000 size 0x00000020];
define region KERNEL = mem:[from 0x00000020 size 0x00008000];
define region FLASH = mem:[from 0x00008020 size 0x00177FE0]
| mem:[from 0x00180000 size 0x00180000];
define region STACK = mem:[from 0x08000000 size 0x00002500];
define region KRAM = mem:[from 0x08002500 size 0x00000800];
define region RAM = mem:[from (0x08002500+0x00000800) size (0x0003F800 - 0x00000800)];
define block HEAP with size = 0x800, alignment = 8{ };
initialize by copy {readwrite};
do not initialize {section .noinit};
place in VECTORS {readonly section .intvecs};
place in KERNEL {readonly section .kernelTEXT};
place in FLASH {readonly};
place in RAM {readwrite section .kernelHEAP};
place in KRAM {readwrite section .kernelBSS};
place in RAM {readwrite};
place in RAM {block HEAP};
/*----------------------------------------------------------------------------*/
static void prvSetupDefaultMPU( void ) { /* make sure MPU is disabled */ prvMpuDisable(); /* First setup the entire flash for unprivileged read only access. */ prvMpuSetRegion(portUNPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_4MB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the first 32K for privileged only access. This is where the kernel code is placed. */ prvMpuSetRegion(portPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_32KB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the the entire RAM region for privileged read-write and unprivileged read only access */ prvMpuSetRegion(portPRIVILEGED_RAM_REGION, 0x08000000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RW_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Default peripherals setup */ prvMpuSetRegion(portGENERAL_PERIPHERALS_REGION, 0xF0000000, portMPU_SIZE_256MB | portMPU_REGION_ENABLE | portMPU_SUBREGION_1_DISABLE | portMPU_SUBREGION_2_DISABLE | portMPU_SUBREGION_3_DISABLE | portMPU_SUBREGION_4_DISABLE, portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* Privilege System Region setup */ prvMpuSetRegion(portPRIVILEGED_SYSTEM_REGION, 0xFFF80000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RO_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* Enable MPU */ prvMpuEnable(); }