Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

Port from CM3 to CM0 Problems

Posted by A S on May 23, 2013
Developing under Keil. Have been developing and executing for CM3 based NXP processor for several months. Trying to port same code to CM0 based processor but get several compiler errors from port.c and assemble errors from my startup file. I assume I should be using a different port.c but am unclear which one to choose from or whether there is one delivered with the standard FreeRTOS download. I am using the port.c in the RVDS\ARM_CM3 directory and the FreeRTOS version is 7.3.0. Below are the errors I am getting.

..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(197): error: A1874E: Specified register list cannot be loaded or stored in target instruction set
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(199): error: A1859E: Flag preserving form of this instruction not available
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(200): error: A1477E: This register combination results in UNPREDICTABLE behaviour
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(201): error: A1618E: Specified instruction is not supported by the current instruction set
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(292): error: A1874E: Specified register list cannot be loaded or stored in target instruction set
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(296): error: A1859E: Flag preserving form of this instruction not available
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(297): error: A1477E: This register combination results in UNPREDICTABLE behaviour
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(299): error: A1859E: Flag preserving form of this instruction not available
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(300): error: A1477E: This register combination results in UNPREDICTABLE behaviour
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(301): error: A1874E: Specified register list cannot be loaded or stored in target instruction set
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(305): error: A1874E: Specified register list cannot be loaded or stored in target instruction set
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(474): error: A1477E: This register combination results in UNPREDICTABLE behaviour
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(475): error: A1859E: Flag preserving form of this instruction not available
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(476): error: A1477E: This register combination results in UNPREDICTABLE behaviour
..\..\..\..\validation_framework\FreeRTOSV7.3.0\FreeRTOSV7.3.0\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c(485): error: A1477E: This register combination results in UNPREDICTABLE behaviour




RE: Port from CM3 to CM0 Problems

Posted by Richard on May 23, 2013
You won't be able to use the CM3 port on a CM0. There are official FreeRTOS CM0 ports for IAR and GCC, but unfortunately not Keil. You may find an NXP Keil port on http://www.lpcware.com if you are lucky, but the NXP port is slightly different to the FreeRTOS distributed code.

You could probably create a port by comparing the GCC CM3 port.c and portmacro.h with their CM0 equivalents. The main difference is going to be in the assembly code used to context switch because the CM0 needs to access the 'high' registers separately from the 'low' registers, whereas the CM3 just accesses (that is, pushes and pops) all the registers at once.

Regards.

RE: Port from CM3 to CM0 Problems

Posted by A S on May 30, 2013
Thanks Richard. I ported this to CM0. Seems to work although I haven't done an exhaustive test suite on it. If somebody wants the code, happy to post it.

RE: Port from CM3 to CM0 Problems

Posted by Erich Styger on July 25, 2013
Hi blindeye2,
I porting FreeRTOS to Cortex-M0 with Keil, and I'm stuck at the same problem as you. You offered to post your solution/code, I would be happy to see how you solved the Keil assembly problem.

Thanks,
Erich

RE: Port from CM3 to CM0 Problems

Posted by A S on July 25, 2013
Hi Erich,

I'm currently traveling and don't have access to the codebase. I'll try to get to this in the next couple of days. Is it possible to upload files to this forum? If not please send me an email address I can send them to.


RE: Port from CM3 to CM0 Problems

Posted by Richard on July 25, 2013
Regrettably it is not possible to upload code directly in this forum. However, if you can upload code in the Interactive site (http://interactive.freertos.org), then post a link here.

Regards.

RE: Port from CM3 to CM0 Problems

Posted by Erich Styger on July 25, 2013
Hi blindEye2,
ok, thanks for your offer. You might simply copy-paste your assembly code to reply. I think all the magic is in your implementation of vPortSVCHandler() and vPortSVCHandler(), so should be fairly short assembly code.

I'll work until then if I can resolve the thing myself, just in case.

Thanks!
Erich

RE: Port from CM3 to CM0 Problems

Posted by Erich Styger on July 25, 2013
Ok, I got it sorted out :-)
Still need some testing, but below is the code working with Keil and Cortex-M0+.

/*-----------------------------------------------------------*/
__asm void vPortStartFirstTask(void) {
/* Use the NVIC offset register to locate the stack. */
ldr r0, =0xE000ED08
ldr r0, [r0]
ldr r0, [r0]
/* Set the msp back to the start of the stack. */
msr msp, r0
/* Globally enable interrupts. */
cpsie i
/* Call SVC to start the first task. */
svc 0
nop
nop
}
/*-----------------------------------------------------------*/
__asm void vPortSVCHandler(void) {
IMPORT pxCurrentTCB

/* Get the location of the current TCB. */
ldr r3, =pxCurrentTCB /* Restore the context. */
ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
adds r0, #16 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Pop the high registers. */
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7

msr psp, r0 /* Remember the new top of stack for the task. */

subs r0, #32 /* Go back for the low registers that are not automatically restored. */
ldmia r0!, {r4-r7} /* Pop low registers. */
mov r1, r14 /* OR R14 with 0x0d. */
movs r0, #0x0d
orrs r1, r0
bx r1
}
/*-----------------------------------------------------------*/
__asm void vPortPendSVHandler(void) {
EXTERN pxCurrentTCB
IMPORT vTaskSwitchContext

mrs r0, psp

ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
ldr r2, [r3]

subs r0, #32 /* Make space for the remaining low registers. */
str r0, [r2] /* Save the new top of stack. */
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
mov r4, r8 /* Store the high registers. */
mov r5, r9
mov r6, r10
mov r7, r11
stmia r0!, {r4-r7}

push {r3, r14}
cpsid i
bl vTaskSwitchContext
cpsie i
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */

ldr r1, [r2]
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
adds r0, #16 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Pop the high registers. */
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7

msr psp, r0 /* Remember the new top of stack for the task. */

subs r0, #32 /* Go back for the low registers that are not automatically restored. */
ldmia r0!, {r4-r7} /* Pop low registers. */

bx r3
}

I'm working on some details, as well supporting M4 with and without floating point unit.

Erich


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner