Комментарии 63
memset(app_pointer->key, 0, 8);
app_pointer->key[2] = KEY_W;
app_pointer->key[3] = KEY_O;
app_pointer->key[4] = KEY_N;
app_pointer->key[5] = KEY_D;
app_pointer->key[6] = KEY_E;
app_pointer->key[7] = KEY_R;
app_pointer->usb_composite->usb_send_packet(app_pointer->key, 8);
app_pointer->key[2] = 0;
app_pointer->key[3] = 0;
app_pointer->key[4] = 0;
app_pointer->key[5] = 0;
app_pointer->key[6] = 0;
app_pointer->key[7] = 0;
1. Магическая константа 8. Стоит поменять размер массива — имеем жуткий головняк с отловом константы.
2. Как следствие первого — первый и второй аргументы memset между собой не связаны. Компилятор никак не сможет предупредить нас, если что-то пошло не так. Напоминаю, что у вас C++, а значит есть шаблоны. Можно сделать все проверки очень красиво и в compile time.
3. Обнуление — классный кусок «китайского кода». Вам работу построчно оплачивают? Это раздутый кирпич кода, весь семантический смысл которого — memset. Если вы думаете, что цикл будет работать дольше — заставьте компилятор его раскрутить.
template<typename T> void ZeroIt(T& value)
{
memset(&value,0,sizeof(value));
}
Тест на IDEONE
Мой pull-request
И ещё. Вы не сумели разобраться, что делает этот код. А это — ОДНОРАЗОВЫЙ тест, он посылает сообщение «WONDER WOMEN». Живет такой тест — полчаса. И чем тупее в нем код — тем лучше. Тест должен тестировать остальные части программы, а не быть источником ошибок.
Этот код не помещается на один экран стандартного монитора. Следовательно, нарушает эргономику — для его обозрения нужно дергать свою кратковременную память и скроллить туда-сюда.
Этот код у неподготовленного читателя вызывает необходимость сверки индексов — а вдруг, там не все и не подряд? И там ведь действительно — не все, а с двойки.
И про «тестовость» и «временность». Такие чудесные времянки потом, в условиях цейтнота, перерастают в Главное Техническое Решение Продукта и живут потом годами.
Да, согласен, иногда времянки живут долго. Но это именно ИНОГДА. А в данном случае — ЗАВЕДОМО одноразовый тест.
У вас мышление преподавателя. а не ИНЖЕНЕРА. У инженера к разным частям кода — разные требования. К одним — скорость, к другим — читаемость, к третьим — быстрота написания, к четвертым — отсутствие ошибок. А преподаватель считает, что есть две точки зрения — одна ЕГО, а другая неправильная.
Я уже видел, как отличный ученик таких вот преподавателей стал УЖАСНЫМ инженером. его код был красив, параметризован, обвешан кучей темплейтов и классов. Он даже работал — но только с данными от сферической лошади в вакууме. Чуть что реальное — и все, случайно залетевший дятел рушил всю цивилизацию.
В инженерных понятиях — код должен эффективно выполнять СВОЮ задачу. Причем для каждой задачи — понятие эффективности разное. Но практически никогда таким критерием не является КРАСОТА кода. Да, да для некоторого кода ПОЛЕЗНА сопровождаемость. Но не тогда, когда она идет в ущерб главной задаче.
А когда второстепенные критерии становятся на первое место — это не инженер. Это вечный студентик, работающий ради отметки.
http://easyelectronics.ru/rabota-s-portami-vvoda-vyvoda-mikrokontrollerov-na-si.html
Если вы используете раннее связывание, то оверхеда перед прибиванием гвоздями нет совершенно никакого. При этом код типа
typedef Led<PortA,4> led1;
typedef Led<PortA,5> led2;
led1::init();
led2::init();
led1::toggle();
led2::toggle();
приятнее читать и удобнее сопровождать
Ртос это уже другого поля ягоды, при этом в текущем проекте никто не запрещал мне критичный к времени выполнения код обрабатывать в прерываниях с более высоким приоритетом прямо поверх шедулера.
Или вы ради вашей красоты просто отказываетесь от проектов, где заказчиком жестко задан процессор?
Что касается сложности верификации — ну вы же профи, вы алгоритмы работы своих устройств выучили на зубок. А для обычного человека намного проще, когда код работы с устройством идет в тех же понятиях, что и в описании устройства. А любая абстракция — мешает верифицировать код по документации, Потому что сегодня одно устройство, завтра другое, послезавтра третье. И на каждое — 50-100 страниц доки.
я не профи во встраиваемых системах. Полдюжины embeded проектов, где работает мой код — это мало. Потому часть, связанную с железом мне проще писать ровно по доке. Без выкрутасов крутых ембедчиков, которые эти доки помнят наизусть.
Зато мой код — РАБОТАЕТ. А коллеге, любившему темплейты — оказалось проще уволиться, чем отладить свой код. У него вся энергия ушла в многоуровневые навороты. В итоге навороты красивые, но функции своей не выполняют. Хотя если бы обошелся без красивостей и код был бы меньше раза в 3-4 и работал бы намного правильней. УВЫ, темплейты и классы — отличный способ спустить пар в свисток.
На компиляторах от Keil и Iar все работает прекрасно.
Миландр (привет разным российскими процессорам) тоже поддерживает C++ и шаблоны. Любые армы поддерживают C++ и шаблоны, микроконтроллеры авр поддерживают C++ и шаблоны. Пики и 8051 только остались за бортом, но их никто не использует.
Так что похоже вы сами себе придумали проблему и сами поставили ее мне в укор.
Раз пошло время придуманых ситуаций, я тоже задам вам вопрос.
Что вы будете делать если микроконтроллер не поддерживает ни C++ ни С а только ADA? Или вы ради вашей красоты просто отказываетесь от проектов, где заказчиком жестко задан процессор?
Вы опять же не поверите, но параметризацию устройства можно тоже вынести в отдельный класс и получить великолепную абстракцию, причем человеку который пишет не надо знать что и как там инкапсулированно, настроил phy микросхему на 10 Мбит, ок, на 100 надо? Не будем перелапачивать весь код, а просто добавим реализацию конфигурирования на 100мБит.
Зато мой код — РАБОТАЕТ. А коллеге, любившему темплейты — оказалось проще уволиться, чем отладить свой код.Вот это характеристика только ваша и коллеги. МОЙ КОД ТОЖЕ РАБОТАЕТ!!!!!!!!!!!..
Это сродни истории
«К нам в бригаду строителей пришел странный какой то, все молотками забивают гвозди, а он пневматический принес, поковырялся там, гвоздей не забил ни одного на компрессор пожаловался и уволился.»
Это же не пневматического молотка проблема, это человека. А вы экстраполировали своего коллегу на все сообщество C++ программистов.
Первичное — код должен РАБОТАТЬ. ПРАВИЛЬНО работать. Выполнять нужные функции. Вторичное — это НАДЕЖНОСТЬ кода. Работоспособность кода при ошибках в данных, при изменении условий, На третьем месте — СКОРОСТЬ и затраты памяти. И только на четвертом — СОПРОВОЖДАЕМОСТЬ. Потому что в большинстве случаев сопровождение надежно работающего кода — не нужно.
Бывают ситуации, когда сопровождаемость вылезает на второе место. это когда известно, что проект будет развиваться годами.
А вот на ПЕРВОМ месте сопровождаемость лишь тогда, когда код НЕ РАБОТАЕТ Не выполняет своих функций. Вот тогда 99% сил будут потрачены на сопровождение и поиск ошибок.
Ну и сдача экзаменов — на экзаменах, конечно СТИЛЬ написания намного важнее, работает программа или нет.
В итоге после ВУЗа мы получаем специалистов с отличным стилем и неработоспобными программами. И это ОБЩАЯ ситуация.
Поймите, вы ставите телегу впереди лошади. То есть стиль впереди работоспособности. Мне ЖАЛЬ, что вы не понимаете, насколько это вредно.
Из более 30 лет своей программистом карьеры я лет 20 занимался именно сопровождением чужого кода.И код, в котором на первом месте сопровождаемость — исправить невозможно. Его можно только написать заново. А если код рабоспособен и надежен — проблем с ним немного. Если он плохо написан — его несложно отрефакторить.
Теперь ответы на ваши вопросы.
1) Код без темплейтов и С++сных наворотов я перепишу на что угодно. Не только на АДА, но даже на РАЯ (он же Ершол). Даром что ли я на полусотне языков читаю. А вот ваши красивости на АДА просто так не перенесешь.
2) имелся ввиду 1879ВЯ1Я от модуля. Для DSP там российский компилятор.
3) GCC 2.95 — да, шаблоны поддерживает. Но далеко не все, что умеет GCC 5.0
4) Кого выносить в отдельный модуль — решение архитектурное, а не стилевое. Давайте не путать предмет спора. Хорошая архитектура — действительно полезна для проекта. Но если вы не понимаете отличие архитектуры от стиля — значит вы не готовы к серьезному обсуждению.
ИТОГ. О ваших проектах вы не рассказали ничего. Есть чего рассказывать или все под NDA как незабвенная Bolgeos?
В данный момент разрабатываю измерительные системы для антенных комплексов.
Видео
На данном видео можно увидеть комплекс, в разработке которого я принимал участие.
Дальнейшую дискуссию с вами продолжать не могу, в силу отстуствия конструктивной составляющей. Похоже шаблоны и С++ для вас есть вселенское зло, которое надо искоренять всеми силами
Я правильно понимаю, что вы разрабатываете измеритель для одного спутника, потом немного дописываете — и получаете измеритель для второго, потом — для третьего? То есть в ВАШЕЙ задаче сопровождаемость действительно может стоять даже на первом месте. То есть вам может быть важнее выдать 10 похожих приборов, чем работоспособность отдельного прибора. И уж точнее важнее время разработки всей серии, чем время разработки отдельного прибора.
Осталось понять, что это ВАШ частный случай. Который не имеет отношения к той же пастильде.
Шаблоны и разные С++ные хитрости — это СРЕДСТВА. На своем месте — они хороши. А когда их написание идет в ущерб работоспособности кода — они плохи.
Прошу прощения, спойлеры мне недоступны.
http://bash.im/quote/420672
Вася и Петя одновременно начали писать один и тот же продукт.
Вася был «ориентирован на результат» и начал сразу писать говнокод не продумав толком архитектуру.
А Петя месяц разрабатывал архитектуру, месяц делал удобный интуитивный интерфейс, которому позавидывал бы Джони Айв, потом месяц писал тесты, потом два месяца писал сам код и получил идеальное стабильное приложение.
Но Вася выпустил уже через месяц первую версию программы, пусть и не идеальную, пусть с багами, но рабочую, и начал её продавать. Ещё через месяц выпустил вторую версию исправляющие баги первой и добавляющие новые баги. Ещё через месяц на доходы от продаж нанял двух толковых программеров, которые за два месяца перелопатили весь код, согласно пожеланиям пользователей допилили интерфейс и выпустили третью версию программы.
Итого, через пять месяцев у Васи было два работника, куча клиентов и сносно работающее приложение отвечающее желаниям клиентов.
У Пети было вылизанное никому не известное приложение, минус на банковском счёте и ни одного клиента.
В завершение этого выдуманного примера можно сказать, что через полгода Вася купил все наработки Пети, Петю взял в штат тестировщиком, а сам по пьяни разбился на своём новеньком Туареге
Судя по минусам — тут много народу, кто путает средства с целями. Ну что же, мне жаль. :-(
(Куда? Не задавался давно этим вопросом; может, кто-то подскажет? Нашёл только похожую функцию в одном гаджете для планшетов — клавиатура через USB)
После долгой работы на маке, переходя на PC, начинаешь на автомате использовать command+c вместо ctr+c и т.п. А переопределить такие штуки глобальным хуком (на Win32) не всегда можно. Аппаратный транслятор в этом смысле имел бы преимущество.
Уверен много интересного напишет.
- подходящий ли контроллер мы выбрали?
- а память?
- нам нужно где-то хранить расшифрованную БД, так может рядом с флешом поставить еще и энергозависимую память?
- а что со скоростью работы устройства? не пора ли нам использовать RTOS?
и многое другое.
К бд имеет смысл стучаться, используя шифрование/дешифрование «на лету».
http://www.riot-os.org/#features
Интересно, можно ли в принципе на stm32f4 одновременно завести hid и uvc? Использую stm32 usb device library. М.б. есть какие-либо примеры?
Какую комбинацию клавиш надо нажать чтобы Пастильда вставила только пароль, а не логин и пароль?
Существует ли способ микроконтроллером со стороны прошивки прочитать состояние зелёных LED светодиодов CapsLock/NumLock/ScrollLock?
Вот библиотека STM32_USB_Host_Library похоже, что не позволяет такое делать.
STM32_USB_Host_Library How to read CapsLock LED status
https://community.st.com/t5/stm32cubemx-mcus/read-state-of-caps-lock-from-keyboard/td-p/273899
По-моему только комп их отсылает
Тогда как STM32 USB Device HID устройство может прочитать у PC состояние зелёных светодиодов для USB клавиатуры?
Архитектурно за состояние диодов отвечает хост, он сообщает клавиатуре что включить/выключить. В общем случае у него может не быть способа прочитать что там думает по этому поводу клавиатура. Но вроде всё же можно: https://community.st.com/t5/stm32cubeide-mcus/usb-host-keyboard-output-report-how-to-control-the-3-leds/m-p/308465/highlight/true#M16633
Я пробовал функцию USBH_HID_GetReport. И она всегда возвращает нули.
![](https://habrastorage.org/getpro/habr/upload_files/19c/847/d79/19c847d790612e623de521d4b13f46ba.png)
И потом, не понятно откуда взялись эти магические чиселки: 2 и 0 на месте 2го и 3го аргумента?
Даже если принудительно включить все LED функцией
uint8_t led_byte = 7;
status = USBH_HID_SetReport(phost, 2, 0, &led_byte, 1);
то функция
status = USBH_HID_GetReport(phost, 2, 0, &led_byte, 1);
всё равно возвращает нули
![](https://habrastorage.org/getpro/habr/upload_files/ede/544/ecb/ede544ecb86001352775fc47c4f3ac4a.png)
Вот тут человек @LitLageR
https://habr.com/ru/articles/788844/
написал, что ему якобы удалось с клавиатуры прочитать состояние xxxxLock LEDы.
Однако подробности реализации отсутствуют.
Вот там человек пришет, что он приделал к своей клавиатуре получение команд от хоста "включи лампочку хххЛок", которые ST в своей типовой библиотеке не сделал.
Полистайте первоисточник: https://usb.org/sites/default/files/hid1_11.pdf
Там в конце есть AppendixB, в котором протокол типовой клавиатуры приведён. И в нём нет возможности достать из клавиатуры статус этих лампочек. Это только хост может скомандовать. Когда захочет.
Два в одном: USB хост и составное USB устройство