Очень интересно, чем не угодили разработчики. Так-то, упоминаемый Кулибин как раз был в современном понимании разработчиком; а кто под разработчиком понимается тут?
Собственно, самое простое определение инженера/разработчика - это человек, результат труда которого можно потрогать; ну там, фен, стиральную машину, телевизор. Программист - не инженер, хотя их почему-то часто так называют. Хотя, конечно, способности к инженерии и программированию могут уживаться в одном человеке. Как правило, это характерно для специалистов по встроенным системам. Девопс, естесственно, тем более не инженер, если только это не "девопс" АСУТП.
В прочем, я уже давно в курсе, что инженеры - это люди, о которых мало что знают. Пожалуй, мы видим очередное подтверждение этого факта. Впрочем хорошо, что само понятие идет в массы.
ШИМ же позволяет сделать так чтобы светодиод не успевал сгореть от превышения тока.
Подход, достойный Ардуино. :)))
Нет. Нормальная схема должна гарантированно обеспечить штатный режим. Так что в данном случае резистор - самый адекватный выход. Городить что-то более серьезное смысла тут нет.
я единственный, кто последовательно, логично и с примерами отстаивает свою позицию.
Переход на аргументы ad hominem плохо сочетается с перечисленными добродетелями. :)
Вы правда хотите какой-то программой исправить вышеозначенные косяки аппаратуры, на которой эта же программа и исполняется?
В реальном мире никогда не будет идеальных условий эксплуатации — просто примите это. Причем чем специфичнее применение, тем условия, как правило, тяжелее. И программа, по-возможности, должна если и не спасать положение целиком, то хотя бы минимизировать финальный ущерб. Это достигается не только программными средствами, конечно; критичные функции всегда защищаются аппаратно, насколько это возможно.
Кстати, от выбивания битов в памяти не имунна полностью и «правильная» по вашему мнению элементная база. Да, в технологии с диэлектрическими подложками тиристорного эффекта не будет, но вероятность повреждения памяти заряженными частицами все равно есть. Предлагаете делать на лампах? Вот они да, 100% защищены от всех эффектов.
Сразу скажу, что свинцовая или какая-то другая защита не спасет. Попадание частицы с космическим уровнем энергии в материал вызывает лавину вторичных частиц, что усугубляет проблему. Как видите, есть много нюансов.
Жизнь сложна и многообразна; защищаться воплями «ЭТО НАРУШЕНИЕ ПРАВИЛ ЭКСПЛУАТАЦИИ ВЫ САМИ ВИНОВАТЫ!!!1111» — так себе вариант. Надо предполагать работу аппаратуры и в нештатных условиях. В том числе и не предусмотренных ТЗ, но вероятных, в том числе и в результате возможного раздолбайства.
Вы таки продемонстрируете код?
Эээ, вам написать switch, в котором в блоке default осуществляется вызов обработчика ошибки?
Ну, если человеку (не вам лично, я вообще) кажется хардкором отсутствие динамического выделения памяти — значит он очень далек от эмбеда. :)
Статическое объявление всего — вообще первая особенность программирования под железо. Во-первых, в 90% случаев отсутствует ОС, так что по умолчанию следить за памятью нечему, а реализации менеджера памяти в стандартной библиотеке не слишком оптимальны. При этом действительно хорошая реализация malloc() может занимать места столько же, сколько вся программа.
Ну и я уже не говорю о том, что выделение памяти, действительно, недетерминированная операция; нет никакой гарантии, что в нужный момент окажется доступным нужный объем памяти.
Да вот только правило говорит нам, что следует всегда использовать default.
Лучше перебдеть.
Действительно не поверю. Если программа гадит не пойми куда ...
Хехе, сразу видно программиста не-железячника.
Программа тут не при чем. Может прилететь частица и изменить бит в памяти (нормальная ситуация для аппаратуры на спутниках), может случиться скачок/просадка напряжения и повредить участок FLASH/EEPROM (например, если BOD настроен неверно и запись в NVM прошла при нештатном напряжении) или область RAM, может быть повреждена линия к внешней микросхеме памяти, и еще куча вариантов.
Только при чём тут default?
Это самый простой способ отловить неожиданное значение.
Иногда бывает полезно иметь скриптовый язык в устройстве, особенно когда стоит задача дать пользователю возможность слегка модифицировать логику работы, но при этом не дать натворить непоправимого.
Lua кстати — самый шустрый и легковесный вариант для таких случаев. По работе делал примерно то же самое, что описано в статье, для местного испытательного комплекса. Только у нас там еще и самописный WEB-сервер (сеть через Ethernet). Все вместе занимает 144380 байт во флеше STM32F429 (FreeRTOS + драйвера + Lua + стек TCP/IP + WEB-сервер).
Какой чудесный комментарий. :) Ну да, мало кто помнит, как работают структуры и указатели. Нынче людям интереснее разбираться с синглтонами и прочими модными штуками. :)
А теперь внимательно-внимательно посмотрите, что делает каждая запись.
Эти записи пишут в одно и то же место. Только одна использует инструкцию записи слова, а другая — байта.
Во второй записи происходит следующее: мы берем адрес регистра (потому что структура отображается непосредственно на область памяти, которую занимает модуль SPI), приводим его к типу указателя на uint8_t и разыменовываем обратно.
В первом случае мы пишем просто в регистр, который в структуре объявлен как uint16_t.
Потому что может быть случай, когда человек хотел сделать именно так. Может это какой-то хитрый регистр, обращение к которому по такому правилу вызывает определенный эффект?
Скажем, в STM32F0 модуль SPI устроен так, что обращения
SPIx->DR = byte;
и
*((uint8_t *)(&(SPIx->DR))) = byte;
вызывают разный аппаратный эффект. Внезапно, да?
Вообще, корректно работать с указателями на уровне рефлекса — первое, чему должен научиться разработчик встроенных систем.
мне тоже приходятся байтики ворочать, просто их обычно в районе 10-100 миллиардов, и они все в памяти, и мне надо уметь быстро по ним отвечать на запросы, или что-то матрично-машинно-обучательное воротить.
При этом количество памяти измеряется сотнями гигабайт, частоты процессоров — гигагерцами, а их количество — сотнями? Тогда ваша позиция неудивительна.
Поймите меня верно, я совершенно не подвергаю сомнению ваш опыт в обработке больших массивов данных, но, поверьте, контроллер микроволновки программируется совсем по-другому, и тут навыки в описываемой области так же бесполезны, как и мои навыки в программировании контроллеров бесполезны применительно к big data.
Гхм, эээ, простите. :) Просто я в восторге — вот так и надо писать статьи и учебники. Отличный пример хорошей подачи материала. Я очень надеюсь, что такой стиль будет распространяться и вытеснять из практики преподавания нынешний академический стиль.
Очень интересно, чем не угодили разработчики. Так-то, упоминаемый Кулибин как раз был в современном понимании разработчиком; а кто под разработчиком понимается тут?
Собственно, самое простое определение инженера/разработчика - это человек, результат труда которого можно потрогать; ну там, фен, стиральную машину, телевизор. Программист - не инженер, хотя их почему-то часто так называют. Хотя, конечно, способности к инженерии и программированию могут уживаться в одном человеке. Как правило, это характерно для специалистов по встроенным системам. Девопс, естесственно, тем более не инженер, если только это не "девопс" АСУТП.
В прочем, я уже давно в курсе, что инженеры - это люди, о которых мало что знают. Пожалуй, мы видим очередное подтверждение этого факта. Впрочем хорошо, что само понятие идет в массы.
Ооо! Ооо! Распаковать что ли свои запасы ATtiny10... Страшно сказать, я их лет пять назад покупал поиграться, и вот все никак руки пока не дошли...
Зато я в рамках работы применял "новые" серии, ATtiny2xx. Очень приятные чипы, мне понравились.
Подход, достойный Ардуино. :)))
Нет. Нормальная схема должна гарантированно обеспечить штатный режим. Так что в данном случае резистор - самый адекватный выход. Городить что-то более серьезное смысла тут нет.
А версия AVR-GCC, которую вы использовали, уже научилась не копировать константы в RAM при таком их объявлении?
Классически, чтобы читать константы из FLASH, не копируя их в RAM, надо было использовать avr/pgmspace.h и макрос PROGMEM.
Или вы сознательно решили пожертвовать частью RAM, чтобы не тратить FLASH на код загрузки из FLASH (pgm_read_xxx)?
Пробовать отладочные платы надо с осциллографом на столе и макеткой рядом, а то и паяльником в руках.
Кстати, если вы так настаиваете, я тоже перейду на личности и спрошу — а вы сами далеко ушли от Arduino? Похоже нет.
То, что наличие дополнительной обработки ошибок лучше, чем ее отсутствие, не очевидно?
Переход на аргументы ad hominem плохо сочетается с перечисленными добродетелями. :)
В реальном мире никогда не будет идеальных условий эксплуатации — просто примите это. Причем чем специфичнее применение, тем условия, как правило, тяжелее. И программа, по-возможности, должна если и не спасать положение целиком, то хотя бы минимизировать финальный ущерб. Это достигается не только программными средствами, конечно; критичные функции всегда защищаются аппаратно, насколько это возможно.
Кстати, от выбивания битов в памяти не имунна полностью и «правильная» по вашему мнению элементная база. Да, в технологии с диэлектрическими подложками тиристорного эффекта не будет, но вероятность повреждения памяти заряженными частицами все равно есть. Предлагаете делать на лампах? Вот они да, 100% защищены от всех эффектов.
Сразу скажу, что свинцовая или какая-то другая защита не спасет. Попадание частицы с космическим уровнем энергии в материал вызывает лавину вторичных частиц, что усугубляет проблему. Как видите, есть много нюансов.
Жизнь сложна и многообразна; защищаться воплями «ЭТО НАРУШЕНИЕ ПРАВИЛ ЭКСПЛУАТАЦИИ ВЫ САМИ ВИНОВАТЫ!!!1111» — так себе вариант. Надо предполагать работу аппаратуры и в нештатных условиях. В том числе и не предусмотренных ТЗ, но вероятных, в том числе и в результате возможного раздолбайства.
Эээ, вам написать switch, в котором в блоке default осуществляется вызов обработчика ошибки?
Статическое объявление всего — вообще первая особенность программирования под железо. Во-первых, в 90% случаев отсутствует ОС, так что по умолчанию следить за памятью нечему, а реализации менеджера памяти в стандартной библиотеке не слишком оптимальны. При этом действительно хорошая реализация malloc() может занимать места столько же, сколько вся программа.
Ну и я уже не говорю о том, что выделение памяти, действительно, недетерминированная операция; нет никакой гарантии, что в нужный момент окажется доступным нужный объем памяти.
Лучше перебдеть.
Хехе, сразу видно программиста не-железячника.
Программа тут не при чем. Может прилететь частица и изменить бит в памяти (нормальная ситуация для аппаратуры на спутниках), может случиться скачок/просадка напряжения и повредить участок FLASH/EEPROM (например, если BOD настроен неверно и запись в NVM прошла при нештатном напряжении) или область RAM, может быть повреждена линия к внешней микросхеме памяти, и еще куча вариантов.
Это самый простой способ отловить неожиданное значение.
2. Память контроллера, не поверите, может быть испорчена в рантайме. Или даже не память — некорректное значение может прийти через USART, например.
Вкратце: не всегда switch делается по членам enum'а.
Склоняюсь к тому, что это просто дело вкуса. Но лично мне в темной теме сложнее сфокусироваться на нужных элементах, и вообще глаз хуже адаптируется.
В тех системах, с которыми работаю я, MPU обычно нет. :)
Может тогда уж лучше TCL? :)
Lua кстати — самый шустрый и легковесный вариант для таких случаев. По работе делал примерно то же самое, что описано в статье, для местного испытательного комплекса. Только у нас там еще и самописный WEB-сервер (сеть через Ethernet). Все вместе занимает 144380 байт во флеше STM32F429 (FreeRTOS + драйвера + Lua + стек TCP/IP + WEB-сервер).
А теперь внимательно-внимательно посмотрите, что делает каждая запись.
Эти записи пишут в одно и то же место. Только одна использует инструкцию записи слова, а другая — байта.
Во второй записи происходит следующее: мы берем адрес регистра (потому что структура отображается непосредственно на область памяти, которую занимает модуль SPI), приводим его к типу указателя на uint8_t и разыменовываем обратно.
В первом случае мы пишем просто в регистр, который в структуре объявлен как uint16_t.
Потому что может быть случай, когда человек хотел сделать именно так. Может это какой-то хитрый регистр, обращение к которому по такому правилу вызывает определенный эффект?
Скажем, в STM32F0 модуль SPI устроен так, что обращения
SPIx->DR = byte;
и
*((uint8_t *)(&(SPIx->DR))) = byte;
вызывают разный аппаратный эффект. Внезапно, да?
Вообще, корректно работать с указателями на уровне рефлекса — первое, чему должен научиться разработчик встроенных систем.
При этом количество памяти измеряется сотнями гигабайт, частоты процессоров — гигагерцами, а их количество — сотнями? Тогда ваша позиция неудивительна.
Поймите меня верно, я совершенно не подвергаю сомнению ваш опыт в обработке больших массивов данных, но, поверьте, контроллер микроволновки программируется совсем по-другому, и тут навыки в описываемой области так же бесполезны, как и мои навыки в программировании контроллеров бесполезны применительно к big data.
ААААААААА!!!!11111
Гхм, эээ, простите. :) Просто я в восторге — вот так и надо писать статьи и учебники. Отличный пример хорошей подачи материала. Я очень надеюсь, что такой стиль будет распространяться и вытеснять из практики преподавания нынешний академический стиль.