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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Начальная инициализация статических переменных.
Вячик13
сообщение Jul 9 2012, 06:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Среда - Keil Arm. Контроллер STM32F103.
В Keil имеется функция SystemInit(), которая выполняется перед main().

Описание эффекта.
В функции SystemInit() инициализируется несколько указателей-параметров объекта. При входе в функцию main() эти параметры обнуляются.

Вопрос.
Что это? Возможно начальная инициализация статических переменных происходит после выполнения SystemInit()? Не похоже. Какие-то "заморочки со стеком?" может я какую-то "галочку" в опциях проекта не поставил?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 06:49
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 09:36) *
В функции SystemInit() инициализируется несколько указателей-параметров объекта.

Например?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 07:09
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 09:49) *
Например?


typedef struct TExtADCResult {
bool Exist;
unsigned long Value;
} TExtADCResult;

typedef struct TExtADC {
TSPI *SPIPtr;
void (*Select)(void);
void (*Unselect)(void);
void (*Start)(void);
void (*Stop)(void);
bool (*Ready)(void);
void (*Reset)(void);
TExtADCResult Result[8];
bool Exist;
} TExtADC;

#define ExtADC_CHAN_NUMBER 2

TExtADC ExtADCChanel[ExtADC_CHAN_NUMBER];

void SystemInit(void) {
PeriferInit();
}

void PeriferInit(void) {
TExtADC_Create(&ExtADCChanel[0],&SPIChanel[0],&ExtADC1_Select,&ExtADC1_Unselect,&ExtADC_Start,&ExtADC_Stop,ExtADC1_Ready,ExtADC_Reset);
TExtADC_Create(&ExtADCChanel[1],&SPIChanel[0],&ExtADC2_Select,&ExtADC2_Unselect,&ExtADC_Start,&ExtADC_Stop,ExtADC2_Ready,ExtADC_Reset);
}

В TExtADC_Create() идёт обыкновенное присвоение указателям ссылок на функции. Смотрю объект ExtADCChanel[0].

Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 07:30
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Смотрите, что есть в startup.
Код
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Видите __main - вот там все и устанавливается.
Вы сами добавили кода в SystemInit()? А чем не устроило сделать это в main?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 07:36
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 10:30) *
Смотрите, что есть в startup.
Код
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Видите __main - вот там все и устанавливается.
Вы сами добавили кода в SystemInit()? А чем не устроило сделать это в main?


Вот мой startup:

Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
По-моему не отличается ничем.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 07:50
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 10:36) *
По-моему не отличается ничем.

И это правильно. Еще раз прочитайте мой ответ.

Цитата(Вячик13 @ Jul 9 2012, 09:36) *
Возможно начальная инициализация статических переменных происходит после выполнения SystemInit()? Не похоже.

Не "не похоже", а именно так!
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 08:05
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 10:50) *
И это правильно. Еще раз прочитайте мой ответ.


Не "не похоже", а именно так!


Не понял, а где именно выполняется инициализация переменных? Где вызов подпрограммы? В приведенном ассемблерном коде я его не вижу. Ну и что из того, что сначала выполняется SystemInit(), а потом main()? Или инициализация выполняется в начале работы main()?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 08:11
Сообщение #8


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 11:05) *
Не понял, а где именно выполняется инициализация переменных? Где вызов подпрограммы? В приведенном ассемблерном коде я его не вижу. Ну и что из того, что сначала выполняется SystemInit(), а потом main()? Или инициализация выполняется в начале работы main()?

где же main(), если __main()?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 08:20
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 11:11) *
где же main(), если __main()?


А... Теперь понял. Спасибо, учту в программе.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 10 2012, 10:16
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



в 20х числах июня, Томас Дреслер из ST совместно с дистрибьюторами проводил семинары (Москва, Питер, Ебург) на тему STM32F4... и как раз это все разжевал. Многие при этом возмущались - зачем типа нам это все знать.
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

Сообщение отредактировал kan35 - Jul 10 2012, 10:17
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 11 2012, 04:58
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(kan35 @ Jul 10 2012, 13:16) *
в 20х числах июня, Томас Дреслер из ST совместно с дистрибьюторами проводил семинары (Москва, Питер, Ебург) на тему STM32F4... и как раз это все разжевал. Многие при этом возмущались - зачем типа нам это все знать.
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

С удовольствием съездил бы послушал. Но попасть на эти семинары в те города, которые Вы перечислили, из моего провинциального украинского городка и небольшой частной фирмы - это всё равно, что слетать на Луну. Так что пока единственное спасение - это вот такие конференции и бескорыстная помощь моих уважаемых коллег.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 11 2012, 05:19
Сообщение #12


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(kan35 @ Jul 10 2012, 13:16) *
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

И почему, и что? Как там на семинаре объясняли? Не доложите вкратце?
По-моему - зря функцию установки тактовой частоты назвали SystemInit.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 11 2012, 06:01
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



SystemInit или собственно говоря установка частоты процессора и памяти делается в первую очередь так как происходящее в __main инициализация глобалных и статических переменных на дефолтной частоте может занять ощутимо много времени, если это критично конечно.
Еще, если вы используете массивы в RAM и если они значительные, то для экономии flash (из которой эти данные перегружаются) можно самостоятельно инициализировать их (не в __main), например применяя архивацию данных. Еще в __main инициализируется heap. это все что я вспомнил))
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 11 2012, 21:10
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А по-моему, всё гораздо проще.
SystemInit - это от ST, а __main - от кейла. И ST банально не может вызвать SystemInit после __main, потому что оттуда нет возврата laughing.gif
Косвенно это подтверждается тем фактом, что в стартапе для GCC (TrueSTUDIO) сделано по уму - сначала инициализация data и bss, и только потом - вызов SystemInit.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 12 2012, 04:11
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Цитата(AHTOXA @ Jul 12 2012, 01:10) *
А по-моему, всё гораздо проще.
SystemInit - это от ST, а __main - от кейла. И ST банально не может вызвать SystemInit после __main, потому что оттуда нет возврата laughing.gif

Эти рассуждения не выдерживают никакой критики. Почему бы тогда по вашей логиге банально не вызывать SystemInit в сомом main()? Инициализация на 16МГц и на 168МГц - чувствуете разницу?
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th August 2025 - 04:25
Рейтинг@Mail.ru


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