This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TM4C1231E6PM: Loading a program with bootloader enabling code (with Code Composer) in debug mode in a specific memory location

Part Number: TM4C1231E6PM

Tool/software: Code Composer Studio

We are developping a firmware with a bootloader (the firmware is loaded through UART1 peripheral). 

Up to now we are creating two projects: one for only debug purpose and one to be loaded through UART1.

The reason is the following: if we try to load in debug mode a project that has the code enabling the bootloader, the program starts correctly but it blocks at random points. When I pause the debug, I observe the following message: No source available for "0xfffffffe" and looking in the "view Disassembly" the following message is shown: "???? Memory map prevented reading 0xFFFFFFFE [code=0x20000]".

The project with the the code enabling the bootloader is working correctly if it is loaded at the memory location 0x1000 using LMFLASH programmer (at location 0x0 I have to load before the bootloader).

The project without the code enabling the bootloader is working correctly both if it is loaded with LMFLASH Programmer and if it loaded in debug mode through Code Composer,

The project with the code enabling the bootloader has the following differences with respect to the "standard project":

1)  Introduction of the routine

void
JumpToBootLoader(void)
{
   //
   // We must make sure we turn off SysTick and its interrupt before entering
   // the boot loader!
   //
   ROM_SysTickIntDisable();
   ROM_SysTickDisable();
 
   //
   // Disable all processor interrupts. Instead of disabling them
   // one at a time, a direct write to NVIC is done to disable all
   // peripheral interrupts.
   //
   HWREG(NVIC_DIS0) = 0xffffffff;
   HWREG(NVIC_DIS1) = 0xffffffff;
   HWREG(NVIC_DIS2) = 0xffffffff;
   HWREG(NVIC_DIS3) = 0xffffffff;
   HWREG(NVIC_DIS4) = 0xffffffff;
   //
   // Return control to the boot loader. This is a call to the SVC
   // handler in the boot loader.
   //
   (*((void (*)(void))(*(uint32_t *)0x2c)))();
}

2) The routine UART1IntHandler has been modified in the following way

void
UART1IntHandler(void)
{
   GPIO_PORTF_DATA_R &= ~ TX_EN_RS485;
   uint32_t ui32StatusRX;
 
   RingBufFlush(&rxRingBuf);
   //
   // Get the interrupt status.
   //
   ui32StatusRX = ROM_UARTIntStatus(UART1_BASE, true);
 
   //
   // Clear the asserted interrupts.
   //
   ROM_UARTIntClear(UART1_BASE, ui32StatusRX);
   // The receive timeout interrupt fires when you have received bytes in your FIFO but have not
   // gotten enough to fire your Rx interrupt. This is because the FIFO level select determines when that
   // interrupt goes off.
   if((ui32StatusRX & UART_INT_RT) == UART_INT_RT)
   {
       // While there are bytes to read and there is space in the FIFO.
       while(UARTCharsAvail(UART1_BASE) && RingBufFull(&rxRingBuf) == false)
       {
           uint32_t ch = (uint8_t)ROM_UARTCharGet(UART1_BASE);
 
           if(ch=='?')
                       {
                     GPIO_PORTF_DATA_R|=LED_GREEN;
                           GPIO_PORTF_DATA_R |= TX_EN_RS485;
                           UARTCharPut(UART1_BASE, 'B');
                           while(ROM_UARTBusy(UART1_BASE));
                           UARTCharPut(UART1_BASE, 'o');
                           while(ROM_UARTBusy(UART1_BASE));
                           UARTCharPut(UART1_BASE, 'o');
                           while(ROM_UARTBusy(UART1_BASE));
                           UARTCharPut(UART1_BASE, 't');
                           while(ROM_UARTBusy(UART1_BASE));
                           JumpToBootLoader();
                       }
 
 
           // Write a byte straight from the hardware FIFO into our Rx FIFO for processing later.
           RingBufWriteOne(&rxRingBuf, ch);
       }
   }
   if((ui32StatusRX & UART_INT_RX) == UART_INT_RX)
   {
       //
       // Loop while there are characters in the receive FIFO.
       //
       while(ROM_UARTCharsAvail(UART1_BASE) && RingBufFull(&rxRingBuf) == false)
       {
           //
           // Read the next character from the UART
           //
           uint32_t ch = (uint8_t)ROM_UARTCharGet(UART1_BASE);
           RingBufWriteOne(&rxRingBuf,ch);
       }
   }
}

 

3) In the file .cmd the address APP_BASE becomes 0x00001000 instead of 0x00000000

I am not an expert of bootloader but I guess that the issue is in the way in which the code is loaded through Code Composer.

Is there in Code Composer an option similar to "Program Address Offset" present in LMFlash Programmer?

  • Take a look at the example projects in TivaWare even if you do not have the development board.

    C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\dk-tm4c123g\boot_serial

    C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\dk-tm4c123g\boot_demo1

    Notice that the linker command file (.cmd) for each project is different. They determine where the code gets programmed into the flash when using Code Composer to load the program. It is then not necessary to define an offset when loading the .out files.

    Load the bootloader first, then make sure you don't erase the bootloader when you load the application code. From the "Tools" -> "On-Chip Flash" dialog box, change the Erase Method to "Necessary Pages Only" as shown below.

  • Is it 'Fair/Proper to Ask' ... "Does the poster get 'Graded and/or Paid'  via the 'Volume of Whitespace?'    SO 'Helper UNFRIENDLY!'

    Should 'Poster EASE & Time-Saving' ... CONDEMN  ALL 'Helpers' here - to such (unwanted) OVERLOAD?     IF 'NOT so  advised/alerted' - how will they (ever) improve?

    The, 'Unanticipated Consequence' of such 'difficult postings' is that, 'Multiple other Forum Users will note this' - and (if not corrected) - are inclined to 'Repeat this (unfortunate) Practice.'

  • What my friend is suggesting is that when posting code to the forum, please use the code formatting mode by clicking on the </> box above the text box. You will find that the resulting post is much easier for everyone to read.