Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Выносить ли работу с аппаратурой из кода?
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Программирование
BSVi
Народ - вот интересно - кто выносит код для работы с аппаратурой в другие файлы? Вот к примеру есть модуль для работы с таймером.

Можно прямо в модуле таймера написать

#pragma vector = TIMERA1_VECTOR
__interrupt void TimerA_CMP1_Interrupt()
{
TACCR1+=TIMER_1MS_CONST;
...


А можно сделать так

void timer_interrupt()
{
halSetTimerCCR1 ( halGetTimerCCR1() + 1 );

Где timer_interrupt() будет вызываться их interrupts.h в который собрать все прерывания, halSetTimerCCR1 и halGetTimerCCR1() соответственно гдето в модуле для работы с таймером A.

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

Как бы сделали вы?
Сергей Борщ
Цитата(BSVi @ Sep 2 2008, 10:57) *
Где timer_interrupt() будет вызываться их interrupts.h в который собрать все прерывания, halSetTimerCCR1 и halGetTimerCCR1() соответственно гдето в модуле для работы с таймером A.
Мне кажется, вы не там "делаете талию". И прерывания и таймер - аппаратура, поэтому вместе относятся к HAL.
BSVi
Я немного другой "таймер" имел ввиду - у меня модуль, который из одного аппаратного таймера делает до 255 виртуальных, которые могут быть использованны таким образом

myTimer timer1, timer2

timer1.start( 100, &my_func1 ); // 100 - задержка в миллисекундах
timer2.start( 200, &my_func2 );

когда истекает время, вызывается нужная функция.

Да, действительно тут тонкая граница которую чувствовать нужно ) Скорее всего, это приходит с опытом которого у меня маловато.


Да, может подскажете (или покажите) образцово - показательные исходники на тему - резделение HAL и не HAL )
rezident
Цитата(BSVi @ Sep 2 2008, 15:19) *
Я немного другой "таймер" имел ввиду - у меня модуль, который из одного аппаратного таймера делает до 255 виртуальных, которые могут быть использованны таким образом
По-моему вы пытаетесь изобрести какую-то ОС, но делаете это как-то через (_*_). Извините за сравнение. rolleyes.gif Разделение программы на функциональные модули и применение КА дает вполне нормальные результаты. Раз у вас таймер выполняет системную функцию разделения вычислительных ресурсов по времени (планировщик?), то и делайте этот функционал в одном модуле. А вот вызывать его можно будет из нескольких других. Для этого можно разделить хедер на "внутренний" (для данного модуля) и "внешний" (подключаемый к другим модулям). Во "внутреннем" хедере какие-то константы характерные только для это таймера разместите, например, ту же самую TIMER_1MS_CONST, которая у вас в примере используется. А во "внешнем" типы структур и прототипы вызовов функций, используемых другими модулями из данного.
BSVi
нет, я не делаю ОС - просто программа, где будет много тайм-аутов, для них хочется иметь хороший (удобный) таймер. При этом программа будет работать на msp430, LPC2000 и PC.

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

Про заголовки я так и делаю. Таймеру не нужно много констант, и поэтому там один хедер. Там где нужно их много - типа стеков протоколов связи - так и делаю. Дугое дело вот в чем - где та граница, когда функционал нужно выносить в HAL?

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

Может есть какие-нибуть рекомендации по этому поводу?
jorikdima
В HAL переносится все то, что необходимо менять если смените платформу. Глядя на функцию посмотрите, универсальна ли она (платформонезависима), если нет, то в ХАЛ ее.
aaarrr
Цитата(BSVi @ Sep 3 2008, 11:06) *
Может есть какие-нибуть рекомендации по этому поводу?

Если предполагается использовать много таймаутов, то имеет смысл сделать программный таймер с нужным количеством каналов. Тогда привязка к платфоме сведется к настройке таймера и передаче управления из прерывания на обработчик, а использование софт-таймера организуется через собственное API.
rezident
Цитата(BSVi @ Sep 3 2008, 13:06) *
нет, я не делаю ОС - просто программа, где будет много тайм-аутов, для них хочется иметь хороший (удобный) таймер. При этом программа будет работать на msp430, LPC2000 и PC.
Раз это не ОС, то для организации таймаутов ИМХО вовсе не нужно 255 таймеров. Вполне достаточно одного, "тикающего" с разумно-минимально-требуемым интервалом времени. Каждый процесс в котором требуется таймаут запрашивает у общего таймера его текущее значение и сам сравнивает с величиной требуемого ему таймаута простым беззнаковым вычитанием двух переменных. Если разность внутри диапазона таймаута, то в зависимости от поведенческой модели процесс может передать управление следующему (в суперцикле), либо ожидать окончания таймаута. Если вы используете 1мс "тики" таймера, то 16-и разрядная переменная, инкрементируемая в прерывании от таймера на величину соответствующую 1мс времени, даст максимальный интервал времени в 65,5 с, 32-х разрядная переменная "тиков" дает уже период более, чем в полтора месяца. Только естественно нужно на платформах меньшей разрядности обеспечить атомарность доступа к такой переменной.
Цитата(BSVi @ Sep 3 2008, 13:06) *
Сейчас я решил, что вообще весь модуль таймера нужно вынести в HAL. Те переписать его для всех платформ так, чтоб HAL экспортировал одинаковые функции для таймеров.
Оформите его как функцию-драйвер. С командами инициализации, чтения, записи и т.п. Для разных платформ вам нужно будет лишь поправить аппаратно-зависимую часть инициализации таймера. А обращения/вызовы этой функции-драйвера останутся одинаковыми.
AlexandrY
HAL применим только в определенных известных случаях, и означает несколько другое.

Гораздо острее при разработке на микроконтроллере стоит проблема планирования ресурсов периферии микроконтроллера.
HAL нооборот затрудняет планирование ресурсов, поскольку стремится скрыть их ограниченность.

Пример даный выше типа:
void timer_interrupt()
{
halSetTimerCCR1 ( halGetTimerCCR1() + 1 );

HAL-ом не является поскольку в названиях явно указывается на таймерную логику CCR в канале 1.
Это типичный пример организации BSP, а не HAL.

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

Я в BSP всегда стараюсь явно указывать имена регистров без упрятывания регистровых обращений в какие-то оберточные функции.
Лишние функции усложняют броузинг кода и следовательно затрудняют анализ распределения ресурсов периферии.
Ну и конечно по возможности группирую функции с обращениями к регистрам по тематическим группам.
Например все что работает с UART-ами в один файл, все что с I2C в другой и т.д.

В вашем случае я бы оставил прямое обращение к регистрам, но саму процедуру ISR поместил бы в файл работы с таймерами.

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


Цитата(rezident @ Sep 3 2008, 21:09) *
Оформите его как функцию-драйвер. С командами инициализации, чтения, записи и т.п. Для разных платформ вам нужно будет лишь поправить аппаратно-зависимую часть инициализации таймера. А обращения/вызовы этой функции-драйвера останутся одинаковыми.
doomer#gp
Я делаю следующим образом.
Завожу структуру содержащую указатели на low-level код и служебные данные.
А из процедур "уровня приложения" вызаваю абстрактные функции, которые работают через эти переходники. Для таймеров завжожу связанные списки событий. Теперь можно ставить кучу в обработчиков из разных частей кода (как в ОС). Единственное, чтобы время прохода связанного списка было на порядок меньше минимального таймаута.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.