Jump to content
    

Пишем код для отладки платы + азы

Вот сидел, читал форумы - at91, електроникс, йаха, телесиськи... . все спрашивают "а КАК".

Отвечаем (иар подразумеваю, для других компилеров товарищи добавят описание)

1. Ставим процессор +обвязку+питание и по Жтагу заливаем минимальный код для проверки работоспособности ...

2. Ставим СДРАМ и минимальным кодом проверем работоспособность памяти.

 unsigned int volatile *pSDRAM;
  unsigned int  wCount;
  unsigned int  wRead,
                wWrite;
  
  printf ("CPU %d MHz\n",GetCPUFrequencyMhz() );
  printf ("PCK %d MHz\n",GetPCKFrequencyMhz() );

  while (1){
    printf("-T WR- 0x00000000\n");
   pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
   for ( wCount = 0,wWrite=0x0;wCount < 0x800000;wCount ++  ){
     *pSDRAM = wWrite;
     wRead = *pSDRAM;
     if (wWrite != wRead ) 
       printf ("[0x%08X] = 0x%08X ( 0x%08X,0x%08X)\n",wCount,wRead^wWrite,wRead,wWrite );
     pSDRAM++;
   }
}

Здесь c помощью простого осцилографа можно определить - залипания и не пропай по линиям, конечно же, ставим сначала одну микросхему, потом другую, что бы проще отлаживать было.

 

далее отладили ... теперь очень хочется залить что-нибудь в SDRAM и выполнить оттуда. НО

1. Контроллер SDRAM не инициализирован

2. Частоты ПЛЛ не выставлены.

Вот здесь на помощь нам приходит инструмент Жлинка , а именно его mac файл

 

привожу его

//---- Инициализация PLLA = 200 MHz , PLLB = 48 MHz , PCK = 100MHz
init_PLL()
{
__var     tmp,
        var;

__message("Init Clock");
__writeMemory32(0x0000FF01,0xFFFFFC20,"Memory"); // PMC_MOR: MOSCEN = 1, enable main clock
while( (( var =__readMemory32(0xFFFFFC24,"Memory")) & (0x1 << 16))  == 0 ) { };  // wait time out

// AT91C_BASE_CKGR->CKGR_PLLAR = PLLAR_Register;
__writeMemory32(0x2030BF04,0xFFFFFC28,"Memory");
tmp = 0;
while( !(( var=__readMemory32(0xFFFFFC68,"Memory")) & ( 0x1 <<  1)) && (tmp++ < 100) ) {};

var = __readMemory32(0xFFFFFC28,"Memory");
__message "PLLAR=",var;

//AT91C_BASE_CKGR->CKGR_PLLBR = PLLBR_Register;
  __writeMemory32(0x10533F0E,0xFFFFFC2C,"Memory");
  tmp = 0;
  while( !((var = __readMemory32(0xFFFFFC68,"Memory")) & ( 0x1 <<  2)) && (tmp++ < 100) ) {};


  __writeMemory32( 0x1 ,0xFFFFFC30,"Memory");

  tmp = 0;
  while( !((var = __readMemory32(0xFFFFFC68,"Memory")) & (0x1 << 3)) && (tmp++ < 100) ) {};


//  AT91C_BASE_PMC->PMC_MCKR = MCKR_Register;
  __writeMemory32(0x00000102,0xFFFFFC30,"Memory");

  tmp = 0;
  while( !((var = __readMemory32(0xFFFFFC68,"Memory")) & (0x1 << 3)) && (tmp++ < 100) ) {};


}

//----------- Инициализация SDRAM 2х8х16 (2х MT48LC8M16A2-75)
init_SDRAM ()
{
__var i;
__message("Init SDRAM");

  __writeMemory32(0xFFFF0000,0xFFFFF800 +0x0070,"Memory");
  __writeMemory32(0x0,0xFFFFF800 +0x0074,"Memory");
  __writeMemory32(0xFFFF0000,0xFFFFF804,"Memory");      
  i = __readMemory32(0xFFFFFF60,"Memory");
  __writeMemory32(i|(0x1 << 1),0xFFFFFF60,"Memory");
  __writeMemory32( 0x0 ,0xFFFFFF64,"Memory");


__writeMemory32( 0x2A99C255,0xFFFFFF98,"Memory");

__writeMemory32(0x02,0xFFFFFF90,"Memory");
__writeMemory32(0x0,0x20000000,"Memory");
__writeMemory32(0x04,0xFFFFFF90,"Memory");

for(i=0;i<8;i++)
  __writeMemory32(0x0,0x20000000,"Memory");
__writeMemory32(0x3,0xFFFFFF90,"Memory");
__writeMemory32(0x0,0x20000000,"Memory");

__writeMemory32(0x610,0xFFFFFF94,"Memory");
__writeMemory32(0x00,0x20000000,"Memory");
__writeMemory32(0x0,0xFFFFFF90,"Memory");
__writeMemory32(0x0,0x20000000,"Memory");
}


execUserPreload()
{

init_PLL();
__writeMemory32(0xAAAAAAAA,0x00000000,"Memory");
  if(__readMemory32(0x00000000,"Memory") != 0xAAAAAAAA)
  {
    __writeMemory32(0x01,0xFFFFFF00,"Memory");    // MC_RCR: toggle remap bit
  }
init_SDRAM ();
  __message("Target init macro complete");
}

 

теперь можите компилить код с загрузкой в сдрам и выполнять его отуда.

Замечу , что с адреса 0х0 распологается SRAM и в стартап коде надо перенести в область 0х0 - 0х38

вектора прерывания.

пример стартапа at91_cstartup.s79

        MODULE    ?RESET
;        COMMON    INTVEC:CODE:NOROOT(2); Я убрал, линкер подразумевает эту секцию с 0 , но её мы будем копировать в SRAM
            RSEG    ICODE:CODE:NOROOT(2)
                PUBLIC  __program_start
        EXTERN    ?cstartup
;        EXTERN    undef_handler, swi_handler, prefetch_handler
;        EXTERN    data_handler, irq_handler, fiq_handler
        CODE32; Always ARM mode after reset    
ADRSTART:
        org    0x00+ADRSTART
__program_start
        ldr    pc,=?cstartup; Absolute jump
        org    0x04+ADRSTART
undef_handler:
        ldr    pc,=undef_handler
        org    0x08+ADRSTART
swi_handler:
        ldr    pc,=swi_handler
        org    0x0c+ADRSTART
prefetch_handler:
        ldr    pc,=prefetch_handler
        org    0x10+ADRSTART
data_handler:
        ldr    pc,=data_handler
        org    0x18+ADRSTART
    ldr pc, [pc,#-0xF20]  ; IRQ : read the AIC
        org    0x1c+ADRSTART
fiq_handler:
        ldr    pc,=fiq_handler

; Constant table entries (for ldr pc) will be placed at 0x20
        org    0x20+ADRSTART
        LTORG
;        ENDMOD    __program_start
                ENDMOD


;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
        MODULE    ?CSTARTUP

        RSEG    IRQ_STACK:DATA(2)
        RSEG    SVC_STACK:DATA:NOROOT(2)
        RSEG    CSTACK:DATA(2)
        RSEG    ICODE:CODE:NOROOT(2)
        PUBLIC    ?cstartup
        EXTERN    ?main

; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.


        CODE32
?cstartup

; Add initialization nedded before setup of stackpointers here


; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
                mrs     r0,cpsr                        ; Original PSR value
                bic     r0,r0,#MODE_BITS                  ; Clear the mode bits

.... дальше как было

 

понятно , что в lowlevelinit пишите перемещение области памяти 0х2000000 - 0х20000038 на 0 адрес

или прямо в стартапном коде перемещение делаете.

хотя можно и использовать TTB для ремпаирования, но это вы дальше будете делать...

Share this post


Link to post
Share on other sites

Спасибо! Интересно почитать. Ты рассказал как раз о том, что я уже прошел только что. Процарапался. :)

 

Если бы еще кто привел пример программы, которую возможно загрузить из скажем DataFlash. Ну там, валидный стартап, например.

Что-то я затормозился с этим. :(

Share this post


Link to post
Share on other sites

О , добрался до Москвы. здесь холодно и не уютно... Решил побаловать губителей АРМов... Загрузчиком во флэш стартапного кода.

И так прикладываю два проекта IAR fLoader записывает бинарный образ во флэш. применён механизм линковки бинарного файла ( см закладку Extra Options в линкере)

и сам проект первичного загрузчика , который инициализирует sdram, pll пытается считать из флэша заголовок образа, если заголовок правильный , то загружает, иначе активно моргает светодиодом.

вторичный лодырь

Сначала компилите fBoot , смотрите JTAG как идёт процесс. Затем собираете релиз. Бинарник релиза в дальнейшем будет записан во флэш.

 

В fBoot файл at91_cstartup.s79

FlashInfo DC32 ((1056 << 17) | ( 13 << 13 ) | 6) ;

1056 - размер страницы флэша

13 - 2^13 = 8096 количество страниц в флэше

6 - 6 * 512 = 3072 байт грузится в RAM, что немного больше самого кода 2696 байт

это придётся ручками для ленивых прописать или макросами в автомате. Кстати в fLoader нужно указать размерчик ручками или создать именованный сегмент в xcl.

 

а так в планах ... BSP CE50 ...

Share this post


Link to post
Share on other sites

Если мы пишим программы, так же как и сообщения, то фиг оно заработает :-) Ребята - имейте совесть, это же читать невозможно.

Share this post


Link to post
Share on other sites

О , добрался до Москвы. здесь холодно и не уютно... Решил побаловать губителей АРМов... Загрузчиком во флэш стартапного кода.

 

О!

Я как раз вчера вернулся к этому вопросу. Сегодня таки хочу добить. Или допинать. :)

Спасибочки! :)

 

Кстати, что-то на фоне юкоса не хотят встроенные сервисы работать как нужно (наверное проблема в прерываниях, не успел еще разобраться). Да и не понравилась еррата про снятие CS, если не успею данные подсунуть. Хотя как это ПДП может не успеть- отдельный вопрос, это очень тормозную память наверное нужно (Меня интересует доступ не только для загрузки, но и потом тоже).

 

 

 

Если мы пишим программы, так же как и сообщения, то фиг оно заработает :-) Ребята - имейте совесть, это же читать невозможно.

Опечатки возможны у всех.

Вот можно ли подкорректировать название темы, я не уверен. Понятно, что Администрация все может. :)

Share this post


Link to post
Share on other sites

О , добрался до Москвы. здесь холодно и не уютно... Решил побаловать губителей АРМов...

 

сам проект первичного загрузчика , который инициализирует sdram, pll пытается считать из флэша заголовок образа, если заголовок правильный , то загружает, иначе активно моргает светодиодом.

 

Вот нашел недоработку в загрузчике, связанную с ограничениями ПДП. В связи с тем, что контроллеру ПДП нельзя указывать длину пакетов более 65535 байт, при более длинных прошивках нужно грузить частями. Вот измененный кусочек :

 

 

[/code]

{

unsigned int tmpLoadAddr = hOSImage.LoadAddr;

unsigned int tmpLoadBytes = hOSImage.LoadBytes;

unsigned int tmpFlashAdr = 0x4020; //Это мой адрес начала расположения прошивки в DataFlash

do {

if (tmpLoadBytes > 0xffff){

AT91F_DataFlashArrayRead(&DataFlash,tmpFlashAdr,(unsigned char *)tmpLoadAddr, 0xffff );

tmpFlashAdr = tmpFlashAdr + 0xffff;

tmpLoadAddr = tmpLoadAddr + 0xffff;

tmpLoadBytes = tmpLoadBytes - 0xffff;

}

else{

AT91F_DataFlashArrayRead(&DataFlash,tmpFlashAdr,(unsigned char *)tmpLoadAddr, tmpLoadBytes );

tmpLoadBytes = 0;

}

AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);

}while (tmpLoadBytes != 0);

}

 

Как понимаете, вылазит только в случае загрузки длинных программ. Актуально для таких как я, которые грузят напрямую код, а не вторичный загрузчик. Вот сегодня подключил пару bmp-шек к микроГуе и сразу ощутил эту границу :)

Share this post


Link to post
Share on other sites

printf ("CPU %d MHz\n",GetCPUFrequencyMhz() );

printf ("PCK %d MHz\n",GetPCKFrequencyMhz() );

У меня ругается, что не знает таких функций...

Share this post


Link to post
Share on other sites

Вот сидел, читал форумы - at91, електроникс, йаха, телесиськи... . все спрашивают "а КАК".

Отвечаем (иар подразумеваю, для других компилеров товарищи добавят описание)

1. Ставим процессор +обвязку+питание и по Жтагу заливаем минимальный код для проверки работоспособности ...

2. Ставим СДРАМ и минимальным кодом проверем работоспособность памяти.

 

....

 

Здесь c помощью простого осцилографа можно определить - залипания и не пропай по линиям, конечно же, ставим сначала одну микросхему, потом другую, что бы проще отлаживать было.

 

Вот сидел, ждал, когда же кто нибудь вопросы задаст... видать, кроме меня все разобрались :(

А теперь мне приперло разбираться с АРМами, потому, наверно, в ближайшее время буду сыпать дурные вопросы.

По этому коду ситуация такая - заливается, "работает", залипаний на ногах нет, но и соответствия нет тоже.

 

wRead = *pSDRAM;

if (wWrite != wRead )

printf ("[0x%08X] = 0x%08X ( 0x%08X,0x%08X)\n",wCount,wRead^wWrite,wRead,wWrite );

 

Вопрос чисто дурацкий, где копать, житагом смотрю переменную wRead, она всегда равна нулю, хотя я пробовал туда писать различные значения, константы, пробовал инкрементировать... Вобщем, непонятно, на этой стадии должно ли это работать, или без инициализации ПЛЛ и СДРАМ и не надо туда смотреть?

 

И еще вопрос

и сам проект первичного загрузчика , который инициализирует sdram, pll пытается считать из флэша заголовок образа, если заголовок правильный , то загружает, иначе активно моргает светодиодом.

вторичный лодырь

Сначала компилите fBoot , смотрите JTAG как идёт процесс. Затем собираете релиз. Бинарник релиза в дальнейшем будет записан во флэш.

Я так понимаю, что в дебагере этот код тоже должен работать. У меня же он с ошибкой вылетает

do {

AT91F_DataFlashGetStatus(pDataFlashDesc);

timeout--;

// dummy waiting time

for(i=0;i<10;i++);

} while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout>0) );

pDataFlashDesc->DataFlash_state у меня равно 0x27, при чем осциллографом я не вижу НИКАКОЙ активности на выводах SPI.

 

Ну, на сегодня пока дурацких вопросов хватит :), буду пока сам копаться, потом еще вопросов наберу.

Share this post


Link to post
Share on other sites

Вопрос чисто дурацкий, где копать, житагом смотрю переменную wRead, она всегда равна нулю, хотя я пробовал туда писать различные значения, константы, пробовал инкрементировать... Вобщем, непонятно, на этой стадии должно ли это работать, или без инициализации ПЛЛ и СДРАМ и не надо туда смотреть?

Как минимум СДРАМ надо проинициализировать. Смотрите файл init.c, например из проекта fBoot. Только настройки памяти поменяйте под себя. И кварца, если у Вас другие.

Share this post


Link to post
Share on other sites

Сначала компилите fBoot , смотрите JTAG как идёт процесс. Затем собираете релиз. Бинарник релиза в дальнейшем будет записан во флэш.

 

Кем и как он будет записан во флеш? его надо залить самому или это сделает fLoader ?

Share this post


Link to post
Share on other sites

И ещё дурацкий вопрос: как, имея МТ-линк залить в камень код релиза? при дебаге из ИАРа все понятно. Чего делать, когда есть откомпиленный код?

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

Share this post


Link to post
Share on other sites

Предлагаю пообщаться на предмет проверки памяти. :)

Как я уже где-то писал, код, предложенный [email protected] при некотором стечении обстоятельств не реагирует на сбои. Во всяком случае у меня при нескольких непропаях на шине данных.

Собственно интересует почему и как быть. :) Возможно ли такое при включенном кэше? Как я понимаю кэш - это "фича" ядра и читать про него надо в описании ядра?

Share this post


Link to post
Share on other sites

Возможно ли такое при включенном кэше?

Для теста памяти кэш нужно выключить, иначе можно в результате получить тест кэша :)

Исходя из личного опыта могу сказать, что самая надежная проверка - заполнение всей памяти псевдослучайной последовательностью с последующей проверкой. Тест нужно крутить несколько суток, и желательно в жестких условиях - только тогда можно говорить о достаточно надежной работе памяти.

Share this post


Link to post
Share on other sites

Почитал описание ядра - все кэши отключены после сброса. Наверное я что-то еще не учел.

Про полное заполнение - тоже об этом подумал. По идее и на кэш тогда наплевать, т.к. ему все равно придется "сбрасываться" в память. Осталось найти генератор псевдослучайной последовательности.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...