Зачем stm32 требует самостоятельно настраивать запуск программы (startup.s) и почему AVR этого не требовал?
Может ли компилятор включать код запуска по умолчанию на основании флагов компиляции (gcc)? Как видимо происходит при компиляции для AVR? Если да, то как это сделать?
Или GCC не содержит в себе скриптов инициализации для всего разнообразия STM32, поэтому их надо откуда-то скачать? Либо самому писать исходя и документации чипа (что было бы странно).
Всё зависит от стандартной библиотеки, с которой вы линкуете проект. Если в ней есть стартовый код (наверное для AVR он есть), то можно и без стартапа. Для ARM такой зоопарк чипов, что все их в библиотеку не поместишь. Поэтому, проще под каждый чип стартап иметь. Вообще, это скоре плюс, когда имеешь возможность вмешаться с самой первой исполняемой команды.
Понятно, спасибо.
А где можно взять стандартные (официальные) скрипты инициализации для всего набора stm32 ?
Как я понимаю эти скрипты находились в средах разработки от STM, но сейчас их скачивать не дают.
Последний раз редактировалось ddr4 Чт авг 25, 2022 12:49:03, всего редактировалось 1 раз.
ddr4 писал(а):Зачем stm32 требует самостоятельно настраивать запуск программы (startup.s)
Где это требуется?
Стартап под нужный МК должен быть в проекте, но его настраивать (модифицировать) в большинстве случаев не требуется.
ddr4 писал(а):А где можно взять стандартные (официальные) скрипты инициализации для всего набора stm32 ?
Из репозитория куба например.
Или в какой-то IDE. Например в EmBitz их можно найти в архиве share\EmBitz\templates\wizard\arm\st\st.zip в папке Startup.
Так там особо ничего и не настраивается. Там, например, обнуляется оперативная память, копируются константы из флеша в память, вот такие подобные действия. Всю периферию нужно уже в основной программе настраивать.
Наверно потому, что это на порядок более сложный МК. Кстати, настраивать там ниче не надо, всё работает искаропки, и даже если бы этот файл вовсе не был написан заранее. Нужно всего лишь поместить в определенный адрес флеша одно 4-байное число, чтобы микроконтроллер знал, откудава (с какого адреса) ему следует начать читать программный код. Всё остальное добавляется по мере нужды. Вектора прерываний, вершина стека - это необходимый минимум. Остальное - по желанию.
[uquote="MLX90640",url="/forum/viewtopic.php?p=4278059#p4278059"]Наверно потому, что это на порядок более сложный МК. Кстати, настраивать там ниче не надо, всё работает искаропки, и даже если бы этот файл вовсе не был написан заранее.[/uquote]
И как эта коробка называется?
[uquote="MLX90640",url="/forum/viewtopic.php?p=4278059#p4278059"]Нужно всего лишь поместить в определенный адрес флеша одно 4-байное число, чтобы микроконтроллер знал, откудава (с какого адреса) ему следует начать читать программный код.[/uquote]
Так в stm32 же встроенный загрузчик, который по умолчанию начинает читать c 0x08000000. То есть эта_ещё_одна_функция_stm32() (чтения с адреса) как и "должная" настройка старта (которую разработчики забыли встроить в компилятор - но выдают за фичу), которая мне не нужна.
MLX90640 писал(а):Нужно всего лишь поместить в определенный адрес флеша одно 4-байное число, чтобы микроконтроллер знал, откудава (с какого адреса) ему следует начать читать программный код.
Стек значит не нужен?
ddr4 писал(а):И как эта коробка называется?
IDE называется. Во многих имеются пакеты с библиотеками и требуемые файлы добавляются при создании проекта.
ddr4 писал(а):Так в stm32 же встроенный загрузчик, который по умолчанию начинает читать c 0x08000000.
Что находится по адресам 0x08000000 и 0x08000004?
Если думаете что исполняемый код, то ошибаетесь.
В startup.s вместе с файлом линкера как раз описано что находится по этим адресам и по следующим за ними.
IDE называется. Во многих имеются пакеты с библиотеками и требуемые файлы добавляются при создании проекта.[/uquote]По идее это должно быть в компиляторе, как было в AVR. Ведь компилятор и так собирается под АRM, почему бы на этапе его сборки, не включить стандартные скрипты инициализации для чипов. А в случае старта отличного от стандартного, включать по аргументу компилятора.
STM закрыла скачивание своих IDE, а скачивать скрипты старта из непонятных источников как-то не хочется.
ddr4 писал(а):Так в stm32 же встроенный загрузчик, который по умолчанию начинает читать c 0x08000000.
Что находится по адресам 0x08000000 и 0x08000004?
Если думаете что исполняемый код, то ошибаетесь.
В startup.s вместе с файлом линкера как раз описано что находится по этим адресам и по следующим за ними.[/uquote]Да видимо. С STM постоянно приходится узнавать то, без чего можно было бы обойтись.
ddr4 писал(а):По идее это должно быть в компиляторе, как было в avr.
То есть в компиляторе должны быть библиотеки для всех ядер ARM, всех производителей МК и процев? Хотите чтобы компилятор весил несколько десятков терабайт? Имеете диск такого объема?
ddr4 писал(а):Ведь компилятор и так собирается под АRM
Стартап от задачи и типа МК зависит, так что - не проканает общее сделать.
Кстати, советую стартап на С (или С++ если у вас второе) написать, зачем с этим асмом сношаться?
P.S. На гитхабе есть несколько репозиториев с разными вариантами стартапов, ld-скриптов и CMSIS. Но, повторю, обычно "стандартного" не хватает и нужно свое делать (особенно в отношении ld-скрипта: чтобы хранить настройки и логи во флеш-памяти, скажем).
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4278102#p4278102"]Стартап от задачи и типа МК зависит, так что - не проканает общее сделать.
Кстати, советую стартап на С (или С++ если у вас второе) написать, зачем с этим асмом сношаться?[/uquote]На AVR прокатывало.
Да видимо придётся изобретать стартап. Просто собрать и залить как в AVR не получится. Спасибо STM за прогрессивную архитектуру. )
ddr4, если не нравится - не пользуйся ARMянами. Пользуйся восьмибитками: STM8, 5051 и т.д., и т.п. Там по умолчанию ни стартап, ни линкер-скрипт не нужны, т.к. все "знает компилятор". Правда, там убогий sdcc вместо gcc… Да и производительность (+периферия) намного слабей, хотя цена не сильно-то отличается.
Кстати, если не нужно чего-то эдакого, все можно автоматизировать в Makefile: чтобы и ld-скрипт нужный подхватывался, и стартап… Только проще явно указать их.
P.S. Для всех STM32 у меня один общий стартап (нужное по #define'нам выбирается), да и ld-скрипт общий (только инклюдятся дополнительно данные о конкретном чипе: размер флеша и оперативы).
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Я говорю о минимальном минимуме для запуска микроконтроллера. А для его запуска в работу нужен один только предзаписанный вектор - указание адреса начала исполняемого кода. А указатель стека легко пишется в регистр SP, если чо.
Снова начались споры ниачом. Один безумный кекс ляпнул какую-то ересть, и начали сопли жевать.
Пишите дальше на AVR.
Не стоит сравнивать детский трехкалесный велосипед профессиональным мотоциклом! То что прокатывает на велосипеде, не факт что сработает на мотоцикле.
А вообще в чем проблема со стартапом? Его кто-то заставляет писать? В IDE создаете проект и все требуемые файлы включая стартап и скрипт линкера в него автоматически добавляются.
Хотите все писать руками? Тогда вам прямой путь в линукс! Там таких извращенцев много!
MLX90640 писал(а):Я говорю о минимальном минимуме для запуска микроконтроллера. А для его запуска в работу нужен один только предзаписанный вектор - указание адреса начала исполняемого кода.
Адрес стека находится перед адресом старта программы. Предлагаете оставить его пустым и в коде вручную записать в регистр стека? В чем смысл такого извращения?
MLX90640 писал(а):Снова начались споры ниачом.
Потому что вы бред предлагаете. Нет смысла оставлять в адресе стека мусор. Назовите хоть одну причину для чего это делать и для чего нужно нужно сейчас ТС.
MLX90640 писал(а):Один безумный кекс ляпнул какую-то ересть, и начали сопли жевать.
Ну раз вы себя считаете "безумным кексом"...
Вы во всем правы и можете возвращатся в палату к Наполеону!
Последний раз редактировалось Мурик Чт авг 25, 2022 16:03:40, всего редактировалось 2 раза.
Как тут любят говорить слово "бред", не разобравшись в теме... Проверить самому слабо чтоль и подумать? Лучше детально ответьте, для чего нужен стек. Тогда может быть поймете, почему его можно позднее задать вручную.
ОК помогите разобраться в теме и объясните в чем смысл оставлять в 0x08000000 неопределенное значение а потом в коде записывать в регистр SP адрес стека?
То что это в принципе возможно не означает что в этом есть практический смысл.
MLX90640 писал(а):Тогда может быть поймете, почему его можно позднее задать вручную.
Вопрос не в этом. Зачем оставлять в 0x08000000 мусор, а после в коде записывать адрес стека? Это нелогично и не имеет смысла.
Логично/не логично, но запуску МК не мешает. И вы сами это должны понимать. Я написал о минимальном минимуме. Остальные какашки развезли вы. Зачем и для чего? Поспорить захотелось чтоль? Идите вон с женой спорьте (если есть), я не в настроении спорить.
А когда перейдете на более продвинутый уровень, то поймете, что адрес загрузки может быть не только 0х0800000. Есть вообще "экзотические" адреса типа ITCM Flash
MLX90640 писал(а):Логично/не логично, но запуску МК не мешает.
- Ты говорил что едешь из Москвы в Питер?
- Да.
- А почему билет взял на Владивосток?
- Я еду в Питер через Владивосток!
- Зачем, это же большой крюк и не имеет смысла?
- Какая разница, я же через Владивосток доберусь из Москвы в Питер!
MLX90640 писал(а):Я написал о минимальном минимуме.
#include "stm32f10x.h"
#define StackTop ((uint32_t)(0x20000000 + 20*1024))
static void Reset_Handler(void);
__attribute__((used,section(".isr_vector")))
void (*const g_pfnVectors[])(void) =
{
(void*)StackTop, // Указатель на начало стека.
Reset_Handler // Функция выполняемая при сбросе МК.
};
static void Reset_Handler(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Вкл. тактирование порта GPIOC.
GPIOC->CRH |= GPIO_CRH_MODE13; // Настройка вывода PC13 как выхода.
while(1)
{
GPIOC->ODR ^= (1<<13); // Инвертирование состояния вывода PC13.
for (volatile uint32_t i=0; i<1000000; i++);
}
}
Теперь объясните в чем практический смысл записать 0 или любое другое значение в нулевой элемент массива g_pfnVectors, а после в коде присвоить регистру SP адрес стека?
MLX90640 писал(а):поймете, что адрес загрузки может быть не только 0х0800000.
Это повод оставлять мусор в 0х0800000 и в ручную записывать адрес в SP?