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

Обобщенные драйвера

Есть контроллер (UART, USB, Ethernet, ...). Можно работать с его регистрами напрямую "в лоб", но структурированность и переносимость такого кода нулевые.

 

Можно написать драйвера, которые виртуализируют этот контроллер. И вместо обращения к регистрам происходит использование макросов и функций таких драйверов. Это хорошо, ибо можно написать симулятор контроллера, и отлаживать целевую программу на нем.

 

Более того, симулятор может принимать команды для контроллера, передавать их по каналу связи на железяку с контроллером, и выполнять их там. Обратно можно передавать ответы реального контроллера и данные. Это небыстро, но, зачастую, на начальном этапе освоения контроллера роль ошибок в документации и ошибок воприятия документаци куда важнее скорости. Лично я ненавижу такую процедуру: записал дрова, откомпилил, прошил, запустил, проверил - не в дугу. Написал чуть по другому, собрал, снова залили и т.д.

 

Но накладных расходов никто не отменял! Если вместо проверки бита готовности в регистре я буду вызывать некую функцию, то где-то это может стать просто фатально. Мощность современых контроллеров растет, но все же не хочется закладывать принципиально избыточные решения.

 

Можно пойти по пути макросов, но это сложно и не сильно универсально (макрос раскрывается либо в вызов симулятора, либо в набор операций с регистрами контроллера).

 

Есть более изящный способ!!!!

 

Берем кодогенератор типа Templarian

http://sourceforge.net/projects/templarian

 

В нем прописываем все "методы" объекта контроллера. Для разных вариантов - симулятор, "телепортация", "родное" исполнение кода.

 

В нужных местах проекта вставляем "выход" такого кодогенератора - и вуаля! Автоматическая модификация текста под целевую платформу готова!

 

Преимущества над макросами уже описал. Преимущества над #ifdef очевидны.

 

Если я ничего не путаю, в методиках использования С++ это называется "отделение интерфейса от реализации". Снова я кусок С++ "изобрел" :)

 

Продолжаем тему совершенствования работы с контроллерами.

 

Самое тупое, что бывает при освоении нового контроллера - это чтение линейной PDF документации на него. Т.е. ты вначале парсишь мозгами 10м файл, затем, осознав, из чего же состоит твой контроллер, уже немного начинаешь ориентироваться в нем.

 

Что касается самго процесса написания документации, то я так и вижу уходяшие к горизонту вереницы tecnical wrighters (надо полагать, прикованных за ногу к батарее), которые правят бесчисленные таблицы в документации какой-нибудь ATxmega. Хоть одна ошибка - и плеть надсмотрщика...

 

Мы пойдем другим путем.

 

Берем XML и строим иерархическую структуру типа:

* контроллер

* интерфейс контроллера

* регистр

* битовое поле (офсет и длина)

* зачения этого поля

 

Естественно, к каждой сущности приписано ее описание нормальным языком.

 

(я не считаю XML правильным или неправильным, я привел его как пример иерархической организации данных. Реализация идеи может быть сделана любым другим способом.)

 

Из этой структуры автоматически генерим "картинки с текстом" в виде графа сущностей контроллера. Так будет просто на порядки нагляднее линейнго описания.

 

Теперь берем программистский редактор, который воспринимает наше описание как... DTD! Выглядит этот так:

* жмем кнопарь - хочу работать с периферией

* далее выбираем : контроллер -> интерфейс -> регистр -> битовое поле -> значение

 

На каждом шаге мне автоматически подсовывается список того, из чего я могу выбрать в данный момент. И все это оформляется как "вызов" кодогенератора!

 

Размер исходника будет гораздо больше, но скорость восприятия несопоставимо выше. Мне не надо держать в голове всю информацию о регистрах. Мне нужно примерно помнить, как устроен контроллер, а далее "говорящие названия" все мне скажут.

 

Можно, конечно, наплодить чудо-хидеров, которые отчасти будут использовать ту же идеологию, но:

* чудо-хидер повышает время сборки проекта

* чудо-хидер не гарантирует, что моя IDE осознает его чудо-структуру и так удобно, как я описал, мне все подскажет

* переносимость всего этого чудо-хозяйства между компилерами неочевидна (битовые поля компилеры поддерживают, мягко говоря, по разному).

 

В реальности регистры устройства состоят из многих полей, и, прежде чем проициализировать регистр я должен "синтезировать" все слово, записываемое в регистр.

 

Т.е. в тексте у меня это будет выглядеть как-то так

Обращение к кодогенератору (Ethernet.Control.Satate_Of_Chip_WR,
                PKT_LEN =1560,
                SPEED=100,
                FLOW_CONTROL=ON)

 

что раскроется в выражение типа

*((volatile unsigned int*)0xFFFF0000)=((0x618<<24)|(1<<2)|1));

 

Получается все сбалансированно - описание для кодогенератора совместимо с любым программером :) (и оно совершенно понятно без тщательного чтения доки на чип), а plain С строка совместима с любым С компилятором.

 

Ну и в качестве вершины такого подхода можно предложить обобщенные методы.

 

Например, у нас есть Ethernet_Init, которому в качестве параметров передается длина пакета, скорость, ну и много чего. А этот метод раскрывается в целый кусок кода:

* сборка значений в регистры

* запись в нужной поледовательности

* проверка готовности

* пр.

 

Тогда этот самый Ethernet контроллер для внешнего мира выглядит как компактный набор методов, которые в реальности суть очень эффективный С код.

 

Комбинация двух описанных выше подходов возволяет полностью исключить ручную низкоуровневую модификацию исходников при переходе от навороченного синтетического порта к, например, ATmega88P, которая еще очень долго будет "уделывать" по потреблению все эти супернавороченные ARM'ы при работе от кварца 32768.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть контроллер (UART, USB, Ethernet, ...). Можно работать с его регистрами напрямую "в лоб", но структурированность и переносимость такого кода нулевые.

Со структурированностью - не согласен. Сам работал с пятью(шестью?) контролерами Ethernet. Никто уже чисто изобретением велосипедов не занимается, есть пару подсемейств и сруктурируются они достаточно хорошо. Как пример очень старый проект http://crynwr.com/.

С более простыми вещами, типа UART попытка наворотить еще один уровень абстракции просто отсекает некоторые приятные особености коннкретного чипа, загоняет его под общую гребенку. Ради чего? Ради того, что-бы вместо нескольких десятков строк кода получить десяток строк одинакового кода и несколько сот строк кода почему-то априори считающегося безошибочным виртуализатора?

Ну а если создан структурированный код, то и переносимость уже далеко не нулевая.

Потом появится новый контроллер не слишком вкладывающийся не вкладывающийся в прокрустово ложе. Что будем делать?

Приходит изобретатель:

- Я придумал автомат для бритья!

- И как он работает?

- Клиент опускает монетку в эту щель, засовывает голову в это отверстие — и шесть лезвий начинают его брить.

- Позвольте, но ведь у каждого человека индивидуальное строение лица?

- Ну, в первый раз — да…

 

Такой подход к делу считаю нехорошим, хотя и очень распростаненным. Причем распространеным вне зависимости от того "банальный драйвер", или новая чудо технология. Буквально на прошлой неделе разбирался с Интеловскими драйверами под Linux. Десять c лишним лет развития чипсетов фирмой Intel прошли мимо этих драйверов - добавляем новые VID и PID и минимальная поддержка на уровне базовых функций типа "работает". Все остальное оставляем за бортом.

Ну не получится всех под одну гребенку и

* жмем кнопарь - хочу работать с периферией

без накладных расходов ввиде НЕ ИСПОЛЬЗОВАНИЯ возможностей железа.

 

Если я ничего не путаю, в методиках использования С++ это называется "отделение интерфейса от реализации".

Только вот удачные реализации такого подхода встречаются редко :( И то на относительно высоком уровне - драйвер-система, а отнюдь не регистр_железа-система.

Самое тупое, что бывает при освоении нового контроллера - это чтение линейной PDF документации на него. Т.е. ты вначале парсишь мозгами 10м файл, затем, осознав, из чего же состоит твой контроллер, уже немного начинаешь ориентироваться в нем.

Отнюдь. Как человек освоивший немалое количество контроллеров, могу точно сказать, что дело обстоит совсем не так. Из чего состоит - на певой станице PDF. Дальше конкретные разделы. По тем-же UART - это считанные страницы. Не думаю, что свою абстакцию Вы сможете изложить на меньшем количестве страниц :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, видимо я непонятно выразился.

 

Я не прокрутстово ложе строю. Я строю максимально гибкий способ делать рутинные задачи.

 

Самое главное, что я вынес из чтения буков по С++ (и собственных долгих уединенных размышлений на тему структурирования С исходников) - это то, что хороший язык программирования:

* имеет некий базис примитивов - базовую систему координат

* в этой системе можно любую задачу решить "в лоб". Теоретически.

* но также с его помощью можно построить некую оптимальную систуму координат (оставим пока критерий оптмальности)

* и рамках этой системы координат решить целевую задачу "в два экрана".

 

Сила С++ в том, что он дает непревзойденную гибкость в плане построения целевой системы координат.

 

Способ решения к масштабу никакоего отношения не имеет. Формально контроллер - это объект, и у него есть своим методы - хоть битовые операции.

 

Вопрос в накладных расходах. С++ в лоб для драйвера - спорно и стремно. А вот некий кодогенератор, который на выходе дает plain C код, который тут ту же контролируешь - вот это сила!

 

Ладно, подумаю, как это описать более внятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не прокрутстово ложе строю. Я строю максимально гибкий способ делать рутинные задачи.

Нет такого способа без заметных накладных расходов.

Способ решения к масштабу никакоего отношения не имеет. Формально контроллер - это объект, и у него есть своим методы - хоть битовые операции.

Да бога ради, только вот контроллеры-объекты разные. Вот и получается прокрустово ложе.

А пока я даже не видел хоть скол-нибудь вменяемых визардов генерящих "плайн С код", даже для одного типа контроллера. Обычно результат за гранью приемлимого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ок. Пусть контроллеры сильно разные.

 

Но! У нас все равно есть некие базовые примитивы решаемой задачи

* пакет

* прием пакета

* передача пакета

* ошибки

* управление интерфейсом.

 

А вокруг этих примитивов уже нанизана конкретика.

 

Я хочу, чтобы глядя в код чужого человека сразу видеть каркас кода и связи между отдельными частями. А затем концентрироваться на отдельной, махонькой части, и мозгами разбирать ее. Тут все тулзы отдыхают - мозги лучшая тулза. Но только не надо перегружать его тем, что машина сделаем лучше!!! Хранением иерархической формализованной информации и пр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но! У нас все равно есть некие базовые примитивы решаемой задачи

* пакет

* прием пакета

* передача пакета

* ошибки

* управление интерфейсом.

Только тут кнопочками на битиках в регистрах и не пахнет. Это та самая структурированность к коей всяки разны кодогенераторы имееют отношение десятое. Хорошо стуктурированные вещи можно обернуть кодогененраторами (добавив ошибок и ограничений :) :( ), а можно и нет, ибо это частные мелочи - основная работа структурировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробовал сделать нечто вроде альтернативы описаниям регистров в виде макросов.

 

http://electronix.ru/forum/index.php?showt...=38364&st=0

 

Пример. В чипе есть три куска периферии, пусть UART. Ведь они все похожи, но отличаются только стартовыми адресами и, возможно, парой регистров. Так почему бы не взять шаблон и параметризировать его только начальным адресом, а все отличия описать уже в виде его конкретизации для конкретного класса.

 

Более того. Шаблонов можно написать сколько угодно, но в код они преврататься только при реальном использовани.

 

А еще каждый регистр можно описать шаблоном, которому сообщается начальныq адрес и размер полей, а он (екземпляр) уже пишет данные или сообщает об их некорректности на этапе компиляции.

 

По результатам применения на деле могу сказать, что это замедляет обращение к регистрам в два-три раза, зато пользоваться очень удобно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если есть желание и желающие, то сравните эффективность кода, генерируемого для контроллеров Freescale в следующих вариантах:

1. ProcessorExpert + Metrowerks CodeWarrior

2. Quick_Start + Metrowerks CodeWarrior

3. свой код + Metrowerks CodeWarrior (Это самый тяжелый вариант в плане инициализации)

 

1. ProcessorExpert наглядная среда разработки, очень быстро для малых проектов, большие у меня вообще не пошли.

2. Quick_Start это набор макросов и некоторого стартового кода. Это альтернатива от Freescale ProcessorExpert`у. Накладных ресурсов минимум, работает быстро. На большом проекте именно с Quick_Start все было сделано и достаточно быстро.

3. По счастью до это дело не дошло, выручил п.2.

 

Контроллеры сильно разные по архитектуре, а универсальный и Эффективный набор скорее всего лишь мечта. ProcessorExpert есть под разные семейства, а эффективность кода не очень.Quick_Start есть под очень ограниченное число контроллеров Freescale.

 

grau

 

А еще каждый регистр можно описать шаблоном, которому сообщается начальныq адрес и размер полей, а он (екземпляр) уже пишет данные или сообщает об их некорректности на этапе компиляции.

 

По результатам применения на деле могу сказать, что это замедляет обращение к регистрам в два-три раза, зато пользоваться очень удобно.

Что-то есть общее с Quick_Start.

 

IMHO: универсальность применима при наличии запаса по производительности. В случае жесткого времени или ограниченности ресурсов накладные расходы на универсальность могут свести все к неработоспособной системе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть контроллер (UART, USB, Ethernet, ...). Можно работать с его регистрами напрямую "в лоб", но структурированность и переносимость такого кода нулевые.

 

 

Есть более изящный способ!!!!

 

Берем кодогенератор типа Templarian

http://sourceforge.net/projects/templarian

 

В нем прописываем все "методы" объекта контроллера. Для разных вариантов - симулятор, "телепортация", "родное" исполнение кода.

 

Мы пойдем другим путем.

 

Берем XML и строим иерархическую структуру типа:

* контроллер

* интерфейс контроллера

* регистр

* битовое поле (офсет и длина)

* зачения этого поля

 

Естественно, к каждой сущности приписано ее описание нормальным языком.

Очень заманчивый подход, более того, у все большего количества производителей MCU появляются такие тулзы (по крайней мере на уровне настройки потрохов самих MCU), но тут есть одно НО - те самые xml должен кто-то писать, и что бы не отставать от выпуска новых семейств/чипов этот 'кто-то' должен быть самим производителем, а с этим проблемы :07: Увы даже у них самих зачастую описатели чипов присуствуют в нескольких форматах для разных ихних же тулзов (например у Microchip'а) и с разным заполнением (количество MCU прописанных в ихнем Wizard'е на порядок меньше, чем в MPLAB'е)

 

Можно попытаться конвертировать описания из того же MPLAB'а (там они есть все) в нужные xml автоматически так же натыкается на трудности - в исходных описаниях есть не все, что нужно Wizard'у, кроме того, у разных производителей они принципиально разные :cranky: Так что остаестя ждать, пока какая нибудь крупная фирма не возьмется за титанический труд и не сделает что-нибудь, из чего со временем получится стандарт, или не найдется тысяча другая энтузиастов которые возьмутся за систематизирование информации. :wacko:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен полностью с Евгением, линейное представление документации полностью себя изжило. современные контроллеры обязательно должны быть представлены в древовидном виде. К тому же полностью поддерживаю мысль про xml, т.к. это единственное на сегодняшний момент лучшее средство. преназначенное именно для целей древовидного представления. Скорее всего, не за горами время, когда производители это осознают и начнут повсеместно переводить документацию и средства разработки на иерархические рельсы. Нам остается только ждать. Тем не менее, Евгению, рекомендую, поглубже покопать эту тему и написать диссертацию, т.к. определенно тема отличается новизной и актуальностью. Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...