Перейти к содержанию

Лидеры

Популярный контент

Показан контент с высокой репутацией 24.11.2018 в Записи блога

  1. Вот вы говорите: AVR слишком убоги, чтобы применять на них RTOS... А я рискнул... Сначала попытался рассмотреть имеющиеся варианты, чтобы сделать предварительные выводы. Поиск вываливает примерно с десяток готовых разработок RTOS разной степени крутости, из которых FreeRTOS, естественно, в лидерах. Однако, я оценил свои силы и решил, что вхождение в эту ОС для меня обернется большими сложностями, в основном, из-за большого количества возможностей API, и англоязычным их описанием. Ну не принимает душа русская языка аглицкого, даже со словарем и гуглопереводчиком в больших количествах. А из осей на великом и могучем нашлось только две: кооперативная OSA и присиплюсплюснатая ScmRTOS. Опять-таки из-за собственной ограниченности более современная и продвинутая ScmRTOS мне показалась недоступной - С++ пока что понимаю и принимаю исключительно в качестве наказания. Ну, собственно, и вышло, что начать и закончить поиск осей для AVR можно на OSA. Попробовал - получается. Не без скрипа, но работает. И даже увлекло меня это. Но вот что мне не понравилось в этом варианте. Главная особенность этой ОС, которую следует учитывать при работе (то есть при написании программ), это отсутствие сохранения контекста при переключении задач. Иными словами, если в текущей задаче вызывается сервис операционной системы, переключающий задачи, то все локальные переменные текущей задачи могу потерять свою актуальность. Это означает, в частности, запрет на вызов сервисов системы в циклах по счетчику (значение счетчика будет потеряно). И единственный способ решить эту проблему - вместо автоматических локальных переменных использовать static или вообще отказаться от локальных в пользу глобальных. Сами понимаете, это совсем не гуд. Вторая особенность этой ОС, это возможность вызывать сервисы ОС, преключающие задачи, только из тела самой задачи, но не в вызываемых из неё функций. То есть нельзя сделать функцию, например, ожидающую прием символа из USART при помощи системного сервиса OS_Wait, а затем вызывать эту функцию из разных задач, то есть поступать по аналогии с привычным "не-многозадачным" подходом. Вот представьте себе ситуацию: задачи формируют текстовые сообщения и выводят их в USART. Кажется логичным сделать функцию, которая занимается отправкой в USART строки посимвольно и использовать эту функцию во всех задачах - а нельзя! Более того, не смотря на то, что все задачи ПООЧЕРЕДНО формируют строки (ОС ведь кооперативная), каждая из задач должна иметь собственный промежуточный static-буфер для формирования своей строки - это ведь явно лишний расход памяти! При обычном подходе мы бы работали с локальным буфером в каждой функции, а локальный буфер, как известно, исчезал бы при выходе из функции... Наконец, архитектура этой ОС (под архитектурой я подразумеваю набор файлов-модулей и порядок работы с ними) такова, что почти все файлы инклюдятся друг в друга, что очень сильно нарушает модульный подход при программировании. Напомню, что модульный подход означает, в частности, возможность компиляции каждого Сишного файла отдельно от других сишных файтов. А в OSA системные сишники "вставляются" в один большой "общий" сишник, который затем и компилируется. В итоге я потратил немало времени, чтобы разобраться, как же настроить проект в Eclipse, чтобы можно было комфортно работать. Eclipse очень привык считать все сишники отдельными модулями проекта, и страстно стремится компилировать их отдельно. В общем, знакомство с OSA было увлекательным, недолгим, интересным, но разочаровывающим. Другие же ОС, найденные мной, были не кооперативными, а вытесняющими. Вытесняющие ОС имеют много преимуществ перед кооперативными, но один их недостаток сильно ограничивает применение на AVR: они весьма требовательны к объемам ОЗУ. Именно отсюда растут ноги у паникерских мнений, что AVR и "нормальная" RTOS - понятия несовместимые. И это на самом деле так, если мы говорим о микроконтроллерах младше (т.е. слабее) atmega32. Для справки: OSA вполне себе способна быть полезной не только на atmega8, но даже и на attiny2313! Но, к счастью для меня, не одной atmega32 ограничен мир AVR, и, кроме прочего, не ограничен и я сам. У меня в загашнике есть и at90can128, и даже atmega2560! И, спросил я себя, почему я должен переживать по поводу вытесняющей ОС при таких-то ресурсах? В at90can128 целых 4К ОЗУ, а уж flash-памяти по 8-битным меркам просто немеряно - 128К, а у монстра atmega2560 вдвое больше всего! Правда, если первый МК паять вполне комфортно (TQFP64), то второй без микроскопа уже сложно (TQFP100 c шагом выводов 0,5 мм). А тут еще у меня завалялась отладочная платка DVK90CAN1... Ну, вы поняли... Итак, решающим теперь для меня стал поиск максимально простой операционки - чтобы мне по силам. Их не так мало, как может показаться, но самой простой, по моему мнению, является YAVRTOS (скачать архив с исходниками, примерами и документацией можно по ссылке, но сайт автора уже не существует) - это практически такой же малоизвестный, как OSA, продукт примерно тех же времен (видимо, тогда было можно каждому мастерить свою собственную ОС с блекджеком и девушками низкой социальной ответственности). Не смотря на инглиш, эта ось оказалась мне по силам: всего два файла и с полтора десятка системных функций! За один вечер легко расщелкал все необходимое для первого старта. Плюсы этой RTOS перед OSA неоспоримы: не надо предпринимать практически никаких усилий по оформлению кода - пишется точно так же, как всегда, с локальными переменными, с вложенными вызовами функций и т.д. Разумеется, надо следить за общими ресурсами и блокировать к ним доступ, если необходимо - но это вообще всегда необходимо в многозадачных системах, и даже в ОSA частично так. Минусы, правда, тоже заметны: минимальное приложение, тупо мигающее двумя светодиодами (каждый в своей задаче) занимает почти 2К flash и порядка 400 байт ОЗУ. На просторах выбранного мной МК это даже и не заметно, но для atmega8 может быть близким к техническому пределу. YAVRTOS написана на 99,9% на Си (только сохранение/восстановление контекста реализовано в виде ассемблерной вставки из трех десятков push-pop), всего два файла (task.c и task.h) - все это явный плюс в плане изучения и модификации под себя, если надо (и если хватает ума). Косвенным плюсом (или минусом, если продолжать переживать о ресурсах) является массовое применение malloc в ядре ОС, а значит, и в пользовательском приложении уже вполне оправдано динамическое распределение памяти. И мой энтузиазм просто на взлете от первого опыта! Например, вот как выглядит код задачи и вспомогательных функций для извлечения точного времени из GPS-приемника, подключенному к USART1, и вывода этих показаний на стандартный вывод (stdout, связанный с USART0): const __flash char gps_msg[] = "RMC,"; #define GPS_MSG_SZ (sizeof(gps_msg)-1) // поллинг 1 символа от GPS static uint8_t get_char(void){ while(bit_is_clear(UCSR1A, RXC)) wait_for_increment_of(&tick, 1); return UDR1; } // получение 1 цифры из символа static uint8_t get_dig(void){ return (get_char() - '0'); } // собственно сама задача void p2p_usart(void *p){ uint8_t i; uint8_t h,m,s; while(1){ i = 0; // ждем прихода сообщения с точным временем while((i < GPS_MSG_SZ) && (get_char() == gps_msg[i])) i++; if(i == GPS_MSG_SZ){ // разбираем сообщение по символам h = get_dig()*10 + get_dig() + 3; // +3 - это часовой пояс h %= 24; m = get_dig()*10 + get_dig(); s = get_dig()*10 + get_dig(); // пропускаем сотые доли секунды get_char(); // '.' get_char(); // 's' get_char(); // 's' get_char(); // ',' // проверка корректности времени и его вывод if(get_char() == 'A'){ printf_P(PSTR("GPS Time %02d:%02d.%02d\r"),h,m,s); } else { printf_P(PSTR("No GPS, wait... \r")); } } } } Как видите, код крайне "тупой", то есть прямолинейный, как лом: сплошные ожидания и никакой заботы о том, что параллельно должно что-то еще работать. В моем случае просто мигают 2 светодиода - один с длительностью импульса/паузы в 500 тиков, а второй в 501 (кстати, 1 тик = 1 мс, тактовая частота МК = 8 МГц). Но вместо светодиодов может быть еще две (или сколько надо) аналогично прямолинейно написанных задач, и можно быть уверенным, что все будет работать! Приведу данные по итогам компиляции проекта, чтобы продемонстрировать израсходованные ресурсы: Не так уж и плохо, учитывая свободное применение printf. В активном режиме используется дополнительно 380 байт ОЗУ под стеки задач и ОС, т.е. примерно 10% всего объема - еще много остается. Есть, кроме YAVRTOS, и другие альтернативы, например, FemtoOS, которая поддерживает даже (!!!) attiny25, и при этом тоже является вытесняющей операционкой. Но она существенно "богаче" в плане API, и разобраться с нею будет посложнее, т.к. документирована она явно менее детально. Возможно, я и её попробую на вкус... И, скорее всего, теперь это станет для меня основным способом написания программ. RTOS позволяет сильно упростить себе жизнь. Имхо.
    1 балл
  2. Скопирую сюда сообщение из фотогалереи блоков питания выдались выходные и решил таки добить "проектик выходного дня" Характеристики скромные. Всего 1А суммарно по каждому полюсу. От -15 до +15 весь стандартный ряд напряжений (5-9-12-15 обоих полярностей). Измеряет ток в каждом из полюсов суммарно. По положительному и по отрицательному. Погрешность измерений (по эталонному прибору) не хуже +/-0,5 деления (реально даже лучше). Обеспечивается идеально подогнанными дифференциальными усилителями на ОУ LT1078 и константановыми шунтами. Выдает по отдельному каналу регулируемое опорное напряжение в диапазоне 0...3,3 вольта с точностью не хуже +/-0,00025 вольта (по эталонному прибору с сертификатом поверки и точностью измерений не хуже 6 знаков после запятой). Управляется энкодером. Шаг установки меняется кнопочкой (нажим на ручку энкодера). Управление охладителем ШИМ (бесшумный), полностью пропорциональный. Дисплейчик COG на контроллере ST7032 с шиной I2C. Трансформатор самопальный на сердечнике от трансформатора тока промышленного. Все управление на STM32F051K6T6. Корпус красил в термокамере. Хрен поцарапаешь. Передняя панель - лазер (черный акрил, резка + гравировка у рекламщиков) Фото кишков ниже Кишочки Все собрано в корпусе БП АТХ первого попавшегося. Радиаторы и вентилятор от того же БП. Под нагрузкой 1А в самом плохом варианте (нагружены стабилизаторы 5В) греется прилично, но без корпуса может работать и без вентилятора. В корпусе уже надо обдувать. Но это на максимуме. В обычной жизни вентилятор еще не включался ни разу. Может он не работает просто? ну и контроллер с дисплеем поближе Для дисплея изготовил платку-прилепыш. Там надо немного рассыпухи разместить для работы внутренних преобразователей напряжения дисплея и пару резисторов для настройки ориентации изображения. Есть такая фишка у этой стекляшки. Ну и подтяжки I2C материалы прокта схема для предварительного ознакомления (узел управления) Здесь все элементарно просто. 2 простых дифференциальных усилителя токоизмерительных шунтов. Резисторы для них подбирал вручную и согласовывал. На выходах диодные ограничители и легенькие интеграторы, которые по итогу я даже не впаял. Обвязка контроллера стандартная для работы без кварцевого резонатора и без схемы ручного перезапуска. Разъем внутрисхемного программирования как положено. Питание блока ШИМ вентилятора берется с отдельной обмотки и по максимуму отвязано от схемы, чтобы избавиться от помех от этого узла. Все таки милиамперметр чувствителен к этому делу. Датчик температуры простейший LM35 с аналоговым выходом и RC фильтром на выходе. Для DAC выполнен буфер на ОУ. Просто повторитель, ничего особенного с компенсацией токов утечки. Основная схема питания слеплена из того что было под рукой. Стабилизатор 5 вольт выдран с платы APC (SO8 букашка), 3.3 вольта тоже откуда то отковырен. Можно любые применить. Схема запитки AVсс не совсем обычная, но так тоже работает силовая часть Тоже ничего особенного. Гармошкой по 4 стабилизатора на разные напряжения. В связи с особенностями планируемого использования посчитал такое решение наиболее целесообразным по сочетанию простота/выхлоп. И не ошибся в общем то, как показала практика использования прибора. схемы в DipTrace + дополнительные документы (разведено под стандартный 1602!) финиш.zip исходный код прошивки, проект Keil MDK ARM (вывод на дисплей под ST7032! I2C). Мне переписывать было уже некогда, поэтому расскажу как вернуть назад. Любой кто хоть раз писал под STM32 справится. Надо всего лишь переписать библиотечную функцию вывода на экран не через I2C, а по 4-х проводному параллельному интерфейсу, а все что касается I2C (инитка, дискриптор и резерв GPIO) вырезать к чертям Discrete_power_unit.zip Ну вот пожалуй все материалы. Будут вопросы, задавайте Дальше документалистика процесса для того чтобы закрепить плату контроллера припаял к ней стойки латунные от креплений материнских плат компьютера. Отлично паяются, отлично держатся трансформатор вот намотал из сердечника от старого трансформатора тока промышленного (взят из электрохлама) и катушки запасной от пускателя ПМА. Провода на ней ровнехонько на первичку. Просто взял и перемотал с одного на другое. Изоляция межслойная - пакеты для запекания нарезанные лентой. Бирка от лени написана вручную, все равно смотреть никто не будет Что такое ТСП-40? Очень просто. Трансформатор СамоПальный. Цифра от балды для красоты. Закрепил на плате каким то болтом, куском резины вырезанным из МБС техпластины и шайбой от переходников сноубордических креплений TECHNINE на BURTON. Эта шайба - самая дорогая деталь в устройстве! Те крепы мне обошлись аж в 400 зеленых. Вот шайбочки от переходников остались лишними. Долго не решался использовать, но видимо их черед пришел. тесты под нагрузкой перед сборкой На внешний вид электронной нагрузки не смотрите, это ужасный прототип. Внутри она вполне себе на уровне, но нужно чуть допилить конструктив холодильника. Все руки не доходят немного в процессе разработки контроллера ВНИМАНИЕ! Дисплей мне пришлось заменить. Плата изначально разрабатывалась под обычный WH1602 и первоначально работала с ним. (Поменять прошивку не составит труда для обратной замены, там все предельно ясно и заменена только библиотека дисплея). Дело в том, что стандартный 1602 в корпус не влезал по высоте и мне пришлось заказать сверхминиатюрное исполнение COG 1602. Но он оказался вовсе не тем, что я ожидал. Имел шину управления I2C и немного не похожую систему команд. Пришлось наскоро поправить прошивку под это дело. Дисплей встал на место энкодера (так как на этих ногах I2C и живет), а энкодер перекочевал на место старого дисплея. Пришлось разрезать одну дорогу и припаять +3.3 вольта к одной из ног разъема энкодера (PВ5) и землю на одну из ног разъема дисплея (5-я снизу) для того чтобы старую фишку энкодера не перепаивать. Регулировку констрасности демонтировал.
    1 балл
×
×
  • Создать...