После сдачи на экспертизу сети получаешь разбитый, потерянный, другой телефон. Всё. За свою экспертизу самому платить, экспертов таких нет, на телефоне даже серийника нет, перспективы не ясные (потратить кучу денег и времени и непонятно получить ли хоть что-то обратно).
Потому, что они там собаку съели и каждый день этим занимаются. А ты -- второй раз в жизни.
Но в простых случаях (пока полярный писец не подкрался) им же проще тебе отдать деньги (пока проблемных клиентов -- единицы), чтоб не портить реноме. А когда уже подкрался (массовые возвраты чего-то однотипного), просто не могут иначе, это прямые убытки, если не удастся переложить ответственность на поставщика. И проблема может быть отнюдь не в магазине, а в организации занимающейся гарантийными обязательствами.
Вполне возможно, что рога и копыта, не обладая армией адвокатов, и сдастся быстрей. И нет смысла банкротить фирму если придётся вернуть деньги за два из сотни проданных телефонов.
Только вот нажатия Ctrl-Alt-F2 могут отдаваться, а могут не отдаваться самому линуксу, зависит от настройки иксов (и в некоторых дистрибутивах таки нет никаких консолей). То же самое с Ctrl-Alt-Backspace. А уж Ctrl-Alt-Del и вовсе обрабатывается скринсейвером как обычной программой. Проверяем: открываем xterm, там выбираем "secure keyboard" в меню (Ctrl-LMouse в окне xterm, второй пункт меню сверху). И нажимаем Ctrl-Alt-Del. Ой! В терминале вывелись буковки, скринсейвер не вылез! И до отпускания фокуса и не вылезет, даже по таймауту.
Так вот вражеская программа может нарисовать свой страшный черный экран поверх всего и захватить фокус ввода. Как это делает xterm. После этого xscreensaver даже никогда не запустится (он выведет 50 строк ругани в stderr и вывалится с таймаутом). Далее, после нажатия любой клавиши эта же вражеская программа рисует окно скринсейвера и "вводит пароль". Всё. Пользователь не понимает, с чем он работает, со скринсейвером, или с вражеской программой. У него может сложиться в голове иллюзия не соответствующая действительности. A вражеская программа уже может этот пароль использовать для sudo или чего-то вроде того. Так получили экскалацию привилегий на ровном месте. И почему лучше su без sudo (а пароль в su вводить с опцией "secure keyboard", чтоб другие окна не подслушали).
С консолью можно аналогичный трюк провернуть. Допустим, вы работаете в консоли. У вдруг бах -- и выкинуло из системы и снова логин. И вы ж не понимаете, это настоящий логин или имитация. Да и с ssh можно как-то так же, если пользуетесь паролем, а не ключём (там помимо пароля от ключа ещё и сам ключ стянуть нужно, а он на удалённой машине).
В Kali Linux есть даже специальный инструмент "Fake Logon Screen" для воровства паролей. В виндах. И привычка нажимать Ctrl-Alt-Del перед вводом пароля там защищает. А в линуксе -- без вариантов. Спасает только то, что у всех цветовые темы разные, фиг угадаешь чего там у тебя.
Картошка, лимон, это всё полная чушь, в том смысле, что расходный материал там не карточшка и лимон (они являются электролитом), а расходный материал -- металлы (разные, с одинаковыми ничего не заработает!)
В условиях апокалипсиса, когда вообще ничего нет -- батарею не сделаешь.
Когда остались какие-то разбитые остатки машин и механизмов, содержащих алюминивые конструкции (особенно алюминиевые провода ЛЭП!), то весь алюминий можно перевести на электричество простейшей алюминиево-медной батареей. Нужные компоненты: 1) алюминиевый электрод, 2) медный электрод (первое и второе -- бывшие провода), 3) обычный раствор хлорида натрия (пищевой соли) в воде! Примерно как по ссылке: https://usamodelkina.ru/23618-galvanicheskaja-batareja-med-aljuminij.html
Такая батарея выдает на порядки больше энергии чем поделки из картошки и лимонов. Но алюминивые электроды придётся регулярно заменять. Т.к. фактически выделяется энергия ранее запасённая в алюминии (при его производстве).
Где-то в журнале "Радио" лет 30 тому назад описывалась похожая конструкция, но вроде там один из электродов был угольный и вообще не растворялся. Не уверен. Был бы рад, если бы кто напомнил. Но боюсь медной проволоки найти будет проще, чем заметное количество угля.
Метод, в определённом смысле, широко известный, т.к. массово применяется в микрософтовских API. В частности для строк и где-то ещё.
Если программа взаимодействует с сторонними библиотеками и обменивается с ними объектами, может быть нежданным сюрпризом когда в свой free() приедет чужой указатель, выделенный на стороне (и без такого трюка).
Поэтому, возможно, нет смысла в таком трюке вообще, и нужно просто определить свои стуктуры, где эти деструкторы хранить в явном виде. Хотя да, иногда бывается хочется в неявном...
callback может использовать какие‑то дополнительные значения, поэтому их передаём через указатель resource...
Можно всё вывернуть немного наоборот и получится проще, без опасного "void*", который обычно является источником багов:
typedef struct callback_functor {
void (*callback_fn)(struct callback_fuctor *, void *addr);
/* This structure may be extended... */
} callback_functor_t;
Идея в том, что при необходимости может быть создана другая структура, первым элементом которой будет callback_functor_t (таким образом реализуется "наследование" на C). Затем функция free может вызвать callback_functor_t->callback_fn() с передачей ему указателя на сам callback_functor_t (хранящийся "перед началом" выделенного блока), а внутри коллбэка тип callback_functor_t можно "привести" к типу расширенной структуры с помощью широко известного макроса container_of. Здесь во всей цепочке отсутствует void* (кроме самого указателя на освобождаемую память) и нет практически возможности совместить что-то несовместимое, что привело бы к ошибке.
И это скорей не аналог замыкания, а аналог std::function (фунцкионального объекта), но в сишном стиле.
То, что у вас коллбэки навешиваются после аллокации -- скорей плохо. Это же просто можно забыть сделать. Будет лучше, если бы функция аллокации сразу принимала указатель на коллбэк и его размер, и копировала бы его по значению (в адрес ниже возвращаемого указателя, разумеется выравненный на max_align_t).
Чтоб размер не принимать явно, функция замещающая malloc может быть сделана макросом (внутри которого будет делаться sizeof(*(callback_argument)). Разумеется здесь возникает проблема, что поскольку предполагается расширение типа callback_functor_t другим типом, то собственно типы получаются разные и функция замещающая malloc не может проверить, что ей не подсунули что-то непотребное (либо тип будет приведен к callback_functor_t, но тогда потеряется тип и размер расширенного функтора). Это можно обойти, если договориться, что все взаимозаменяемые типы (унаследованные и базовый) будут содержать специальный именованный член -- пустую структуру, например, первым элементом структуры. Тогда можно передавать ссылку на этот член и легко преобразовывать указатель между разными типами с помощью опять же макроса container_of. Это опять же лучше, чем void*, т.к. совсем уж что угодно присвоить к чему угодно компилятор не позволит, и проверка типов продолжит работать (хотя для программиста появляется возможность сделать ошибку в определении структур, впрочем там сложности никакой и ошибиться тяжело). В данном случае в макросе можно адресовать специальный именованный член стурктуры, чтоб убедиться что стрктура имеет нужный тип (либо там нет такого члена). Это не совсем утиная типизация, т.к. этот самый спец. член всё же может иметь разные типы (пустой структуры, но разные, т.к. ключевое слово struct каждый раз декларирует новый, не совместимый тип) для каждых несовместимых классов объектов. Не знаю понятно ли объяснил, как-то так:
Существенные диэлектрические потери (фактор рассеяния) FR-4 делает его непригодным для высокоскоростных цифровых или высокочастотных аналоговых схем.
Что??? Именно из него и делаются печатные платы абсолютного большинства современных приборов.
Печатные платы для носимых устройств часто должны быть механически гибкими, лёгкими, водонепроницаемыми и ударопрочными. Традиционно они на основе пластика, хотя им обычно не хватает устойчивости и экономический эффективности...
Какой ещё устойчивости? Есть специальные гибкие полимерные материалы, условно акрил и тефлон, из которых может быть изготовлена гибкая печатная плата. Массово, тоннами, на химическом заводе. Это сейчас во внутренностях любого мобильного телефона. Неужели выращивать и сушить грибы проще? Притянуто за уши по-моему. Особенно про устойчивость.
Следовательно сочетание печатных плат на биологической основе и биоразлагаемых компонентов особенно выгодно для носимых устройств...
Скоро всё будет завалено биоразлагаемыми товарами. Которые будут разлагаться сразу после окончания гарантийного срока (http://lib.ru/RUFANT/MUSLIN/42-09.txt)
Надо полагать, в РФ всё это не работает и не будет работать в сколько-нибудь обозримой перспективе. Поэтому разработчики сигнализаций пока не останутся без работы.
Если запахнет жареным -- те и другие будут крутиться как уж на сковородке и в целом с носом останется потребитель.
Был такой аппарат: Toshiba Portege G910. В 2009 году. Они все вышли из строя, многие в течении гарантированного срока. Чем кончилось? Большую часть потребителей морозили 45-дневной экспертизой и отшивали по разным причинам, единицам выдали новый такой же аппарат (который скоро так же вышел из строя), кому-то возможно вернули деньги. Разницы где покупать -- не было, история у всех одна. Не знаю как устроены продажи, но очевидно, у самих продавцов выбить деньги из Тошибы за некачественный товар не очень получалось. А сервис центр вертел всех на одном месте.
На производстве тыкаться осциллографом в каждую плату -- неудобно во-первых, во-вторых долго и дорого, в третьих в сколько-нибудь сложной программе для МК работа внешнего генератора может носить периодический характер (потому, что МК будет "засыпать" вместе с генератором).
И наконец -- осциллограф это не прибор для определения частоты, частоту на нём можно оценить лишь приблизительно. Хотя это действительно не слишком принципиально. И щуп для осциллографа имеет порядочную ёмкостную составляющую, чтоб сбить работу генератора (особенно если забыть про делитель).
Насколько может уйти. В небольшом диапазоне может подстраиваться конденсаторами. Либо может стать сходу в три раза больше/меньше. В случаях повреждения резонатора (достаточно падения об пол) может стать какой угодно. Случаи бывают разные.
В случае перехода на внутреннее тактирование неплохо бы не тихо глючить, а как-то индицировать ошибку. Чтоб сразу было понятно в чём дело, а не трясли в каждом случае разработчика за рукав.
На пару десятков секунд в сутки запросто уходит обычный часовой кварц (не термокомпенсированный, без подстройки), а не RC-цепочка.
В сутках 86400 секунд, и какие-нибудь 5 процентов -- это ЧАС времени, а не 20 секунд.
Точность этой RC-цепочки часто НЕдостаточна для работы с UART во всём температурном диапазоне и хорошо работает лишь на столе, при стандартной температуре. На резонансную частоту этой цепочки влияет не только температура, но и технологическая невозможность получения стабильных характеристик на производстве. И лишь у некоторых контроллеров там то ли какая-то самокалибровка, то ли калибровка лазером на производстве. Не у самых дешёвых.
Вообще возможность подключения часового кварца к МК часто означает возможность отказа от второго высокочастотного резонатора. Можно запуститься с внутренним генератором и периодически подстраивать его работу ориентируясь на часовой кварц. Не для любых применений, но для тех гдe 5% достаточно и где МК позволяет подстраивать частоту HSI -- сгодится.
Вообще замена компонентов на производстве на другой тип (даже с одинаковыми на первый взгляд характеристиками), без разрешения разработчика или заказчика -- ССЗБ. Потому, что после такой замены генератор может запускаться опять же на не своей штатной гармонике просто потому, что важны все составляющие, и ёмкость микроконтроллера, и конденсаторов, и она должна соответствовать выбранному типу резонатора. Просто заменить один 8МГц на другой 8МГц другой фирмы -- может вроде бы и прокатить, но потом на выходе окажется 10% брака, например.
for (uint32_t i = 0; i < 10000; i++){
if(RCC->CR & RCC_CR_HSERDY)
...
Фрагмент кода не очень надёжный в том смысле, что его время выполнения несколько не предсказуемо (неизвестно сколько тактов CPU нужно на итерацию цикла, неизвестно как современные CPU распараллелят инструкции и где будут задержки, всё зависит от опций оптимизации компилятора). Лучше иметь итерацию до достижения таймером заданной величины. А таймер запрограмировать на нужное число тактов в зависимости от текущего выбранного источника тактирования. Генератору с кварцевым резонатором чтоб запуститься нужно от миллисекунд до нескольких десятков миллисекунд (для низкочастотных "часовых" резонаторов на порядок больше). Соответственно таймаут может быть на 100мс, например.
Так как заранее неизвестна частота тактирования низкочастотного резонатора...
Она-то как раз в даташите указывается. С погрешностью порядка 5%, но всё таки известна.
А внешний кварцевый резонатор в особо запущенных случаях запускается на какой-нибудь другой гармонике и частота действительно неизвестна. Это надо сказать типовая неисправность. Она может быть вызвана повреждением резонатора, ошибками монтажа, монтажом неправильных номиналов конденсаторов в цепи резонатора, монтажом не того типа резонатора... И стоило бы хотя бы грубо эту частоту оценить, чтоб принять решение, генератор с внешним резонатором вообще работоспособен или нет.
Обработчики прерывания для всего этого дела -- не нужны. Достаточно в цикле опрашивать специальные регистры. В конце концов, это делается только на старте и процессор в это время ничем другим не занимается.
Определим отношение периодов генератора LSI в тиках HSI к HSE и вернём значение enum, какой частоты генератор подключен...э
Сомнительная техника ввиду сказанного выше: так станет невозможно обнаруживать и сигнализировать о явных неисправностях (например, числом вспышек светодиодика). И не обнаруженная неисправность превращается в куда большую проблему, которую уже должен исследовать инженер (иначе бы ограничилось ремонтом на производстве), и сразу непонятно, программная она или вызвана неправильной работой схемы (потому, что с неправильным кварцем -- "программа глючит", что-то одно работает, что-то другое нет и т.п.)
Поэтому я бы предложил частоту резонатора знать заведомо, или вносить через какой-то механизм конфигурации (путём установки перемычек, путём программирования с компьютера).
В целом представленный программный код изобилует magic numbers в коде. Почему 10000, а не 100500? А если завтра контроллер будет с другой буковкой -- там 10000 ещё нормально, или уже нет? Или почему interruptsCounter == 100? Значит эта сотня где-то ещё закодирована. В code style некоторых компаний чуть ли не вообще запрещают "волшебные числа" в коде. Как минимум -- нужно объявить (через enum или #define в C, через const int в C++) константу и ей пользоваться, самой константе же дать осмысленные имя и комментарий. За исключением нулей, единиц и ряда очевидных констант. Рекомендую следовать такому же стилю.
Есть один очень интересный нюанс, почёрпнутый мною из "Архитектуры современных ОС" Таненбаума, где объяснялось, почему в Windows есть комбинация Ctrl-Alt-Del -- она обрабатывается специально, не как остальные клавиши, и гарантировано выводит на экран специальное меню. И сделано это далеко не совсем просто так, а чтобы избежать ситуации, когда экран блокировки будет нарисован вредоносной программой и пользователь туда введёт свой пароль. А так пользователь нажимает Ctrl-Alt-Del и гарантировано появляется системное меню.
Что характерно, в Linux такого нет... или по крайней мере не повсеместно.
И почему-то мне кажется, что в современных телефонах похожая проблема -- присутствует. Нет однозначного способа убедиться, что содержимое экрана -- меню операционной системы, или стопроцентная подделка. В которой всё точно такое же на первый взгляд. Только некоторые вещи работают немного не так. По крайней мере для андроида устанавливаются же альтернативные "launcher'ы", а выглядеть-то оно может как фирменное меню.
А зачем такой экстеншн, когда есть программы записывающие окно с десктопа. Мне кажется, это несколько более универсально.
Кстати, интересно было бы знать, а как экстеншен работает в ситуации, когда окно браузера скрыто. Свёрнуто или перекрыто другим окном. Ведь по идее тогда само окно, или его часть не обновляется, если там даже что-то и меняется, и записывать нечего. Или браузер в неком своем буфере окна обновляет всегда, просто обновления на уровне X11 или Win32 GDI не делается для свёрнутых окон? В такой ситуации приходилось браузер сажать в Xvfb, чтоб пока с него там картинка записывается можно было с другими программами на компьютере работать. И чтоб можно было несколько браузеров разом запустить.
И со звуком интересно как? Не с микрофона, а из видео в браузере. Если у нас положим десять браузеров и мы с них фильмы хотим сграбить. Опять же приходилось через pulseaudio их растаскивать на разные виртуальные (monitor) девайсы, а с них уже записывать.
И какой из этого вывод? Не использовать полупроводники вообще? Тогда, в первую очередь, откажитесь от бездушных холодных диодов в выпрямителе источника питания. Есть же тёплые и ламповые кенотроны прямого накала...
Суть, повторюсь, не в линейности как таковой, а в количественной её оценке. И для специализированной микросхемы, где в даташите даже приводится THD с двумя нулями после запятой, это ничтожная величина на фоне всего остального усилителя.
После сдачи на экспертизу сети получаешь разбитый, потерянный, другой телефон. Всё. За свою экспертизу самому платить, экспертов таких нет, на телефоне даже серийника нет, перспективы не ясные (потратить кучу денег и времени и непонятно получить ли хоть что-то обратно).
Потому, что они там собаку съели и каждый день этим занимаются. А ты -- второй раз в жизни.
Но в простых случаях (пока полярный писец не подкрался) им же проще тебе отдать деньги (пока проблемных клиентов -- единицы), чтоб не портить реноме. А когда уже подкрался (массовые возвраты чего-то однотипного), просто не могут иначе, это прямые убытки, если не удастся переложить ответственность на поставщика. И проблема может быть отнюдь не в магазине, а в организации занимающейся гарантийными обязательствами.
Вполне возможно, что рога и копыта, не обладая армией адвокатов, и сдастся быстрей. И нет смысла банкротить фирму если придётся вернуть деньги за два из сотни проданных телефонов.
Это для особо умных. А обычные пользователи наверное всё же всё делают через меню.
Только вот нажатия Ctrl-Alt-F2 могут отдаваться, а могут не отдаваться самому линуксу, зависит от настройки иксов (и в некоторых дистрибутивах таки нет никаких консолей). То же самое с Ctrl-Alt-Backspace. А уж Ctrl-Alt-Del и вовсе обрабатывается скринсейвером как обычной программой. Проверяем: открываем xterm, там выбираем "secure keyboard" в меню (Ctrl-LMouse в окне xterm, второй пункт меню сверху). И нажимаем Ctrl-Alt-Del. Ой! В терминале вывелись буковки, скринсейвер не вылез! И до отпускания фокуса и не вылезет, даже по таймауту.
Так вот вражеская программа может нарисовать свой страшный черный экран поверх всего и захватить фокус ввода. Как это делает xterm. После этого xscreensaver даже никогда не запустится (он выведет 50 строк ругани в stderr и вывалится с таймаутом). Далее, после нажатия любой клавиши эта же вражеская программа рисует окно скринсейвера и "вводит пароль". Всё. Пользователь не понимает, с чем он работает, со скринсейвером, или с вражеской программой. У него может сложиться в голове иллюзия не соответствующая действительности. A вражеская программа уже может этот пароль использовать для sudo или чего-то вроде того. Так получили экскалацию привилегий на ровном месте. И почему лучше su без sudo (а пароль в su вводить с опцией "secure keyboard", чтоб другие окна не подслушали).
С консолью можно аналогичный трюк провернуть. Допустим, вы работаете в консоли. У вдруг бах -- и выкинуло из системы и снова логин. И вы ж не понимаете, это настоящий логин или имитация. Да и с ssh можно как-то так же, если пользуетесь паролем, а не ключём (там помимо пароля от ключа ещё и сам ключ стянуть нужно, а он на удалённой машине).
В Kali Linux есть даже специальный инструмент "Fake Logon Screen" для воровства паролей. В виндах. И привычка нажимать Ctrl-Alt-Del перед вводом пароля там защищает. А в линуксе -- без вариантов. Спасает только то, что у всех цветовые темы разные, фиг угадаешь чего там у тебя.
25 лет тому назад была предложена концепция Интернет-Времени. Актуально и на земле.
Картошка, лимон, это всё полная чушь, в том смысле, что расходный материал там не карточшка и лимон (они являются электролитом), а расходный материал -- металлы (разные, с одинаковыми ничего не заработает!)
В условиях апокалипсиса, когда вообще ничего нет -- батарею не сделаешь.
Когда остались какие-то разбитые остатки машин и механизмов, содержащих алюминивые конструкции (особенно алюминиевые провода ЛЭП!), то весь алюминий можно перевести на электричество простейшей алюминиево-медной батареей. Нужные компоненты: 1) алюминиевый электрод, 2) медный электрод (первое и второе -- бывшие провода), 3) обычный раствор хлорида натрия (пищевой соли) в воде! Примерно как по ссылке: https://usamodelkina.ru/23618-galvanicheskaja-batareja-med-aljuminij.html
Такая батарея выдает на порядки больше энергии чем поделки из картошки и лимонов. Но алюминивые электроды придётся регулярно заменять. Т.к. фактически выделяется энергия ранее запасённая в алюминии (при его производстве).
Где-то в журнале "Радио" лет 30 тому назад описывалась похожая конструкция, но вроде там один из электродов был угольный и вообще не растворялся. Не уверен. Был бы рад, если бы кто напомнил. Но боюсь медной проволоки найти будет проще, чем заметное количество угля.
В андроиде батарейки хватит на день максимум.
В голом C нет неявного потока управления, и это мотивация отсутствия там деструкторов. Жалко что не ввели defer в C23...
Метод, в определённом смысле, широко известный, т.к. массово применяется в микрософтовских API. В частности для строк и где-то ещё.
Если программа взаимодействует с сторонними библиотеками и обменивается с ними объектами, может быть нежданным сюрпризом когда в свой free() приедет чужой указатель, выделенный на стороне (и без такого трюка).
Поэтому, возможно, нет смысла в таком трюке вообще, и нужно просто определить свои стуктуры, где эти деструкторы хранить в явном виде. Хотя да, иногда бывается хочется в неявном...
Можно всё вывернуть немного наоборот и получится проще, без опасного "void*", который обычно является источником багов:
Идея в том, что при необходимости может быть создана другая структура, первым элементом которой будет callback_functor_t (таким образом реализуется "наследование" на C). Затем функция free может вызвать callback_functor_t->callback_fn() с передачей ему указателя на сам callback_functor_t (хранящийся "перед началом" выделенного блока), а внутри коллбэка тип callback_functor_t можно "привести" к типу расширенной структуры с помощью широко известного макроса container_of. Здесь во всей цепочке отсутствует void* (кроме самого указателя на освобождаемую память) и нет практически возможности совместить что-то несовместимое, что привело бы к ошибке.
И это скорей не аналог замыкания, а аналог std::function (фунцкионального объекта), но в сишном стиле.
То, что у вас коллбэки навешиваются после аллокации -- скорей плохо. Это же просто можно забыть сделать. Будет лучше, если бы функция аллокации сразу принимала указатель на коллбэк и его размер, и копировала бы его по значению (в адрес ниже возвращаемого указателя, разумеется выравненный на max_align_t).
Чтоб размер не принимать явно, функция замещающая malloc может быть сделана макросом (внутри которого будет делаться sizeof(*(callback_argument)). Разумеется здесь возникает проблема, что поскольку предполагается расширение типа callback_functor_t другим типом, то собственно типы получаются разные и функция замещающая malloc не может проверить, что ей не подсунули что-то непотребное (либо тип будет приведен к callback_functor_t, но тогда потеряется тип и размер расширенного функтора). Это можно обойти, если договориться, что все взаимозаменяемые типы (унаследованные и базовый) будут содержать специальный именованный член -- пустую структуру, например, первым элементом структуры. Тогда можно передавать ссылку на этот член и легко преобразовывать указатель между разными типами с помощью опять же макроса container_of. Это опять же лучше, чем void*, т.к. совсем уж что угодно присвоить к чему угодно компилятор не позволит, и проверка типов продолжит работать (хотя для программиста появляется возможность сделать ошибку в определении структур, впрочем там сложности никакой и ошибиться тяжело). В данном случае в макросе можно адресовать специальный именованный член стурктуры, чтоб убедиться что стрктура имеет нужный тип (либо там нет такого члена). Это не совсем утиная типизация, т.к. этот самый спец. член всё же может иметь разные типы (пустой структуры, но разные, т.к. ключевое слово struct каждый раз декларирует новый, не совместимый тип) для каждых несовместимых классов объектов. Не знаю понятно ли объяснил, как-то так:
Ну разумеется callback_functor_t и всё от него наследуемое -- должно быть перемещаемым (на него нигде в памяти не должно сохраняться указателей).
В принципе то же что у автора примерно, только немного другие механизмы, где нет void*. Реализация container_of макроса может выглядеть вот так:
В линуксе по смыслу такая же, но полагается на GNU-расширения. Впрочем, пустые структуры тоже не строгое соответствие ISO-C.
PS: но может проще писать на C++ тогда... Там std::unique_ptr уже сразу из коробки.
Что??? Именно из него и делаются печатные платы абсолютного большинства современных приборов.
Какой ещё устойчивости? Есть специальные гибкие полимерные материалы, условно акрил и тефлон, из которых может быть изготовлена гибкая печатная плата. Массово, тоннами, на химическом заводе. Это сейчас во внутренностях любого мобильного телефона. Неужели выращивать и сушить грибы проще? Притянуто за уши по-моему. Особенно про устойчивость.
Скоро всё будет завалено биоразлагаемыми товарами. Которые будут разлагаться сразу после окончания гарантийного срока (http://lib.ru/RUFANT/MUSLIN/42-09.txt)
Надо полагать, в РФ всё это не работает и не будет работать в сколько-нибудь обозримой перспективе. Поэтому разработчики сигнализаций пока не останутся без работы.
Через это всё пройдут 2% потребителей. Остальные утрутся. Вот и вся бизнес-логика крупной сети.
Если запахнет жареным -- те и другие будут крутиться как уж на сковородке и в целом с носом останется потребитель.
Был такой аппарат: Toshiba Portege G910. В 2009 году. Они все вышли из строя, многие в течении гарантированного срока. Чем кончилось? Большую часть потребителей морозили 45-дневной экспертизой и отшивали по разным причинам, единицам выдали новый такой же аппарат (который скоро так же вышел из строя), кому-то возможно вернули деньги. Разницы где покупать -- не было, история у всех одна. Не знаю как устроены продажи, но очевидно, у самих продавцов выбить деньги из Тошибы за некачественный товар не очень получалось. А сервис центр вертел всех на одном месте.
На производстве тыкаться осциллографом в каждую плату -- неудобно во-первых, во-вторых долго и дорого, в третьих в сколько-нибудь сложной программе для МК работа внешнего генератора может носить периодический характер (потому, что МК будет "засыпать" вместе с генератором).
И наконец -- осциллограф это не прибор для определения частоты, частоту на нём можно оценить лишь приблизительно. Хотя это действительно не слишком принципиально. И щуп для осциллографа имеет порядочную ёмкостную составляющую, чтоб сбить работу генератора (особенно если забыть про делитель).
Насколько может уйти. В небольшом диапазоне может подстраиваться конденсаторами. Либо может стать сходу в три раза больше/меньше. В случаях повреждения резонатора (достаточно падения об пол) может стать какой угодно. Случаи бывают разные.
В случае перехода на внутреннее тактирование неплохо бы не тихо глючить, а как-то индицировать ошибку. Чтоб сразу было понятно в чём дело, а не трясли в каждом случае разработчика за рукав.
На пару десятков секунд в сутки запросто уходит обычный часовой кварц (не термокомпенсированный, без подстройки), а не RC-цепочка.
В сутках 86400 секунд, и какие-нибудь 5 процентов -- это ЧАС времени, а не 20 секунд.
Точность этой RC-цепочки часто НЕдостаточна для работы с UART во всём температурном диапазоне и хорошо работает лишь на столе, при стандартной температуре. На резонансную частоту этой цепочки влияет не только температура, но и технологическая невозможность получения стабильных характеристик на производстве. И лишь у некоторых контроллеров там то ли какая-то самокалибровка, то ли калибровка лазером на производстве. Не у самых дешёвых.
Вообще возможность подключения часового кварца к МК часто означает возможность отказа от второго высокочастотного резонатора. Можно запуститься с внутренним генератором и периодически подстраивать его работу ориентируясь на часовой кварц. Не для любых применений, но для тех гдe 5% достаточно и где МК позволяет подстраивать частоту HSI -- сгодится.
Вообще замена компонентов на производстве на другой тип (даже с одинаковыми на первый взгляд характеристиками), без разрешения разработчика или заказчика -- ССЗБ. Потому, что после такой замены генератор может запускаться опять же на не своей штатной гармонике просто потому, что важны все составляющие, и ёмкость микроконтроллера, и конденсаторов, и она должна соответствовать выбранному типу резонатора. Просто заменить один 8МГц на другой 8МГц другой фирмы -- может вроде бы и прокатить, но потом на выходе окажется 10% брака, например.
Фрагмент кода не очень надёжный в том смысле, что его время выполнения несколько не предсказуемо (неизвестно сколько тактов CPU нужно на итерацию цикла, неизвестно как современные CPU распараллелят инструкции и где будут задержки, всё зависит от опций оптимизации компилятора). Лучше иметь итерацию до достижения таймером заданной величины. А таймер запрограмировать на нужное число тактов в зависимости от текущего выбранного источника тактирования. Генератору с кварцевым резонатором чтоб запуститься нужно от миллисекунд до нескольких десятков миллисекунд (для низкочастотных "часовых" резонаторов на порядок больше). Соответственно таймаут может быть на 100мс, например.
Она-то как раз в даташите указывается. С погрешностью порядка 5%, но всё таки известна.
А внешний кварцевый резонатор в особо запущенных случаях запускается на какой-нибудь другой гармонике и частота действительно неизвестна. Это надо сказать типовая неисправность. Она может быть вызвана повреждением резонатора, ошибками монтажа, монтажом неправильных номиналов конденсаторов в цепи резонатора, монтажом не того типа резонатора... И стоило бы хотя бы грубо эту частоту оценить, чтоб принять решение, генератор с внешним резонатором вообще работоспособен или нет.
Обработчики прерывания для всего этого дела -- не нужны. Достаточно в цикле опрашивать специальные регистры. В конце концов, это делается только на старте и процессор в это время ничем другим не занимается.
Сомнительная техника ввиду сказанного выше: так станет невозможно обнаруживать и сигнализировать о явных неисправностях (например, числом вспышек светодиодика). И не обнаруженная неисправность превращается в куда большую проблему, которую уже должен исследовать инженер (иначе бы ограничилось ремонтом на производстве), и сразу непонятно, программная она или вызвана неправильной работой схемы (потому, что с неправильным кварцем -- "программа глючит", что-то одно работает, что-то другое нет и т.п.)
Поэтому я бы предложил частоту резонатора знать заведомо, или вносить через какой-то механизм конфигурации (путём установки перемычек, путём программирования с компьютера).
В целом представленный программный код изобилует magic numbers в коде. Почему 10000, а не 100500? А если завтра контроллер будет с другой буковкой -- там 10000 ещё нормально, или уже нет? Или почему interruptsCounter == 100? Значит эта сотня где-то ещё закодирована. В code style некоторых компаний чуть ли не вообще запрещают "волшебные числа" в коде. Как минимум -- нужно объявить (через enum или #define в C, через const int в C++) константу и ей пользоваться, самой константе же дать осмысленные имя и комментарий. За исключением нулей, единиц и ряда очевидных констант. Рекомендую следовать такому же стилю.
Есть один очень интересный нюанс, почёрпнутый мною из "Архитектуры современных ОС" Таненбаума, где объяснялось, почему в Windows есть комбинация Ctrl-Alt-Del -- она обрабатывается специально, не как остальные клавиши, и гарантировано выводит на экран специальное меню. И сделано это далеко не совсем просто так, а чтобы избежать ситуации, когда экран блокировки будет нарисован вредоносной программой и пользователь туда введёт свой пароль. А так пользователь нажимает Ctrl-Alt-Del и гарантировано появляется системное меню.
Что характерно, в Linux такого нет... или по крайней мере не повсеместно.
И почему-то мне кажется, что в современных телефонах похожая проблема -- присутствует. Нет однозначного способа убедиться, что содержимое экрана -- меню операционной системы, или стопроцентная подделка. В которой всё точно такое же на первый взгляд. Только некоторые вещи работают немного не так. По крайней мере для андроида устанавливаются же альтернативные "launcher'ы", а выглядеть-то оно может как фирменное меню.
А зачем такой экстеншн, когда есть программы записывающие окно с десктопа. Мне кажется, это несколько более универсально.
Кстати, интересно было бы знать, а как экстеншен работает в ситуации, когда окно браузера скрыто. Свёрнуто или перекрыто другим окном. Ведь по идее тогда само окно, или его часть не обновляется, если там даже что-то и меняется, и записывать нечего. Или браузер в неком своем буфере окна обновляет всегда, просто обновления на уровне X11 или Win32 GDI не делается для свёрнутых окон? В такой ситуации приходилось браузер сажать в Xvfb, чтоб пока с него там картинка записывается можно было с другими программами на компьютере работать. И чтоб можно было несколько браузеров разом запустить.
И со звуком интересно как? Не с микрофона, а из видео в браузере. Если у нас положим десять браузеров и мы с них фильмы хотим сграбить. Опять же приходилось через pulseaudio их растаскивать на разные виртуальные (monitor) девайсы, а с них уже записывать.
И какой из этого вывод? Не использовать полупроводники вообще? Тогда, в первую очередь, откажитесь от бездушных холодных диодов в выпрямителе источника питания. Есть же тёплые и ламповые кенотроны прямого накала...
Суть, повторюсь, не в линейности как таковой, а в количественной её оценке. И для специализированной микросхемы, где в даташите даже приводится THD с двумя нулями после запятой, это ничтожная величина на фоне всего остального усилителя.