Комментарии 165
1. У нас есть цифры — это 1, 2, 3, 4 и так далее.
2. 2+2=4 Это очень просто, не правда ли?
3. Как очевидно, 6!=720, а lg500=2.699 (что такое! и lg — обычно не объясняется)
4. Теперь, зная все вышеизложенное вы легко решите (тут идет какое-нить монструозное уравнение в 4 этажа с интегралами, логарифмами, степенями и комплексными значениями).
5. Урок окончен. В следующем уроке мы рассмотрим решение дифференциальных уравнений в 18-мерном неевклидовом пространстве.
Примерно так же и тут — начали с регистров, перешли на устройство ОС, а закончили командной строкой линукса — это очень просто, не правда ли?
Вот именно поэтому я так и не научился программировать МК, хотя много раз начинал — всегда застреваешь где-то между «2+2=4» и «что такое логарифм», не говоря уже о том, что получить готовый результат из рассыпухи выходит быстрее, чем вкуривать все это.
Академический — это постепенное разжёвывание знаний, при котором хоть к какой-то реальной практике на живом микроконтроллере можно перейти через полгода, а до того мы будем на транзисторах и 2И-НЕ работу GPIO и ALU моделировать.
Практический предполагает, что у каждого занятия есть, собственно, практический результат.
В нашем случае академический подход не подходит (извиняюсь) в принципе, так как а) всего семь занятий, б) каждое занятие представляет собой пару лекция + лаборатория и в) студенты — с разных направлений и с разным объёмом знаний, есть и электронщики, и программисты, и даже как минимум один человек, который свободно пишет на SPL, но не знаком с RTOS, etc. Если в этой ситуации долго и планомерно давать всю теорию, начиная с азов — у нас через неделю из 40+ студентов останется 20-.
Кроме того, по моему глубокому убеждению, в практических дисциплинах (а программирование микроконтроллеров — ни разу не фундаментальная) достаточно указать направление движения и ориентиры на этом пути, а уж чего-чего, а недостатка детальной информации для желающих её получить в онлайне в наше время избыток.
— Глюк в простой функции? Открываем скомпилированный код на ассемблере, медленно раскуриваем. Поначалу непонятно и страшно, зато потом можно горы сворачивать.
— Непонятно, как работает какая-то функция? Лезем в ее исходник, внимательно читаем.
— Как работать с регистром? Лезем в даташит, ищем. Не нашли? Ищем еще раз, внимательнее. Проблемы с английским? Открываем google translate, переводим.
И в итоге умение решать простые проблемы оказывается гораздо важнее, чем помнить архитектуру конкретного камня или количество памяти на борту.
Прочитайте "Цифровая схемотехника и архитектура компьютера". Вам будет куда более понятно, что происходит, начиная от транзисторов и заканчивая кодом на С.
В этом же курсе как минимум умение писать на C для «больших» систем предполагается изначально.
поэтому я так и не научился программировать МК, хотя много раз начинал — всегда застреваешь где-то между «2+2=4» и «что такое логарифм»
Скорее всего, вам уже просто слишком много лет.
Не соглашусь с вами. Молодые люди вообще в основном форменные идиоты. И когда писанина кода выходит за рамки языков высокого уровня — начинается нытьё. Никто ничего не хочет искать и учить… Разбираться в коде? Отлаживать код? Оптимизировать? Этим занимается "старая гвардия", те, кто ещё помнит, как в малые ресурсы уместить большие данные. Научиться может и 50 летний. Просто люди после 30-40 вообще мало учатся. А те, кто постоянно изучает что-то новое, молодым фору дать могут.
на самом деле, тяжело учиться кататься на коньках, если ты ни разу не видел ни коньков, ни льда…
попробуйте начать с «программирования вообще», а затем уже переползать на МК. Может, стоит попробовать на «презренной ардуине» — помигать светодиодом, подрыгать ногой, попищать пьезиком, поиграться с АЦП и ШИМом… Чтоб без RTOS, только МК и ваша программа…
Могу лишь посоветовать довести какой-нибудь проект до конца «через немогу» и через пинки нормального советчика-«учителя». А «примеры в интернете» — ну так на каждый случай жизни их не напасешься. но как вариант — взять готовый проект, и основываясь на готовой схеме — попытаться написать программу, «подглядывая одним глазом» в готовый результат.
Тут как езда на велосипеде — научившись один раз, трудно разучиться обратно. (хотя МК, в отличие от велосипедов, много разных, и порой сильно отличающихся друг от друга)
Ну почему же нельзя, DMA есть для АЦП. Вы же задаете вопрос "почему нельзя что то умножать, когда уже идет умножение" Через DMA ваши данные из АЦП прекрасно отправятся в память без вмешательства АЛУ процессора. Ну а именно "читать" придется потом, если мы обсуждаем одноядерные МК
Если вы будете и дальше кидаться между всеми тремя областями в пределах одного вечера, причём надеясь найти быстрый ответ в интернете, да ещё и сразу по всем трём, и чтобы с пошаговой инструкцией, у вас и дальше ничего не будет получаться.
«Невозможно делать несколько операций параллельно» не имеет никакого особенного отношения к микроконтроллерам — абсолютное большинство языков программирования, которыми пользуются на больших ПК, точно так же не имеют встроенных средств организации многопоточности. Возьмите банальный Delphi, напишите на нём приложение так, как вы его сейчас пишете для MCU — и на Core i7 на три гигагерца у вас в нём кнопки нажиматься не будут, пока оно внутри что-нибудь перемножает.
Точно так же работа с аналоговыми сигналами и АЦП не имеет никакого особо прямого отношения к микроконтроллеру. Взяв внешний АЦП, вы можете совершенно спокойно прострелить себе ногу несколькими разными способами. Собственно, даже с тупой как пробка ICL7135 у вас есть отличный получить чушь вместо измерений, если не вдумываться, что, как и зачем вы измеряете.
Соответственно, надо знать и схемотехнику поскольку у вас есть и аналоговый сигнал. На практике, вы уже набили шишку с влиянием ядра на АЦП, и больше такую не сделаете. Но тут в принципе и другой выход мог быть — «шум» можно было победить математически усреднением методом скользящего окна(обычное усреднение в данном случае неэффективно) — ведь результат нам не нужен слишком быстро — человек всеравно не воспримет мельтешение цифр чаще чем 1/10 секунды а АЦП за это время может сделать 1000 измерений. В аналоговой части этого АЦП нужен фильтр НЧ высокого порядка на частоту найквиста — НЕ БОЛЕЕ 5кГц(для данных услоовий), а лучше всего ближе к характеристикам измеряемого сигнала вплоть до 100Гц и меньше иначе у вас пролезет другая проблема если в измеряемом сигнале есть ВЧ составляющая.
ну и как всегда есть два пути — «сверху вниз», и «снизу вверх»
«Сверху вниз» — это, грубо говоря, «ардуина». система, где от тебя скрыта бОльшая часть реализации, уровень абстракции весьма высок, и вполне может страдать качество (впрочем, может и не страдать). И постепенно можно углубляться в детали реализации, изменять (возможно, отказываясь от типовых библиотек, например) и переходить на осмысленное управление железом.
«снизу вверх» — это изучать ассемблер и дерганье ножками (а иногда на первом этапе еще и переходят от рассыпухи к МК), затем собирать это все в макросы и библиотеки, подниматься до ЯВУ и библиотек.
все зависит от целей и задач. для обучения предпочитают идти снизу — зная устройство абстрактного железа, и какой-нибудь ассемблер — проще будет осваивать конкретное железо. для практического освоения — чаще выгоден путь сверху (хотя некоторые знания среднего уровня тоже бывают нужны, но это «частности», зависящие от проекта)
Снизу вверх — у вопрошающего проблема — не видит работающего железа за уровнями абстракций, а вот МК-61 в регистрах программировал, значит надо идти снизу вверх, от простого к сложному. Да и ассемблеры все похожи ;) Переносить принципы с одного типа на другой — легко, когда принципы понятны. А за абстрагированием мелочи теряются, для работы полезно — скорость, для обучения — не очень.
«по таблицам опкодов» — ну а почему бы и нет? чтоб задумались, попытались найти в опкодах логику. я уже рассказывал про товарища, который в армии по памяти (опираясь, естественно, на логику), восстановил таблицу команд 80-го проца, и дизассемблировал вручную бейсик из журнала Радио (для Радио-Микро80), отсылая получившийся текст письмами домой… так что это весьма неплохой способ изучения.
И запускали мы, кстати, перекомпилированный бейсик на СПМ-80 (ну, это почти тот же УМК, только больше для отладки «железа»), «Система Проектирования Микропроцессорных устройств для 80 процессора».
А на ассемблер мы «спустились» с фортрана…
то, что половина группы не знает про хекс — так это либо вина учебного плана, либо преподов (ну, если они объясняли, а пол-группы не поняло — вина этой половины группы). но никак не советского проца или эмулятора. Нет компиляторов — прекрасно: вот вам и задача. хороший курсовой для 3 курса.
Кстати для Z80 было два ассембера — один изначальный отражающий суть системы команд и другой адаптированный под стандарты из которого нельзя понять что происходит т.к. команды LD и MOV не различались и была только одна команда MOV… типа, меньше разных слов быстрее студенты язык выучат? Довелось мне пообщаться с этой самой УМК, ну так игрушка. Лабораторку сделал за 15 минут из двух часов, но остальные 28 человек из класса парились до конца так и не поняв что к чему. Всёравно потом списывали.
УМК — ну, а чего там волшебного ожидать? 580-й с обвязкой, 55й в/в. пару килобайт памяти. для обучения достаточно.
у нас еще были аналоги на 584 серии (это секционники).
а вот под 51/48 мы уже делали комплекс на Корветах (нечто отдаленно похожее на то, что потом назовут IDE -редактор, ассемблер, эмулятор-отладчик, эмулятор ПЗУ)
Программисты бы возмутились, если им фортран преподавали до сих пор, они и паскалю с бейсиком не рады, и даже против си в учебных целях. Мы тоже современные технологии хотим!
Сам язык — дело далеко не первое. вон, сыну на первом курсе жаву и си читают. и толку? да они русским языком алгоритм описать не могут. именно этому надо учить. а уж дальше — конкретный инструментарий изучается достаточно быстро.
«организовать» :-) читаем даташит — нет SPI. Нет — значит НЕТ!
:-)))
вы ж SPI, I2C, ADC, таймеры в даташите на STM32F103 видите? видите… значит, там они есть. а в 8080 — нет.
но если серьезно, то 580 процессор и 580 комплект — совершенно разные вещи, совершенно разный подход и т.п. И сравнивать с микроконтроллерами их, имхо, не стоит. Хотя для учебных целей 580 вполне может подойти (а может и не подойти — смотря на кого учат)
В первом случае мы получаем уже готовую систему изменить конфигурацию которой мы не можем, но там как правило периферии больше чем нужно. Но когда нам надо будет организовать 10 штук UART тогда придётся долго думать КАК это сделать на МК(хотя, наверно есть внешние модули UART но я таких не видел). В случае своей системы мы просто ставим нужное количество микросхем на общую открытую шину и разводим их в адресном пространстве. Конечно, энергопотребление микросхем технологии 30-летней давности и их быстродействие оставляет желать лучшего… но если вопрос обучения там такие вещи не критичны. Заодно это можно совместить со схемотехникой, разработкой необходимой логики(дешифратор адреса, формирование управляющих сигналов) и т.д.
С точки зрения коммерческой практики, конечно, STM контроллер гораздо предпочтительней.
Но когда нам надо будет организовать 10 штук UART тогда придётся долго думать КАК это сделать на МК(хотя, наверно есть внешние модули UART но я таких не видел)
Я не очень понимаю эту логику.
А на 580 нам думать не придётся, там как в ардуине — знай себе на Али шилды заказывай?
Или «долго» — это один запрос в гугль, первой строчкой выдающий «MAX3107 SPI/I²C UART with 128-Word FIFOs»?
И несмотря на то, я б не стал использовать 580 более чем для учебных целей, да и то как частный случай (ага, «страшилку»)
что касается 10 UARTов — дык нонче модно поставить три STM8AL по три UARTа в каждом, запрячь их по SPI/I2C, плюс свой внутреннний- и вуаля. по цене будет не сильно отличаться, а вот по гибкости
Микроконтроллеры мелкие сейчас как грязь стоят.
Но вылезает ещё вопрос разработки и прошивки (в т.ч. в готовых изделиях), поэтому на практике жизнеспособны оба варианта.
хотя я б учил на 51/48 вместо 580 (хоть и древнее — но выпускается, и судя по всему будет долго), чонить атмеловское-микрочиповское, и чонить STM32/LPC. хотя бы «галопом по европам».
ну а интефейсы — отдельно.
Но это опять же курс не для программистов как таковых, а для близких к эмбеддингу (11.03.02 Инфокоммуникационные технологии и системы связи, 11.05.01 Радиоэлектронные системы и комплексы, возможно 11.03.03 Конструирование и технология электронных средств и 27.03.04 Управление в технических системах)
И почему выбрана RIOT OS, а не FreeRTOS?
Наша разработка идёт на RIOT, и в рамках основных занятий в Лаборатории студенты работают с модулями с готовыми прошивками на RIOT.
… вопрос преимущества RIOT перед FreeRTOS не раскрыт…
А дайте ссылочку где можно скачать SPL например для серии STM32L0, ...L4, STM32F7 или STM32H7
А почему сразу не для Microchip или TI? Мы работаем с STM32L1, для STM32L1 SPL существует, официально считается активным и широчайше используется в реальной жизни.
вопрос преимущества RIOT перед FreeRTOS не раскрыт
Первая проблема в том, что FreeRTOS — это вообще не ОС, а только ядро. На которое далее надо ещё навесить BSP, расширения, драйверы и всё прочее, что из ядра делает полноценную ОС.
Кроме того, в рамках учебного курса подходит любая достаточно современная и логично выглядящая ОС. Почему, собственно, это должна быть именно FreeRTOS?
А почему сразу не для Microchip или TI?
это типа «ответ»? (из серии «сам дурак»?)
Почему, собственно, это должна быть именно FreeRTOS?
попробуйте погуглить FreeRTOS & RIOT…
попробуйте погуглить FreeRTOS & RIOT…
У меня они обе на ноутбуке, с которого я пишу этот комментарий, есть, с какой целью мне их «гуглить»?
Если же вы всё-таки хотите почему-то научиться программировать микроконтроллеры, то конкретная RTOS в принципе неважна, а конкретно RIOT удобен тем, что это готовое решение, а не голое ядро, вокруг которого ОС ещё собрать надо.
А относительно FreeRTOS — посмотрите примеры проектов от производителя (STElectronics) с использованием RTOS — они все сделаны на FreeRTOS. Спрашивается зачем «забивать» мозги студенту малопопулярными вещами типа RIOT?
* FreeRTOS — это вообще не RTOS.
* Если вы хотите учить студентов тому, на что больше всего ссылок — то это «менеджер по продажам».
* Обучение в вузе — это не вбивание навыков работы руками на конкретном станке, для этого ПТУ есть.
FreeRTOS — это вообще не RTOS
сочувствую студентам…
Обучение в вузе — это не вбивание навыков работы руками на конкретном станке, для этого ПТУ есть
а разве RIOT — это не «конкретный станок»? (причем еще и малораспостраненный)
narodstream.ru/programmirovanie-mk-stm32
Более того, последнее веяние моды (после того, как HAL, который должен был стать всем тем, чем не стал SPL, получил свою кучу бурчания со стороны пользователей) — это «как с SPL перейти на LL». Я не знаю, в каком мире SPL «давно успешно заменена», но разжёвывания, как наконец с неё перейти на LL, ST по сию пору выпускает.
P.S. В скобках также замечу, что абсолютно никакой проблемы сконфигурировать десяток интерфейсов без CubeMX нет. Неумение это делать — может быть, а проблемы — нет.
В скобках также замечу, что абсолютно никакой проблемы сконфигурировать десяток интерфейсов без CubeMX нет. Неумение это делать — может быть, а проблемы — нет.
Проблема как раз есть — и очень существенная она называется «время-деньги». При проектировании например в корпусе TQFP208 она обязательно всплывет
Вы какими-то словами на русском языке описать можете, в чём конкретно заключается проблема-то ваша и куда уходит больше пятнадцати минут?
Открываете даташит, там таблица «Alternate function input/output», смотрите, на каких ногах может висеть условный USART1, со схемотехником обсуждаете, на каких ногах вам его удобнее повесить, схемотехник идёт вешать, а вы в условном board.h или где там у вас в используемой ОС описывается плата долистываете до секции с USART'ами и вписываете туда условный .tx = GPIO_PIN(PORT_A, 10), .rx = GPIO_PIN(PORT_A, 9).
И?
Где здесь проблема-то?
TQFP208 — это вообще даже головная боль схемотехника в первую очередь, а не программиста. Вот только схемотехник CubeMX использует исключительно как визуальную подсказку, на какие ноги что можно вывести, HAL ему при этом нужен примерно как рыбе зонтик.
головная боль схемотехника в первую очередь, а не программиста
о чем это вы?
я сам лично и схемотехник и программист и сборщик и настройщик и тестировщик и снабженец немножко в одном лице, поэтому про «рыбу, зонтик» это вы рыбам и раскажите
Мы работаем с ОС. В ней всё это уже сделано. 2018 год на дворе, люди не пишут код с нуля каждый раз.
Так зачем Вы выбранный вами путь советуете как истинный? Вы выбрали редкую ОС, редкую spl прослойку… это ваше право. Но "мы так работаем" и курс начинающих разные вещи
То есть я вот понимаю, что, например, в Contiki — там многозадачность с инвалидностью третьей группы, там надо в треде либо без switch-case, либо без сообщений жить. Этому в университете всех учить не надо, кому в жизни не посчастливится — сами научатся.
А в RIOT чего конкретно такого нет, без чего студентов научить работать с микроконтроллерной ОС нельзя?
редкую spl прослойку
Во-первых, если бы вы прочитали текст, под которым оставляете комментарии, вы бы были в курсе, что мы не используем SPL.
Печально, что вы его не прочитали.
Во-вторых, про редкость — процентов проектов под STM32, написанных с HAL, против процента написанных с SPL, сможете привести?
Каюсь, прочитал через слово, извините. Просто я считаю, что МК в наших реалиях сильно тяготеют к электронике, чем к программированию. Уверен, что phyton или java программисту МК — несложно. Но вот чтобы запустить его — понадобятся некоторые знание из хоровица и хила. По процентам не скажу, все что брал с гитхаба — все НАL
Понимаете ли, проблема у программиста МК — она не с тем, чтобы hello world написать.
Она с тем, что там, например, работа с памятью такая, что по сравнению с ней не то что питон — по сравнению с ней C на винде сказкой покажется. Потому что MMU тупо нет, зато есть пятнадцать способов прострелить себе ногу так, что пуля сначала будет пять минут зигзагом летать. И после того, как она таки долетит, вы будете не сегфолт и аккуратный дамп памяти иметь, а какой-нибудь Configurable Fault Status Register, из которого извлечь что-то разумное обычно тупо невозможно.
Что в общем правильно, из всего этого зоопарка LL представляется наиболее разумным балансом между простотой, надёжностью и универсальностью.
Выше описан не только баг, но и его решение, которое добавляет аж целую строчку кода, выполняющуюся… сколько там, пару тактов?
а проблема банально вылезет когда произойдет прерывание в этом месте и задержит исполнение HAL'овского кода
Это, кстати, вообще отличная засада — когда увеличение частоты какого-нибудь постороннего прерывания переводит проблему из гипотетической (т.е. с настолько низкой вероятностью, что если с ней кто-то и встретится, посчитает за случайный глюк, ну мало ли, космический луч пролетел, свет Венеры отразился) в практическую.
А это может быть вообще какая-нибудь обработка GPIO, частота дёргания которого зависит от того, какую железку эксплуатант в разъём на этот раз воткнул.
Если у вас библиотека не thread-safe/interrupt-safe в вашем окружении, то вы можете думать как угодно, но пока вы в неё не залезете руками, она безопасной не станет. Максимум, что вы можете «думать» — это каждый относящийся к ней чих завернуть в многослойную прокладку: запретить вложенные прерывания, запретить тики шедулера в ОС с вытесняющей многозадачностью, etc.
То есть, «думать» вы можете в этой ситуации не «многопоточно», а ровно наоборот.
GPIOA->MODER &= ~(0b11 << (pin_num*2))
Есть макросы Волкова, есть битовые поля, есть те же функции настройки через HAL, они намного удобнее и наделать в них дурацких ошибок не в пример труднее.
GPIOA->MODER &= ~(0b11 << (pin_num*2));и тут же альтернативу
GPIOA->MODER |= 0b01 << (pin_num*2);
BitClear(GPIOA->MODER,(0b11<<(pin_num*2)));
BitSet(GPIOA->MODER,(0b01<<(pin_num*2)));
и следующую альтернативу
GPIOMode(GPIOA,pin_num,0b01);
и следующую альтернативу
GPIOA->MODE.PORT4=OUT;
и объяснить, что все это приведет к (почти) одинаковым командам и показать, к каким именно.
А пусть студенты дальше сами решают, что удобнее и чем пользоваться.
Если да, то зачем вы мне рассказываете, что работать с регистрами напрямую — неудобно?
Одна из причине, почему мы будем работать с RIOT OS и без использования каких-либо средств разработки (IDE) — в получающем в последнее время всё большее распространение магическом мышлении.
Перевернули с ног на голову. IDE — это плохо, будем корячиться в cmd. ОС это хорошо нам же не важно что там внутри МК.
— хз о чем вы, я только умею использовать тип Tasks из <name_os> и программный таймер.
здравствуйте, реализуйте пожалуйста минимальный невытесняющий диспетчер задач для МК, используя только один аппаратный счетчик
— Здравствуйте, у вас отличный невытесняющий диспетчер задач на одном аппаратном счётчике. А теперь реализуйте мне на нём, пожалуйста, парсер протокола вот этих датчиков избыточного давления на Modbus RTU с автоматическим опросом, передачей почасового инкрементального архива с привязкой к реальному времени по радиосети с гарантированной доставкой и имитозащитой сообщений. В смысле — «полгода»? Что вы там полгода делать собрались?!
Говоря короче, не думали ли вы, что задачи и программисты бывают разные, и что не всем, работающим с микроконтроллерами, приходится реализовывать свой невытесняющий диспетчер задач?
То, что вы тут написали вообще непонятно какое отношение к эмбеддед имеет. Вроде курс для начинающих, регистры там всякие. А то, что вы тут написали — это и на пентиуме времени достаточно займет.
это вы так назвали единственный вызов make и ручное редактирование одного Makefile
И вызов MakeFile и какой то дебаг (ну да, он же не нужен), а завтра студент захочет вынести свой модуль в отдельный файл и опять редактируй файлы. Зачем заранее ограничивать людей в инструментах?
И в тоже время: Вот вам абстрактная ОС, зачем вам знать что такое цикл обработки, и программные счетчики?
Я в меньшей мере хочу показать насколько, уж простите, ущербный данный курс. Я пытаюсь у Вас (именно у Вас) спросить — чему вы хотите обучить студентов?
Использование ОС не обучит студентов грамотному подходу к работе с МК и его периферией. Более того, приняв это за догму, они будут отрицать все нормальные подходы.
И тогда: Если работа под ОС на МК не отличается, от обычного прикладного программирования, зачем тогда по сути вобще нужны эти контроллеры? Просто обучайте людей программировать… хотите ножек/светодиодов. Дайте людям Raspberry и обучайте — суть от этого не изменится, знания будут эквивалентны.
По поводу «практичности» (в противовес академичности) вашего курса, мне кажется, куда более лучше научить студентов использовать периферию в связи ADC+DMA, SPI+кольцевые буферы, и все это в контексте вашего МК (L151). Таким образои, они поймут в каких задача и что нужно использовать, а главное ПОЧЕМУ. И вот тогда, венцом вашей работы будет.."… теперь мы подошли к тому моменту, когда у нас 100500 обработчиков аппаратных и программных, куча вложенных прерываний и шанс что мы в этом запутаемся, поэтому давайте ознакомимся с ОС и проблемами которые они решают".
Людям, не нужна как вы выразились практичность, людям нужна доступность, и понимание «зачем это все» (вспомните себя на уроках геометрии/математики в школе), и вот когда они поймут зачем, они без вас смогут это использовать на практике.
ЗЫ. Выше подметили статьи от ДиХальта: посмотрите с чгео он начинает — с проблематики, и только потом решение.
а завтра студент захочет вынести свой модуль в отдельный файл и опять редактируй файлы. Зачем заранее ограничивать людей в инструментах?
Вот ровно за этим.
Чтобы завтра студент знал, что всё, вообще всё, что у него тут происходит — это всего лишь текст в файлах, которые можно редактировать обычным текстовым редактором, а не магия волшебной кнопочки в IDE.
В целом, я никоим образом не говорю что против данных курсов, просто их ценность очень близка к «Курсам программиста/тестировщика за 10 дней в твоем городе».
Даже за 8 занятий, можно очень грамотно изложить материал: в меньшей мере настройка блокнота и make, в большей — целевой материал.
Все же выскажусь. Начинал я, как и многие, с Z80 (ни разу ни микроконтроллер, только принципы те же). Потом появился замечательный AT89c2051, 2 кб флеша и 128 байт озу. Но шить неудобно — паралелльно. Потом глоток воздуха at90s1200 глючный, но вот его последователь 90s2313 уже удобен. Ну а потом поехало, 16 бит фуджитсу, арм7тдми, кортексы 3, 4, 7. Разницы особой нет ни у кого. А для быстрого старта, с учетом того, что молодые с Линуксом знакомы… советую распберри пи. Удобно, знакомые тулзы, вот не предоставляю человека который хорошо управляется с малинкой, но несчастный кортекс3 вводит в ступор
Во-вторых, на последнем занятии показывал студентам, что бывает при переполнении стека.
Когда, например, процедура, вылезшая за границы своего стека в два раза от его размера, совершенно спокойно работает неограниченно долгое время (sic!), но вторая процедура, совершенно не зависящая от первой и запускающаяся в какой-то произвольный момент времени, мгновенно рушит всю систему в хардфолт.
Сможете это в линуксе показать?
Распберри дает навык с gpio (а часто и spi, uart). Этого достаточно, чтобы понять архитектуру любого мк. Чем по вашему распберри отличается от мк? Озу отдельное и флешка. Это мелочи. По большому счету программеру с распберри надо только очень хорошо понять смысл слова volatile. В остальном программирование под МК особенностей не имеет (как бы я этого не хотел, ведь всегда хочется иметь редкую специальность). Другое дело что эмбеддерщики берут свое, когда знают, что в сеансе радиоприема или считывания АЦП надо ядро усыпить, или что резисторы проходные нужны, дабы снизить скорость нарастания фронтов и убрать помехи. Но это с опытом
И я всё ещё жду, как вы на любом линуксе мне покажете распространённейшую проблему с переполнением стека в исполнении микроконтроллера без MMU.
Я это и на пентиуме покажу.
В линуксе? Нет, в линуксе не покажете. Спросите у гугля, что такое Memory Management Unit и зачем он нужен.
Это memory mapped device, он везде такой
Простите, где именно в /sys/class/gpio у вас есть хотя бы маленький шанс увидеть «memory mapped», и на каком конкретно микроконтроллере у вас есть хотя бы маленький шанс увидеть /sys/class/gpio?
Или вы всем рекомендуете из-под линукса с GPIO работать обращениями напрямую по 0x20200000?
Мне кажется что STM32 надо начинать с STM32CubeMX и генерации кода из него. Чтобы абстрагироваться от того как это прописывать в коде, а сосредоточиться на возможностях микроконтроллера.
Чтобы не тратить время на страницу кода только на запуск всего хозяйства, есть ОС, в которой эта страница кода уже написана. Чтобы потом посмотреть, как оно работает внутри — та же ОС значительно удобнее, т.к. SPL/HAL/LL довольно трудны для чтения из-за размазывания на десятки мелких подфункций, а производимый кодогенератором код хуже структурирован, чем код ОС.
Я не ставлю под сомнение что RIOT — возможно хорошая вещь, особенно IoT. И вы сделали большую работу по подготовке презентации этого дела под STM32L1.
Но Cube — это официально поддерживаемая и рекомендуемая ST система. Если рассматривать именно STM32 то несомненно надо начинать со средств от самого разработчика.
(Хороши они или плохи — это уже второй вопрос. Как по мне то Cube — оК. По крайне мере регулярно фиксится и обновляется, в HAL есть какая-то логика. Но это мое IMHO, в такой же степени как ваша оценка HAL в коменте :) )
Если рассматривать именно STM32 то несомненно надо начинать со средств от самого разработчика
Обоснуйте.
В контексте учебного процесса.
Средства от самого разработчика позволяют изучить лучше, чем сторонние средства… что конкретно?
Средства от разработчика обычно оказываются самыми долгоживущими/поддерживаемыми/с наибольшей базой пользователя. Поэтому этот тезис имеет смысл с точки зрения долгосрочной полезности изученного материала. Далеко не везде где используют STM32 вообще слышали от RIOT, а вот от Cube/HAL/SPL слышали (как плохое так и хорошее — но по крайне мере слышали об его существовании).
пс: Если что, это сугубо мое личное мнение, но основанное на 7-и летнем опыте использования STM32 в разных компаниях и четырех разных странах (в том числе и в Самсунге и Корее).
Кроме того, никакой долгосрочной полезности у Cube/HAL/SPL нет, не было и не будет. Это всего лишь инструмент, использованию которого можно обучиться за неделю максимум.
Обоснуйте.
Вот я запущу CubeMX. Настрою ножки, быть может кристалл выбиру тот, что я впаял вместо штатного на китайской борте STM32F103C8T6, настрою ножки, добавлю WatchDog, FreeRTOS да сгенерирую код для «кокоса» или для связки Visual Studio + VisualGDB.
А вот с RIOT мне надо будет разобраться что и на что изменить в конфиге от NucleoF103 (самое близкое что нашел на ГитХаб). Это если мне повезет и конфиги совместимы.
PS: я еще не пробовал портировать RIOT на ширпотреб китайский вроде STM32F103C8T6… может это и не так страшно, но визуальные средства конфигурации не помешали бы.
Как вы относитесь к отмене уроков алгебры в связи с тем, что на калькуляторе считать удобнее?
Что бы натыкать, нужно знать что происходит при каждом «тычке»
Нет, не нужно. И для того, чтобы на автомобиле ездить, про цикл Карно знать не обязательно.
Кроме того, весь код сгенерированный CubeMX открыт — всегда можно посмотреть что конкретно там происходит и в случае чего подправить
Вот только если вы всю жизнь в него только мышкой тыкали — первая встреча с реальным кодом (тем более, с кодом HAL) принесёт вам много удивительных, но не очень приятных моментов.
Нет, не нужно. И вокруг ходят толпы погромистов, которые могут натыкать мышкой в CubeMX и впадают в ступор при виде регистра.
При чём тут вообще ОС? Какая ОС и куда у вас что прячет? В файлы *.c и *.h, что ли?
Что вы вообще несёте?
Для того, чтобы в CubeMX тыцнуть в ножку и сказать, что это будет BUTTON_1 с подтяжкой к питанию, совершенно не требуется знать, что это действие превратится в две страницы кода с записью в полдюжины регистров — а тем более, каких конкретно регистров.
Можете проверить, оно работает.
Во-вторых, сами вы, я полагаю, код HAL смотрели теоретически, если считаете, что его внутреннее нагромождение мелких функций, структур и макросов по наглядности сравнимо с ОС, в которой регистровый код собран в функционально завершённые конструкции.
int pin_num = 2; /* PA2*/
GPIOA->MODER &= ~(0b11 << (pin_num*2)); /* сбросили биты настройки ножки PA2 на всякий случай */
GPIOA->MODER |= 0b01 << (pin_num*2); /* установили биты настройки ножки PA2 в 01 — выход */
GPIOA->ODR |= 1 << pin_num; /* установили ножку PA2 в 1 */
GPIOA->MODER &= ~(0b11 << (pin_num*2)); /* сбросили биты настройки ножки PA2, теперь это вход */
uint32_t pa2_value = GPIOA->IDR & (1 << pin_num); /* прочитали состояние ножки PA2 */
Объясните пожалуйста на пальцах что здесь происходит. Что делают операции смещения (это же они, да?), что за ~, почему 0b11 и 0b01? Почему где то И где то ИЛИ?
Теперь нам надо сбросить указанные биты, т.е. там где мы запишем «1» в маске в регистре бит должен сбросится. Для этого нам надо… сделать операцию «И» (& в выражении) с инверсной(~ символ) маской(там где у нас были до этого 1 стали 0 и наоборот).
Чтобы установить какие-то биты в регистре, нам надо сделать операцию OR с константой в которой установлены только нужные биты в «1».
Вот собственно и весь секрет.
п.с. иногда логика регистров обратная, например, чтобы сбросить признак прерывания(читается как «1» в регистре) нужно в регистр записать «1» в нужный бит. Это должно быть записано в даташите.
Если нельзя биты, то прочитать что было и записать что было с изменениями нельзя?
Типа GPIOA[9:8] <= 2'b01 или GPIOA <= {GPIOA[31:10],2'b01,GPIOA[7:0]}
Есть конечно команды работающие конкретно с битами, но там свои заморочки и их почему-то не используют так широко как хотелось бы. Наверно потому, что изменять отдельный бит порта требуется крайне редко а меняют их обычно группами и часто требуется менять синхронно.
Работать с отдельными группами битов КОНТРОЛЛЕР НЕ УМЕЕТ АППАРАТНО в любом случае работа ведется минимальными порциями по 32 бита, даже если требуется изменить 3 бита затрагиваются все 32 т.к. контроллер умеет оперировать только целыми регистрами. Даже если у вас и получится реализовать что-то вроде GPIOA[9:8] <= 2'b01 то дёргать оно будет всеравно целый 32-битный регистр.
Да, обратите внимание что есть ещё такая логическая операция как XOR — исключающее ИЛИ, которое позволяет инвертировать указанные в маске биты. Многие почему-то забывают про такую операцию и начинают городить сложные конструкции if-then-else.
А для начальной конфигурации, когда мы сами все биты выставляем не проще ли сразу писать все биты (т.е. если мы настраиваем в нескольких местах меняем биты в переменной а в конце фигачим все настройки в один регистр одной записью, без чтения и логических операций с масками, т.е. свалить все сложности на компилятор, чтобы он не делал кучу отдельных команд ассемблера с and, or и константами)?
А какие например проблемы с битовыми операциями бывают?
Для начальной конфигурации — можно и писать сразу целиком одним словом. (такое часто называют «волшебное число», «magic value»). Но гораздо лучше показать, как и откуда это волшебное число берется. все эти операции (int pin_num = 2;GPIOA->MODER &= ~(0b11 << (pin_num*2));) оптимизирующий компилятор вполне вычислит на этапе компиляции.
и помните — вы пишете программу, которую будет читать человек. вот и пишите так, чтобы любой человек понял, что и зачем вы написали.
Цель программирования — не создание программы, а получение результатов вычисления.
Кодирование, увы, само по себе ничего не стоит — существенны результаты!
Помните: программы читаются людьми.
Делайте комментариев больше, чем это кажется необходимым.
Используйте вводные комментарии.
Делайте оглавление в больших программах.
Комментарии должны содержать дополнительную информацию, а не перефразировать программу.
Располагайте комментарии таким образом, чтобы это не делало программу менее наглядной.
Неправильные комментарии хуже, чем их отсутствие.
Делайте пробелы для улучшения читаемости программы.
Используйте имена с подходящей мнемоникой.
При наименовании файлов используйте определенный префикс или суффикс.
Одного оператора в строке достаточно.
Упорядочивайте списки по алфавиту.
Скобки обходятся дешевле, чем ошибки.
Для выявления структуры программы используйте отступы.
Для выявления структуры данных используйте отступы.
2. Проектирование программ.
Большие программы подобны спагетти на тарелке: тянешь с одной стороны — что-то движется с другой.
Хорошее правило — ожидать всегда наихудшего; это относится и к программам.
Я не программирую и наполовину своих возможностей.
Стремитесь к простоте.
Добивайтесь точности при определении задачи.
Выбирайте алгоритм задачи самым тщательным образом.
Выбирайте представление данных, соответствующее задаче.
Используйте в качестве параметров переменные, а не константы.
Создавайте универсальные программы.
Не перепрограммируйте функцию квадратного корня.
Устанавливайте цели проекта заблаговременно и точно.
Сначала напишите программу на естественном языке.
Разрабатывайте тестовые данные заранее.
Прежде, чем начать программировать, разработайте проект.
Исключайте ошибки с самого начала.
Короткие модули предпочтительнее длинных.
Стремитесь к минмиальному использованию операторов GOTO.
Прежде, чем программировать, запишите программу в псевдокодах.
Планируйте возможные изменения в программе.
Начинайте документирование на стадии разработки программы.
Не бойтесь начинать программирование сначала.
3. Эффективность программ.
Отчего у нас никогда нет времени сделать что-либо хорошо, но всегда находится время на переделку.
Высокая эффективность программ снижает расходы по эксплуатации и делает возможным то, что нельзя сделать, если программы неэффективны.
Если программа неправильна, не имеет значения, какова ее эффективность.
Определяйте требования к эффективности программы на стадии проектирования.
Удобочитаемость программы обычно более важна, чем эффективность.
Используйте оптимизирующий компилятор.
Профилируйте ваши программы.
Инициируйте переменные во время компилирования.
Избегайте смешанных типов данных.
Оптимизируйте сначала внутренние циклы.
Используйте для индексации наиболее предпочтительный тип данных.
Группируйте записи в эффективные блоки для ввода-вывода.
Используйте загрузочные модули.
4. Отладка программ.
… Возмездье
Рукой бесстрастной чашу с нашим ядом
Подносит нам же…
Шекспир. Макбет
Одно из затруднений, связанных со скрытыми дефектами программ, заключается в том, что вероятность их проявления возрастает со временем и с расширением масштабов использования программы.
Программа, свободная от ошибок, есть абстрактное теоретическое понятие.
Применяйте отладочный компилятор.
Первым делом проверяйте программу за столом.
Выполняйте эхо-проверку вводимых данных.
Вводите средства отладки как можно раньше.
Контролируйте правдоподобность вводимых данных.
Используйте доступные для вас средства отладки.
Делайте программу правильной с самого начала.
5. Тестирование (испытание) программ.
Тестирование призвано указывать на наличие, а не на отсутствие ошибок.
Дейкстра.
О тестировании необходимо думать на протяжении всего периода разработки программы.
Обходитесь минимальным количеством контрольных примеров.
Учитывая, что исчерпывающее тестирование невозможно, испытывайте программу разумно.
Начинайте тестирование как можно раньше.
Прежде всего проводите ручную проверку.
Старайтесь проверять правильность принципов построения системы на ее простом варианте.
Старайтесь применять тестирование по методу сверху вниз.
В каждом следующем тесте должен использоваться класс данных, отличный от предыдущего.
Испытывайте программу в нормальных, экстремальных и исключительных условиях.
Подготавливайте тестовые данные для проверки каждой ветви алгоритма.
Повторяйте тестирование после каждого случая внесения изменений в программу.
© www.delphikingdom.com/asp/viewitem.asp?catalogid=528
А про просто битовые операции не расскажете?
(вообще, сейчас написать на ассемблере оптимальнее оптимизирующего компилятора весьма сложно. )
что вы хотите узнать про битовые операции — я не совсем понял.
но опять же, чем это поможет? либо у вас номера битов станут «волшебными числами», либо вы все равно станете их вычислять, и в итоге получите то же самое в двойном количестве :-)
Будет одна строчка вместо одной. Или две вместо одной. А вот что такое "аналитически заданные" — я не понимаю… Заданные числом (константой), или заданные выражением? Если константой — упирается в "волшебные числа". Если выражением — то выражений потребуется как минимум не меньше.
xxx[pin_num*2+1:pin_num*2] И это повезёт, если настройки в регистре так равномерно красиво разложены, наверняка бывает и по другому и тут уже без «волшебных таблиц», где хранятся нужные адреса не обойтись и со сдвигами так красиво не получится.
Да, я посмотрел на этот ассемблер — в нем есть работа с битовыми полями, и весьма неплохая.
наверняка бывает и по другому и тут уже без «волшебных таблиц», где хранятся нужные адреса не обойтись и со сдвигами так красиво не получится.
Для конфигурационных регистров (CR) и регистров статуса (SR), в которых лежит куча разнотипных и разноразмерных кусочков, в CMSIS определны константы, соответствующие конкретным битам.
Так что там операции выглядят так примерно (пишу названия наобум):
RCC->CR &= ~RCC_CR_MSIRANGE_Msk;
RCC->CR |= RCC_CR_MSIRANGE_6;
while (!(RCC->SR & RCC_SR_MSIREADY)) {}
А в случае с регистрами GPIO и подобными в ста случаях из ста удобнее использовать сдвиг, т.к. номер нужного бита элементарно вычисляется.
P.S. Бывают ещё случаи, когда настройки одного порта размазаны по двум регистрам, тогда вычисления сложнее, конечно, но тоже возможны.
В совсем клиническом случае они выглядят как-то так (это реальный код из cpu/stm32_common/periph/gpio.c):
/* enable specific pin as exti sources */
SYSCFG->EXTICR[pin_num >> 2] &= ~(0xf << ((pin_num & 0x03) * 4));
SYSCFG->EXTICR[pin_num >> 2] |= (port_num << ((pin_num & 0x03) * 4));
Здесь EXTICR — это несколько регистров, но т.к. они идут один за другим, с ними удобно работать как с массивом, через индексы.
А для начальной конфигурации, когда мы сами все биты выставляем не проще ли сразу писать все биты
Иногда проще. Иногда вы вообще не уверены, как вы в эту начальную конфигурацию пришли (например, из бутлоадера), и потому хотите установить все значения регистра в состояние по умолчанию. А иногда, наоборот, у вас в регистре полтора десятка полей и флагов разного размера, его дефолтное значение отлично от нуля, и вы не хотите заморачиваться с установкой того, что вам сейчас не нужно изменять, чтобы не захламлять код.
и что не менее важно — он формирует привычку к такому стилю. (иначе привыкнете везде числа пихать)
Другое дело, что — возможно — это было нужно объяснить. с другой стороны, в требованиях с студентам вроде как ясно сказано: «знакомых с языком C и базовыми понятиями электроники и электротехники». а вся строка — это как раз базовые понятия языка.
Я, конечно, постараюсь посмотреть запись лекции, чтоб «быть на одной волне», но…
Одной записью в регистр установить всё можно, но не всегда. Это если регистр статический тогда без проблем… А бывает так что надо сделать целый обряд — сначала установить одни биты, подождать и потом установить другие. Как пример можно взять настройку вач-дог таймера из программы. Включить/выключить одной командой его нельзя и сделано это для того чтобы он не дергался от «помех» в момент подачи питания на контроллер. Такая же история с EEPROM — защита от затирания ячейки «случайной» командой записи в момент подачи напряжения когда дешифратор команд находится в неопределённом состоянии.
1)поле настройки (каждой) ноги — 2 бита.
2)0b11 — это слово, в котором установлено только 2 бита
3)pin_num*2 — это на столько позиций нужно сдвинуться от начала слово, чтоб попасть в биты настройки ноги номер pin_num (т.к. см. п.1), остальные позиции нулевые
4) ~(0b11 << (pin_num*2)) — это мы инвертировали наше слово. на месте единичек, стоящих в позиции настройки нужной нам ноги (см. п 3.), оказались нули (на остальных позициях единички)
5) GPIOA->MODER &= — делаем «логическое И» текущего состояния GPIOA->MODER, и аргумента, и результат пишем в GPIOA->MODER. в аргументе у нас слово из единичек кроме двух нулей, стоящих на позиции настройки нужной ноги (см. п.4.). таким образом, в результате мы сбросим два бита на позиции нужной нам ноги, а остальные биты оставим в текущем состоянии.
— GPIOA->MODER |= 0b01 << (pin_num*2) — мы установим «01» на позиции нужной нам ноги.
ну и т.д.
скрыть релизацию можно. но совершенно не обязательно.
но я не вижу ни одной причины, чтоб не объяснять способ настройки. Даже если реализация и скрыта.
А потом эти люди приходят ко мне и рассказывают — реальный случай, и это был ни разу не студент на собеседовании, а практически государев человек, на большой и важной должности — цитирую, «только Arduino позволяет запускать один и тот же код на разных процессорах».
А почему они это рассказывают?
А потому что у них только в Arduino есть менюшка, в которую можно ткнуть мышкой и выбрать процессор.
А что там внутри после тыкания мышкой происходит — ну понятно что, магия. Вам про неё знать не надо, вам надо знать, куда мышкой тыкать.
1) человек знает, что происходит ниже
2) человек не рассуждает о том, что происходит ниже
По факту же мы имеем вокруг всё больше низкоквалифицированных высокомотированных людей, которые не знают, но рассуждают. Если это вчерашний студент, который просто завалит собеседование — это одно, а если это какой-нибудь замдиректора вуза, подписывающий финансирование учебных программ в нём?
Ну, мы будем иметь вуз, в котором на четвёртом курсе учат ардуину, потому что она «уникальна по своим возможностям».
с другой стороны, если выбор между изучением *дуйни, и изучением, как написали выше, УМК на 580м с программированием с пульта в хексе — я проголосую за дуйню.
зы. «Ректор университета просмотрел смету, которую ему принес декан физического факультета, и, вздохнув, сказал:
— Почему это физики всегда требуют такое дорогое оборудование? Вот, например, математики просят лишь деньги на бумагу, карандаши и ластики!
Подумав, добавил:
— а философы, те ещё лучше, им даже ластики не нужны… „©
Собственно, пляшем от этого тезиса.
Нужный адрес у нас задаётся дефайнами в CMSIS, чтобы не вбивать его руками, в примере выше это GPIOA->MODER (GPIOA указывает на базовый адрес блока регистров порта A, а MODER задаёт смещение от него до нужного регистра).
Теперь нам надо поменять в нём третий бит. Мы можем для каждой ножки (биты от 0 до 15) записывать константу с 1 на месте нужного бита, но это громоздко и бессмысленно — проще взять 1 и сдвинуть вправо на нужное число бит: 1 << N.
С местом бита определились, но с одиночным битом у нас могут быть две операции — либо установить его в единицу, либо сбросить в ноль.
Чтобы сбросить один бит в 0, надо провести операцию И с этим битом и нулём — тогда что бы в нём ни было, на выходе будет ноль.
Чтобы установить бит в 1, надо провести операцию ИЛИ с ним и единицей — тогда что бы в нём ни было, на выходе будет ноль.
Чтобы не поменять значение остальных битов в регистре (мы же дёргаем только одну ножку), нужно в первом случае их все поставить в 1 (1 & 1 = 1, 0 & 1 = 0, значение сохранили), а во втором — их все поставить в ноль.
У нас есть полученное сдвигом число 0000 0000 0000 0000 0000 0000 0000 0100. Для ИЛИ (установка третьего бита в 1) мы его применяем как есть, для И его надо инвертировать.
Собственно, вот и получили:
* сброс бита в ноль: GPIOA->MODER &= ~(1 << N)
* установка бита в единицу: GPIOA->MODER |= (1 << N)
С этим всё хорошо, пока у нас бит один — но есть масса настроек, задающихся двумя-тремя-четырьмя битами, часть из которых нам надо поставить в ноль, а часть — в единицу. При этом мы заранее не знаем, в каком значении они сейчас (мало ли кто и где их в другой части программы под себя менял), поэтому сначала их надо привести к известному значению.
Обычно это делают, сбрасывая их в ноль:
REG &= ~(0b111 << N)
Теперь мы знаем, что все три бита точно в нуле, и можно нужные из них установить в 1:
REG |= (0b010 << N)
Собственно, всё.
Дальше случаются всякие нюансы:
* биты, отвечающие за флаги разных событий, устанавливаемых микроконтроллером самостоятельно (аппаратные ошибки, например), часто сбрасываются в 0 записью в них 1
* сброс блока битов в регистре с последующей записью нужного значения не есть атомарная операция, поэтому часто это делают через промежуточную переменную: читают в неё регистр, переставляют нужные битики, а потом одни куском кладут её обратно в регистр
* ну и там уже совсем тонкие нюансы со спецификой синхронизации шин, возможностью немгновенного изменения состояния регистра после записи в него и т.п.
1. RIOT OS ориентирована исключительно на dev-платы? (не нашел никаких упоминаний драйверов периферии в коде, за исключением i2c, uart, adc, причем без DMA, и со стартом на фиксированных частотах без ориентирования на энергопотребление).
2. В комментариях указывается об информации о регистрах из Datasheet`ов. Но ее там нет. Для понимания расположения регистров, их значения, примеров использования в МК STM32 — необходимо читать Reference Manual. Вы считаете данную неточность мелочью, которая начинающим разработчикам никак не помешает?
3. Увидел много кода файловых систем, консоли и прочих не специфичных для МК вещей. Я правильно понимаю, что данная ОС больше ориентирована на то, чтобы сделать из МК полноценный слабенький, но универсальный компьютер, нежели на выполнение заранее заложенных алгоритмов?
Не очень понял, какой периферии вы не нашли в коде. Для L1 поддерживаются GPIO во всех вариантах, ADC, DAC, I2C, SPI, UART, RTC, ШИМ на таймерах, EEPROM. Собственно, из коробки нет только контроллера ЖК и узкоспециального функционала тех же таймеров или компараторов, который применяется не шибко часто.
Что такое «старт на фиксированных частотах»? Динамически менять частоту работы периферии в 999 случаях из 1000 нет вообще никакого смысла, а статическую можно в конфигурации платы задать.
2. Вы считаете, что я обязан реагировать на каждый комментарий, проводя его полный разбор? У меня другое мнение.
3. Чем файловая система не специфична для МК — вы никогда не писали с МК на SD-карту? Что такое «заранее заложенный алгоритм»? Если у устройства есть одна кнопка управления — это заранее заложенный алгоритм или уже нет? А если у него десять кнопок? Сто?
Вот это вот:
«Сегодняшняя лекция — первая, поэтому на ней будут разбираться общие понятия: что такое вообще микроконтроллер и зачем он нужен, что такое прошивка и как она получается, зачем нам нужна операционная система, и наконец — как работать с git. Результат практического занятия — собственный репозитарий на GitHub с исходными кодами ОС, а также успешно настроенная среда сборки на локальном компьютере.»
Как согласутся с:
«Я не буду описывать здесь детали работы с GitHub и Git — в интернете есть масса отличных пошаговых руководств, повторять которые нет смысла.»
???
Так вы бы и написали тогда уж — вот есть фирма ST, она выпускает микроконтроллеры, а вот ещё есть RIOT. Остальное нагуглите сами, лекция окончена.
Впрочем, наивно было с моей стороны чего-то ожидать от МИРЭА.
Ну или что вот там видео висит, можно в него мышкой ткнуть?
Впрочем, вижу, не приходила.
Только негодование, что вам кашицу разжёванную в рот не положили.
И таки вот это: «Результат практического занятия — собственный репозитарий на GitHub с исходными кодами ОС, а также успешно настроенная среда сборки на локальном компьютере.» — это публичная оферта? Или дайте мне это знание или пишите статьи так, чтобы было понятно, что читатель этого не получит.
Выбор RIOT OS может и не очевидный, но правильный в плане того, что это нормальная ОС. На её примере хоть научатся использовать нормальные абстракции.
Отказ от IDE тоже поддерживаю. Любой нормальный сишник сначала должен понимать этапы сборки и сборочные средства типа make, cmake и т.д Дальше пусть уже натсраивает IDE по вкусу.
GPIOA->MODER &= ~(0b11 << (pin_num*2));
Бинарных литералов нет в стандарте Си, плохому лучше не учить.
PS: Буду рад если в будущих лекциях будет больше уделено внимания именно CMSIS. После прихода все возможных библиотек от ST, обучающие ресурсы положили большой болт то на чем STM жили, живут и будут жить. А зря)
Поэтому я надеюсь, что они заранее поймут, что ценность специалиста по закручиванию гаек с левой резьбой — она очень сомнительная независимо от распространённости в мире гаек с левой резьбой.
Если я скажу своему руководителю, а давайте вы будете не в привычном вам кейле а в каком то не понятном редакторе проверять мой код
Если вы придёте ко мне на собеседование и скажете, что работать вы умеете только в Keil, а всё остальное для вас тёмный лес и что там делать, вы не понимаете, то собеседование на этом и закончится.
1) Необязательно прописывать путь к /opt/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/bin, достаточно пути к /opt/gcc-arm-none-eabi-7-2017-q4-major/bin, там лежат симлинки на все, что нужно
2) Необязательно вносить пути для текущей сессии, проще сделать так — сразу сделать экспорт в bashrc, а затем применить эти изменения для нынешней сессии, командой source.
cd /opt
sudo tar xf /mnt/c/Users/vasya/Downloads/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2
echo "export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/:\$PATH" >> ~/.bashrc
source ~/.bashrc
Программирование современных микроконтроллеров: лекция 1