ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
23 декабря
1035662 Топик полностью
Связанные сообщения
C-Startup
Открыл для себя недавно появившийся сайт по изучению C++. Читаю, узнал много интересного (изменения стандарта с C++11). Ненапряж...2024-03-25
Обработку прерывания от FSMC и таймаут на то что PLL (не)заведётся сделал? Я делал... Иногда срабатывало. Плохая пайка, плохой к...2020-09-10
Из функции _start (в C-стартапе, до main) пересчитывается CRC32 прошивки, например, и сравнивается с значениями записанными по с...2017-07-12
Я для ARM7 писал на асме, и обработчик прерываний тоже. А он там, в отличии от жалких кортексов, достаточно замороченный.2016-05-03
Вначале пишешь (вообще по LR, дальше исключительно для одептов оссемблира):2012-01-26
fk0легенда (11.09.2020 18:42, просмотров: 784) ответил evgeniy1294 на startup-файлы и вопросы по ним:
Стартап делает гораздо больше вещей. Вообще отчасти это задача операционной системы: как-то разместить в памяти аргументы программы, переменные окружения, и передать указатели на них. И заодно сделать доступной в адресном пространстве программу (загрузить её, библиотеки, релоцировать...), стек, настроить регистры... 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]