Keil Logo

Secondary bootloader using sd-card

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Salman Liaquat
Posted
4-Oct-2011 13:05 GMT
Toolset
ARM
New! 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: http://www.nxp.com/documents/other/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

Read-Only
Author
Andrew Neil
Posted
4-Oct-2011 14:08 GMT
Toolset
None
New! RE: Have i missed something

Fix the warnings!

Read-Only
Author
Per Westermark
Posted
4-Oct-2011 14:20 GMT
Toolset
None
New! RE: Have i missed something

Note that even if unsigned and unsigned long are both same size (32-bit) on many 32-bit compilers, they may still complain about them being different data types. And it may sometimes require unsigned long and sometimes unsigned long long to get a 64-bit number (if the compiler even supports 64-bit integers).

The difference between a 32-bit unsigned and a 32-bit unsigned long is important, since printf()/scanf() use different formatting strings for unsigned and unsigned long. So recompiling on a target where they are not the same size will result in failed calls to printf()/scanf().

Read-Only
Author
hunt the real cause zeusti
Posted
4-Oct-2011 15:01 GMT
Toolset
None
New! RE: Have i missed something

<quote>Fix the warnings!</quote>

what???

he can fix most warnings so easy. just paint the code with typecasts.

but no nO NO

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

Always yo're freind.

Zeusti

Read-Only
Author
Andrew Neil
Posted
4-Oct-2011 15:31 GMT
Toolset
None
New! RE: just paint the code with typecasts

"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.

Read-Only
Author
Salman Liaquat
Posted
4-Oct-2011 16:32 GMT
Toolset
None
New! RE: just paint the code with typecasts

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);
}
Read-Only
Author
Andrew Queisser
Posted
4-Oct-2011 17:06 GMT
Toolset
None
New! RE: just paint the code with typecasts

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

Read-Only
Author
Salman Liaquat
Posted
5-Oct-2011 12:52 GMT
Toolset
None
New! RE: Have i missed something

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.

Read-Only
Author
Andrew Queisser
Posted
5-Oct-2011 16:21 GMT
Toolset
None
New! RE: Have i missed something

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".

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.