cancel
Showing results for 
Search instead for 
Did you mean: 

How to relocate the Cortex-M0 Vector Table

alerico90
Associate
Posted on June 19, 2015 at 17:44

Hello I have a problem with the vector table relocating, I moved the vector table with the following code, but when I am activating the usart interrupts the programs hangs

#define APPLICATION_ADDRESS     (uint32_t)0x08003000

 __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));

 

int main (void)

{

uint32_t i = 0;

/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/  

  /* Copy the vector table from the Flash (mapped at the base of the application

     load address 0x08003000) to the base address of the SRAM at 0x20000000. */

  for(i = 0; i < 48; i++)

  {

    VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));

  }

 /* Enable the SYSCFG peripheral clock*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

/* Remap SRAM at 0x00000000 */

SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);

init_SystickClock();

rtc_ini();

init_SPI1();

init_led();

init_LCD ();

Delayms(500);

init_USART1(9600);

}

void init_USART1(uint32_t baudrate) // this funcion initializes the USART1 peripheral

{

// RCC_ClocksTypeDef RCC_Clocks;

GPIO_InitTypeDef        GPIO_InitStructure; // this is for the GPIO pins 

USART_InitTypeDef USART1_InitStructure; // this is for the USART1 initilization

//

//************ Enable USART CLOCK ************//

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* GPIOA Periph clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

//************ Configure the TX and RX PIN ************//

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

//************ Configure the RTS PIN ************//

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 

GPIO_Init(GPIOA, &GPIO_InitStructure);

//************ Configure the CTS PIN ************//

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 

GPIO_Init(GPIOA, &GPIO_InitStructure);

//************ Asigned the AF (connect USART1 pins to USART1 alternate function) ************//

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); // TX

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); // RX

GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_1); // CTS

GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_1); // RTS

USART1_InitStructure.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function

USART1_InitStructure.USART_WordLength = USART_WordLength_8b; // we want the data frame size to be 8 bits (standard)

USART1_InitStructure.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)

USART1_InitStructure.USART_Parity = USART_Parity_Even; // we don't want a parity bit (standard)

USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; // we don't want flow control (standard)

USART1_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx; // we want to enable the transmitter and the receiver

USART_Init(USART1, &USART1_InitStructure); // again all the properties are passed to the USART_Init function which takes care of all the bit setting

  // finally this enables the complete USART1 peripheral

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Pins 9 (TX) and 10 (RX) are used

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate!

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain)

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); //

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

  USART1_InitStructure.USART_BaudRate = 9600; // the baudrate is set to the value we passed into this init function

  USART1_InitStructure.USART_WordLength = USART_WordLength_9b; // we want the data frame size to be 8 bits (standard)

  USART1_InitStructure.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)

  USART1_InitStructure.USART_Parity = USART_Parity_Even; // we don't want a parity bit (standard)

  USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)

  USART1_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver

  USART_Init(USART1, &USART1_InitStructure);

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt

  USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // enable the USART1  interrupt

//USART_ITConfig(USART1, USART_IT_RTO, ENABLE); // enable the USART1 timeout interrupt

// USART_SetReceiverTimeOut(USART1, 200);

GPIO_ResetBits(GPIOA,GPIO_Pin_12);// RTS Usart1

  USART_Cmd(USART1, ENABLE);

}

6 REPLIES 6
Posted on June 19, 2015 at 18:07

Probably shouldn't permit it to leave main()

Review the USART IRQ, if you don't service that TXE interrupt you've enabled it will be stuck there for ever.

Can you use a debugger? Where does the processor get stuck up? Does the vector table at 0x00000000 and 0x20000000 look valid?

How do you get to the code at 0x08003000, have you confirmed that works?

Is the code actually built to reside at 0x08003000, and have you confirmed that by reviewing the .MAP file, to confirm the placement of the image and the vector table definition you've provided?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
alerico90
Associate
Posted on June 19, 2015 at 22:22

Hello, well, my code gets stuck here: 

USART_ITConfig(USART2,USART_IT_RXNE,ENABLE)}

that line configures the Receiver interrupt, I am using a standard library where the USART_IT_RXNE  and the other interrupts definition are:

/** @defgroup USART_Interrupt_definition 

  * @brief USART Interrupt definition

  * USART_IT possible values

  * Elements values convention: 0xZZZZYYXX

  *   XX: Position of the corresponding Interrupt

  *   YY: Register index

  *   ZZZZ: Flag position

  * @{

  */

#define USART_IT_WU                          ((uint32_t)0x00140316)

#define USART_IT_CM                          ((uint32_t)0x0011010E)

#define USART_IT_EOB                         ((uint32_t)0x000C011B)

#define USART_IT_RTO                         ((uint32_t)0x000B011A)

#define USART_IT_PE                          ((uint32_t)0x00000108)

#define USART_IT_TXE                         ((uint32_t)0x00070107)

#define USART_IT_TC                          ((uint32_t)0x00060106)

#define USART_IT_RXNE                        ((uint32_t)0x00050105)

#define USART_IT_IDLE                        ((uint32_t)0x00040104)

#define USART_IT_LBD                         ((uint32_t)0x00080206)

#define USART_IT_CTS                         ((uint32_t)0x0009030A) 

#define USART_IT_ERR                         ((uint32_t)0x00000300)

#define USART_IT_ORE                         ((uint32_t)0x00030300)

#define USART_IT_NE                          ((uint32_t)0x00020300)

#define USART_IT_FE                          ((uint32_t)0x00010300)

Posted on June 19, 2015 at 22:42

You need to prove that the vector table is correctly instantiated.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pacman
Associate III
Posted on June 20, 2015 at 04:13

Which device are you using, and is it a Cortex-M0+ or a 'plain' Cortex-M0 ?

I hate breaking bad news to people, but it may at least save you a lot of trouble.

Normally, the Cortex-M0 does not allow moving the vector table.

The Cortex-M0+ does allow moving the vector table, though; to do this, you'll need to modify the VTOR hardware register.

Please let us know the name of the device, which you're trying to move the vector table for.

Posted on June 20, 2015 at 04:56

Normally, the Cortex-M0 does not allow moving the vector table.

That is exactly why you can change the memory that is shadowed at the zero memory base. A technique that's been in use for at least 3 decades.

The issue here is what the content of the table is, whether the NVIC has been setup or if there's any exception vectors (Hard Fault) to catch anything else.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pacman
Associate III
Posted on June 20, 2015 at 05:30

Sorry for the noise, I completely forgot about remapping; thanks for waking me up! 🙂