|
|
  |
дерганье ножками lpc2xxx, не наступайте на грабли! |
|
|
|
Jun 26 2008, 12:08
|
Участник

Группа: Свой
Сообщений: 54
Регистрация: 25-11-04
Из: Тула
Пользователь №: 1 228

|
Казалось бы такая простая вещь дергать ножкой... В Примерах к китам, повсеместно для установка пинов вызывается что типа: Код IO1SET |= 0x00000001; Как то раньше не задумывалься, пока глюку не словил, ножка "сама" прыгала в "1", хорошо это было направления 485 и контроллер просто переставал отвечать оставаясь в передаче, тяжело было не заметить. Проблема в том что операция не атомарная, и при наличии нескольких потоков, одновременно работающих с портом, в порт может быть выведена ерунда: если после загрузки значения IOSET в регистр произойдет переключение потоков, в другом потоке будут сброшены битики, потом управление будет возвращено первому потоку, он установить сброшеные биты обратно в "1" (аналогично для IOCLR). Решается проблема просто использованием Код IO1SET = 0x00000001 IO1CLR = 0x00000001 или помещением в критическую секцию. Тем более что Код IO1SET |= .. бесмысленно, т.к. запись нуля ничего не меняет. вот как выглядет на асме: Код //IO1SET |= 0x1; LDR R0, [PC, #+156] LDR R1, [PC, #+152] LDR R1, [R1, #+0] ORRS R1, R1, #0x1 STR R1, [R0, #+0]
//IO1SET_bit.P0_1 = 1; LDR R0, [PC, #+136] LDR R1, [PC, #+132] LDR R1, [R1, #+0] ORRS R1, R1, #0x2 STR R1, [R0, #+0]
//IO1SET = 0x1; LDR R0, [PC, #+116] MOV R1, #+1 STR R1, [R0, #+0]
|
|
|
|
|
Jun 26 2008, 12:26
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(HEX @ Jun 26 2008, 14:08)  Казалось бы такая простая вещь дергать ножкой... Тем не менее, извините, Вам удалось облажаться и эту лажу вынести на всеобщее обозрение. Цитата В Примерах к китам, повсеместно для установка пинов вызывается что типа: Код IO1SET |= 0x00000001; Нет. Для тех, кто читал документацию, это выглядит так. Код IO1SET = 0x00000001; Цитата Проблема в том что операция не атомарная Операция атомарная  , а IOSET, IOCLR и IOPIN это совсем разные регистры.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 26 2008, 12:47
|
Участник

Группа: Свой
Сообщений: 54
Регистрация: 25-11-04
Из: Тула
Пользователь №: 1 228

|
Цитата(zltigo @ Jun 26 2008, 16:26)  Тем не менее, извините, Вам удалось облажаться и эту лажу вынести на всеобщее обозрение. Поясните пожалуйста, чем вызвано оскарбление в мой адрес, и как это относится к теме сообщений?
|
|
|
|
|
Jun 26 2008, 13:19
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(HEX @ Jun 26 2008, 14:47)  Поясните пожалуйста,... Погорячился  изрядно. Извините. Цитата это относится к теме сообщений? К теме сообщения это относится так - Вы совершенно неправильно работаете с регистами установки и очистки битов, посему Ваше прeдупреждение ложно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 26 2008, 15:16
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Jun 26 2008, 16:19)  К теме сообщения это относится так - Вы совершенно неправильно работаете с регистами установки и очистки битов, посему Ваше прeдупреждение ложно. Предупреждение не ложно. Возможно ложен "наезд" на примеры к КИТам, но не само предупреждение. Надо бы просто перефразировать: IOSET/CLR - WriteOnly регистры и читать их бессмыслено. операции |= и &= и любые другие "чтение-мод-запись" к WriteOnly регистрам неприменимы ни при каких условиях - будь-то один поток или несколько.
|
|
|
|
|
Jun 26 2008, 15:50
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Jun 26 2008, 17:16)  Возможно ложен "наезд" на примеры к КИТам, но не само предупреждение. Ну чего только в "примерах" не выкладывают  лучше просто не смотреть, если не достигли приличного уровня владения вопросом  . Цитата Надо бы просто перефразировать: Или более общая формулировка - смотреть только документацию (за нее хоть кто-то в ответе), к примерам от производителя (их уже пишут и студенты, и индийцы...) относиться скептически, ко всем прочим (хорошее "просто так" очень редко встречается) - очень насторожено и не использовать до тех пор, пока четко не поймете и не пропустите через себя то, что там кто-то написал. Цитата(defunct @ Jun 26 2008, 17:16)  IOSET/CLR - WriteOnly регистры и читать их бессмыслено. IOSET можно (и бывает нужно!) читать, только вот почему-то рассчитывать на атомарность нескольких подряд операций c GPIO совершенно наивно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 27 2008, 19:50
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Jun 27 2008, 01:45)  Как для себя причислил сей регистр к WriteOnly и горя не знаю. А напрасно. GetSmart показывал интересный пример, когда это может быть чревато неприятностями. Не буду настаивать, что вам надо менять привычки, но взять на заметку, скорее всего, не помешает.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 28 2008, 23:54
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Jun 27 2008, 22:50)  но взять на заметку, скорее всего, не помешает. Спасибо, как на заметку пригодится. Хотя задач, где бы понадобилась слепая инверсия порта, не могу даже представить. Цитата когда это может быть чревато неприятностями. Ну почему же сразу неприятностями? Есть выход без неприятностей - просто использовать переменную, сработает для любой архитектуры. На некоторых архитектурах в частности на ARM такое решение будет более эффективным, за счет сокращения обращений к APB.
|
|
|
|
|
Jun 29 2008, 10:33
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(defunct) Спасибо, как на заметку пригодится. Хотя задач, где бы понадобилась слепая инверсия порта, не могу даже представить. Почему слепая? Простая нормальная инверсия. В отличие от "слепой", а точнее кривой инверсии через IOPIN. Цитата(defunct) На некоторых архитектурах в частности на ARM такое решение будет более эффективным, за счет сокращения обращений к APB. Обращение к порту - 7 тактов максимум. Чтение и запись в дополнительную переменную в раме - 5 тактов, плюс ещё загрузка адресных регистров - тактов 10. Так что не будет эффективнее. По крайней мере в большинстве случаев.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jun 29 2008, 19:03
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(GetSmart @ Jun 29 2008, 13:33)  Почему слепая? Простая нормальная инверсия. Потому что процессору все равно что выведено в порт, цель проинвертировать. В задачах с которыми я сталкиваюсь инвертировать (слепо - переворачивать значение порта) не нужно, нужно выводить конкетные значения. Цитата Обращение к порту - 7 тактов максимум. Чтение и запись в дополнительную переменную в раме - 5 тактов, плюс ещё загрузка адресных регистров - тактов 10. Так что не будет эффективнее. Загрузка адресных регистров есть и там и там. Или есть способ обратиться к APB без загрузки адреса? Забыли учесть возможное наличие кеш памяти, и то, что такты APB и такты процессора могут быть разной длительности.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|