Forums

TMS470 with IAR C++ Compiler

Started by Hagar January 22, 2009
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!




On Thu, 22 Jan 2009 10:32:38 -0600, "Hagar"
<mm283729@spamcorptastic.com> wrote:

>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!
C and C++ aren't interchangeable. Can you post the code? George
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&acute;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!





>On Thu, 22 Jan 2009 10:32:38 -0600, "Hagar" ><mm283729@spamcorptastic.com> wrote: > >>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! > >C and C++ aren't interchangeable. Can you post the code? > >George >
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 << 16) + SAM + TSEG1_13 + TSEG2_2 + SJW_1;

  	// Setup local acceptance mask LAM0
  	// Receive any incoming standard/extended ID message
  	SCC1CANLAM0 = LAMI + 0x1fffffff;

  	// Configure mailbox 0 for receive
  	SCC1CANMID0 = AME;     // Use acceptance mask LAM0
  	SCC1CANMCF0 = 0x00;
  	SCC1CANMDL0 = 0x00;
  	SCC1CANMDH0 = 0x00;
  		
	SCC1CANMD = MD0;       // Use mbox 0 for RX
  	SCC1CANOPC = OPC0;     // Protect against overwrite
  	SCC1CANME = ME0;      // Enable mailbox 0

  	// Start CAN module
  	SCC1CANMC &= ~CCR;
	
	// Wait until CAN module is started
  	while (SCC1CANES & CCE);
		
	REQMASK = (1 << CIM_SCCB);
}

__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;    			
  	}	
}

================ 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 << 16) + SAM + TSEG1_13 + TSEG2_2 + SJW_1;

	//Set local acceptance mask for mailbox 0
	SCC1CANLAM0 = LAMI + 0x1FFFFFFF;	//LAMI = extended and standard frames
can be received
										//0x1FFFFFFF = receive any package
	
	//Configure mailbox 0 for receive
	SCC1CANMID0 = AME;					//aceptance mask is used
	//Can data register
	SCC1CANMCF0	= 0x00;
	SCC1CANMDL0 = 0x00;
	SCC1CANMDH0 = 0x00;

	//Configure maibox 0 for receive
	SCC1CANMD = MD0;			//receive mailbox
	SCC1CANOPC = OPC0;         	//Protect against overwrite
  	SCC1CANME = ME0;           	 //Enable mailbox 0
	
	// Start CAN module
	SCC1CANMC &= ~CCR;
	while (SCC1CANES & CCE);	//Wait until CAN module is started

	REQMASK = (1 << CIM_SCCB);
}

void Can::enableInterrupt(bool b)
{
	if(b)
		REQMASK = (1 << CIM_SCCB); 
	else
		REQMASK = (0 << CIM_SCCB);
}
> __irq __arm void IRQ_Handler()
Check in your map file that this function is actually linked in. If not, try: extern "C" __irq __arm void IRQ_Handler() Leo Havm&#2013266168;ller.
It worked!

extern "C" __irq __arm void IRQ_Handler();

Thank you so much!
It was driving me crazy since yesterday!
Hagar wrote:
> > It worked! > > extern "C" __irq __arm void IRQ_Handler();
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: <http://www.catb.org/~esr/faqs/smart-questions.html> <http://www.caliburn.nl/topposting.html> <http://www.netmeister.org/news/learn2quote.html> <http://cfaj.freeshell.org/google/> (taming google) <http://members.fortunecity.com/nnqweb/> (newusers) -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.
On Fri, 23 Jan 2009 09:24:44 -0600, "Hagar"
<mm283729@spamcorptastic.com> wrote:

>It worked! > >extern "C" __irq __arm void IRQ_Handler(); > >Thank you so much! >It was driving me crazy since yesterday!
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