Golikov 0 13 апреля, 2015 Опубликовано 13 апреля, 2015 · Жалоба понятно, спасибо... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 13 апреля, 2015 Опубликовано 13 апреля, 2015 · Жалоба Вы знаете, но честно говоря меня напрягают оценки результатов труда одного программиста, другим. Прога это такая субъективная вещь ... Я правда тоже тут с одним образчиком творчества работаю .... Тоже разговариваю одними междометиями и нецензурными словами, но всё же ... Можно понять и тех кто делал тот же stdlib или куб. Когда я последний проект начинал был только stdlib - посмотрел, что он для меня обладает избыточной функциональностью. И отказался от него. Особенно меня напрягла работа с портами. Для инициализации порта требуется ввести три енума потом три массива и работать через процедуры. Короче на первый взгляд значительный и неоправданный оверхед. Особенно в сравнении с тем как я привык писать. Но когда потом смотрел некоторые части понимаешь смысл написанного. Так как у меня написано - не стандартизуешь. Мы разные цели ставим перед собой. Они изначально закладывают избыточность и пишут библиотеки, чтобы максимально перекрыть все возможные применения. А я строю реальное приложение, устраняю избыточность, нацелен на локальное использование. В общем объёме приложения - объём драйверов у меня составляет единицы процентов. Учитывая что я их пишу в 2 - 3 уровня, то получается драйвера камнезависимые вообще копейки. Поэтому я могу себе позволить их написать. Хоть каждый раз. А стандартными воспользоваться как примером в каких то случаях. Это общие моменты, а конкретно ... Я вижу что куб был рассчитан на применение в составе ОСи. Причём обкатывался с разными. Приведу пример. Я использовал драйвер Ethernet из куба. Поскольку у меня не было заведено прерывания на обрыв линии, как это реализовано в кубе, то мне пришлось это сделать опросом в другой задаче... Я посмотрел их код и вижу например heth->State ... Это для чего написано? Для разруливания работы с устройством из под разных задач. И некоторые другие вещи. И как результат подключение не вызвало никаких проблем. У меня всё заработало устойчиво. Наверняка там тоже есть что оптимизировать. Так этим никто не запрещает заниматься. Даже механизм блокировки вы можете привести в соответствие с применяемой осью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 13 апреля, 2015 Опубликовано 13 апреля, 2015 · Жалоба Особенно меня напрягла работа с портами. Для инициализации порта требуется ввести три енума потом три массива и работать через процедуры. Короче на первый взгляд значительный и неоправданный оверхед. Мне вот тоже не всегда понятна логика программеров на разных процах при работе с портами. Вот сам пишу процедуры таким образом: Настройка порта на вывод, с параметрами ножки(там 0 или 1) на ввод(пуллап, даун, 3е сост.) и процедуры опроса линии, BitIsSet() BitIsClear() Вот что еще надо для работы с ними? А как ни посмотришь, в творения от СТ, фрискала и пр ... жуть какая-то :crying: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба А вот теперь я задумался, а как с учетом заточености под RTOS правильно делать передачу данных, допустим по SPI в режиме мастера, допустим с какой-нибудь FRAM? Ведь там есть послать данные, подождать бита готовности памяти и принять их. Как бита ждать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Тут всё просто. Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага. Если недолго, то ждать, опрашивая в цикле. В частности, FRAM работает быстро, поэтому есть вероятность, что от попыток переноса ожидания в прерывания будут только дополнительные тормоза. Естественно, ожидание в цикле опроса желательно производить в менее приоритетной задаче, чтобы более важные задачи могли этот цикл прервать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dr.Alex 0 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага. Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита? Если недолго, то ждать, опрашивая в цикле. Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу. Можно сделать while (нет бита) шедьюлинг(); правда тогда период опроса будет много миллисекунд, что может быть долго. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 14 апреля, 2015 Опубликовано 14 апреля, 2015 (изменено) · Жалоба А вот теперь я задумался, а как с учетом заточености под RTOS правильно делать передачу данных, допустим по SPI в режиме мастера, допустим с какой-нибудь FRAM? Ведь там есть послать данные, подождать бита готовности памяти и принять их. Как бита ждать? Вообще-то для этого под оси и пишутся драйвера, они висят на прерываниях железа, более высокого уровня, чем переключатель контента у оси, и работают через стандартные потоки, как драйвер ком-порта под виндой, например... Ну или ждите в вечном цикле, если это устройство монопольно используется. Изменено 14 апреля, 2015 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита? Прерывание мне никто не создаст, придётся самому :-) Под флагом я имел в виду какой-нибудь объект синхронизации операционной системы (event, mutex). Соответственно, ожидание такого флага -- усыпляет ожидающий процесс. Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу. Можно сделать while (нет бита) шедьюлинг(); Ну зачем же вечный? Можно с тайм-аутом. Мысль моя была о том, что если период ожидания бита ожидается короткий (например, гарантирован в даташите на FRAM), то такое ожидание ничем не отличается от просто небольшого цикла по ходу выполнения. Поэтому принимать специальные меры для перевода процесса в сон на время этого ожидания вряд ли целесообразно. Например, я не усыпляю процессор на время передачи пары байт по SPI. А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю, ибо уже успею за это время сделать что-нибудь ещё полезное. ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dr.Alex 0 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Ну зачем же вечный? Можно с тайм-аутом. С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки. ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1); Осёвый "sleep" это и есть функция, вызывающая шедьюлинг.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки. Нет. С тайм-аутом цикл не вечный. Это просто несколько шагов выполнения алгоритма. То, что они оформлены в цикл - ничего не меняет. Так можно договориться до того, что и вычисление математических функций тоже придётся признать "вечным циклом", неприменимым в программировании с ОС. А что, какой-нибудь atan2() - вон как долго вычисляется! Значительно дольше, чем я буду ожидать флага опустошения передатчика SPI перед отправкой туда символа. Осёвый "sleep" это и есть функция, вызывающая шедьюлинг.. Нет. Осёвый "sleep" не просто вызывает шедулинг, он ещё перед этим переводит текущий процесс в состояние ожидания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Вообще-то для этого под оси и пишутся драйвера, они висят на прерываниях железа, более высокого уровня, чем переключатель контента у оси, и работают через стандартные потоки, как драйвер ком-порта под виндой, например... Ну или ждите в вечном цикле, если это устройство монопольно используется. это плохой ответ, не о чем... А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю, Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так? Подытожим, у нас есть варианты: 1. усыпление процесса и возврат к нему с долгими интервалами для проверки дождались или нет (ожидание чего-то очень долгого) 2. это прерывание на окончание ожидания и в нем какой-то симафор, что позволяет ожидающую задачу усыпить до появления симафора. (если надо подождать среднюю длительность) 3. это долбим проверку интервала прямо в задаче циклом. В некоторых ОС будут переключать задачи по временным интервалам, если ожидание затянется, а в некоторых все задачи будут ждать эту. (ожидаем чего-то очень короткого) правильные варианты? Мне как-то внутренне кажется устраивать заопарк прерываний в ОС не верно. Ну то есть отправку UART сделать буфер, и прерывание символ ушел - пихать следующий символ, и так поступить со всеми интерфейсами. Боюсь что так система станет слабо предсказуемой и постоянно что-то ковыряющейся в прерываниях... Ведь их то между собой поделить будет нельзя, посылки по UART забьют передачи по другим интерфейсам, например... Не понятно как это решить в универсальной библиотеке Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 14 апреля, 2015 Опубликовано 14 апреля, 2015 · Жалоба Мне как-то внутренне кажется устраивать заопарк прерываний в ОС не верно. Именно, о чем я вам и говорил. В драйверах доступа к всяческой памяти никаких вытеснений и семафоров RTOS. Кто так делает убивает RTOS и получает просто примитивную многозадачность. Нельзя надеятся, что RTOS облегчит написание низкоуровневых драйверов. Наоборот она их усложняет. Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний. Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA. Сами прерывания это прерывания уровня ядра. Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний. Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA. Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними. Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код. В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача": создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в ISR-псевдозадачу. Получается простой хорошо читаемый линейный код вместо леса автомата состояний. Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня. Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных. О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так? Не в sleep, а в wait(). В ожидание объекта синхронизации (event, mutex, ...). А объект синхронизации взводится в прерывании по окончании передачи. В этом случае ОС не будет возвращаться к ожидающей задаче с каким-бы то ни было интервалом - задача будет спать чётко до момента окончания передачи. И затем практически сразу проснётся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними. Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код. В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача": создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в ISR-псевдозадачу. Получается простой хорошо читаемый линейный код вместо леса автомата состояний. Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня. О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п.. В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же. Во первых в скоростной периферии важнее хорошая отлаживаемость Во вторых хорошо читаемый только короткий код. Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться