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

*stupid* How to declare ISR?

Posted by sven-de on April 15, 2011
Hi, my setup is an ICSwift board with AT91SAM7X256 running the GCC/Eclipse-Demo. I managed to set up simple tasks on my own to blink the LEDs and to send out a simple countdown via CAN which I monitor with a CAN PC-card. Except for the uIP all of the demo tasks are disabled.

Now I'm trying to set up an Interrupt to react on incoming CAN-messages, but whenever I sent a message (ie. trigger the interrupt) this totally resets the controller. This is visible by the LEDs, the CAN-Countdown restarts and even the network-connection is lost for an instant.

I'm fairy certain this is because I don't declare my ISR as such, but failed the whole morning to find out how to do this. So please, tell me the obviuous: how to declare an ISR?

Am I missing something else, like clearing the Interrupt after being done?
void CAN_IR_Handler(void)
{
volatile unsigned int status;
status = AT91C_BASE_CAN->CAN_SR & AT91C_BASE_CAN->CAN_IMR;

if(status & AT91C_CAN_WAKEUP) {
AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP;
flagCAN = 1;
}

if(status & AT91C_CAN_MB0) {
AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;
}
}

RE: *stupid* How to declare ISR?

Posted by sven-de on April 15, 2011
After repeated reading of the demo documentation I tried this declaration
void CAN_IR_Handler(void) __attribute__((interrupt("IRQ")));

But got the Error, that "ISR cannot be coded in thumb mode"

I figure it could also be, that the IR-vector points to the wrong location, so here's the code for setting that up:
AT91F_AIC_ConfigureIt( AT91C_ID_CAN, 1, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, CAN_IR_Handler);
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN;

RE: *stupid* How to declare ISR?

Posted by Dave on April 15, 2011
On an ARM7 you have to use ARM mode for interrupts, or at least the interrupt entry point. Different versions of GCC have different bugs when it comes to trying to use the __attribute__((interrupt)), so it is best avoided. Instead, write your own interrupt entry code. There are lots of examples on the FreeRTOS web site, and in the download source code. For example look at the Interrupt Service Routines section on this page http://www.freertos.org/portat91fr40008.html

Even then it suggests using an attribute((naked)) function for the entry point, but that too has issues with some GCC versions. I would say, write the wrapper in ARM assembly code, and write the handler that is called by the wrapper in C code. I'm sure there are examples of that in the download too.

RE: *stupid* How to declare ISR?

Posted by sven-de on April 18, 2011
Hi Dave, thanks for your quick reply. I've been following your advice without success, the CAN-Interrupt still resets the whole controller. What bugs me most is that the code in SAM7_EMAC.c and EMAC_ISR.c looks just like mine but is working (incoming traffic doesn't reset everything).

One strange thing I observed: The order of Handler/Wrapper-definition makes a difference. When defining the handler first an the wrapper second (as below) I get the mentioned reset. But when switching the order to wrapper first, handler second (as in EMAC_ISR.c) I get a total freeze. Also removing flagCAN = 1; in the Handler causes a freeze. This behaviour contradicts everything I believed to know about programming.

Speaking of strange: When using portSAVE_CONTEXT() and portRESTORE_CONTEXT() as in EMAC_ISR.c the compiler complains with a couple of these: "Error: selected processor does not support `stmdb SP!,{R0}'". Meanwhile EMAC_ISR.c compiles just fine.

This is my current code:
void CAN_IR_Wrapper(void) __attribute__ ((naked));
void CAN_IR_Handler(void) __attribute__ ((noinline));

void CAN_IR_Wrapper(void)
{
//portSAVE_CONTEXT();

__asm volatile ("bl CAN_IR_Handler");

//portRESTORE_CONTEXT();
}

void CAN_IR_Handler(void)
{
volatile unsigned int status;
status = AT91C_BASE_CAN->CAN_SR & AT91C_BASE_CAN->CAN_IMR;

if(status & AT91C_CAN_WAKEUP) {
AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP;
flagCAN = 1;
}

if(status & AT91C_CAN_MB0) {
AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;
}
/* Clear the interrupt. */
AT91C_BASE_AIC->AIC_EOICR = 1;
}

// within main() before starting the scheduler or any tasks:
portENTER_CRITICAL();
// CAN Interrupt aktivieren
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_MB0;

AT91F_AIC_ConfigureIt( AT91C_ID_CAN, 6, 0, ( void (*)( void ) ) CAN_IR_Wrapper);
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN;
portEXIT_CRITICAL();

RE: *stupid* How to declare ISR?

Posted by sven-de on April 18, 2011
PROBLEM SOLVED

The ARM vs. THUMB mode aspect never really fired in my brain so I hat the ISR in my main.c. By coincidence I had a look into the makefile and only then realised my mistake. The ISR need to be in a dedicated file listed among those destined for compilation in ARM mode.

Jesus, am I glad. Free hugs for everyone!


[ 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