|
|
  |
__low_level_init (void), Объясните пожалуйста |
|
|
|
Dec 1 2005, 22:16
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
СИшный main это тоже функция, которая может иметь вход и выход, несмотря на то, что ее обычно зацикливают (делают бесконечный цикл). В секции __low_level_init вы можете разместить какой-то кусок программы, который будет выполняться ДО начала выполнения main. Например, процедуру, которая будет определять причину сброса и/или процедуру, которая будет выполнять функции начального загрузчика системы и/или процедуру проверки целостности (контрольной суммы) программы, хранящейся во Flash и/или процедуру, которая будет ремаппить вектора прерываний в ОЗУ и/или ... ну мало ли что вам захочется выполнить до начала выполнения main
|
|
|
|
|
Aug 21 2006, 15:34
|
Группа: Участник
Сообщений: 11
Регистрация: 3-08-06
Пользователь №: 19 282

|
..мало ли что вам захочется выполнить до начала выполнения main.
И есть еще кое что, что вам вроде бы захочеться сделать в main, но в main вы просто не попадете! Так как Watch dog по умолчанию включен и время его срабатывания запросто может оказаться меньше времени инициализации (например если область переменных в RAM требующих инициализации достаточно большая). То он успешно сработает еще до входа в main! поэтому ПРИДЕТЬСЯ (а не захочеться) его остановить именно в этой функции. Также если при програмном сбросе нужно сохранить значение некоторых переменных (показания часов например) а не затирать их значением по умолчанию, то сделать это можно только в этой функции.
|
|
|
|
|
Aug 21 2006, 15:50
|
Группа: Участник
Сообщений: 11
Регистрация: 3-08-06
Пользователь №: 19 282

|
Пример, когда вам вроде бы не хочеться использовать __low_level_init, но придется http://electronix.ru/forum/index.php?showtopic=4298Проблема оказалась именно в инициализации большого блока памяти. Во время которой сработал watchdog.
|
|
|
|
|
Aug 22 2006, 13:35
|
Участник

Группа: Свой
Сообщений: 63
Регистрация: 16-06-04
Из: Россия, Уфа
Пользователь №: 31

|
Цитата(rezident @ Aug 21 2006, 22:05)  В той ветке не было подтверждения, что причиной подвисания был WDT. У вас у самого были реальные случаи срабатывания WDT при инициализации памяти? По моим грубым прикидкам получается, что инициализация даже 10кБайт занимает времени меньше (примерно на 20%) периода срабатывания WDT при его настройках и тактировании по умолчанию (то бишь после PUC или POR). Вот запустил в симуляторе программу для 1611. Поставил точку останову на main(). По бряку имеем 77842 cycles (при этом это не С++, т.е. без вызова конструкторов глобальных объектов). Таким образом, получается 77842 * 800kHz = ~97мс. Учитывая дефолтные ~32мс для watchdog, гарантированно имеем PUC, если не настроим/отключим тактирование/ватчдог в __low_level_init
|
|
|
|
|
Aug 24 2006, 16:20
|
Группа: Участник
Сообщений: 11
Регистрация: 3-08-06
Пользователь №: 19 282

|
>>В той ветке не было подтверждения, что причиной подвисания был WDT. У вас у самого были реальные случаи срабатывания WDT при инициализации памяти?
На уроке: - Гоги, докажи теорему. - МАМОЙ КЛЯНУС!
Если бы не было, я бы об этой функции тоже ничего не знал, не нужна была бы она нам. Самое неприятное тут что пока программа относительно небольшая, то все ОК, но в один прекрасный день когда ты ее полгода уже пишешь и все железо отлажено, а все порты давно корректно проинциализированы это случаештся и ты сидишь и думаешь "А ГДЕ ГРАБЛИ ТО?" ну добавил очередную глобальную или статическую переменную и БАЦ (вернее PUC) - висим, убрал и опять работает.
Где точная граница мы выяснять не стали, (тем более что зависит от версии библиотеки) но у меня это МЕНЕЕ половины RAM на MSP430F169.
Да, еще инициализация массивов одним значением идет гораздо быстрее, чем отдельных переменных, находящихся по разным адресам и разными значениями. Так что, если ваш тест был с большими массивами, то его нельзя считать корректным, и вообще врят ли имеет смысл искать эту границу.
|
|
|
|
|
Sep 4 2006, 08:49
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 22-08-06
Пользователь №: 19 736

|
Что-то я так и не смог подлинковать lowinit.c к своему проекту. Вроде бы все сделал так, как написано в инструкциях - в отдельном файле и т.д. Компилит замечательно, а в итоговом проекте - нету. В итоговом проекте идут инициализация стека, потом call #__data16_memzer и следом за ним call #main
Не мог бы кто-нибудь объяснить, как все же прикомпилировать __low_lewel_init к проекту. Компилятор V3.40A/W32 (3.40.1.1) А то я с этим ватчдогом уже поимел проблем.
|
|
|
|
|
Sep 4 2006, 11:04
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
Сейчас в один из файлов проекта вставил Код /* --- __low_level_init() --------------------------------------------------------------------------------- ** * * -------------------------------------------------------------------------------------------------------- */ int __low_level_init( void ) { /* Insert your low-level initializations here */ WDTCTL = WDTPW + WDTHOLD; // Stop WDT
/*==================================*/ /* Choose if segment initialization */ /* should be done or not. */ /* Return: 0 to omit seg_init */ /* 1 to run seg_init */ /*==================================*/ return ( 1 ); } в мар файле появилась строка Код Segment part 21. ROOT. ENTRY ADDRESS REF BY ===== ======= ====== __low_level_init 506A ?cstart_call_low_level_init (?cstart) stack 1 = 00000000 ( 00000002 ) и для main нашел, чтоб ее адрес знать Код CODE Relative segment, address: 1A10 - 1BA5 (0x196 bytes), align: 1 Segment part 16. ENTRY ADDRESS REF BY ===== ======= ====== main 1A10 Segment part 12 (?cstart) calls direct stack 1 = 00000000 ( 0000000C ) в симуляторе вижу: Код 001400 3140000A mov.w #0xA00,SP 001404 B0126A50 call #0x506A [b]это вызов __low_level_init[/b] 001408 0C93 tst.w R12 00140A 0F24 jeq 0x142A 00140C 3C400C02 mov.w #0x20C,R12 001410 3E40B303 mov.w #0x3B3,R14 001414 B0120A6B call #0x6B0A 001418 3C400002 mov.w #0x200,R12 00141C 3E40F894 mov.w #0x94F8,R14 001420 30120C00 push.w #0xC 001424 B0121C6B call #0x6B1C 001428 2153 incd.w SP 00142A B012101A call #0x1A10 [b]это вызов main[/b] Все появилось
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Sep 4 2006, 11:10
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Цитата(and_pp @ Sep 4 2006, 11:49)  Что-то я так и не смог подлинковать lowinit.c к своему проекту. Вроде бы все сделал так, как написано в инструкциях - в отдельном файле и т.д. Компилит замечательно, а в итоговом проекте - нету. В итоговом проекте идут инициализация стека, потом call #__data16_memzer и следом за ним call #main
Не мог бы кто-нибудь объяснить, как все же прикомпилировать __low_lewel_init к проекту. Компилятор V3.40A/W32 (3.40.1.1) А то я с этим ватчдогом уже поимел проблем. Обратите внимание на проект. Если он сделан на с++, то нужно добавить екстерн с или его аналог в ввиде макроса.
|
|
|
|
|
Sep 5 2006, 10:35
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 22-08-06
Пользователь №: 19 736

|
Цитата(ig_z @ Sep 4 2006, 15:10)  Обратите внимание на проект. Если он сделан на с++, то нужно добавить екстерн с или его аналог в ввиде макроса. А ведь действительно у меня проект был на С++ Добавил extern "C" { ... } - все заработало. Огромное спасибо!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|