реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> BootLoader для LPC1766, Как правильно вызывать прикладную программу.
Vitaliy_ARM
сообщение Jan 28 2010, 15:37
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Был у меня загрузчик для 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 - прикладная программа в отладочном режиме без загрузчика.

Как правильно вызывать?
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 28 2010, 15:42
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Vitaliy_ARM @ Jan 28 2010, 18:37) *
В ассемблерном коде используется BLX на адрес, 10001, хотя должен был быть 10002.

А почему, собственно, 0x10000 + 0x01 должно быть равно 0x10002?
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 28 2010, 16:04
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(aaarrr @ Jan 28 2010, 18:42) *
А почему, собственно, 0x10000 + 0x01 должно быть равно 0x10002?

cranky.gif наверное никак.
Сбил с толку указанный выше пример:

Код
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 ( 568.33 килобайт ) Кол-во скачиваний: 54
 


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 28 2010, 17:21
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Vitaliy_ARM @ Jan 28 2010, 19:04) *
А что может находиться по адресу 0x10000 + 0x01? На сколько мне известно при 16 битных инструкциях прыгать нужно на адреса, выровненные под 16 битное пространство (т.е. в последнем бите должен быть 0).

Младший бит адреса BLX выбирает режим работы процессора. В данном случае он должен быть равен "1", т.к. процессор может работать только в Thumb.

Цитата(Vitaliy_ARM @ Jan 28 2010, 18:37) *
В приложенных файлах 001 и 002 показаны скриншоты яра при работе загрузчика и уходе в прикладную программу. На 003 - прикладная программа в отладочном режиме без загрузчика.

Судя по скриншотам, прикладная программа просто неправильно записана.
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 10:05
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(aaarrr @ Jan 28 2010, 20:21) *
Младший бит адреса BLX выбирает режим работы процессора. В данном случае он должен быть равен "1", т.к. процессор может работать только в Thumb.

Теперь понятно.
Цитата(aaarrr @ Jan 28 2010, 20:21) *
Судя по скриншотам, прикладная программа просто неправильно записана.

Да, действительно. smile3046.gif
Спасибо.

Рано обрадовался. Были неправильные скриншоты. После скринов будлодера я несколько изменил прошивку.
Теперь сделал все заново. Прошики совпадают.


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 11:07
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Правильные скриншоты:
1 - дамп памяти в яре при отладке прикладной программы без загрузчика
2 - бинарь, который генерит яр при компиляции прикладной программы
3 - дамп памяти этой же прошивки, после загрузки ее загрузчиком

Проблема осталась таже.
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
prgjz
сообщение Jan 29 2010, 13:52
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 3-01-07
Из: Germany
Пользователь №: 24 071



Для 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 начало программы
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 15:45
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(prgjz @ Jan 29 2010, 16:52) *
Для 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 (и т.п.) после сброса?


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 29 2010, 15:54
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Vitaliy_ARM @ Jan 29 2010, 18:45) *
Вопрос, на какой адрес прыгает процессор LPC1766 (и т.п.) после сброса?

По адресу, записанному в Reset Handler таблицы векторов:
Код
        DCD     __iar_program_start; Reset Handler
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 16:18
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Запись в даташите:

Цитата
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.


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 29 2010, 16:21
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Vitaliy_ARM @ Jan 29 2010, 19:18) *
Понятно, по какому адресу?

Что по какому адресу? После сброса Reset Handler находится по адресу 0x04.
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 16:42
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(aaarrr @ Jan 29 2010, 19:21) *
Что по какому адресу? После сброса Reset Handler находится по адресу 0x04.

Забиваю адрес 0x04 в PC при отладке, указатель начинает бежать по векторам подряд и через некоторое время вылетает в аппаратный хендел. Если забить в него адрес __iar_program_start, то программа начинает работать. Может так нельзя делать? Или проблема собственно что резет находится в этот момент не по 0х04 адресу?


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 29 2010, 16:47
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



PC загружается из 0x04, а не им.
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jan 29 2010, 16:56
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(aaarrr @ Jan 29 2010, 19:47) *
PC загружается из 0x04, а не им.


Немного не понял что это значит. Поясните пожалуйста.


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 29 2010, 17:14
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Считывается слово из адреса Reset Handler (0x04), и загружается в PC.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01532 секунд с 7
ELECTRONIX ©2004-2016