STM32 новичку в ARM что к чему
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Это где такое обилие стартапов валяется?
Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...
Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...
- Реклама
Re: STM32 новичку в ARM что к чему
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049401#p4049401"]Это где такое обилие стартапов валяется?
Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...[/uquote]
Всё, что надо для стандартного использования согласно CMSIS - https://www.keil.com/pack/doc/CMSIS/Cor ... ng_pg.html
- у STM32 имеется.
Всё лежит в свободном доступе на Github. Под все камни... например, под F4 https://github.com/STMicroelectronics/cmsis_device_f4
Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...[/uquote]
Всё, что надо для стандартного использования согласно CMSIS - https://www.keil.com/pack/doc/CMSIS/Cor ... ng_pg.html
- у STM32 имеется.
Всё лежит в свободном доступе на Github. Под все камни... например, под F4 https://github.com/STMicroelectronics/cmsis_device_f4
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: STM32 новичку в ARM что к чему
[uquote="VladislavS",url="/forum/viewtopic.php?p=4049390#p4049390"]Отсутствием совместимости.[/uquote]
Отсутствием совместимости платформо-зависимого кода с чем?
Отсутствием совместимости платформо-зависимого кода с чем?
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: STM32 новичку в ARM что к чему
[uquote="avtoneru",url="/forum/viewtopic.php?p=4049418#p4049418"]Под все камни... например, под F4 https://github.com/STMicroelectronics/cmsis_device_f4[/uquote]
Там нет вменяемого стартапа — зачем-то на асме только! Извращенцы чертовы!!!
Там нет вменяемого стартапа — зачем-то на асме только! Извращенцы чертовы!!!
Re: STM32 новичку в ARM что к чему
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049429#p4049429"][uquote="avtoneru",url="/forum/viewtopic.php?p=4049418#p4049418"]Под все камни... например, под F4 https://github.com/STMicroelectronics/cmsis_device_f4[/uquote]
Там нет вменяемого стартапа — зачем-то на асме только! Извращенцы чертовы!!![/uquote]
Почему-то ко всем МК STM32 файл первоначального старта идет на ассемблере. Хотя в CMSIS пишется, что это устаревший формат файла. Зачем они так делают - мне непонятно, но видимо "потому что".
Вместе с этим - там на ассемблере всего несколько строчек... понятных...
Интересовался уже, а что надо менять в этом файле, и зачем? Это может быть полезной информацией.
Там нет вменяемого стартапа — зачем-то на асме только! Извращенцы чертовы!!![/uquote]
Почему-то ко всем МК STM32 файл первоначального старта идет на ассемблере. Хотя в CMSIS пишется, что это устаревший формат файла. Зачем они так делают - мне непонятно, но видимо "потому что".
Вместе с этим - там на ассемблере всего несколько строчек... понятных...
Интересовался уже, а что надо менять в этом файле, и зачем? Это может быть полезной информацией.
- Реклама
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Я стартап утащил из opencm3. Там объявляются обработчики прерываний, а в reset_handler вот это:
Меня это полностью устраивает, так что я не переопределяю его.
Но еще нужно выполнить базовую настройку тактирования и т.п., это у меня в заголовочном файле stm32fX.h (где X - 0, 1 или 3), функцию эту я обозвал sysreset(), выполняю ее сразу после начала main() (но при необходимости можно ее и в другом месте вызвать или вообще не вызывать). Оттуда же подключаются нужные заголовочные файлы с определением регистров.
Код: Выделить всё
void WEAK __attribute__ ((naked)) __attribute__ ((noreturn)) reset_handler(void){
extern char _sdata; // .data section start
extern char _edata; // .data section end
extern char _sbss; // .bss section start
extern char _ebss; // .bss section end
extern char _ldata; // .data load address
char *dst = &_sdata;
char *src = &_ldata;
// enable 8-byte stack alignment to comply with AAPCS
SCB->CCR |= 0x00000200;
// copy initialized variables data
while ( dst < &_edata ) { *dst++ = *src++; }
// clear uninitialized variables
for ( dst = &_sbss; dst < &_ebss; dst++ ) { *dst = 0; }
// call main
main();
// halt
for(;;) {}
}Но еще нужно выполнить базовую настройку тактирования и т.п., это у меня в заголовочном файле stm32fX.h (где X - 0, 1 или 3), функцию эту я обозвал sysreset(), выполняю ее сразу после начала main() (но при необходимости можно ее и в другом месте вызвать или вообще не вызывать). Оттуда же подключаются нужные заголовочные файлы с определением регистров.
Re: STM32 новичку в ARM что к чему
Eddy_Em, вместо некоего "стандартного" использования, которое производитель ядра ARM описывает как CMSIS, Вы написали свой вариант...
Это тоже вариант написания кода.
Но большинство будет придерживаться некой общей парадигмы.
Хотя кого я обманываю. Большинство будет, как всегда, копипастить и искать "мудрость" в видео, блогах и статьях. Читать документы должен кто-то другой.
Добавлено after 32 minutes 32 seconds:
По поводу того, почему startup на ассемблере : https://community.st.com/s/question/0D5 ... m-asm-to-c
Это тоже вариант написания кода.
Но большинство будет придерживаться некой общей парадигмы.
Хотя кого я обманываю. Большинство будет, как всегда, копипастить и искать "мудрость" в видео, блогах и статьях. Читать документы должен кто-то другой.
Добавлено after 32 minutes 32 seconds:
По поводу того, почему startup на ассемблере : https://community.st.com/s/question/0D5 ... m-asm-to-c
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4049428#p4049428"]Отсутствием совместимости платформо-зависимого кода с чем?[/uquote]Между разными компиляторами.
Добавлено after 6 minutes 5 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049401#p4049401"]Это где такое обилие стартапов валяется?[/uquote]Почему валяется? Аккуратненько так разложено по сериям для всего STM32 и не только. В VisualGDB. Там ещё скрипты линкера и заголовочные файлы на всё приложены.
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049401#p4049401"]Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...[/uquote]Как можно хаять куб и хотеть его одновременно?
Добавлено after 6 minutes 5 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049401#p4049401"]Это где такое обилие стартапов валяется?[/uquote]Почему валяется? Аккуратненько так разложено по сериям для всего STM32 и не только. В VisualGDB. Там ещё скрипты линкера и заголовочные файлы на всё приложены.
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049401#p4049401"]Может там еще и функции инициализации при старте есть? Чтобы самому не писать, вчитываясь в даташиты...[/uquote]Как можно хаять куб и хотеть его одновременно?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4049435#p4049435"]Я стартап утащил из opencm3.[/uquote]Секции выровнены по 32 бита. Зачем их побайтово копировать/занулять? Вот так эффективнее
PS: да и SystemInit() надо до инициализации вызывать. Во-первых, RAM может быть выключена при старте. Во-вторых, тактовую поднять. А то так и получите, что ARM тормознее AVR.
Код: Выделить всё
extern uint32_t _sidata[], _sdata[], _edata[], _sbss[], _ebss[];
for (volatile uint32_t *pSrc = _sidata, *pDst = _sdata; pDst != _edata; *pDst++ = *pSrc++);
for (volatile uint32_t *pDst = _sbss; pDst != _ebss; *pDst++ = 0);
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: STM32 новичку в ARM что к чему
Добрый день. Методика, которую использую я для изучения микроконтроллеров "От случая к случаю, когда есть время" дает очень плохие результаты...
Однако, желание не пропадает, а времени на все просто не хватает. Прошу помочь уже много лет начинающиму расшифровать эту строчку:
А точнее, ее правую часть.
1. Правильно же я понял, что TIM2_BASE - это просто число - адерс памяти, по которму находится первый регистр для таймера2?
2. А TIM_TypeDef - это название типа (структуры), у которой есть поля, которые в свою очередь являются РЕГИСТРАМИ для настройки этого таймера?
3. И так как, эти поля как целые 32 разрядные типы, то первое поле имеет смещение 0 и, следовательно, первый регистр в этой структуре будет равен адресу TIM2_BASE, а второй уже будет равен TIM2_BASE+32? и т.д.
4. А сама запись (TIM_TypeDef *) TIM2_BASE Что-то я туплю... Тут же нету пременных? Если я беру адрес переменной через & и присваиваю его перменной-указателю, то более или менее понятно. Гоню. Ест перменная TIM_TypeDef типа структуры. В нее почему через звездочку запихивают значение адреса? Потому что нет переменной у которой надо брать адрес через разыменование?
Короче, надо более подробно про работу указателей и структур ИМЕННО в связке микроконтроллера. Простое изучение Си для компьютера порождает путаницу в голове, т.к. для компа понятно, там используются названия переменных, а для микроконтроллера не очень, т.к. здесь получается простая адерсная арифметика на числах...
Добавлено after 4 minutes 27 seconds:
И в догонку. Правильно я понимаю, что организация памяти этих микроконтроллеров (и ИМЕННО она) позволила сделать подобное, чтобы можно было все регистры расписать через структуры, а потом к ним обращаться? Т.е. в этом принципиальное различие от тех же АВР контроллеров?
Добавлено after 4 minutes 15 seconds:
З.Ы. я подозреваю, что сам на свои вопросы отвечаю. Но все же лучше уточнить.
Однако, желание не пропадает, а времени на все просто не хватает. Прошу помочь уже много лет начинающиму расшифровать эту строчку:
Код: Выделить всё
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)1. Правильно же я понял, что TIM2_BASE - это просто число - адерс памяти, по которму находится первый регистр для таймера2?
2. А TIM_TypeDef - это название типа (структуры), у которой есть поля, которые в свою очередь являются РЕГИСТРАМИ для настройки этого таймера?
3. И так как, эти поля как целые 32 разрядные типы, то первое поле имеет смещение 0 и, следовательно, первый регистр в этой структуре будет равен адресу TIM2_BASE, а второй уже будет равен TIM2_BASE+32? и т.д.
4. А сама запись (TIM_TypeDef *) TIM2_BASE Что-то я туплю... Тут же нету пременных? Если я беру адрес переменной через & и присваиваю его перменной-указателю, то более или менее понятно. Гоню. Ест перменная TIM_TypeDef типа структуры. В нее почему через звездочку запихивают значение адреса? Потому что нет переменной у которой надо брать адрес через разыменование?
Короче, надо более подробно про работу указателей и структур ИМЕННО в связке микроконтроллера. Простое изучение Си для компьютера порождает путаницу в голове, т.к. для компа понятно, там используются названия переменных, а для микроконтроллера не очень, т.к. здесь получается простая адерсная арифметика на числах...
Добавлено after 4 minutes 27 seconds:
И в догонку. Правильно я понимаю, что организация памяти этих микроконтроллеров (и ИМЕННО она) позволила сделать подобное, чтобы можно было все регистры расписать через структуры, а потом к ним обращаться? Т.е. в этом принципиальное различие от тех же АВР контроллеров?
Добавлено after 4 minutes 15 seconds:
З.Ы. я подозреваю, что сам на свои вопросы отвечаю. Но все же лучше уточнить.
Станислав
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Именно так.СКАЗОЧНИК писал(а):Правильно же я понял, что TIM2_BASE - это просто число - адерс памяти, по которму находится первый регистр для таймера2?
Код: Выделить всё
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)Соответственно, первое поле этой структуры имеет тот же адрес (смещение 0), следующее уже имеет смещение +4, и так далее. И эти смещения очевидным образом дают доступ к регистрам TIM2, как они описаны в RM.
В принципе, ничто особо не мешает таким же способом и в AVR организовать доступ. Но у простых AVR и периферия обычно более простая, по 2-3 регистра, и делать из этого развёрнутые структуры особого смысла нет. А у STM32 регистров много у каждой периферии, плюс однотипных периферий (тех же таймеров) по нескольку штук, так что организация всего этого через поля структур достаточно удобна.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
Это всего лишь указатель на структуру. В системе команд ARM удобный доступ к памяти со смещением от базового адреса. Он позволяет бесплатно получать доступ к полям структуры, имея только лишь начальный её адрес (читай указатель).
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: STM32 новичку в ARM что к чему
Прочитал и ппросмотрел кучу информации про указатели. И даже очень понятные объяснения нашел. НО всегда получается путаница, когда переходят к указателям на функции, структуры и т.д. И начинаешь путаться в операциях взятия адреса и разыменования. Везде объясняют язык Си с позиции "для компьютера" чтобы написаать программку и вывести ее результаты в консоль.
Все таки для микроконтроллеров чуток "другой" Си. Точнее, другое его использование. Никто в компьютре в примерах не присваивал адрес напрямую в указатель. Т.к. это не возможно из-за того, что не известно что там выделено под память для твоей программы. А в МК как раз именно это важно.
Считаю, что одни из самых сложных и основных тем для работы с МК на Си - это указатели, структуры и приведение типов. (наверное). А они не явно и не подробно освещены в тех источниках, где можно почитать про МК.
Кстати, я вверху да, ошибся, когда написал такое:
TIM2_BASE+32
Действительно, мы же не биты прибавляем. А целиком смещение по адресу. Но не явно и такое, что +4 смещение для следующего регистра, если не идет акцент на почему именно так? Почему байтами, а не словами? Почему еще слова могут быть разные и 16 бит и 32. ? Если у меня указан тип как ИНТ32, то значит надо вообще к адерсу +1 прибавлять?
Добавлено after 1 minute 43 seconds:
И правильно я понимаю, что УКАЗАТЕЛЬ на структуру - это переменная?
Все таки для микроконтроллеров чуток "другой" Си. Точнее, другое его использование. Никто в компьютре в примерах не присваивал адрес напрямую в указатель. Т.к. это не возможно из-за того, что не известно что там выделено под память для твоей программы. А в МК как раз именно это важно.
Считаю, что одни из самых сложных и основных тем для работы с МК на Си - это указатели, структуры и приведение типов. (наверное). А они не явно и не подробно освещены в тех источниках, где можно почитать про МК.
Кстати, я вверху да, ошибся, когда написал такое:
TIM2_BASE+32
Действительно, мы же не биты прибавляем. А целиком смещение по адресу. Но не явно и такое, что +4 смещение для следующего регистра, если не идет акцент на почему именно так? Почему байтами, а не словами? Почему еще слова могут быть разные и 16 бит и 32. ? Если у меня указан тип как ИНТ32, то значит надо вообще к адерсу +1 прибавлять?
Добавлено after 1 minute 43 seconds:
И правильно я понимаю, что УКАЗАТЕЛЬ на структуру - это переменная?
Станислав
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
Ничем С для микроконтроллеров не отличается от обычного С. Адресная арифметика везде одинакова. Изучаем теорию и в бой.
И указатель не обязательно переменная, чего бы ему не быть константой?
И указатель не обязательно переменная, чего бы ему не быть константой?
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: STM32 новичку в ARM что к чему
Т.е. это не переменная, а просто объявили в файле константу и присвоили ей жестко число (адрес)?
Добавлено after 2 minutes 1 second:
Почти понял, что МК оперирует только цифрами. Т.е. в я могу написать тупо цифры адреса регистра и по этому адресу расставлять биты?
Добавлено after 27 seconds:
Как это будет выглядеть для примера?
Станислав
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
Не присвоили, а сделали приведение типа из числа к указателю на структуру. Выполните все макроподстановки вручную и всё поймёте.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: STM32 новичку в ARM что к чему
(TIM_TypeDef *)0х40010000
Как-то так получается. Но все равно втупляю. Если я так сделаю в "обычном" си на компьютере, то
(TIM_TypeDef *) var
переменная var будет типа структуры?
VladislavS,WiseLord спасибо, что помогаете. )
Как-то так получается. Но все равно втупляю. Если я так сделаю в "обычном" си на компьютере, то
(TIM_TypeDef *) var
переменная var будет типа структуры?
VladislavS,WiseLord спасибо, что помогаете. )
Станислав
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32 новичку в ARM что к чему
Кто вам запрещает так сделать в "обычном C на компьютере"? Компилятор всё откомпилирует и получится программа. Разве что в момент выполнения операционная система не даст в защищённую область получить доступ и прихлопнет такую программу.
Добавлено after 3 minutes 17 seconds:
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=4050543#p4050543"](TIM_TypeDef *) var
переменная var будет типа структуры?[/uquote]Переменная var будет тем чем и была, как вы её определили ранее. А вот (TIM_TypeDef *)var это приведение типа к указателю на структуру.
PS: В принципе, в микроконтроллерах тоже встречается модуль защиты памяти и можно сделать, чтобы так же как не компьютере, доступ куда не положено вызывал исключения.
Добавлено after 3 minutes 17 seconds:
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=4050543#p4050543"](TIM_TypeDef *) var
переменная var будет типа структуры?[/uquote]Переменная var будет тем чем и была, как вы её определили ранее. А вот (TIM_TypeDef *)var это приведение типа к указателю на структуру.
PS: В принципе, в микроконтроллерах тоже встречается модуль защиты памяти и можно сделать, чтобы так же как не компьютере, доступ куда не положено вызывал исключения.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: STM32 новичку в ARM что к чему
Как везде написано и как я запомнил, что
указатель - это перменная, которая хранит адрес другой переменной (структуры, функции)... И это мне изначально вполне понятно.
А вот, когда указателем становится просто число (адрес памяти) уже туго...
Как в железе все это выглядит? Или здесь только для компилятора это важно, а в железе все равно цифры только будут.
указатель - это перменная, которая хранит адрес другой переменной (структуры, функции)... И это мне изначально вполне понятно.
А вот, когда указателем становится просто число (адрес памяти) уже туго...
Как в железе все это выглядит? Или здесь только для компилятора это важно, а в железе все равно цифры только будут.
Станислав
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Возьмём для примера тот же TIM2. Структура, описывающая его:
Раскручиваем адрес TIM2:
Получается, группа регистров TIM2 начинается с адреса 0x40000000. А регистр, например, CR2 лежит уже по адресу 0x40000004.
Поэтому к CR2 можно обратиться либо "как принято", (TIM2->CR2 = 0x5555AAAA). Либо, можно в стиле AVR:
Ну и да, __IO - это синоним volatile.
Добавлено after 5 minutes 7 seconds:
Грубо, можно то что выше "расшифровать" так:
Код: Выделить всё
typedef struct
{
__IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
__IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
__IO uint32_t SMCR; /*!< TIM slave Mode Control register, Address offset: 0x08 */
...
}TIM_TypeDef;Код: Выделить всё
#define TIM2 ((TIM_TypeDef *)TIM2_BASE)
#define TIM2_BASE (APB1PERIPH_BASE + 0x00000000UL)
#define APB1PERIPH_BASE PERIPH_BASE
#define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */Поэтому к CR2 можно обратиться либо "как принято", (TIM2->CR2 = 0x5555AAAA). Либо, можно в стиле AVR:
Код: Выделить всё
#define CR1 (*(__IO uint32_t*)0x40000000)
#define CR2 (*(__IO uint32_t*)0x40000004)
#define SMCR (*(__IO uint32_t*)0x40000008)
...
// Присванивание:
CR2 = 0x5555AAAA;Добавлено after 5 minutes 7 seconds:
Грубо, можно то что выше "расшифровать" так:
Код: Выделить всё
volatile uint32_t *ptr;
ptr = 0x40000004;
*ptr = 0x5555AAAA;
Последний раз редактировалось WiseLord Пн июн 21, 2021 11:40:26, всего редактировалось 1 раз.


