Отговори на тема  [ 34 мнения ]  Отиди на страница 1, 2, 3  Следваща
Проблем с флашването на LPC1754 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Проблем с флашването на LPC1754
Здравейте, искам да споделя един проблем с флашването на LPC1754. Флашването на устройството става посредством т.нар. In-Application (IAP) programming процедура, описана в каталогът на самият микроконтролер. Използвам готови функции, които не съм ги писал аз, но трябва да се настроят така че да може това флашване да бъде факт. Основната такава има следният вид:
Код:
Bool fshProgram_flash_region(uint8_t *addr, uint8_t *p, uint16_t n)
{
   uint8_t status;
   /* use ahb sram bank 0 as a cache */
   int x, len;
   uint32_t * xbuf = (uint32_t *) 0x2007c000;

   x = get_sector_of_addr((uint32_t) addr);
   if (x >= 10)
      return FALSE;
   if (x == 9)
      len = 0x1000;
   else
      len = 0x1000 * 2;
   memcpy(xbuf, (uint32_t) addr & ~ (0x1000 - 1), len);
   if (len == 0x1000 * 2)
      lpc17xx_flash_erase_sector(x + 1);
   lpc17xx_flash_erase_sector(x);
   memcpy(((uint32_t) xbuf) + ((uint32_t) addr & (0x1000 - 1)), p, n);
   lpc17xx_flash_program_words(x * 0x1000, xbuf, len >> 2);
   return TRUE;
}

единият проблем който срещам е че функцията get_sector_of_addr() връща стойност 10 и от там fshProgram_flash_region() излиза с резултат FALSE, което изобщо не минава през процедурите за флашване в раят на fshProgram_flash_region().
В get_sector_of_addr() се определя големината на секторът за флашване:
Код:
int get_sector_of_addr(uint32_t addr)
{
uint32_t i, x;

   for (x = i = 0; flash_sector_sizes[i]; x += flash_sector_sizes[i ++])
      if (x <= addr && addr < x + flash_sector_sizes[i])         
         break;
   return i;
}
/*****************************************************/
static const uint32_t flash_sector_sizes[] =
{
        4 * 1024, 4 * 1024, 4 * 1024, 4 * 1024,
        4 * 1024, 4 * 1024, 4 * 1024, 4 * 1024,
        4 * 1024, 4 * 1024, 4 * 1024, 4 * 1024,
        4 * 1024, 4 * 1024, 4 * 1024, 4 * 1024,

        32 * 1024, 32 * 1024,

        0,
};

въпросът ми е кога get_sector_of_addr() би могла да върне стойност 10, понеже масивът flash_sector_sizes[] има повече от 10 елемента. Ако е нужен още фърмуер, бих могъл да листна оща малко от самият полиморфизъм. Благодаря предварително да помоща :)!


Чет Яну 30, 2014 3:40 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение Re: Проблем с флашването на LPC1754
Ами при условие че имаш 16 сектора по 4к, сигурен ли си че
Цитат:
Код:
   if (x >= 10)
      return FALSE;


не е if (x >= 0x10) ?


Чет Яну 30, 2014 5:02 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Проблем с флашването на LPC1754
Страница 620 от user manual-а на LPC17xx - там е дадено разпределението на FLASH-а по сектори съответно и стартовите адреси на всеки сектор за дивайсите от серията.
Кода който ползваш има нужда от повече преправяне за да отговаря на FLASH-а на LPC1754.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Чет Яну 30, 2014 11:42 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Мисля че с адресът който задавам, нахвърлям това ограничение от 10. Някой занимавал ли се е с флашване на този вид процесори, може ли примерен код да се ориентирам как точно стават нещата, пък аз ще се опитам да вържа логиката с диаграмата от страница 620 от каталогът. Благодаря ви :)!


Пет Яну 31, 2014 11:38 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Проблем с флашването на LPC1754
На пръв поглед
int get_sector_of_addr(uint32_t addr);
връща броя сектори които заема кода, който буутлоадъра ще флашва .
При NXP, както си видял вече в юзър мануала, секторите са с различна големина. Трябва да ги опишеш в масива:
flash_sector_sizes[]
Този масив трябва да завършва с нула.

Функцията:
Bool fshProgram_flash_region(uint8_t *addr, uint8_t *p, uint16_t n);
трябва да се преработи изцяло.
Мога да ти помогна, но само със съвети. Ако дадеш линк към сорсовете от които тръгваш ще улесниш тая работа.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пет Яну 31, 2014 10:18 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Няма проблем ще листна полиморфизъмът за флашването, но една част от кодовете останаха в офисът. Повече инфо мога да дам най-рано в понеделник. Ще видя с какво разполагам и тук, но съм сигурен че полиморфизъмът не е целият .....


Пет Яну 31, 2014 10:40 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Прикачам С файл с полиморфизъмът с флашването. В него има у функции които работят с IAP процедурите, описани в каталогът на LPC-то. Опитал съм се да извадя почти функции и параметри, работещи с този механизъм, но ако съм пропуснал нещо може да кача още код....


Прикачени файлове:
Коментар на файл: Полиформизъм за флашване на LPC1754.
Flash.c [6.63 KiB]
363 пъти
Вто Фев 04, 2014 10:12 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: Проблем с флашването на LPC1754
Колега, само да попитам какво имаш в предвид с "полиморфизъм"? Имам чувството, че го използваш вместо "такова" :)

_________________
Мразя да мразя ...


Вто Фев 04, 2014 3:31 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Имам предвид, частта от фърмуерът, която е свързана с въпросният флаш.


Вто Фев 04, 2014 3:43 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Проблем с флашването на LPC1754
Днес прегледах сорсовете във файла който си постнал. Първо да се поправя, функцията int get_sector_of_addr(uint32_t addr); връща в кой сектор ти се намира началото на блока който ще флашваш. Така както са написани функциите, се използват само първите 10 сектора. Тези сектори при LPC1754 са по 4к и това не е параметризирано в кода.
Ако това което ще записваш във флаша допуска да му се премести началния адрес и ако големината му позволява да се побереш само в първите 10 сектора, го направи и не се занимавай с преправяне на съществуващия код. От начина по който пишеш мисля, че не си още добре ориентиран и смятам че това ще е по-добрия вариант за теб.
"Полиморфизма" не е удачен термин за това за което го използваш. Макар, че вероятно има някаква връзка с начина по който смяташ да използваш този код.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Сря Фев 05, 2014 8:13 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Здревйте, искам да попитам нещо: Понеже възнамерявам да ползвам следният алгоритъм преди въпросното флашване:
Код:
void getFile_entry(void){
uint8_t RSReceveBuf[2048] = {0};
uint8_t c;
uint16_t cnt;

      cnt=0;
      c = 0;
      while (1)
      {
         c = comGetchar_host();

                  if(c!=0x18 && c!=0x1B && c!=0x76)
               {
                       if(c!=0x2C && c!=0x0D)
                           {                 
                          RSReceveBuf[cnt] = c;
                          cnt++;
                        }
               }
         if (RSReceveBuf[cnt] != EOF)
         {
         }
         else
         break;
      }
}

идеята ми е да напълня RSReceveBuf с байтове, предавани серийно (примерно да изпратя txt файл с размер от 2К) и след това да гетна адресът на този масив от RAM-а и да го флашна в Flash паметта на контролерът с помощта на функциите които вече качих. Знам че EOF е константа която се използва в ОС. Въпросът ми е може ли да се направи механизъм който да следи за краят на файлът който предавам по RS-а, така че като достигна този край да ми брейква while(1) цикълът. Константа EOF нямам иплементирана във фърмуерът. Благодаря още един пат за помощта на всички отзовали се :)


Чет Фев 06, 2014 3:26 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Zdrav написа:
Днес прегледах сорсовете във файла който си постнал. Първо да се поправя, функцията int get_sector_of_addr(uint32_t addr); връща в кой сектор ти се намира началото на блока който ще флашваш. Така както са написани функциите, се използват само първите 10 сектора. Тези сектори при LPC1754 са по 4к и това не е параметризирано в кода.
Ако това което ще записваш във флаша допуска да му се премести началния адрес и ако големината му позволява да се побереш само в първите 10 сектора, го направи и не се занимавай с преправяне на съществуващия код. От начина по който пишеш мисля, че не си още добре ориентиран и смятам че това ще е по-добрия вариант за теб.
"Полиморфизма" не е удачен термин за това за което го използваш. Макар, че вероятно има някаква връзка с начина по който смяташ да използваш този код.


Здравей Zdrav, понеже в момента се опитвам да дебъгна кодовете които ти пратих, Резултатите които наблюдавам са:
в редът на функцията fshProgram_flash_region() - lpc17xx_flash_program_words(x * 0x1000, xbuf, len >> 2);, това x * 0x1000, предполагам че ще ми върне кръгъл адрес, примерно 0х3000, 0х4000 и т.н.т. в зависимост от това на променливата "х" кой сектор ще ми се върне. Понеже аз искам да пиша на някой от следните адреси 0х5400 или 0х5В10 или 0х6220 (тестовете ги правя с последният). Това което виждам в меморито е че ми е изтрило всичко от адрес 0х6000 с указана дължина n=1808 (третият член на функцията fshProgram_flash_region()), без да е флашнало нищо от този адрес. Начинът по който викам fshProgram_flash_region() е следният:
Код:
b = fshProgram_flash_region((uint8_t *)0x6220,(uint8_t *)&RSReceveBuf[0], 1808);

Проверих че в RSReceveBuf[] съм записал каквото трябва. Предполагам че нещо не е наред в lpc17xx_flash_program_words(), но не знам какво точно? Възможно ли е тя да не сработва както трябва?
Към коментарът прикачам и Memory-то след опитът за флаш.


Прикачени файлове:
Memory Debug.JPG
Memory Debug.JPG [ 138.34 KiB | Прегледано 4198 пъти ]
Чет Фев 06, 2014 5:43 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Проблем с флашването на LPC1754
стр. 631 в user manual-а на LPC1754 - InApplicationProgramming(IAP)
Можеш да дебъгнеш кода като следиш какво има в структурата flash_data преди и след всяко викане на IAP команда. Т.е. преди и след всяко извикване на lpc17xx_run_iap_routine().
И първо провери дали полето flash_data.cclk в тази структура е инициализирано със стойността на системния ти клок в Hz. Това не се вижда от парчето сорс, което си дал.

По въпроса в предния ти пост, не е ясно кой предава, кой приема по тоя "RS". Вероятно LPC1754 е приемащия, но от къде идват данните...?
Този който ти праща по серийния канал данните трябва да прати и някаква служебна информация в която например да ти казва каква е дължината им. Т.е. изпращащия да определи дължината на файла.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Чет Фев 06, 2014 9:51 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Съб Сеп 17, 2011 10:13 am
Мнения: 112
Мнение Re: Проблем с флашването на LPC1754
Здравей :) - данните ги пращам от хипер терминалът на PC-то, а ги приемам от контролерът. Задаването на въпросната дължина на данните трябва да е нещо от този ли формат -> данни+служебен символ-> където служебният символ да ми индицира краят на пакетът от данни. Проблемът който се сещам в моментът е, моите данни които пращам са в обхват от 0х00 до 0хFF. Променливата която ми гетва тези данни е от тип unsigned char. Въпросът в случаят е какъв служебен символ да сложа, индициращ ми краят на пакетът от данни?
Това което казваш с дебъгването ще го проверя да вида какво ми се пълни и какво не. Към този проблем има едни въпрос - нужно ли е да се забранят интеръптите на контролерът преди флашването или не? Питам понеже разглеждах примерни кодове за IAP флашването в които това не се прави, а в каталогът мисля че срешнат това уточнение, че трябва да се забранят преди да се извърши CopyRAM2Flash (според една от IAP командите). Благодаря!
-------------- Edit ---------------------
Резултатите които ще поста са с извикването на lpc17xx_flash_erase_sector в fshProgram_flash_region(). След дебъгването получавам последователно следният резултат:

---- При извикване на int lpc17xx_flash_erase_sector(uint32_t sector_nr):
cmd[0]=0x34
cmd[1]=0x06
cmd[2]=0x06
cmd[3]=0x000186A (което десетично е 100 000, а според каталогът това трябва да са KHz)
result[0]=0x00

---- При извикване на int lpc17xx_flash_program_words(uint32_t dest, uint32_t * src, int wordcnt):
cmd[0]=0x33
cmd[1]=0x6000 (dst)
cmd[2]=0x2007 С000 (src)
cmd[3]=0x2000 (wordcout*4)
cmd[4]=0x000186A (което десетично е 100 000, а според каталогът това трябва да са KHz)
result[0]=0x06

Редът memcpy(((uint32_t) xbuf) + ((uint32_t) addr & (0x1000 - 1)), p, n); от Bool fshProgram_flash_region(uint8_t *addr, uint8_t *p, uint16_t n) функцията, указателят *p към първият елемент на масивът, който го пълня аз по RS-a (проверих го с дебъгерът).
Резултатът в паметта след извикването на lpc17xx_flash_erase_sector е този на картинката, която съм сложил в предният коментар. След извикването на lpc17xx_flash_program_words тази картинка не се променя.
Функцията която ми е свързана с клокът на процесорът има следният вид :
Код:
void init_lpc17xx(void)
{
   flash_data.cclk = 100 * 1000000;
}

това което правя за да запиша данните които пращам от PC-то към контролерът има следният алгоритъм:
Код:
Bool getFile_entry(void){
uint8_t RSReceveBuf[2048] = {0};
uint8_t c, b;
uint16_t cnt;

   cnt=0;
   c = 0;
   b = 0;
   while (1)
   {
      c = comGetchar_host();

            if(c!=0x18 && c!=0x1B && c!=0x76)
         {
              if(c!=0x2C && c!=0x0D)
               {         
              RSReceveBuf[cnt] = c;
              cnt++;
            }
         }
     if (cnt>1700)
     {
         break;
     }
   }
//Flash process on 0x6220 Address with size 2K.
   appFlush_dotline(TRUE);
   init_lpc17xx();
      b = fshProgram_flash_region((uint8_t *)0x6220,(uint8_t *)&RSReceveBuf[0], 1808);
   return b;
}


Пет Фев 07, 2014 9:48 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Проблем с флашването на LPC1754
breaniac написа:
Задаването на въпросната дължина на данните трябва да е нещо от този ли формат -> данни+служебен символ-> където служебният символ да ми индицира краят на пакетът от данни.

Имах предвид да изпратиш дължината като число в началото преди данните.
Опитваш се сам да налучкаш основни неща, които хората отдавна използват, но нищо. Ето ти няколко жокера: избери си контролен символ, например '\'(0x5C). Винаги когато срещнеш този символ в стрийма от серийно постъпващи байтове, интерпретираш следващия след него за команден байт. Изваждаш тези два символа от потока данни ('\' и този след него). За да не губиш символ от 0 до 0xFF, 0x5C('\') го предаваш като два последователни '\\".
Втори жокер: Когато имаш асинхронна комуникация, винаги залагай преустановяване на приемането по таймаут. Защото винаги стават и непредвидени неща - грешки в комуникацията, изгубени байтове, дръпнат кабел по време на приемане, дръпнат и след това пак включен и т.н.

Относно дебъгването на IAP не очаквай аз да чета вместо теб. Имаш user manual-a проверяваш правилно ли е подготвена структурата flash_data преди извикване на командата и след това проверяваш какво е върнала като резултат от изпълнението съответната IAP команда.
Относно забраняването на прекъсванията, мисля че предишни дивайси от LPC серията го изискваха като задължително. Сега гледам, че за LPC1754 не е необходимо, но и имай предвид че докато се флашва нещо в FLASH-a на микроконтролера, не може да се фетчва и изпълнява код от там(от FLASH-а).
Предполагам нямаш някакви задачи за които трябва микроконтролера да следи непрекъснато. Така че забраняване на прекъсванията не би трябвало да те вълнува.

flash_data.clck е в Hz. В cmd[4] се подава клока в kHz. Ако системния ти клок е инициализиран на 100 MHz всичко е OK.

Дерзай. Близо си :)

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пет Фев 07, 2014 8:56 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 34 мнения ]  Отиди на страница 1, 2, 3  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни