ВходНаше всё Теги codebook PARTS Поиск Опросы Закон Пятница
25 сентября
/1035662
Топик полностью
fk0 (11.09.2020 18:42, просмотров: 118) в ответ на startup-файлы и вопросы по ним: - автор: evgeniy1294
Стартап делает гораздо больше вещей. Вообще отчасти это задача операционной системы: как-то разместить в памяти аргументы программы, переменные окружения, и передать указатели на них. И заодно сделать доступной в адресном пространстве программу (загрузить её, библиотеки, релоцировать...), стек, настроить регистры... C-стартап должен подготовить "рантайм" к работе и инициализировать C-библиотеку.... 

В первую очередь обнулить секцию BSS -- переменные (не)инициализированные нулём (вообще это как бы делает ОС, но в embedded её нет), скопировать инициализированные переменные из ROM в RAM -- секция DATA (тоже делает загрузчик программ в ОС), если C++ -- то вызвать функции конструкторов глобальных/статических экземпляров классов (кроме синглтонов -- static внутри функций, инициализирующихся при первом использовании). Кстати у GCC тоже конструкторы есть в голом C (атрибут "constructor").


Потом должны вызваться функции инициализирующие C-библиотеку: инициализировать стандартные файлы ввода-вывода, кучу (malloc), таймзону (локаль инициализируется пользователем через явный вызов setlocale). Потом вызывается main и предполагается, что он вернётся и будет вызван exit(). Тогда должны вызваться все деструкторы: для статических/глобальных объектов и для синглтонов, потом должны выполниться пользовательские функции зарегистрированные через atexit(), потом должна быть вызвана функция ОС _exit(code). Код возврата как-то передаётся в ОС, в контроллере может быть просто перезапуск. Вообще в контроллере exit() и возврат из main смысла не имеют, как и вызов деструкторов на выходе.


Но программа выйти и через аварийный выход: через abort(), который может вызываться из assert'ов, из std::terminate() в C++, последний вызывается из необрабатываемых исключений. Вот этот выход нужно как-то ловить и сигнализировать, протоколировать, чтоб вообще с ошибками потом разобраться.


Кроме того, возможны аппаратные исключения, у ARM это HardFault_Handler в котором очень весело написан while(1). Конечно там должен быть не цикл -- прибор не должен зависать. Тут неплохо бы распечатать регистры, просигнализировать об ошибке, записать куда-то причину ошибки и диагностику и перезапуститься. Я недавно писал (старое, для не-кортексов), ссылки ниже.


Кроме того в embedded стартап должен выполнить некоторые базовые вещи заранее, до main, иначе старт будет долгим или не завершится вообще:


1) настроить тактовый генератор на высокую частоту, дождаться, убедиться, что PLL работает (иначе -- сигнализация сбоя на низкой частоте и перезапуск);

2) проверить целостность CRC прошивки (иначе -- сигнализация сбоя...);

3) всё остальное перечисленное выше...


См. далее по ссылкам:

https://embeddedartistry.com/blog/2019/04/08/a-general-overview-of-what-happens-before-main/


Ссылки по теме на caxapa:

http://caxapa.ru/1035383

http://caxapa.ru/902079

http://caxapa.ru/768150

http://caxapa.ru/301879 http://caxapa.ru/672102

[ZX]
c-startup
Ответить
Ответы