TMS470 with IAR C++ Compiler

Hi all.

I'm trying to use C++ and IAR for TMS470 uC's but I'm getting some weird troubles with C++.

For example: I have a simple test code to receive CAN frames using interrupts. It compiles ok but when the frame arrives the application blows! If I use the same logic and configurations with C compiler everything works perfectly.

I did a research for C++ Projects with TMS470 but didn't find anything... Do you have a link or a simple C++ IAR project using interrupts?

Any help will be appreciated!

Thanks a lot!

Reply to
Hagar
Loading thread data ...

C and C++ aren't interchangeable. Can you post the code?

George

Reply to
George Neuner

Hi George! Thanks for the fast response!

I know C and C++ aren't interchangeable. Sorry for bad explanation. I was at work trying to solve this problems and didn't explained well.

I have got simple code from TI website which configures CAN module (SCC) to receive any CAN message. This code works well if I use IAR C Compiler Version 5.1, but if I create another project using IAR C++ Compiler it doesn't recognizes CAN interruption. In fact, when the message is received the software stops working, like if there wasn´t an IRQ routine!

In C project all the configurations and register's setups are made in only one source file (main.c). In C++ project registers setup and configurations are the same, the difference are, of course, the compiler and a "Can" class. I'm sure the logic is the same (I've compared all the registers in both projects and they are identical).

After many attempts to solve this (web researches, reference guide, datasheets, help files...) I decided to test both codes in IAR Version 4, which I have installed in an old machine, and both projects (C and C++) worked well!

Reading IAR documents about the two versions (IAR V4 and V5) I didn't find any huge difference that could interfere in V5 C++ Compiler. I suspect of different startup operation (cstartup.s file) between this versions but didn't find more explanations about it! Does anyone have some material about startup code?

Summarizing:

- IAR Embedded Workbench V4: C and C++ projects working fine!

- IAR Embedded Workbench V5: Only C version works.

- The source codes used to test the different versions are the same!

- No errors or warnings are shown in either version.

- Code optimization is turned off.

- With IAR Version 5 and C++ project the Interruption Routine seems to be "ignored" by the compiler (but it don't generate warning or errors).

- I'm using the same IAR Development Board to test both projects.

I'm at home now and don't have the code with me, but tomorrow I'll post it.

Any idea that could show a new way?

Sorry for huge email and thanks a lot for your attention and time!

weird

anything...

Reply to
Hagar

Here the codes:

================== C Working Code =========================

//IDE libraries #include "QuantumCanStack.h"

//################### Functions Prototypes ################## void systemInit(void); //###########################################################

int main() { systemInit(); __enable_interrupt(); HETDIR = 0xFFFFFFFF; // HETx Output direction HETDOUT = 0xFFFFFFFF;

HETDOUT = 0x01; while(1) { if (!(GIODINA & 0x04)) HETDOUT = 0x00; if (!(GIODINA & 0x08)) HETDOUT = 0x01; } }

/** Initializes the hardware

**/ void systemInit(void) { //Clock Init GCR = 0x00000008; PCR = 0x00000006|PENABLE; // Use CANTX pin for the CAN transmit functions SCC1CANTIOC = TXFUNC; // Use CANRX pin for the CAN receive functions SCC1CANRIOC = RXFUNC;

// Set SCC interrupt configuration. Mailbox 0 (receive mailbox) generates // low-priority interrupts (int line 1 --> CIM_SCCB). SCC1CANMIL = MIL0; // Use int line 1 for mbox 0 SCC1CANMIM = MIM0; // Enable int for mbox 0 SCC1CANGIM = I1EN; // Enable int line 1

// Setup master control register // Enable configuration mode, activate auto bus on after bus off condition

SCC1CANMC = CCR + ABO;

// Wait until CPU has access to CAN configuration registers while (!(SCC1CANES & CCE));

// Setup CAN bit timing for 125kbit/s according to CiA specifications: // 8us nominal bit time w/ 16TQs/bit, sample point is located at 7us (14TQ)

// BRP = 5 (Prescaler 6, w/ ICLK = 12MHz) // Sample 3x, TSEG1 = 13, TSEG2 = 2, SJW = 1 SCC1CANBTC = (5

Reply to
Hagar

================ C++ ===============================

//IDE libraries #include "QuantumCanStack.h" #include "Can.h" #include "Clock.h"

//################### Functions Prototypes ################## void systemInit(void); //###########################################################

Clock clock; Can can;

int main() { systemInit(); __enable_interrupt(); HETDIR = 0xFFFFFFFF; // HETx Output direction HETDOUT = 0xFFFFFFFF;

HETDOUT = 0x01; while(1) { if (!(GIODINA & 0x04)) HETDOUT = 0x00; if (!(GIODINA & 0x08)) HETDOUT = 0x01; } }

/** Initializes the hardware

**/ void systemInit(void) { clock.init();

can.init(); //can.enableInterrupt(true); }

__irq __arm void IRQ_Handler() { switch ((IRQIVEC & 0xff) - 1) // Convert IVEC index to { // CIM interrupt channel case CIM_SCCB: // SCC interrupt B

HETDOUT = 0x00; SCC1CANRMP = RMP0; break; } }

========================== CAN Class =========================

#include "Can.h"

void Can::init(void) { //Function pins SCC1CANTIOC = TXFUNC; //CANTX pin for CAN transmit functions SCC1CANRIOC = RXFUNC; //CANRX pin for CAN receive functions

//Interrupt Configuration SCC1CANMIL = MIL0; //Interrupt generated in Line 1 SCC1CANMIM = MIM0; //Enable interrupt for mailbox 0 SCC1CANGIM = I1EN; //Enable interrupt in Line 1

//Enable configuration mode. Activate auto bus on after bus off condition

SCC1CANMC = CCR + ABO; //CCR = write access requested, set bus off state.

//ABO = after bus off state automatically returns to bus on state

// Wait until CPU has access to CAN configuration registers while(!SCC1CANES & CCE);

// Setup CAN bit timing for 125kbit/s according to CiA specifications: // 8us nominal bit time w/ 16TQs/bit, sample point is located at 7us (14TQ)

// BRP = 5 (Prescaler 6, w/ ICLK = 12MHz) // Sample 3x, TSEG1 = 13, TSEG2 = 2, SJW = 1 SCC1CANBTC = (5

Reply to
Hagar

Check in your map file that this function is actually linked in. If not, try: extern "C" __irq __arm void IRQ_Handler()

Leo Havmøller.

Reply to
Leo Havmøller

It worked!

extern "C" __irq __arm void IRQ_Handler();

Thank you so much! It was driving me crazy since yesterday!

Reply to
Hagar

In future, please do not top-post, especially on technical newsgroups. Your answer belongs after (or intermixed with) the quoted material to which you reply, after snipping all irrelevant material. See the following links:

(taming google) (newusers)

--
 [mail]: Chuck F (cbfalconer at maineline dot net) 
 [page]: 
            Try the download section.
Reply to
CBFalconer

I see Leo beat me to it. I'm glad the solution was simple. I was worried that the C code was doing something that breaks in C++.

Most people forget (or never knew) that C++ isn't a superset of C. The functional overlap is better than 99% but not all C code is legal C++ and some which is legal doesn't work the same.

George

Reply to
George Neuner

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.