Flash Driver Front End

At this point, the portions of the flash device driver that directly touch the flash are copied to RAM so that the system can still execute out of the 29F040 while performing flash operations. However, the lowest level functions, FlashWrite040() and FlashErase040() , are device-dependent. I need to add another layer before I start allowing the rest of the system to use this functionality. I need a front end that allows me to write to any flash device using an interface similar to memcpy () (i.e., source and destination plus a size ). For erasure, I need the ability to call a function and specify the sector I wish to erase. This function eliminates the need for the higher-level code to know about the specific flash device.

At the command line, flash memory is manipulated with the flash command. This section explains how this command can manipulate the flash memory without knowing any device specifics.

Listing 6.8: The flash Command.
image from book
 int FlashCmd(int argc,char *argv[]) {     int ret;     ulong   dest, src, oints;     long    bytecnt, rslt;     struct  flashinfo *fbnk;     fbnk = &FlashBank[FlashCurrentBank];     ret = CMD_SUCCESS;     if (strcmp(argv[1],"bank") == 0)  {         int tmpbank;         if (argc == 3) {             tmpbank = atoi(argv[2]);             if (tmpbank < FLASHBANKS)                 FlashCurrentBank = tmpbank;                 printf("Subsequent flash ops apply to bank %d\n",                     FlashCurrentBank);         }         else              printf("Current flash bank: %d\n",FlashCurrentBank);     }     else if (!strcmp(argv[1],"write")) {         if (argc == 5) {             dest = strtoul(argv[2],(char **)0,0);             src = strtoul(argv[3],(char **)0,0);             bytecnt = (long)strtoul(argv[4],(char **)0,0);             rslt = AppFlashWrite((ulong *)dest,(ulong *)src,bytecnt);             if (rslt == -1)                 printf("Write failed\n");         }         else             ret = CMD_PARAM_ERROR;     }     else if (!strcmp(argv[1],"opw")) {         FlashProtectWindow = 2;     }     else {         ret = CMD_PARAM_ERROR;     }     return(ret); } 
image from book
 

The format for the flash command i flash {command} [args based on command]

For example flash write 0x1000 0xfff80000 128

copies 128 bytes from 0xfff80000 to the flash destination of 0x1000 . Theres nothing fancy here. This command doesnt take any options (see Listing 6.8), so getopt() is not used. The content of FlashCurrentBank points to the appropriate bank. Based on the earlier discussion, we know the 29F040-based target has only one bank, but multiples can be supported by increasing the size of the FlashBank[] array to the number of banks in the system. Listing 6.8 also shows how the FlashProtectWindow variable gets set so that the other flash operations that might be software protected can run. The most important thing to notice in FlashCMD() is the call to AppFlashWrite() .

The AppFlashWrite() function (in Listing 6.9) is used to abstract the characteristics of the flash memory. Notice that no device-specific information is passed to this function; hence, the caller is unaware of the underlying flash device characteristics.

Listing 6.9: Abstracting Flash Memory Characteristics.
image from book
 int AppFlashWrite(uchar *dest,uchar *src, long bytecnt) {     struct  flashinfo *fbnk;     int     ret;     long    tmpcnt;     ret = 0;     while(bytecnt > 0) {         fbnk = addrtobank(dest);         if (!fbnk)             return(-1);         if (((int)dest + bytecnt) <= (int)(fbnk->end))             tmpcnt = bytecnt;         else             tmpcnt = ((int)(fbnk->end) - (int)dest) + 1;              ret = fdev->flwrite(fbnk,dest,src,tmpcnt);         if (ret < 0) {             printf("AppFlashWrite(0x%lx,0x%lx,%ld) failed\n",                 (ulong)dest,(ulong)src,bytecnt);             break;         }         dest += tmpcnt;         src += tmpcnt;         bytecnt -= tmpcnt;     }     return(ret); } struct flashinfo * addrtobank(uchar *addr) {     struct  flashinfo *fbnk;     int     dev;     for(dev=0;dev<FLASHBANKS;dev++) {         fbnk = &FlashBank[dev];         if ((addr >= fbnk->base) && (addr <= fbnk->end))             return(fbnk);     }     printf("addrtobank(0x%lx) failed\n",(ulong)addr);     return(0); } 
image from book
 

A few neat things occur in AppFlashWrite() . Notice that addrtobank() converts the destination address into a corresponding flashinfo structure pointer. Then the destination address is compared to the end address of the bank. If the destination + bytecount passes the end of the bank, the byte count shrinks to a value that ends at the last address in the bank. Then on the next pass through the loop, addrtobank() is called again, and the new flashinfo pointer is returned for the next block write. Finally, notice that the flashinfo structure is once again used to call the flash write function (through the function pointer fdev->flwrite that corresponds to the bank of flash memory that overlaps the destination address). This is only applicable to systems that have more than one flash bank.



Embedded Systems Firmware Demystified
Embedded Systems Firmware Demystified (With CD-ROM)
ISBN: 1578200997
EAN: 2147483647
Year: 2002
Pages: 118
Authors: Ed Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net