Hi Jez
I just looked into the state of the Beta and confirm the compiler errors.
To get around the first problem simply define
#define __interrupt
__interrupt is never needed with the Cortex M3
In the Beta version there is still the following:
#if defined COMPILE_IAR || defined COMPILE_KEIL
#if defined COMPILE_IAR
#define __interrupt __irq __arm
#else
#define __interrupt __irq
#define __root
#endif
#else
#define __interrupt
#define __root
#endif
This can be deleted since it is otherwise setting the __irq __arm, which is invalid for IAR and the Cortex M3.
There is however another problem due to the way that IAR works. Looking in my notes I found that we discussed this back in January in private email exchanges when I was making the IAR5 adaptations. I have copied this here (check your mail from 29.1.2010 for the original. With this it compiles and links so there is still hope for your Keil board ;-)
Regards
Mark
***************************************************
I now have a compatible solution for the IAR checksum case.
In lpc17xx.h
typedef struct stVECTOR_TABLE_MINIMUM
{
RESET_VECTOR reset_vect;
unsigned long ulDummyNMI;
unsigned long ulDummyHardFault;
unsigned long ulDummyMemMan;
unsigned long ulDummyBusFault;
unsigned long ulDummyUsageFault;
#ifndef COMPILE_IAR5
unsigned long ulLPC1XXX_CS;
#endif
} VECTOR_TABLE_MINIMUM;
In lpc17xx.c
// The initial stack pointer and PC value - this is linked at address 0x00000000
//
#if defined COMPILE_IAR5
__root const VECTOR_TABLE_MINIMUM __vector_table @ ".intvec" // __root forces the function to be linked in IAR project
#elif defined COMPILE_IAR
__root const VECTOR_TABLE_MINIMUM reset_vect @ "RESETVECT" // __root forces the function to be linked in IAR project
#elif defined _GNU
const VECTOR_TABLE_MINIMUM __attribute__((section(".vectors"))) reset_vect
#elif defined _COMPILE_KEIL
__attribute__((section("RESET"))) const VECTOR_TABLE_MINIMUM reset_vect
#else
const VECTOR_TABLE_MINIMUM reset_vect
#endif
= {
{
(void *)(RAM_START_ADDRESS + SIZE_OF_RAM), // stack pointer to top of RAM
(void (*)(void))START_CODE, // start address
},
0x53415475, // dummy vector values (for recognition)
0x2052454b,
0x3143504c,
0x20585858,
0x2e522e43,
#ifndef COMPILE_IAR5
0xffffffff, // blank for check sum
#endif
};
#if defined COMPILE_IAR5
__root const unsigned long __vector_table_0x1c @ ".intvec" = 0xffffffff;
#endif
This allows the .icf file to be left as it was. Since the IAR linker finds the variable __vector_table_0x1c at the correct location it then fills it out correctly.
Below is a copy of my developer’s log in case you need more background info.
***************************************************
Reset and Interrupt vectors
The reset is slightly different in comparison to the LPC2XXX. The first location in FLASH is the initial value of the Stack pointer and the second is the PC value to be loaded. Following this there are interrupt vectors similar to the ARM7 (although not identical). To get an idea of the layout the vector tables struc is shown here:
typedef struct stVECTOR_TABLE
{
RESET_VECTOR reset_vect;
void (*ptrNMI)(void);
void (*ptrHardFault)(void);
void (*ptrMemManagement)(void);
void (*ptrBusFault)(void);
void (*ptrUsageFault)(void);
void *ptrReserved1[4];
void (*ptrSVCall)(void);
void (*ptrDebugMonitor)(void);
void *ptrReserved2;
void (*ptrPendSV)(void);
void (*ptrSysTick)(void);
PROCESSOR_IRQ processor_interrupts; // length is processor specific
} VECTOR_TABLE;
After the reset vector (the initial SP and initial PC values) there are the first 5 fixed interrupt vectors. These are followed by 4 reserved locations. In a similar manner to the LPC2XXX the first of these reserved locations are used as check sum by the internal boot loader. The values of the reset vector plus the first 5 interrupt vectors are used to calculate the value that the boot loader expects to find at the first reserved location (long word addressed at 0x1c).
The Cortex M3 doesn’t need the interrupt vectors to be located here since they can be remapped to other locations; even when this is the case (as in the µTasker project) it is necessary to keep the location 0x1c free – its value is generally calculated when downloading the code. The µTasker project this uses a few fixed values, with 0xffffffff at 0x1c so that the boot’s check sum can be correctly set.
Since the Cortex M3 allows assembler code to be avoided in most situations the µTasker project also attempts to stick with this strategy wherever possible. This helps in keeping code portable and also in understanding its operation – assembler code is often specific to a particular compiler and is not always immediately understandable when written for a different compiler packages as one is used to.
The reset vector (actually a reduced version of the vector table) can be found in LPC17XX.c.
const VECTOR_TABLE_MINIMUM __attribute__((section(".vectors"))) reset_vect = {
{
(void *)(RAM_START_ADDRESS + SIZE_OF_RAM), // stack pointer to top of RAM
(void (*)(void))START_CODE, // start address
},
0x53415475, // dummy vector values (for recognition)
0x2052454b,
0x3143504c,
0x20585858,
0x2e522e43,
0xffffffff, // blank for check sum
};
The constant table is forced to be at address 0x00000000 (section .vectors in the GCC linker script file) – this is also a bit compiler dependent but an appropriate form exists in the code to suit the supported compilers.
Since the interrupts are located in SRAM for actual use the values before the reserved location which is used as a checksum are not of importance – they are in fact ASCII for “uTASKER LPC1xxx C.S.” for recognition by a debugger. When the code is downloaded by FlashMagic or Rowley, etc. the checksum will automatically be added.
IAR is an exception since it doesn’t add the checksum automatically when it loads the code. It requires that an automated post-linking step performs it by modifying the generated file.
This is controlled by the file LPC1766.i76 in the IAR directory arm\config\devices\NXP\ which includes a direction
NXPLPCchecksum=__vector_table_0x1c:4,sum32:2;__vector_table-__vector_table+0x1B
If this is removed from the file the file can still be loaded using FlashMagic but the check sum will be missing if loaded from within IAR. If the direction is left in the linker step will fail unless it can find the location that it wants to calculate and modify.
To solve this, the following change was made to suit IAR:
#if defined COMPILE_IAR5
__root const VECTOR_TABLE_MINIMUM __vector_table @ ".intvec" // __root forces the function to be linked in IAR project
#elif defined _GNU
const VECTOR_TABLE_MINIMUM __attribute__((section(".vectors"))) reset_vect
#elif defined _COMPILE_KEIL
__attribute__((section("RESET"))) const VECTOR_TABLE_MINIMUM reset_vect
#else
const VECTOR_TABLE_MINIMUM reset_vect
#endif
= {
{
(void *)(RAM_START_ADDRESS + SIZE_OF_RAM), // stack pointer to top of RAM
(void (*)(void))START_CODE, // start address
},
0x53415475, // dummy vector values (for recognition)
0x2052454b,
0x3143504c,
0x20585858,
0x2e522e43,
#ifndef COMPILE_IAR5
0xffffffff, // blank for check sum
#endif
};
#if defined COMPILE_IAR5
__root const unsigned long __vector_table_0x1c @ ".intvec" = 0xffffffff;
#endif
This definition of VECTOR_TABLE_MINIMUM is also modified in this case to be one long word shorter, after which the compulsory variable is positioned. This allows the check sum to be inserted by IAR during the linking phase.
***************************************************