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

Troubles while setting up FreeRTOS @ SAM7X

Posted by Nobody/Anonymous on December 20, 2006
Hello alltogether!

I knew that this is not a FreeRTOS forum, but i think there are many people here which are very familiar with freeRTOS on ARM microcontrollers.

What is the problem?

I used the provided port files for the SAM7 and copied it to my project at eclipse (using yagarto). Further I took the startup code which is provided at Jim Lynch's great tutorial.

But I have to tell the Controller with the startup code where to jump if there occurs a software Interrupt? Is this correct?

I modified the Startup code as follows:

Code (originally by J. P. Lynch):


/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */
.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */
.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */
.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */
.set SVC_STACK_SIZE, 0x00000010 /* stack for "SVC" supervisor mode is 16 bytes */

/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set MODE_USR, 0x10 /* Normal User Mode */
.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */

/* Interrupt controller offsets */
.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */
.set AIC_IVR, 256 /* IRQ Vector Register */
.set AIC_EOICR, 304 /* End of Interrupt Command Register */

/* identify all GLOBAL symbols */
.global _vec_reset
.global _vec_undef
.global _vec_swi
.global _vec_pabt
.global _vec_dabt
.global _vec_rsv
.global _vec_irq
.global _vec_fiq
.global AT91F_Irq_Handler
.global AT91F_Default_FIQ_handler
.global AT91F_Default_IRQ_handler
.global AT91F_Spurious_handler

/* GNU assembler controls */
.text /* all assembler code that follows will go into .text section */
.arm /* compile for 32-bit ARM instruction set */
.align /* align section on 32-bit boundary */

/* ============================================================ */
/* VECTOR TABLE */
/* */
/* Must be located in FLASH at address 0x00000000 */
/* */
/* Easy to do if this file crt.s is first in the list */
/* for the linker step in the makefile, e.g. */
/* */
/* $(LD) $(LFLAGS) -o main.out crt.o main.o */
/* */
/* ============================================================ */
/* FreeRTOS SWI Interrupt - needed by PORTYIELD */

_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */
_vec_undef: b _vec_undef /* Undefined Instruction vector */
_vec_swi: b _yield_handler /* Software Interrupt vector */
_vec_pabt: b _vec_pabt /* Prefetch abort vector */
_vec_dabt: b _vec_dabt /* Data abort vector */
_vec_rsv: b _vec_rsv /* Reserved vector */
_vec_irq: b _vec_irq /* Interrupt Request (IRQ) vector */
_vec_fiq: b _vec_fiq /* Fast interrupt request (FIQ) vector */



_yield_handler: b vPortYieldProcessor

/* Reset Handler */
_init_reset:
/* Setup a stack for each mode with interrupts initially disabled. */
ldr r0, =_stack_end /* r0 = top-of-stack */

msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */
mov sp, r0 /* set stack pointer for UND mode */
sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */

msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */
mov sp, r0 /* set stack pointer for ABT mode */
sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */

msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */
mov sp, r0 /* set stack pointer for FIQ mode */
sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */

msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */
mov sp, r0 /* set stack pointer for IRQ mode */
sub r0, r0, #IRQ_STACK_SIZE /* adjust r0 past IRQ stack */

msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* switch to Supervisor Mode */
mov sp, r0 /* set stack pointer for SVC mode */
sub r0, r0, #SVC_STACK_SIZE /* adjust r0 past SVC stack */

msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* switch to System Mode */
mov sp, r0 /* set stack pointer for SYS mode */
/* we now start execution in SYSTEM mode */
/* This is exactly like USER mode (same stack) */
/* but SYSTEM mode has more privileges */

/* copy initialized variables .data section (Copy from ROM to RAM) */
ldr R1, =_etext
ldr R2, =_data
ldr R3, =_edata
1: cmp R2, R3
ldrlo R0, [R1], #4
strlo R0, [R2], #4
blo 1b

/* Clear uninitialized variables .bss section (Zero init) */
mov R0, #0
ldr R1, =_bss_start
ldr R2, =_bss_end
2: cmp R1, R2
strlo R0, [R1], #4
blo 2b

/* Enter the C code */
b main



/* ========================================================== */
/* - Function : AT91F_Irq_Handler */
/* - Treatments : IRQ Controller Interrupt Handler. */
/* - Called Functions : AIC_IVR[interrupt] */
/* ---------------------------------------------------------- */
AT91F_Irq_Handler:

/* Adjust and save LR_irq in IRQ stack */
sub lr, lr, #4
stmfd sp!, {lr}

/* Save and r0 in IRQ stack */
stmfd sp!, {r0}

/* Write in the IVR to support Protect Mode */
/* No effect in Normal Mode */
/* De-assert the NIRQ and clear the source in Protect Mode */
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]

/* Enable Interrupt and Switch in Supervisor Mode */
msr CPSR_c, #MODE_SVC

/* Save scratch/used registers and LR in User Stack */
stmfd sp!, { r1-r3, r12, r14}


/* =============================================== */
/* Branch to the routine pointed by the AIC_IVR */
/* =============================================== */

/* Branch to the routine pointed by the AIC_IVR */
mov r14, pc
bx r0

/* =============================================== */
/* Manage Exception Exit */
/* =============================================== */

/* Restore scratch/used registers and LR from User Stack */
ldmia sp!, { r1-r3, r12, r14}

/* Disable Interrupt and switch back in IRQ mode */
msr CPSR_c, #MODE_IRQ|I_BIT

/* Mark the End of Interrupt on the AIC */
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]

/* Restore SPSR_irq and r0 from IRQ stack */
ldmia sp!, {r0}

/* Restore adjusted LR_irq from IRQ stack directly in the PC */
ldmia sp!, {pc}^


AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler

AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler

AT91F_Spurious_handler: b AT91F_Spurious_handler

.end



In fact, i only inserted the vPortYieldProcessor function to the SWI Interrupt source.


And this is my application code which creates one task:
Code:


//***************************************************************************
// FREERTOS - APPLICATION
//***************************************************************************

#include "./include/AT91SAM7X256.h"
#include "./include/board_ex256.h"
#include "./include/registers.h"
#include "./include/lcd.h"
#include "./include/debug.h"

/* FreeRTOS includes */

#include "./freeRTOS/include/FreeRTOS.h"
#include "./freeRTOS/include/task.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


extern void LowLevelInit(void);

void init(void);
//void IRQ_Routine (void) __attribute__ ((interrupt("IRQ")));
void FIQ_Routine (void) __attribute__ ((interrupt("FIQ")));
//void SWI_Routine (void) __attribute__ ((interrupt("SWI")));
void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));


/* Task functions */

void OS_Setup(void);
void TaskBlink(void *taskData);

/* Set the TaskStack Size to the default minimal value */
#define TaskStackSize configMINIMAL_STACK_SIZE

void OS_Setup(void)
{
unsigned int taskData = 0x0;
xTaskHandle taskHandle;

/* Lets create the Application TASKS */
xTaskCreate(TaskBlink, "TaskBlink", TaskStackSize, (void *) &taskData, tskIDLE_PRIORITY+1, &taskHandle);
printf("Task Created \n\r");
vTaskStartScheduler();
}

void TaskBlink(void *taskData)
{
char debugMessage[100];
taskData = taskData;
printf("We are in Task Blink now \n\r");

while(1==1){
Backlight(BKLGHT_LCD_ON);
printf("FREE_RTOS: Backlight ON \n\r");
vTaskDelay(1000);
Backlight(BKLGHT_LCD_OFF);
printf("FREE_RTOS: Backlight OFF \n\r");
vTaskDelay(1000);
}
}



int main(int argc, char **argv) {
init();
initDbgUnit();
printf("Trying to start FREE_RTOS \n\r");
OS_Setup();
while(1==1){
/* Hopefully the OS never returns here */
;
}
}


void init(void) {

//*************** lowlevel init (watchdog, PLL clock, default interrupts, etc.)
LowLevelInit();

//*************** inint defined state
//set all Ports to PIO controlled, not on-chip peripheral
pPIOA->PIO_PER = 0xffffffff;
pPIOB->PIO_PER = 0xffffffff;
//we coould also have used
//pSYS->PIOA_PER = 0xffffffff;
//pSYS->PIOB_PER = 0xffffffff;

//enable all pull ups
pSYS->PIOA_PPUER = 0xffffffff;
pSYS->PIOB_PPUER = 0xffffffff;

//select multiplex function A (should be default). only needed if
//on-chip peripheral was selected
pSYS->PIOA_ASR = 0xffffffff;
pSYS->PIOB_ASR = 0xffffffff;

//we use PIO controlled i/o lines (see above) and set them to input
pSYS->PIOA_ODR = 0xffffffff;
pSYS->PIOB_ODR = 0xffffffff;

//****************** init lcd
InitLCD();
LCDSettings();

//for buttons interrupt do not forget to enable PIO Clock

}//init


/* Stubs for various interrupts (may be replaced later) */
/* ---------------------------------------------------- */

void FIQ_Routine (void) {
while (1) ;
}

void UNDEF_Routine (void) {
while (1) ;
}


My problem is that after i call vTaskStartScheduler(); the program stopps and the task code is not executed.

My first idea was that there is something wrong with the OS tick timer. How could i figure out if the tick timer is not running?

Do i have to add further modifications at my startup code to get freeRTOS running?

Any help is welcome. Thanks a lot in advance.

rain

RE: Troubles while setting up FreeRTOS @ SAM7X

Posted by Nobody/Anonymous on December 20, 2006
Just looking at the startup code I can see a number of problems. Use the startup code that comes with FreeRTOS download for the SAM7X (in the lwIP demo directory there are all the files you need). The startup code is provided for you - you do not need to rewrite it although you may want to tweak it a bit.

SVC_STACK_SIZE way too small.

Exception entry and exit is going to mangle the stack compared to how FreeRTOS expectes it. You can either vector directly to the FreeRTOS code (as per the SAM7X GCC example) or have handler code that saves/restores the context as FreeRTOS expects it (as per the STR750 GCC example).

Likewise the SWI handler.

I'm not familiar with Yagarto but there have been people mentioning differences between WinARM and GNUARM. Yagarto is another one in the mix. You might be better off starting with GNUARM as this is what the demos were written using.

RE: Troubles while setting up FreeRTOS @ SAM7

Posted by Nobody/Anonymous on December 21, 2006
thanks for the reply.

I change the Stack Sizes, but it is still not running.

Sorry, but i downloaded the Code from FreeRTOS.org but i couldn't find a startup code for SAM7X and GCC. Maybe someone can tell me where this startup code is located at the file structure.

Thanks a lot in advance.

RE: Troubles while setting up FreeRTOS @ SAM7

Posted by Nobody/Anonymous on December 21, 2006
Demo\lwIP_Demo_Rowley_ARM7\boot.s, and
Demo\lwIP_Demo_Rowley_ARM7\makefile and also the linker script.

I would suggest:

i/ Downloading gnuarm from gnuarm.org. This has the same functionality as YAG. Set the bin directory in your path instead of YAG.

ii/ From the command prompt, rather than in Eclipse, go to the above referenced directory and type make. You should be able to build the code with no problems :-)

iii/ Take out anything from the makefile that you don't want. Maybe you want to just leave the flash demo tasks to flash some LED's to start with and remove all else. You will also have to edit main.c to stop calling the functions to start tasks that are no longer in the makefile.

iv/ Update partest.c (Demo\lwIP_Demo_Rowley_ARM7\ParTest) to access the LEDs that are on your board. They are currently set to flash the LEDs that are on the SAM7X EK board from atmel.

v/ Once this is all running - go back to using Ecliplse and try to build the same project from in that environment.


I don't think Eclipse gains you much other than a very slow clunky IDE full of oddity and restriction. I prefer the command line approach which is fast. If you want a good fast easy IDE at a low price consider buying a personal license of CrossWorks.


[ 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