Vitaliy_ARM 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Был у меня загрузчик для LPC2378 и прочих. Теперь стала задача переписать его под LPC1766. Все переписалось без особых проблем, однако камнем предкновения оказалось сделать вызов прикладной программы. Прикладная программа заливается вместе с векторами начиная с адреса 0x1 0000 (16-я страница). Т.е. в ней находятся сначала вектора, а потом все остальное. Код вызова программы: #define FIRST_PAGE_ADDR 0x10000 #define NVIC_VectTab_FLASH (0x00000000) // код вызова приложения volatile unsigned long *p = (volatile unsigned long*)NVIC_VECT_TABLE; *p = NVIC_VectTab_FLASH | (USER_FLASH_START & 0x1FFFFF80); void (*App)() = (void(*)())(FIRST_PAGE_ADDR + 1); App(); // уходим в прикладную программу Код вызова брал по аналогии из LPC1700 USB Bootloader. Сделал прикладную программу, которая настраивает порт светодиода на плате и зажигает его. Прикладная программа вызывается неправильно. В ассемблерном коде используется BLX на адрес, 10001, хотя должен был быть 10002. И яр отображает код совсем подругому. В приложенных файлах 001 и 002 показаны скриншоты яра при работе загрузчика и уходе в прикладную программу. На 003 - прикладная программа в отладочном режиме без загрузчика. Как правильно вызывать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба В ассемблерном коде используется BLX на адрес, 10001, хотя должен был быть 10002. А почему, собственно, 0x10000 + 0x01 должно быть равно 0x10002? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба А почему, собственно, 0x10000 + 0x01 должно быть равно 0x10002? :cranky: наверное никак. Сбил с толку указанный выше пример: void execute_user_code(void) { void (*user_code_entry)(void); /* Change the Vector Table to the USER_FLASH_START in case the user application uses interrupts */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, USER_FLASH_START); user_code_entry = (void (*)(void))((USER_FLASH_START)+1); user_code_entry(); } А что может находиться по адресу 0x10000 + 0x01? На сколько мне известно при 16 битных инструкциях прыгать нужно на адреса, выровненные под 16 битное пространство (т.е. в последнем бите должен быть 0). LPC1700_USB_Bootloader.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба А что может находиться по адресу 0x10000 + 0x01? На сколько мне известно при 16 битных инструкциях прыгать нужно на адреса, выровненные под 16 битное пространство (т.е. в последнем бите должен быть 0). Младший бит адреса BLX выбирает режим работы процессора. В данном случае он должен быть равен "1", т.к. процессор может работать только в Thumb. В приложенных файлах 001 и 002 показаны скриншоты яра при работе загрузчика и уходе в прикладную программу. На 003 - прикладная программа в отладочном режиме без загрузчика. Судя по скриншотам, прикладная программа просто неправильно записана. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Младший бит адреса BLX выбирает режим работы процессора. В данном случае он должен быть равен "1", т.к. процессор может работать только в Thumb. Теперь понятно. Судя по скриншотам, прикладная программа просто неправильно записана. Да, действительно. :smile3046: Спасибо. Рано обрадовался. Были неправильные скриншоты. После скринов будлодера я несколько изменил прошивку. Теперь сделал все заново. Прошики совпадают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Правильные скриншоты: 1 - дамп памяти в яре при отладке прикладной программы без загрузчика 2 - бинарь, который генерит яр при компиляции прикладной программы 3 - дамп памяти этой же прошивки, после загрузки ее загрузчиком Проблема осталась таже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prgjz 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Для STM32 применяю так: Загрузчик находится 0х0800 0000 Программа #define KERNEL_START_APP 0x08004000 __SYSJUMP(KERNEL_START_APP); ;******************************************************************************* ; Function Name : __SYSJUMP ; Description : Assembler function for the jump to App. from Boot ; Input : - r0 : Application Start Addres. ; Return : None ;******************************************************************************* __SYSJUMP MOVS R4,R0 CPSID i LDR R0,[R4, #+0] ; set the stack pointer to app MSR MSP, R0 LDR PC,[R4, #+4] ; load PC with reset vector from APP END Обратите внимание что у кортекса в начале вектора прерывания находится указатель на стек а +4 начало программы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Для STM32 применяю так: Загрузчик находится 0х0800 0000 Программа #define KERNEL_START_APP 0x08004000 Обратите внимание что у кортекса в начале вектора прерывания находится указатель на стек а +4 начало программы Спасибо за код. Но для начала хочу понять весь механизм. Все знают что в иар по резету происходит переход в __iar_program_start . Я в прикладной программе нашел адрес этой подпрограммы. И в загрузчике сделал вызов именно по этому адресу, забив адрес в регистр PC. Прошивка заработала! Однако когда я забиваю в PC в прикладной программе начало таблицы векторов 0x10000 со смещением: 0x00000, 0x00002, 0x00004 и т.д. процессор улетает в хардваре еррор дефаулт хэндл. Т.е. ошибка состоит в том, что в вызове прикладной программы происходит переход "НЕ ТУДА". Вот кусок яровского стартапа: EXTERN __iar_program_start PUBLIC __vector_table PUBLIC __vector_table_0x1c DATA __vector_table DCD sfe(CSTACK) ; Top of Stack DCD __iar_program_start ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler __vector_table_0x1c DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler DCD WDT_IRQHandler ; Watchdog Handler DCD TMR0_IRQHandler ; TIMER0 Handler DCD TMR1_IRQHandler ; TIMER1 Handler DCD TMR2_IRQHandler ; TIMER2 Handler DCD TMR3_IRQHandler ; TIMER3 Handler DCD UART0_IRQHandler ; UART0 Handler DCD UART1_IRQHandler ; UART1 Handler DCD UART2_IRQHandler ; UART2 Handler DCD UART3_IRQHandler ; UART3 Handler DCD PWM1_IRQHandler ; PWM1 Handler DCD I2C0_IRQHandler ; I2C0 Handler DCD I2C1_IRQHandler ; I2C1 Handler DCD I2C2_IRQHandler ; I2C2 Handler DCD SPI_IRQHandler ; SPI Handler DCD SSP0_IRQHandler ; SSP0 Handler DCD SSP1_IRQHandler ; SSP1 Handler DCD PLL0_IRQHandler ; PLL0 Handler DCD RTC_IRQHandler ; RTC Handler DCD EINT0_IRQHandler ; EXT Interupt 0 Handler DCD EINT1_IRQHandler ; EXT Interupt 1 Handler DCD EINT2_IRQHandler ; EXT Interupt 2 Handler DCD EINT3_IRQHandler ; EXT Interupt 3 Handler DCD ADC_IRQHandler ; ADC Handler DCD BOD_IRQHandler ; BOD Handler DCD USB_IRQHandler ; USB Handler DCD CAN_IRQHandler ; CAN Handler DCD GPDMA_IRQHandler ; General Purpose DMA Handler DCD I2S_IRQHandler ; I2S Handler DCD Ethernet_IRQHandler ; Ethernet Handler DCD RIT_IRQHandler ; Repetitive Interrupt Timer Handler DCD MotorControlPWM_IRQHandler; Motor Control PWM Handler DCD QE_IRQHandler ; Quadrature Encoder Handler DCD PLL1_IRQHandler ; PLL1 Handler Вопрос, на какой адрес прыгает процессор LPC1766 (и т.п.) после сброса? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Вопрос, на какой адрес прыгает процессор LPC1766 (и т.п.) после сброса? По адресу, записанному в Reset Handler таблицы векторов: DCD __iar_program_start; Reset Handler Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Запись в даташите: Following a hardware reset, the Boot ROM is temporarily mapped to address 0. This is normally transparent to the user. However, if execution is halted immediately after reset by a debugger, it should correct the mapping for the user. See Section 33–6. В секции 33: Following chip reset, a portion of the Boot ROM is mapped to address 0 so that it will be automatically executed. The Boot ROM switches the map to point to Flash memory prior to user code being executed. In this way a user normally does not need to know that this re-mapping occurs. However, when a debugger halts CPU execution immediately following reset, the Boot ROM is still mapped to address 0 and can cause confusion. Ideally, the debugger should correct the mapping automatically in this case, so that a user does not need to deal with it. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Понятно, по какому адресу? Что по какому адресу? После сброса Reset Handler находится по адресу 0x04. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Что по какому адресу? После сброса Reset Handler находится по адресу 0x04. Забиваю адрес 0x04 в PC при отладке, указатель начинает бежать по векторам подряд и через некоторое время вылетает в аппаратный хендел. Если забить в него адрес __iar_program_start, то программа начинает работать. Может так нельзя делать? Или проблема собственно что резет находится в этот момент не по 0х04 адресу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба PC загружается из 0x04, а не им. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба PC загружается из 0x04, а не им. Немного не понял что это значит. Поясните пожалуйста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Считывается слово из адреса Reset Handler (0x04), и загружается в PC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться