LPC23xx port with Keil/RV compiler

This is a simple modification of the port files for the LPC21xx, working with KEIL and RealView, to use freeRTOS with the LPC23xx family.


In particular I’ve used the Keil uVision 4.0.


ATTENTION. This guide is not definitive. It should be improved. Also the port files.


1. Change to startup file.

The LPC21xx port use an old startup file. It’s better to use the newer one supplied with the compiler. Usually this is named LPC2300.s

There are few changes to do:

a - from the Configuration Wizard, change the dimension of the stack.

I use:

Undefined Mode = 0x0000 0000;

Supervisor Mode = 0x0000 0300; (It’s so big because the kernel run in this mode)

Abort Mode = 0x0000 0000;

Fast Interrupt Mode = 0x0000 0008;

Interrupt Mode = 0x0000 0300;

User/System Mode = 0x0000 0008;


This configuration works. However I think that the dimension of the Supervisor, interrupt and user/system should be modified to fit better.


b – Change the heap size, I use 0x0000A000.


c – In the asm code of the startup file, search the line:


SWI_Addr        DCD     SWI_Handler


And replace with:


            IMPORT         vPortYieldProcessor

SWI_Addr        DCD     vPortYieldProcessor


Don’t forget a space or a tab before IMPORT.


d – always in the startup file replace

               MSR     CPSR_c, #Mode_USR

                IF      :DEF:__MICROLIB


                EXPORT __initial_sp




                MOV     SP, R0

                SUB     SL, SP, #USR_Stack_Size






                IF      :DEF:__MICROLIB

                EXPORT __initial_sp



In this way we disable entering in the user mode, so the scheduler starts in the supervisor mode. Also we let to use the “microlib” from Keil.


2. In the portable.h insert:

#ifdef ARM7_LPC23xx_KEIL_RVDS

            #include "..\..\Source\portable\RVDS\ARM7_LPC23xx\portmacro.h"



Replace the path with the correct one.

In the option for the project, insert the C/C++ pre-processor symbol ARM7_LPC23xx_KEIL_RVDS


3. Include in the project the file: port.c, portmacro.h, portASM.s 

4. Configure the FreeRTOSConfig.h and include the header:

#include <LPC23xx.H>



When the main() starts, you are in supervisor mode and interrupts are disable.

If you need to enable interrupts before calling vTaskStartScheduler() you need to call __enable_irq().



Riccardo Cusatelli

14 april 2010




EDIT: 19 april 2010

if you want you call some functions of the kernel (like vSemaphoreCreateBinary) BEFORE calling vTaskStartScheduler() you should use these changes in "port.c":

1 -replace

"volatile unsigned portLONG ulCriticalNesting = 9999UL;"


"volatile unsigned portLONG ulCriticalNesting = 0;"

2 - in  xPortStartScheduler() add these 2 lines at the beginning



ulCriticalNesting = 9999UL;




Please sign in to leave a comment.