Linker in sektorji v flashu

Moderator: tilz0R

Linker in sektorji v flashu

OdgovorNapisal/-a s54mtb » 15 Feb 2016, 01:20

Kako v keil uVision dodam področje v flashu na adresi 0x08007c00 dolžine 1k, ki ga linker pusti pri miru za čečkanje med delovanjem programa? Če sedaj počečkam po flashu, mi ob naslednjem zagonu po resetu skoči v hard fault med izvajanjem __scatter_load (še pred main-om).


Če dolžino IROM skrajšam za 1k je sicer vcse OK, samo to se mi zdi precej šlampasto. Bi raje linkerju ekspicitno povedal, kaj hočem.


Koda: Izberi vse
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00007000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00007000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00004000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a Kroko » 15 Feb 2016, 01:43

mogoče takole?

char reserved[1024] __attribute__((at(0x08007c00)));
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a s54mtb » 15 Feb 2016, 01:53

Saj tako imam. Samo, ko spremenim vsebino takega polja, mi ob naslednjem resetu konča v hard fault še preden pride do main-a. S tistim scatter inicializacijskim fajlom dopoveš linkerju, da je nek del flasha r/w.
Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a tilz0R » 15 Feb 2016, 08:12

Po moje probaj z const char. Po flashu nemoreš prosto pisat kot spremenljivka.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 2403
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 264 krat
Prejel zahvalo: 767 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a s54mtb » 15 Feb 2016, 08:30

Saj ni težava vpis v flash. Tole deluje brez težav:

Koda: Izberi vse
#define FLASH_STORE_ADR            0x8007c00
#define FLASH_BACKUP_ADR      0x8007800

/* Flash storage for settings at absolute address */
const settings_t settings_Store[SETTINGS_CATLEN] __attribute__((at(FLASH_STORE_ADR)));
const settings_t backup_settings_Store[SETTINGS_CATLEN] __attribute__((at(FLASH_BACKUP_ADR)));


/**
   * @brief Store settinfgs to specified position
   * @param Message string
   * @param del - 0 = normal write, 1 - delete
   * @retval None
   */
void cmd_store(char *argstr_buf, uint8_t del)
{
   char izp[32];
   int x,i;
   HAL_StatusTypeDef FLstatus;
   FLASH_EraseInitTypeDef eraseinit;
   uint32_t PageError;
   uint32_t stadr;
   uint64_t buf;
   uint32_t fladr;
   uint8_t *adr;
   settings_t    tmp_settings;
   
   if ((argstr_buf != NULL) & (strlen(argstr_buf)>0))
   {      
    x = atoi(argstr_buf);
      if ((x>0) & (x<=SETTINGS_CATLEN))
      {
         x--; // x = 1...n
         FLstatus = HAL_FLASH_Unlock(); 

         // Erase backup sector
         eraseinit.NbPages = 1;
         eraseinit.PageAddress = FLASH_BACKUP_ADR;
         eraseinit.TypeErase = TYPEERASE_PAGES;
         FLstatus = HAL_FLASHEx_Erase(&eraseinit, &PageError);   
         
         // copy store to backup
         for (i = 0; i< SETTINGS_CATLEN; i++)
         {
            adr = (uint8_t *)&tmp_settings;
            memcpy(adr, &settings_Store[i], sizeof(settings_t));
            fladr = FLASH_BACKUP_ADR+sizeof(settings_t)*(i);
            for (stadr = 0; stadr<(sizeof(settings_t)/8); stadr++)
            {
               memcpy(&buf, adr, 8);
               FLstatus =  HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, fladr, buf);
               adr+=8;
               fladr+=8;
            }

        }
         snprintf(izp, 32, "Backup... status %d\n\r", FLstatus);
        USB_write((uint8_t *)izp, strlen(izp));

         // erase store
         eraseinit.NbPages = 1;
         eraseinit.PageAddress = FLASH_STORE_ADR;
         eraseinit.TypeErase = TYPEERASE_PAGES;
         FLstatus = HAL_FLASHEx_Erase(&eraseinit, &PageError);   
         
         // and write to it from new data and backup

         for (i = 0; i< SETTINGS_CATLEN; i++)
         {
        if (i == x) // actual location is written with new data
            {
               if (del == 1) // delete
               {
                  // do nothing, keep erased flash
               }
               else
               {                     
                  adr = (uint8_t *)&settings;
                  fladr = FLASH_STORE_ADR+sizeof(settings_t)*x;
                  for (stadr = 0; stadr<(sizeof(settings_t)/8); stadr++)
                  {
                     memcpy(&buf, adr, 8);
                     FLstatus =  HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, fladr, buf);
                     adr+=8;
                     fladr+=8;
                  }
               }
            }  // if i==x
            else
            {
               adr = (uint8_t *)&tmp_settings;
               memcpy(adr, &backup_settings_Store[i], sizeof(settings_t));
               fladr = FLASH_STORE_ADR+sizeof(settings_t)*(i);
               for (stadr = 0; stadr<(sizeof(settings_t)/8); stadr++)
               {
                  memcpy(&buf, adr, 8);
                  FLstatus =  HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, fladr, buf);
                  adr+=8;
                  fladr+=8;
               }
               
            }
         }  /*  for ... */
         snprintf(izp, 32, "Writing... status %d\n\r", FLstatus);
        USB_write((uint8_t *)izp, strlen(izp));


         FLstatus = HAL_FLASH_Lock(); 
      }
  }
}



/**
   * @brief Load settinfgs from specified position
   * @param Message string
   * @param del - 0 = normal write, 1 - delete
   * @retval None
   */
void cmd_load(char *argstr_buf)
{
   int x;
   uint8_t *adr;
   char izp[32];
   
   if ((argstr_buf != NULL) & (strlen(argstr_buf)>0))
   {      
    x = atoi(argstr_buf);
      if ((x>0) & (x<=SETTINGS_CATLEN))
      {
         x--; // x = 1...n
         adr = (uint8_t *)&settings;
         memcpy(adr, &settings_Store[x], sizeof(settings_t));
         snprintf(izp, 32, "Loaded %d: ", x+1);
        USB_write((uint8_t *)izp, strlen(izp));         
         DisplaySettings(&settings);
         snprintf(izp, 32, "\n\r");
         USB_write((uint8_t *)izp, strlen(izp));      
    }
  }
}





/**
   * @brief Catalog stored settings
   * @param None
   * @param None
   * @retval None
   */
void cmd_cat(void)
{
   int i;
   char izp[32];
   char firstchar;
   
   for (i=0; i<SETTINGS_CATLEN; i++)
   {
      // Print number
      snprintf(izp, 32, "%x: ",i+1);  // avoid 0
      USB_write((uint8_t *)izp, strlen(izp));
      // Print out settings ID
      firstchar = settings_Store[i].Ident[0];
      if ((strlen(settings_Store[i].Ident) > 0) & (firstchar!=0xff))
      {
         DisplaySettings((settings_t *)&settings_Store[i]);
      }
      else
      {
         snprintf(izp, 32, " <Empty> ");
         USB_write((uint8_t *)izp, strlen(izp));
      }

      snprintf(izp, 32, "\n\r");
      USB_write((uint8_t *)izp, strlen(izp));
      
   }
   
}



V debugerju pred vpisom:
Koda: Izberi vse
d 0x08007c00
0x08007C00  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C10  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C20  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C30  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C40  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C50  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C60  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C70  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................


Po vpisu:
Koda: Izberi vse
d 0x08007c00
0x08007C00  54 45 53 54 00 00 00 00 - 00 00 00 00 00 00 00 00 TEST............
0x08007C10  31 32 33 34 35 36 00 00 - 00 00 00 00 00 00 00 00 123456..........
0x08007C20  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C30  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C40  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C50  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C60  FF FF FF FF 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0x08007C70  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a Kroko » 15 Feb 2016, 10:05

Ne razumem v čem je problem.
Po flashu kar precej telovadim. Spomnim se, da sem poskušal tudi s scatter datoteko. Ampak se mi ni zdelo ok.

V flash ponavadi ne moreš pisati kamor hočeš ampak samo v cele bloke. Si to preveril v datasheetu?
Problematičen zna biti tudi timing write cikla. Preveri če kaj piše v errata. No, v vsakem primeru je dobro da čase povečaš in s tem podaljšaš življensko dobo flashu. Jaz sem čase povečal za 3x.
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a s54mtb » 15 Feb 2016, 10:41

Problem je v tem, da linker doda neke rutine v sam zagon, ki ali preverja nek čeksum, ali pa kaj drugega, zaradi česar po tem, ko v flash nekaj vpišem, konča v hard fault. Če IROM skrajšam za en sketor je ok, samo kaj pa če bi hotel imeti vpis v flash nekje na sredi?
Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Linker in sektorji v flashu

OdgovorNapisal/-a Kroko » 15 Feb 2016, 10:56

Aha, razumem. "Flash signature generation" je problem:
http://www.keil.com/support/man/docs/uv ... elfdwt.htm

Mogoče dobiš tule idejo:
https://www.lpcware.com/content/forum/l ... generation
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255


Vrni se na C in sorodni jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost