This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Secondary bootloader using sd-card

Hi, I am trying to run the secondary bootloader demo code using sd-card and flash file system. I picked up the demo code from here: www.nxp.com/.../LPC2000_Series_Secondary_Bootloader.zip In the folder Bootloader_SD. Since it is written for LPC2387, while i am using LPC2138. So, i replaced MMC driver funtions with SPI driver functions. I also changed the UART1 port to UART0 port for (in serial.c) LPC2138 for pc interface. On compiling, only 5 waarnings:

SD\BL_SD.c(279): warning: #167-D: argument of type "U32 *" is incompatible with parameter of type "unsigned long *"
SD\BL_SD.c(353): warning: #167-D: argument of type "U32 *" is incompatible with parameter of type "unsigned long *"
SD\BL_SD.c(366): warning: #177-D: variable "IAP_return" was declared but never referenced
SD\BL_SD.c(554): warning: #167-D: argument of type "U32 *" is incompatible with parameter of type "unsigned long *"
SD\BL_SD.c(364): warning: C3017W: sector_size may be used before being set

On running, i can see the menu on Hyper-terminal. I am also able to see the list of files present in the sd-card using DIR command. But when i issue command
CMD>> PROG ZCODE.BIN(enter) (Zcode.bin is binary file present in sd-card)
it says programing ZCODE.BIN at 0x10000....
and that's it. hangs there.........
It does so also on erase command. i.e ERASE 10 20(enter) ...hangs....
Have i missed something. I think the IAP.c file is valid for whole LPC2000 family..

Regards,
Salman

Parents Reply Children
  • "a good programmer must understand what the warnings indicate and make appropriate corrections. they could have a deeper underlying cause."

    Very true.

    A type-cast might be an appropriate correction in some cases - but, as you say, that needs to be found as the result of careful study & consideration of the code.

  • Ok i am trying to find out why is the warning
    SD\BL_SD.c(364): warning: C3017W: sector_size may be used before being set
    coming in the following function. One simple way is to initialize sector_size to 0, but that would be a blind solution. I can't find why is this warning.

    static void cmd_prog (char *par)
    {
            char *fname, *entry, *next;
            FILE *fin;
            U32 app_addr, sector_index, sector_size , sector_size_sum, total, cnt; // warning here
            BOOL prog_done, new_sector;
            //U32 IAP_return[2];
    
            // fname: BIN filename, only BIN file is supported now
            fname = get_entry (par, &next);      // Image file name
            if (fname == NULL) {
              printf ("\nImage filename missing.\n");
              return;
            }
            if (strcmp(fname+strlen(fname)-3, "BIN") != 0 &&
                    strcmp(fname+strlen(fname)-3, "bin") != 0)
            {
                    printf("\nOnly BIN file is supported.\n");
                    return;
            }
    
            // program address
            entry = get_entry (next, &next);  // Image entry point
            if (entry == NULL)
                    app_addr = DEFAULT_PROG_ADDR;
            else
                    app_addr = strtoul(entry);
    
            // app_addr should be a starting address of some sector,
            // it's better to verify here
    
            sector_index = getSectorIndex(app_addr);
            if (sector_index == INVALID_RESULT)
            {
                    printf("\nInvalid application address!\n");
                    return;
            }
            if (sector_index <= bl_sector_endidx)
            {
                    printf("\nApplication address overlapped with boot loader!\n");
                    return;
            }
    
    
            printf("\nProgramming %s to 0x%x...\n", fname, app_addr);
    
            fin = fopen (fname,"rb");           /* open the file for reading           */
            if (fin == NULL) {
              printf ("\nFile %s not found!\n",fname);
              return;
            }
    
            prog_done = 0;
            new_sector = 1;
    
            total = 0;
            sector_size_sum = 0;
    
    
            do
            {
                    cnt = fread (&IAP_Buf, 1, IAP_BUF_SIZE, fin);
                    if (cnt == 0) /* error of EOF */
                    {
                            prog_done = 1;
                            break;
                    }
                    else
                    {
                            if (new_sector)
                            {
                                    if (IAP_PrepareErase(sector_index) != 0 )
                                    {
                                            printf("\nFailed to prepare/erase sector %d.\n", sector_index);
                                            prog_done = 1;
                                            break;
                                    }
    #if 0
                                    // prepre sector [sector_index] to erase
                                    if(IAP_PrepareSec(sector_index, sector_index) != IAP_STA_CMD_SUCCESS)
                                    {
                                            printf("\nFailed to prepare sector %d.\n", sector_index);
                                            prog_done = 1;
                                            break;
                                    }
                                    // erase sector [sector_index]
                                    IRQDisable();
                                    if (IAP_EraseSec(sector_index, sector_index) != IAP_STA_CMD_SUCCESS)
                                    {
                                            printf("\nFailed to erase sector %d.\n", sector_index);
                                            prog_done = 1;
                                            break;
                                    }
                                    IRQEnable();
    #endif
    
                                    sector_size = (getSectorSize(sector_index) << 10);
                                    sector_size_sum = 0;
                                    new_sector = 0;
                            }
    
                            if (IAP_Program(sector_index, app_addr) != 0)
                            {
                                    printf("\nFailed to program at 0x%x.\n", app_addr);
                                    prog_done = 1;
                                    break;
                            }
    
    #if 0
                            // program 1kb [app_addr]
                            // prepre sector [sector_index] to write
                            if(IAP_PrepareSec(sector_index, sector_index) != IAP_STA_CMD_SUCCESS)
                            {
                                    printf("\nFailed to prepare sector %d.\n", sector_index);
                                    prog_done = 1;
                                    break;
                            }
                            IRQDisable();
                            if ((IAP_CopyRAMToFlash(app_addr, (U32)IAP_Buf, IAP_BUF_SIZE)) != IAP_STA_CMD_SUCCESS)
                            {
                                    printf("\nFailed to program at 0x%x.\n", app_addr);
                                    prog_done = 1;
                                    break;
                            }
                            if (IAP_Compare(app_addr, (U32)IAP_Buf, IAP_BUF_SIZE, IAP_return) != IAP_STA_CMD_SUCCESS)
                            {
                                    printf("\nVerify failed at 0x%x.\n", app_addr);
                                    prog_done = 1;
                                    break;
                            }
                            IRQEnable();
    #endif
    
                            app_addr += IAP_BUF_SIZE;
                            total += cnt;
                            sector_size_sum +=      IAP_BUF_SIZE;
                            if (sector_size_sum     == sector_size)
                            {
                                    sector_index++;
                                    new_sector = 1;
                            }
                    }
    
            } while (prog_done==0);
    
       printf("\n%d bytes programmed.\n", total);
    
       fclose (fin);
    }
    

  • The compiler thinks that the if statement with sector_size could be executed before sector_size is assigned to. In reality it's not because of your new_sector flag so you could initialize sector_size to anything to make the compiler happy.

    I'm pretty sure the compiler warnings aren't your problem. More likely something about programming while running out of flash or similar, although I assume the IAP routines take that into account.

    Andrew

  • My problem is solved now. Reason was, I replaced the startup file of LPC23xx.s with LPC21xx.s and i didn't changed this portion (don't had the idea that it needs to be changed):

    SWI_Handler B SWI_Hndler      ;needs to be replaced
    ;with this one
    IMPORT SoftwareInterrupt
    SWI_Handler     B               SoftwareInterrupt
    

    Though i still have little understanding of what this is, but my code is working fine now.

  • Glad to hear it's working. What you did was replace an endless loop with a branch to an actual handler. Before the change a SWI would cause your code to endlessly execute the "B SWI_Hndler" line. After the change a SWI causes your code to jump to the routine "SoftwareInterrupt".