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

Как ПРАВИЛЬНО программировать на С++

Я вам более реальный пример приведу.

Прибегает снабженец и говорит такую речь:

У атмеля проблемы с поставками, поэтому вместо ATMega128 я закупил ящик msp430f149.

У вас неделя, чтобы привести в порядок документацию.

 

Вопрос: что будет делать ваша библиотека?

Если бы случилась такая фигня, то лично моя библиотека бы ничего не стала делать.

Снабженец был бы просто уволен.

Потому что это не в его компетенции - делать подобные вещи.

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

 

 

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


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

Пардон, PORTB.1 а не 0...

 

Пардон, PORTB.1 а не 0...

Гы... Короче, A.0, A.1, R.1, R.5

 

Предлагаю посоревноваться с автором листингами записи групп на ХМЕГА. Будем туда писать постоянные, переменные... Например, исходно имеем группу из 4...6 бит. Часть из них на виртуальном порту, часть - нет. Предлагайте варианты как расположить битовые группы и что туда загнать. Если интересно, конечно...

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


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

Если бы случилась такая фигня, то лично моя библиотека бы ничего не стала делать.

Снабженец был бы просто уволен.

Да, согласен, утрировал немного (самую малость).

Но и товарищ был не прав, выдавая частный случай и свою узкозаточенную реализацию (без исходников, кстати) за истину в последней инстанции.

 

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


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

Да, согласен, утрировал немного (самую малость).

Но и товарищ был не прав, выдавая частный случай и свою узкозаточенную реализацию (без исходников, кстати) за истину в последней инстанции.

Исходники для XMEGA обещаны. Если посоревнуемся и они окажутся достойными авторских, конечно... А если они окажутся плохими, то зачем миру мои нелепые исходники? :)

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


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

Гость DL36

Есть хорошая статья, Атомарный доступ к структурам по поводу атомарности.

О "волшебном" свойстве XOR я знал давно, но формализованный подход увидел первый раз на форуме microchip.com. Автор замечательной коммерческой RTOS AVIX-RT выложил макрос, который использует inline ассемблер для реализации xor доступа. Затем в состав AVIX вошел заголовочный файл, в котором реализованы расширенные варианты подобного макроса для архитектур PIC24/dsPIC (компилятор C30) и PIC32 (MIPS32 M4K, компилятор C32).

 

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

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


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

Есть хорошая статья, Атомарный доступ к структурам по поводу атомарности.

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

А ведь действительно...

В последнее время всё чаще приходится воевать с "чудесами" в структурах.

Надо будет тщательнее рассмотреть...

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


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

Есть хорошая статья, Атомарный доступ к структурам по поводу атомарности.

 

 

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

Боюсь для tiny/maga AVR этот матод не реализуем - нету в них атомарного xor. Для XMaga он не нужен - есть специальные регистры для атомарного И/ИЛИ. А для MSP430 не знаю, надо разбираться, может и сработает.

 

Строго говоря, приведённый код не является атомарным. Прерывание так-же может произойти между чтением регистра и его модификацией/записью с помощью xor. Однако побочные эффекты при этом будут другие: если в прерывании изменятся биты, которые должны быть изменены с помощью последнего xor, то их значение будет ошибочно инвертировано.

Лучше это или хуже чем терять значение записанное в прерывании не знаю, ни то не другое не есть хорошо и прерывания всё равно прийдётся запрещать.

 

 002FA  801630     mov.w TRISB, W0
002FC  68006A     xor.w W0, #0x000A, W0
002FE  60006F     and.w W0, #0x000F, W0
00300  B6A2C6     xor.w TRISB

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


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

Боюсь для tiny/maga AVR этот матод не реализуем - нету в них атомарного xor. Для XMaga он не нужен - есть специальные регистры для атомарного И/ИЛИ. А для MSP430 не знаю, надо разбираться, может и сработает.

Для Хмега тоже есть изюминки. Там SBI за 1 такт выполняется, поэтому, если порт отображен на виртуальный, && количество бит, принадлежащих этому порту порту, 1 или 2, то выгоднее по тактам обращаться побитно через SBI/CBI VPORTn_OUT, а иначе - через OUTSET/OUTCLR физического порта.

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


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

Строго говоря, приведённый код не является атомарным. Прерывание так-же может произойти между чтением регистра и его модификацией/записью с помощью xor. Однако побочные эффекты при этом будут другие: если в прерывании изменятся биты, которые должны быть изменены с помощью последнего xor, то их значение будет ошибочно инвертировано.

Лучше это или хуже чем терять значение записанное в прерывании не знаю, ни то не другое не есть хорошо и прерывания всё равно прийдётся запрещать.

Как раз-таки нет.

Насколько я понял, на биты, которые мы отгородили для XOR-енья, оставшиеся никак влиять не будут, при условии, естественно, что они модифицируются аналогичным образом.

Всё потому, что мы накладываем на XOR-ную маску ещё маску пинов, то есть на "чужие" пины она никакого влияния не окажет.

_______

Вот какая полезная тема оказалась, я бы до такого сам бы не дошёл!

Причём совершенно параллельно, на си это написано или на плюсах...

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


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

А с проблемой атомарности там на хмеге действительно легче. Кроме одного случая: групповая конфигурация режимов пина. Там тоже надо ставить критическую секцию. Но тут еще проблема - ГДЕ ставить начало критической секции. Если в группе несколько портов с битовым доступом и всего для одной пары бит нужна критическая секция - зачем же запрещать прерывания в самом начале? Это ж на сколько лишних татктов МК "оглохнет"! Надо запрещать прерывания только перед той операцией, где это действительно требуется.

 

Вот какая полезная тема оказалась, я бы до такого сам бы не дошёл!

Причём совершенно параллельно, на си это написано или на плюсах...

Вот видите, самипоняли важность, а то недоумевали - зачем этот пришлый выскочка поднял такую узкую тему. Атомарность это ого-го. PS.На Телесистемах перестройка - я с вашего разрешения тут пережду. Заодно поколыхаю немножко вашу тихую заводь :)

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


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

Как раз-таки нет.

Насколько я понял, на биты, которые мы отгородили для XOR-енья, оставшиеся никак влиять не будут, при условии, естественно, что они модифицируются аналогичным образом.

Всё потому, что мы накладываем на XOR-ную маску ещё маску пинов, то есть на "чужие" пины она никакого влияния не окажет.

_______

Вот какая полезная тема оказалась, я бы до такого сам бы не дошёл!

Причём совершенно параллельно, на си это написано или на плюсах...

 

mov.w TRISB, W0 //TRISB == 0x0000

xor.w W0, #0x000A, W0 //W == 0x000A

and.w W0, #0x000F, W0 //W == 0x000A

 

//прерыване

//сохраняем W и т.д.

mov.w TRISB, W0 //TRISB == 0x0000

xor.w W0, #0x0028, W0 //W == 0x0028

and.w W0, #0x003C, W0 //W == 0x003C

xor.w TRISB //TRISB == 0x0028

//восстанавливаем W и т.д.

//конец прерывания

//W == 0x000A, TRISB == 0x0028

xor.w TRISB // TRISB = 0x0022 --> один бит потеряли, должно быть 0x002A

 

Так, что и тут есть подводные камни. Но только в случае, если модифицируется пересекающееся множество бит.

Если модифицируемые биты различны, то проблем нет.

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


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

xor.w TRISB // TRISB = 0x0022 --> один бит потеряли, должно быть 0x002A

У вас маски перекрываются, так не договаривались :rolleyes:

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


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

Если правильно спроектировать код - то не будет такого бреда, как запись в порт в прерывании и в основном потоке.

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


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

Если правильно спроектировать код - то не будет такого бреда, как запись в порт в прерывании и в основном потоке.

Согласен, в большинстве случаев этого можно и нужно избегать, но иногда это бывает оправдано.

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


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

Если правильно спроектировать код - то не будет такого бреда, как запись в порт в прерывании и в основном потоке.

 

Это никакой не бред. Gpio - они на то и Gpio, чтобы ими можно было программно махать.

При проектировании аппаратной части устройства те сигналы, которые управляются через gpio могут использоваться много для каких целей, от простейшего управления светодиодами, до каких-то сигналов стробирования периферийных устройств(работающих по прерываниям), генерации последовательностей импульсов, напрмер управления шаговиками (это то что пришло на ум сразу из того, что я реально делал). Часть этих портов могут управляться из фоновой программы, частью - целесообразно управлять из прерываний. Если используется RTOS - то управление может производится в том числе из разных задач. И только не говорите, что это неправильно спроектированный софт и бред. Бред как раз - это обеспечивать управление всеми gpio из одной задачи в случае RTOS, или только из background при ее отсутствии.

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

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

Я с АВР давно уже не работаю и не отслеживаю, что там у них и как со свойствами периферии и/или системой команд.

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

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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