VladislavS писал(а):А зачем? Ведь это имеет смысл, если ты это делаешь лучше производителя.
В случае с STM32 - да, нет смысла вручную писать.
А вот у STM8 вообще никаких макросов не было изначально! Выдирать из SPL нельзя, т.к. там построение аналогично построению для STM32 (на структурах), но sdcc (по крайней мере, когда я только начал работать с STM8) не умеет оптимально раскрывать структуры, как gcc. В итоге это приводило к оверхеду.
Вот я и выдрал где-то базовый include файлик для STM8, а потом постепенно дописывал в него новую периферию. По его составу можно увидеть, что, скажем, с CAN на STM8 я ни разу не работал (хотя было один раз желание, но я себя пересилил — STM32 намного удобней для работы, а цена отличается совсем незначительно).
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
[uquote="VladislavS",url="/forum/viewtopic.php?p=3745543#p3745543"]А зачем? Ведь это имеет смысл, если ты это делаешь лучше производителя. Чем твоё описание лучше? Стоит оно того, учитывая что это ещё и источник ошибок?[/uquote]Затем что так удобнее. В штатных хидерах зачастую имена регистров - длинные, несовпадающие с именами в даташитах. Да ещё - оформлены в разных стилях у разных производителей.
Да ещё часто - трудно используемые в макросах привязки периферии.
Я же все оформляю короткими, совпадающими с именами в даташитах на периферию и в едином стиле для всех используемых МК.
Ошибок быть не может. Так как описание делается по мере изучения периферии и отладке её драйвера.
[uquote="dosikus",url="/forum/viewtopic.php?p=3745566#p3745566"]То есть вы пишите только для себя любимого и в стол?[/uquote]
Почему в стол? Почему для себя, откуда такой вывод? На мой взгляд, 99% последователей тупо заливают прошивку (ставят компонент, паяют по схеме и т.д.), не разбираясь, кто там чё написал-проектировал. Это при условии, если она выложена. Выложено (продано, подарено) может быть и готовое устройство. У Вас же нет к каждому заводскому девайсу в доме исходников? И какая разница тогда, как они сделаны?
[uquote="jcxz",url="/forum/viewtopic.php?p=3745608#p3745608"]все оформляю короткими, совпадающими с именами в даташитах[/uquote]
Согласен.
Этот бодрый лозунг о великой абстракции и легкости перехода с одного проца на другой - это просто какая-то толерантная фигня, дань моде кроссплатформенности, оопнутости и проч., выражающаяся в раздутости и нечитабельности кода.
[uquote="dosikus",url="/forum/viewtopic.php?p=3745566#p3745566"]То есть вы пишите только для себя любимого и в стол?[/uquote]Я пишу для заказчика. Для решения его задачи. И стараюсь это делать так, чтобы легче было разбираться и ориентироваться в коде. Для последующей поддержки. Если некий "стандарт" этому мешает - он идёт лесом. Также идут лесом какие-то "окружающие", которые вообще не понятно какое имеют отношение к моей разработке.
Это решается с помощью самодокументируемого кода.
То что описываете вы есть отсебятина и полная галиматья.
Нечто подобное было у корабельникова знаменитого прозаика в эмбедде. Царство ему небесное.
[uquote="dosikus",url="/forum/viewtopic.php?p=3746650#p3746650"]То что описываете вы есть отсебятина и полная галиматья.[/uquote]Тогда любое написание своего кода - отсебятина и галиматья. И всё нужно покупать у индусов.
В принципе, со всем можно согласиться, кроме этого:[uquote="jcxz",url="/forum/viewtopic.php?p=3745608#p3745608"]Ошибок быть не может.[/uquote]Тут уже и до нимба недалеко
[uquote="VladislavS",url="/forum/viewtopic.php?p=3746863#p3746863"]Тут уже и до нимба недалеко [/uquote]И у вас ошибок не будет если так будете делать.
Потому как я же написал: "пишу описание регистров периферии по мере изучения этих регистров, написания драйвера, работающего с ними" - а значит если я какой-то регистр описал неправильно, то я тут же его использовал -> у меня не заработало -> отладил, нашёл причину -> поправил описание регистра. Всё.
Если у Вас программа работает правильно, как и ожидалось, это же говорит, что она написана правильно и все её компоненты скорей всего - написаны правильно. Хотя возможно конечны какие-то баги даже в работающей программе. Но в отлаженных описаниях регистров - маловероятны.
Если описывать регистры периферии просто "в стол" без их использования сразу - вот тогда вероятность бага в описании высока, да. Это кстати вижу по таким описаниям "от производителя", не раз уже находил.
У сабжей кстати довольно прикольный asm. Но вот програмить на нем лично я рискнул только небольшие вставки, которые на си тяжко. Целиком на ассемблере - перебор. Не то чтобы невозможно, но выглядит не очень. Фичастая периферия просит использования. Значит кода может стать больше чем это комфортно на ассемблере. На сях то же самое получается более читаемо - а компилятор в лучшем случае сделает вполне сравнимую по эффеткивности конструкцию. А иной раз так и получше.
[uquote="iddqd",url="/forum/viewtopic.php?p=3927158#p3927158"]У сабжей кстати довольно прикольный asm. Но вот програмить на нем лично я рискнул только небольшие вставки, которые на си тяжко. Целиком на ассемблере - перебор. Не то чтобы невозможно, но выглядит не очень. Фичастая периферия просит использования. Значит кода может стать больше чем это комфортно на ассемблере. На сях то же самое получается более читаемо - а компилятор в лучшем случае сделает вполне сравнимую по эффеткивности конструкцию. А иной раз так и получше.[/uquote] А в какой программе программил на asm? По тексту - смотря какие задачи. Контроллер управления ключами специальных силовых преобразователей можно только на ассемблере, очень быстрые реакции надо. И часто тайминги точные времени срабатывания.
[uquote="ВячеславX",url="/forum/viewtopic.php?p=3928699#p3928699"]А в какой программе программил на asm?[/uquote] Ну например, старт другого кода с указанным PC и SP. Дергается то из сей, и позволяет, ну, например, запустить вон ту прошивку как будто это железо при ресете сделало, т.е. [0x0] -> SP, [0x4] -> PC. Но можно что угодно еще, я условно называю это "bootload()" и оно берет как параметры 2 uint32, entry и stack. Стэк, в случае прошивки, конечно из 0x8000000 лучше взять если это флешь - за наивное чтение uint32 из адреса 0x0 - HardFault, хе-хе.
На вот именно сях, именно синхронно, именно это, так, чтоб компилер не пернул в стэк сдуру или не одурел когда стэк вон там уже снесли - проблематично, ну вот нет в си инструментов для жесткого контроля этого. А на асме что, там это уже никто не оспорит, лишнего делать никто не будет, а потом управление перейдет тому коду. И уже не важно что там компилер хотел бы, камень уже целиком отдан другому... как будто меня там вообще не было, например, так что адресат может получить ВЕСЬ стэк и проч.
А что до ключей - их логично аппаратным PWMом крутить, так можно и сотни кГц лупить без напряга. Вон я спрашивал насчет DMA, и в конце концов сделал, вроде удобно получается: ADC сам загребает пачку сканов, DMA сам кладет это в буфер, вся последовательность - в железе, оба долбят по кольцу, ограничены только скоростью скана ADC последовательности. А софту делать ничего не надо. В конце всего цикла оно может IRQ пульнуть, например по поводу "трансфер комплит". Это логичная точка для коррекции PWM на основе свежих замеров. Как-то так и ощущается почему у STM'а крутое и правильное железо... мало того что ядро круче 8-битников, так еще и железо хорошо подпирает тяжелые и быстрые операции, выигрыш больше чем могло бы показаться на первый взгляд. Наверное за это их и расхватали на цитаты, клонов F1xx довольно много фирм делает.
[uquote="iddqd",url="/forum/viewtopic.php?p=3928734#p3928734"]ну, например, запустить вон ту прошивку как будто это железо при ресете сделало, т.е. [0x0] -> SP, [0x4] -> PC.[/uquote]Из-за этой ерунды такой батхед?
Вот так си использовать - очень так себе на мой вкус. Ну то-есть оно как бы даже может работать. Но...
1) кто и какие ГАРАНТИИ даст что и как компилер будет со стэком в промежутке между его установкой и фактическим вызовом вон той штуки делать?
2) чисто технически тот же gcc имеет право что-нибудь пушить в стэк что ему там угодно и когда угодно, обратное хоть как-то верно только для naked функций, которые, барабанная дробь, по задумке пишутся на ассемблере. мне теперь что, отныне и во веки веков листинги за ним разгребать? Это основано на чтении документации GCC, которой я предпочитаю доверять.
3) флаги компила и версии компилеров - не мировая константа, мне теперь при каждом их изменении проверять что он там сгенерит? А если еще LTO какое привинтить, оно точно всегда и везде правильно отвзаимодействует?
4) И, кстати, вот это - my_app() случайно не стрескает сколько-то стэка на потенциально-возможный возврат в Boot()? Вообще совсем ни на что? Потому что возврата как бы не будет, фирмавре заведомо некуда возвращаться. Или что в этом месте компилеру не даст в стэк что-то запушить? Может оптимизатор и заметит, конечно. Но гарантии - какие? Постоянное чтение кода за компилером?
5) __set_MSP((*(volatile uint32_t *)adr)); конечно здорово, но то что вы асм в интринсик "перепрятали" вовсе не означает что вы вообще можете __set_MSP() (или его эквивалент) на вот именно сях накатать. Ну вот не умеет си доступаться в регистры которые не mem-mapped. Так что __set_MSP унутрях написан скорее всего на асме.
А написав такое на асме я 100% уверен что оно всегда сработает ровно так как задумано, покуда gcc свой асмовый синтаксис вообще жрет. И стэк отдается ровно в том же виде как это железо сделало бы, SP выставлен на именно это значение, а не плюс-минус лапоть из-за вызова функции. Ну, потому что mov PC, ... - стэка вообще совсем не требует, в отличие от вызова функции в си, и в этом я на 100% уверен, в отличие от упования на то что (не) сгенерит компилятор которое не основано вообще совсем ни на чем. Никакими стандартами и документами это поведение не регламентировано, а UB мне и без этого хватит.
iddqd, как страшно жить в мире, где компиляторы делают что захотят. У меня всё как-то то что я им укажу.
[uquote="iddqd",url="/forum/viewtopic.php?p=3929334#p3929334"]4) И, кстати, вот это - my_app() случайно не стрескает сколько-то стэка на потенциально-возможный возврат в Boot()?[/uquote]Вы вроде хвастались знанием ассемблера, листинги я выложил.
[uquote="iddqd",url="/forum/viewtopic.php?p=3929334#p3929334"]5) __set_MSP((*(volatile uint32_t *)adr)); конечно здорово, но то что вы асм в интринсик "перепрятали" вовсе не означает что вы вообще можете __set_MSP() (или его эквивалент) на вот именно сях накатать. Ну вот не умеет си доступаться в регистры которые не mem-mapped. Так что __set_MSP унутрях написан скорее всего на асме.[/uquote]А чего гадать то? Можно посмотреть определение. В GCC и Keil это действительно ассемблераная вставка
// В IAR
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
#define __arm_wsr __iar_builtin_wsr
__ATTRIBUTES void __iar_builtin_wsr(__sys_reg special_register, unsigned int value);
#define __ATTRIBUTES __intrinsic __nounwind
Но это, вообще говоря, не принципиально. Я пишу на С/С++ и не вижу этих подстановок. Файлов на асме в проекте нет, транслятор асма в принципе не запускается. Работает так как заявлено. Что ещё для счастья надо?
Листинги это прекрасно. И я вроде согласился что в конкретном случае - прокатило. Однако, я со своей стороны считаю что в C и так дофига undefined behavior, чтобы еще мины замедленного действия раскладывать в местах идентифицированных как таковые после чтения док на компилер и стандарты.
Насчет ассемблера - чел спросил где я его использую. Я сказал. Вы сказали что это батхед. Я позволил себе не согласиться. И даже заметил что ваш код не является гарантированно корректным, он уповает на конкретное поведение компилера и оптимизатора, которое никто никому нигде никогда вообще не обещал. Т.е. образцовый UB, неизвестно зачем. Если там компилятор сделает что-то другое - он в своем праве! О чем в документации GCC даже написано. А то что в каком-то конкретном случае прокатило - ничего не говорит сработает ли этот трюк завтра, с другим компилером или его версиями, оптимизациями, и проч. Чем UB и плох - может даже работать как надо в конкретной ситуации но однажды вылезет очень неприятное открытие.
Читать листинги после каждого компила мне все же не хочется, это убивает половину смысла использования си. Поэтому я предпочитаю вариант когда я могу быть более-менее уверен в корректности кода без настолько дотошного изучения кода и гадания кто кого обдурит в этот раз - я компилера или он - меня.
Насчет интринсика в iar прикольно, перепрятали даже дважды - и все-равно это не есть стандартные сишные конструкции. А занимать позу страуса - мол, это кто-то другой накодил - я как-то не хочу. И вообще не понимаю почему бы мне должно быть принципиально нельзя самому подобный "интринсик" накодить, если это что-то дает. Другое дело что все подряд на ассемблере я выписывать все же не стану, это получится разлапистый и малочитаемый код. Если кто-то считает иначе, он в своем праве попробовать.