Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

ARM7 LPC2138 problem with portRESTORE_CONTEXT

Posted by Martin Kupke on February 14, 2008
Hi,

at first i've to say that i'm new to FreeRTOS. I'm working with the WinIDEA application from iSystem and started using FreeRTOS by looking as it is handled by the ARM7_LPC2138_Rowley demo.
If i debug the complete SW i can see that the xTaskCreate for my only single task successfully completes, also i can see that the memory for the task structure is allocated and the task stack is also allocated. The task stack points even to valid memory.
In the moment i call vTaskStartScheduler it crashes, so i started debugging. First the IDLE task will be created, which works fine, too. Then xPortStartScheduler is called and initializes all registers to use timer0, this even works fine. I checked the values of the SFRs (Special Function Registers), so far so good.
Then i come to he point where the task(s) shall start and the function vPortISRStartFirstTask is called. The function calls the macro portRESTORE_CONTEXT and if this is called, my MCU gets reset.
I'm not very familiar with assembler programming, but i tried to find out why it crashes by debugging the assembler source. At the point where the instruction "ldmia r14,{r0-r14}^" is called, all processor registers are initialized with pattern values. R0 = 00000000, R1 = 01010101, R2 = 02020202, R3 = 03030303, ... R12 = 12121212. Then R13 contains a pointer into the memory and R14 = AAAAAAAA.
The register R14 set to AAAAAAAA is the problem, because the assembler instruction "ldr r14,[r14,003c]" tries to load the content pointed by R14 plus the 003c offset.

I don't use the THUMB mode, just plain 32bit compilation. FreeRTOS used in version V4.7.1 and GCC in version 4.0.2.

If theres anybody here working with LPC2138 using FreeRTOS and has a minimal sample for me, or has helpful information regarding my problem, please help.

Thanks in advance,
Kuppi...

RE: ARM7 LPC2138 problem with portRESTORE_CONTEXT

Posted by Ricky on February 14, 2008
It appears you're in user mode. Make sure you're in supervisor mode when you start the scheduler.

The ^ at the end of the ldmia instruction tells the processor to load the user mode registers. But the ldr r14 instruction expects you to be in supervisor mode because it's the supervisor r14 that's being used.

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 15, 2008
Now at CPU start i set the different modes and initialize stack pointers. Then i set a breakpoint in main and verify that the CPSR register is correctly set to supervisor mode (0x13). In fact the portRESTORE_CONTEXT now really sets the PC (program counter) to the address of my only created task and if i set a breakpoint to the first assembler instruction of my task, the debugger stops there. So far it is as expected, but...
In the moment my task is called, i see that the mode in CPSR is set to 0x1F (Mode_SYS). Within the task (which is now been called) i use vTaskDelay and then my CPU runs into UNDEFINED INSTRUCTION INTERRUPT. :-(
I debugged the source tasks.c and found the point where it crashes, it's the macro taskYIELD(). If i look into the assembler source, i see the instruction "swi 000000" and if this is executed the CPU runs into the exception.

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 15, 2008
I've read about SWI (Software Interrupts) on a page <http://www.heyrick.co.uk/assembler/swi.html> i found by google and now i've to correct my last comment. It is not an UNDEFINED INSTRUCTION INTERRUPT, instead it is a wanted SOFTWARE INTERRUPT and the CPU does what it should do. The "swi 000000" instructions sets the PC (program counter) to address 0x8 and continues the work. If i understand correctly, then there should be an address (branch location) at position 8 that schedules the tasks.

Which address (or better which function) will be called if a SWI is executed on your side?

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Richard on February 15, 2008
You need to install the SWI handler in the SWI vector. Take a look at Demo\ARM7_LPC2106_GCC\boot.s for an example (search for vPortYieldProcessor in the file). All the other GCC demos have similar start up asm files.

Regards.

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 15, 2008
Yepp, i found the definition for swi_handler within the FreeRTOSConfig.h and added it to the vector table. My only (stupid dummy) task is created and will be called, verified by setting breakpoint. If taskYIELD() now is called (due to the vTaskDelay in my task), the software interrupt is called and vPortYieldProcessor is called. If i debug through the many routines (especially the switchContext) and have a look on the variable pxCurrentTCB, then i see that the values from my own created task change to the idle task. This is also what i would expect, because my own task called vTaskDelay.
After this i come into the function
static portTASK_FUNCTION( prvIdleTask, pvParameters )
While debugging in this function i can see that the line
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )
is never true and so never taskYIELD() is called.
The more problem is, the breakpoint on taskYIELD() will never be reached. Stepping many times through this by hand is no problem, but setting a breakpoint at taskYIELD() and let the CPU run always crashes.
Breakpoint is never reached and the CPU restarts.

Do you have any further ideas what i can look for to solve this.

Thanks in advance,
Kuppi...

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Richard on February 15, 2008
You have shown that the manual context switch (yield) works, now it sounds like your preemptive switch is not working.

The idle task will not necessarily every yield, but should get preempted by your application task when its block period expires.

Have you verified that the tick interrupt is working? How do you handle the tick interrupt? There are two methods demonstrated by various FreeRTOS.org demos - the first vectors directly to the interrupt and the interrupt performs the context save and restore, the second has a single save and restore point in a common interrupt entry point before calling the handler itself.

Regards.

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 18, 2008
Aaaargh, you got it Richard. The interrupt registers for Timer0 are loaded in function prvSetupTimerInterrupt, but the interrupt isn't enabled. Even i can't find the position (source) where the VIC is reset like VICVectAddr = 0x00000000.
The interrupt function vTickISR is never been called. What am I doing wrong? In my little starting project i just calling xTaskCreate and vTaskStartScheduler, anything more to do?
If i have to enable interrupts, or reset VIC, or whatever, please let me also know at which position i have to add it.

Many thanks for your help,
Kuppi...

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 18, 2008
Additional infos to my problem and my comment before from 2008-02-18 13:23. If i stop execution with breakpoint within my task and have a look on the SFR (Special Function Registers), then i see that TIMER0 bit in the VIC IRQ Status register is set. Within the VIC Raw Interrupt Status register the bits for RTC, PLL, TIMER0 and ARMCore1 are set. The VIC Interrupt Enable register has only bit TIMER0 set. The VIC Vector Address and the VIC Vector Address Register 0 are both pointing to address of vTickISR. T0IR (Timer 0 Interrupt) register has bit MR0 (Interrupt Flag for Match Ch.) set and also i can see that timer0 is counting, because of the T0TC (Timer 0 Timer Counter) register.
It seems that all is working, but the vTickISR routine is never called.

Bye,
Kuppi...

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 18, 2008
And once again me (i'm sorry). Here are now additional information which should clarify my problem. I intialized the address table beginning from 0 as follows:
.global _start
B_start /* RESET INTERRUPT */
B_start /* UNDEFINED INSTRUCTION INTERRUPT */
Bswi_handler /* SOFTWARE INTERRUPT */
B_start /* ABORT (PREFETCH) INTERRUPT */
B_start /* ABORT (DATA) INTERRUPT */
B_start /* RESERVED */
Birq_handler /* IRQ INTERRUPT */
B_start /* FIQ INTERRUPT */
.end
After reset the PC is set to 0 and calls _start, which is the default startup assembler routine. If now taskYIELD() is called, the PC is set to 8 and the swi_handler is called. After calling xTaskCreate and vTaskStartScheduler i can see that PC is set to 0x18 and irq_handler is called, but this my default IRQ handler and i would have expected that the vectored interrupt for vTickISR will be called, too.
So it seems that my interrupt (VIC) isn't setup correctly.
I have only the datasheet for LPC2138 MCU from NXP website and the documentation for programming is very bad (nearly nothing), especially for the VIC.

Thanks for your help,
Kuppi...

RE: ARM7 LPC2138 problem with portRESTORE_CON

Posted by Martin Kupke on February 20, 2008
I downloaded on NXP website the additional documentation "LPC213x User Manual" and read about the interrupt processing. Now i adapted the interrupt handler to handle vectored interrupts and the vTickISR is called, but this happens only once. Additionally i read the section within the manual about timer and interrupt handling, i found that the clear condition is setting the corresponding bit to zero.

The following instruction within the vTickISR interrupt service routine
/* Ready for the next interrupt. */
T0_IR = portTIMER_MATCH_ISR_BIT;
is not correct, from my point of view.
After modifying the portISR.c file at the given position to the following
/* Ready for the next interrupt. */
T0_IR &= ~portTIMER_MATCH_ISR_BIT;
everything works fine.

Now i have FreeRTOS running on my ARM7TDMI (LPC2138) board.

Many thanks for your support,
Kuppi...


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists