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

 
 
> Что делает Си-код до main?
imiron13
сообщение Sep 28 2010, 06:57
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 22-02-09
Из: Минск
Пользователь №: 45 206



Немного почитал про это здесь:
http://infocenter.arm.com/help/index.jsp?t...i/Bce3gfea.html
(использую RVDS4)

Не совсем понятно с настройкой стека. Там пишут, что настройку стека выполняет пользовательский стартап код.
Я так и делаю, но еще до main библиотечная функция (sys_stackheap_outer) меняет указатель стека. Что это означает? Может ли библиотечный код пытаться настроить стеки сам? Я вроде даже не давал ему никакой информации о размещении памяти на МК.
Если из стартапа вызываю сразу main, то программа работает, но не инициализируются глобальные переменные. Но если я вызываю __main, то указатель стека изменяется и программа не доходит до main.

Также библиотечный код генерирует программное прерывание (SWI) с кодом 0x123456. Зачем это нужно?


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
msalov
сообщение Sep 28 2010, 10:23
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Для корректного перехода в Main необходим текущий стек правильно настроить. Стартап помимо инициализации указателя на вершину стека инициализирует глобальные и статические переменные. Если вы пишете свой стартап - то должны реализовать необходимый минимум.
Go to the top of the page
 
+Quote Post
imiron13
сообщение Sep 28 2010, 11:27
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 22-02-09
Из: Минск
Пользователь №: 45 206



Цитата(gotty @ Sep 28 2010, 13:23) *
Для корректного перехода в Main необходим текущий стек правильно настроить. Стартап помимо инициализации указателя на вершину стека инициализирует глобальные и статические переменные. Если вы пишете свой стартап - то должны реализовать необходимый минимум.

Ну, на страничке, ссылку на которую я кидал, написано так:
Сначала вызывается начальный код пользователя, который должен:
- инициализировать указатели стеков
- настроить MMU/MPU
- настроить кэш/включить TCM

После должна вызываться __main из стандартной библиотеки Си . __main выполняет следующие действия:
-копирует код (?)
-копирует/распаковывает RW-данные (поэтому нет ничего удивительного, что когда я вызывал сразу main не инициализировались глобальные переменные)
-обнуляет неинициализированные данные

Далее вызывается __rt_entry, которая
- инициализирует библиотечные функции
- вызывает __user_initial_stackheap()
- вызывает $Sub$main()
В основном коде функции __user_initial_stackheap() и $Sub$main() я не переопределял, значит будут вызваны библиотечные. Там же написано, что если используется scatter-файл для линкера, то линкер создаст __user_initial_stackheap(). Scatter-файл я не использую. Что происходит в этом случае?
После этого вызывается main().

Проблема в том, что библиотечный код изменяет указатель стека и прога рушится. Изменение SP происходит в функции sys_stackheap_outer.



Go to the top of the page
 
+Quote Post
vallav
сообщение Sep 29 2010, 17:38
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 197
Регистрация: 8-04-05
Пользователь №: 3 977



Цитата(imiron13 @ Sep 28 2010, 15:27) *
Проблема в том, что библиотечный код изменяет указатель стека и прога рушится. Изменение SP происходит в функции sys_stackheap_outer.


У Вас до исполнения библиотечного кода SP имеет нужное Вам значение?
Чему оно равно и в каком месте присваивается SP?
В Keil для nxp176x сделано так - в стартапе под стек выделяется место в ОЗУ, адрес вершины этого блока ОЗУ и присваивается SP при исполнении
кода, который до main.
А сам код запускается так - делается переход из бутлоадера по адресу, равному значению первого слова во флеше.
В нулевое слово флеша обычно записывается это самое значение для SP, но значение нулевого слова нигде не используется.
Go to the top of the page
 
+Quote Post
imiron13
сообщение Sep 30 2010, 07:43
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 22-02-09
Из: Минск
Пользователь №: 45 206



Цитата(vallav @ Sep 29 2010, 20:38) *
У Вас до исполнения библиотечного кода SP имеет нужное Вам значение?
Чему оно равно и в каком месте присваивается SP?

Да до исполнения библиотечного кода все ок, вот этот кусочек стартапа(стартап самодельный: МК нестандартный) настраивает указатели стека (0x007fff0 - конец ОЗУ)

Код
isrReset
                ldr  r1, =0x007fff0                     ; SP для FIQ
                msr  cpsr_c, #(17 | 0xC0)          ; переход в режи FIQ
                mov  sp, r1
                sub  r1, r1, #1024                     ;FIQ_STACK_SIZE
                msr  cpsr_c, #(18 | 0xC0)         ; переход в режим IRQ
                mov  sp, r1
                sub  r1, r1, #1024                     ;IRQ_STACK_SIZE
                msr  cpsr_c, #(19 | 0xC0)         ; переход в режим Supervisor
                mov  sp, r1                            ; Supervisor SP

Теперь указатели стека имеют верные значения (0007FFF0-FIQ,0007FBF0-IRQ,0007F7F0-SV). Далее работа идет в режиме Supervisor. В конце стартапа:
Код
        ldr     R0, = __main
        BX      R0

Далее выполняется библиотечный код, который изменяет SP. Изменение происходит в функции sys_stackheap_outer (сверял адрес выполняемого кода в отладчике с map-файлом). Ситуация усложняется тем, что не знаю армовский асм, и не могу разобраться, что пытается сделать код, изменяющий SP. Кусочек, изменяющий SP на скрине (до выполнения mov sp,r0 в SP все еще верное значение; вообще-то SP сохраняется в R1, затем в SP возвращается значение из R1, но оно уже затерто). У меня ступор, буду оч благодарен за помощь и советы.
Прикрепленное изображение


Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 07:19
Рейтинг@Mail.ru


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