Цитата(Сега @ Sep 28 2010, 10:03)

Хорошо, ну а какой смысл вообще оборачивать конструкторы в критические секции? Ну сработало прерывание (не касающееся этой периферии, так как инициализация еще не завершилась), отработали его, вернулись к инициализации и поползли дальше по конструктору, что должно сломаться?
ЗЫ: я не спорю, мне просто интересно
Так смысл абсолютно тот же, что и обсуждается сейчас здесь про неатомарные команды модификации битов порта.
Поясню на примере с ARM NXP.
Eсть регистр ввода-вывода (32 битный). В этом регистре настраиваются 16 линий порта на некоторые альтернативные функции, по 2 бита на пин. То есть, чтобы перенастроить некоторую линию (или группу линий) на другую функцию - нужно:
1. Считать значение IO регистра
2. Модифицировать значение нужным образом.
3. Записать новое значение в IO регистр.
При этом в конкретном драйвере мне нужно (предположим) перенастроить только 2 IO линии из 16-ти, за которые отвечает этот регистр.
Теперь - у меня RTOS с вытеснением (аналогичные рассуждения для прерываний).
В другой задаче у меня так же есть код, который оперирует настройкой линий IO в пределах тех же 16-ти линий того же порта.
Проследите, что будет, если где-то между 1. и 3. произойдет переключение контекста на другую задачу, которая решит также перенастроить линии порта (другие линии, но находящиеся в пределах этих 16-ти).
1a. Считать значение IO регистра
--- контекст a->b
1б. Считать значение IO регистра
2б. Модифицировать значение нужным образом.
3б. Записать новое значение в IO регистр.
--- контекст b->a
2a. Модифицировать значение нужным образом.
3a. Записать новое значение в IO регистр.
В результате операции, выполненные в 1б, 2б, 3б - будут похерены.
ЗЫ: Проблема в том, что подобные баги - трудноуловимы. Их проявление - стечение обстоятельств. То есть как правило - это нечто вроде: "У меня софт прекрасно работает месяц, но потом иногда затыкается обмен данными".
Или: "У меня 1 раз из 100 устройство не включается, но после включения все 99 раз все дальше работает без сбоев".