Перейти к содержанию
    

USB загрузчик для LPC2368

На данный момент такой загрузчик существует (по крайней мере, для LPC2148)

и находится в стадии тестирования. Скоро появится в доступе...

Доступен уже с 20 мая - AN10711 USB Secondary ISP Bootloader with Source Files

an10711.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос по TNK-loader:

...
//---- Set interrupts vectors
ptr = (unsigned int *)IRQ_RAM_ADDR;
*ptr = 0xE59FF018;                //-- ldr pc, [pc, #24]
ptr = (unsigned int *)FIQ_RAM_ADDR;
*ptr = 0xE59FF018;    
...

 

Зачем по адресу IRQ_RAM_ADDR(FIQ_RAM_ADDR) кладется число 0xE59FF018?

 

 

И попутный вопрос:

void  tn_usb_lpc_cmd_write(int cmd, int data)
{
       E1A0C00D   mov r12, sp
       E92DD800   stmfd sp!, {r11-r12, lr-pc}
       E24CB004   sub r11, r12, #0x00000004
       E24DD008   sub sp, sp, #0x00000008
       E50B0010   str r0, [r11, #-0x010]
       E50B1014   str r1, [r11, #-0x014]
   USBDevIntClr = CDFULL | CCEMTY;            // clear CDFULL/CCEMTY
       E3A0328F   mov r3, #0xF0000008
       E28336FE   add r3, r3, #0x0FE00000
       E2833CC2   add r3, r3, #0x0000C200
       E3A02030   mov r2, #0x00000030
       E5832000   str r2, [r3]
   USBCmdCode = 0x00000500 | (cmd << 16);    // write command code
       E59F208C   ldr r2, [pc, #+0x08C]
       E51B3010   ldr r3, [r11, #-0x010]
       E1A03803   mov r3, r3, lsl #0x10
       E3833C05   orr r3, r3, #0x00000500
[color=#FF0000]===>>>E5823000   str r3, [r2]  <<<<<<=============[/color]
   while(!(USBDevIntSt & CCEMTY));
       E3A034FF   mov r3, #0xFF000000
       E283360E   add r3, r3, #0x00E00000
       E2833CC2   add r3, r3, #0x0000C200
       E5933000   ldr r3, [r3]
       E2033010   and r3, r3, #0x00000010
       E3530000   cmp r3, #0x00000000
       0AFFFFF8   beq 0x000032E0
...

До выполнения указанной строчки регистры:

r0 = 0xfe

r1 = 0x00

r2 = 0xffe0c210

r3 = 0x00fe0500

c r4 по r10 = 0x00

r11 = 0x4000209c

r12 = 0x400020a0

r13(sp) = 0x40002088

r14 = 0x00000db0

r15 = 0x000032dc

cpsr = 0xa00000df

данные:

data = 0x00

cmd = 0x000000fe

 

После выполнения указанной строчки проваливаемся в dabort_handler.

Может кто-то сможет пояснить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем по адресу IRQ_RAM_ADDR(FIQ_RAM_ADDR) кладется число 0xE59FF018?
Там же в коментариях написано: это код команды ldr pc, [pc, #24]

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там же в коментариях написано: это код команды ldr pc, [pc, #24]

Сергей. Я прекрасно вижу, что написано в коментариях. Лучше скажите зачем это нужно!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сергей. Я прекрасно вижу, что написано в коментариях. Лучше скажите зачем это нужно!

Это инициализация векторов прерываний (таблица в RAM), делается перед remap (MEMMAP =0x2).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там же в коментариях написано: это код команды ldr pc, [pc, #24]

Смысл какой? Просто увеличить PC? Или же, всё-таки, разместить по адресу IRQ_RAM_ADDR число 0xe59ff018? Если же просто увеличить PC, то я смысл этого действия вообще не вижу.

Может сможет кто объяснить?

 

Это инициализация векторов прерываний (таблица в RAM), делается перед remap (MEMMAP =0x2).

int main()
{
    unsigned int * ptr;
    int state;
    
    MEMMAP = 0x1;
    
    //tn_arm_disable_interrupts();
        ctl_global_interrupts_disable();
    
    Init_CRC32_Table();
    
    //---- Set interrupts vectors
    ptr = (unsigned int *)IRQ_RAM_ADDR;
    *ptr = 0xE59FF018;                //-- ldr pc, [pc, #24]
    ptr = (unsigned int *)FIQ_RAM_ADDR;
    *ptr = 0xE59FF018;                //-- ldr pc, [pc, #24]
    
    //--- Put IRQ & FIQ vectors in RAM
    ptr = (unsigned int *)IRQ_RAM_FUNC_ADDR;
    *ptr = (unsigned int)&cpu_irq_isr;
    ptr = (unsigned int *)FIQ_RAM_FUNC_ADDR;
    *ptr = (unsigned int)&cpu_fiq_isr;
    
    #ifndef RUN_FW_ALWAYS
    
    //--- Check 'Run as Loader' mark
    ptr =(unsigned int *)RAM_START_ADDR;
    if(!(*ptr == 0x12345678 && *(ptr+1) == 0x43211234))
    {
        do_switch_to_firmware();   //-- Never returns
    }
    #else
    start_firmware(); //-- Never returns
    #endif
    
    //------ Clear FW loader marks
    ptr =(unsigned int *)RAM_START_ADDR;
    *ptr = 0;
    ptr++;
    *ptr = 0;
    
    HardwareInit(); и т.д. и т.п.........

(В курсе: MEMMAP =0x2 -> User RAM Mode. Interrupt vectors are re-mapped to Static RAM).

Вектора IRQ, FIQ он явно кладет по нужным адресам.

MEMMAP же нигде в программе больше не трогается.

???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смысл какой? Просто увеличить PC? Или же, всё-таки, разместить по адресу IRQ_RAM_ADDR число 0xe59ff018? Если же просто увеличить PC, то я смысл этого действия вообще не вижу.

Может сможет кто объяснить?

ldr pc, [pc, #24] - это не увеличить PC, а загрузить его из ячейки по адресу PC+24+8.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ldr pc, [pc, #24] - это не увеличить PC, а загрузить его из ячейки по адресу PC+24+8.

Вот код этого дела.

    //---- Set interrupts vectors
    ptr = (unsigned int *)IRQ_RAM_ADDR;
       E3A03161   mov r3, #0x40000018
       E50B3014   str r3, [r11, #-0x014]
    *ptr = 0xE59FF018;                //-- ldr pc, [pc, #24]
       E51B2014   ldr r2, [r11, #-0x014]
       E3E03EFE   mvn r3, #0x00000FE0
       E2433271   sub r3, r3, #0x10000007
       E24336A6   sub r3, r3, #0x0A600000
       E5823000   str r3, [r2]
    ptr = (unsigned int *)FIQ_RAM_ADDR;
       E3A03171   mov r3, #0x4000001C
       E50B3014   str r3, [r11, #-0x014]
    *ptr = 0xE59FF018;                //-- ldr pc, [pc, #24]
       E51B2014   ldr r2, [r11, #-0x014]
       E3E03EFE   mvn r3, #0x00000FE0
       E2433271   sub r3, r3, #0x10000007
       E24336A6   sub r3, r3, #0x0A600000
       E5823000   str r3, [r2]

Может поможете увидеть где здесь загрузка из ячейки по адресу PC+24+8?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после выполнения вышеприведенного кода пресловутая команда загрузки будет лежать в ОЗУ по адресу вектора IRQ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(В курсе: MEMMAP =0x2 -> User RAM Mode. Interrupt vectors are re-mapped to Static RAM).

Вектора IRQ, FIQ он явно кладет по нужным адресам.

MEMMAP же нигде в программе больше не трогается.

???

Здесь MEMMAP не используется. Если вы посмотрите в fwu_startup_iar.s79 :

reset           ldr     pc, ?vect_entry
                ldr     pc, ?vect_entry +  4
                ldr     pc, ?vect_entry +  8
                ldr     pc, ?vect_entry + 12
                ldr     pc, ?vect_entry + 16
                DC32    0xB8A06F58          /* 0 - (sum of other vectors instructions) */
                ldr     pc, ?vect_entry + 24
                ldr     pc, ?vect_entry + 28

?vect_entry:
                DC32    ?cstartup; RES    (  0)
                DC32    ?cstartup; UND    ( +4)
                DC32    ?cstartup; SWI    ( +8)
                DC32    ?cstartup; P_ABT  (+12)
                DC32    ?cstartup; D_ABT  (+16)
                DC32    0; ARM-reserved vector  (+20)
                DC32    0x40000018; cpu_irq_isr; IRQ    (+24)
                DC32    0x4000001C; cpu_fiq_isr; FRQ    (+28)

видно, что 0x40000018 и 0x4000001C - адреса, по которым будет передаваться управление при IRQ и FIQ. Фактически комбинация ldr pc,xxx и собственно ячейки xxx,например

ldr     pc, ?vect_entry
?vect_entry:
DC32    ?cstartup; RES    (  0)

это branch, то есть безусловный переход в любое место в пределах адресного пространства.

В tnkernel таким образом сделаны векторы прерываний для того, чтобы проложение могло установить свой вектор (в flash-то лежат векторы загрузчика). Совершенно нормальный подход. Хотя я в своем загрузчике использую немного другой подход, по мотивам кода уважаемого Zltigo.

__program_start:
                ldr     pc,(?vect_entry + 4*0)  // 00
                ldr     pc,(?vect_entry + 4*1)  // 04
                ldr     pc,(?vect_entry + 4*2)  // 08
                ldr     pc,(?vect_entry + 4*3)  // 0C
                ldr     pc,(?vect_entry + 4*4)  // 10
                dc32    0                       // 14 Summ of other vectors instructions
                ldr     pc,[pc,#-0x0120]        // 18 Jump directly to the address given by the VIC
                                                // from [0xFFFFFF00] Curent 18h +8(conveyer)=20h
                ldr     pc,(?vect_entry + 4*7)  // 1C
//---------------------------------------------------------------------------
                ORG     0x20       // Constant table entries (for ldr pc) will be placed at 0x20
?vect_entry:
                dc32    ?cstartup               // Reset
                dc32    ?cstartup               // UND
                dc32    Application_SWI         // SWI
                dc32    PABT_handler            // P_ABT
                dc32    DABT_handler            // D_ABT
                dc32    0                       // ARM-reserved vector
                dc32    0                       // IRQ (Jump directly!)
                dc32    Application_FIQ         // FIQ

Здесь адрес обработчика IRQ берется непосредственно из VIC, reset в начало загрузчика, SWI и FIQ берутся из заголовка приложения по адресу, где приложение будет располагаться. Вот заголовок приложения:

//== With Loader 
        dc8    Hardware_Version        // 00 Hardware revision
        dc8    Bootloader_Version       // 01 
        dc8    Application_VersionL       // 02 
        dc8    Application_VersionH        // 03
        dc32    SFB(CHECKSUM)           // 04 End of code         address
        ldr     pc,[pc,#-0x4]           // 08 Start Entry Point
        dc32    ?cstartup               // 0C *Reset
        ldr     pc,[pc,#-0x4]           // 10 SWI
        dc32    ?cstartup  //vPortYieldProcessor     // 14 *SWI
// Place for FIQ Handler ----------------------------------------------------
        ldr     pc,[pc,#-0x4]        // 18 FIQ
        dc32    FIQ_ISR_handler         // 1C *FIQ

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

Единственное что, поскольку в загрузчике жестко прописан переход по SWI в приложение, при необходимости использования SWI (или FIQ) в загрузчике приходится использовать MEMMAP=2.

Здесь ldr pc,[pc,#-0x4] грузит в pc на самом деле константу из следующих четырех байт, из-за конвеера тут -4(+8) а не +4.

Уфф.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответы. Кое-что стало понятно.

Как команду "ldr pc, [pc, #24]" перевели в число "0xE59FF018"?

И наоборот из числа в команду?

Изменено пользователем Alex_akn

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответы. Кое-что стало понятно.

Как команду "ldr pc, [pc, #24]" перевели в число "0xE59FF018"?

И наоборот из числа в команду?

Можно с помощью ассемблера, посмотрев листинг. А обратно - где-то в интернете видел. Можно использовать дизассемблер, или почитать документацию от ARM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно с помощью ассемблера, посмотрев листинг. А обратно - где-то в интернете видел. Можно использовать дизассемблер, или почитать документацию от ARM.

Спасибо! :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Загрузчик заработал, но выяснилась такая вещь:

в главной функции завел статическую переменную

И эта переменная располагается по адресу 0x40000000.

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

Как в кросс ворксе сделать так, чтобы эта статическая переменная лежала за адресом, допустим, 0x40000100?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...