2016-12-20 3 views
0

Можно ли разделить выровненную целочисленную переменную, не превышающую естественное слово процессора, с изменчивым квалификатором, между основной программой и ISR в C? Гарантировано ли, что никакие рваные чтения или записи не могут произойти?Можно ли делиться изменчивой переменной между основной программой и ISR в C?

+0

Возможный дубликат ключевого слова [C 'Volatile' в ISR и многопоточной программе?] (Http://stackoverflow.com/questions/12738672/c-volatile-keyword-in-isr-and-multithreaded-program) –

+0

Зависит от в системе ... Я использовал систему (Z80), где вам нужно было отключить прерывания, чтобы гарантировать безопасную запись 2-байтового значения в присутствии ISR –

+0

@AN Это не дубликат. Мой вопрос касается атомарности и рваных записей/чтений, которые не охватываются указанным вами вопросом. – mrn

ответ

3

Ключевое слово volatile не означает атомарность - это просто гарантирует, что переменная явно прочитана и не предполагается, что она не изменилась.Для безопасного совместного доступа без какого-либо другого механизма защиты переменная должна быть как атомарной, так и объявленной volatile.

Компилятор может документировать типы, которые являются атомарными для любой конкретной цели, и для этой цели может определять sig_atomic_t.

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

+0

Нет никакой гарантии, что все, что вам нужно, - это явное чтение/запись и атомарность. Будущие аппаратные платформы могут иметь другие требования, о которых мы не знаем сегодня. Там просто нет гарантии, периода. –

+0

@DavidSchwartz: При написании системного кода уровня, вероятно, справедливо предположить, что вы знаете о зависимостях платформы, которые не зависят от языка. Кроме того, для написания системного кода вы пишете определенную систему * сейчас *, а не какую-то возможную неизвестную будущую систему. – Clifford

+0

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

0

Проверьте свой компилятор. ISR нестандартны. Кроме того, у C нет реального понятия «естественное слово процессора», кроме, возможно, int.

1

Что касается ключевого слова volatile, он просто защищает от возможных неправильных оптимизаций компилятором. Это не помогает в обеспечении безопасности потоков.

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

В противном случае вы можете сделать «мьютекс бедных» с помощью bool. Это работает только для конкретного случая ISR микроконтроллеров, которые не могут быть прерваны другими прерываниями. Поскольку вы знаете, что ISR не может быть прервана, вы можете сделать это:

static volatile bool busy; 
static volatile uint16_t shared; 

void isr (void) 
{ 
    if(!busy) 
    { 
    shared = something; 
    } 
} 


void main (void) 
{ 
    ... 

    busy = true; 
    do_something(shared); 
    busy = false; 

    ... 
} 

При таком подходе, это не имеет значения, если busy или shared атомарные или нет. Независимо от того, где триггеры прерывания, shared не будет уничтожен средним доступом.

0

Ответ «иногда». Если либо ISR, либо основной процесс изменяет переменную, тогда вы в порядке. Однако, если оба манипулируют переменной, что-то вроде

main 
Var = Var + 10 

ISR 
Var = Var + 10 

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

Main - Get Var 
ISR -   Get Var 
       Add 10 
       Store Var 
       Return 
     Add 10 
     Store Var 

Тогда конечный результат будет 10, а не 20

Как предыдущий плакат сказал, что нужно будет у вас есть код защиты, чтобы предотвратить это.

1

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

От С99 стандарт 7.14:

2 типа, который определен в

sig_atomic_t

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

+0

'sig_atomic_t' является булевым типом. И C99 не является стандартным C. Стандарт C обеспечивает атомарность опционально. – Olaf

+0

@Olaf Ну, стандартные авторы наверняка потратили впустую время, включив 'SIG_ATOMIC_MIN' и' SIG_ATOMIC_MAX', если вы правы относительно '' '' '' '' '' '' '' '' '' '' '' '' булев. Но они также сэкономили время, не изменив определение 'sig_atomic_t' между C99 и C11. Так и есть. –

+0

(Извините, я ошибся в том, что 'sig_atomic_t' является булевым типом). Во всяком случае, 'sig_atomic_t' является частью' signal.h' и не требуется для самостоятельной реализации и среды, и большинство из них не предоставляют его. ОП, похоже, использует такую ​​среду. 'stdatomic.h' OTOH ** ** предоставляется для некоторых реализаций, например. gcc на платформах ARM. Так что это, безусловно, лучшая идея для использования. Также этот заголовок предоставляет информацию, если к обычным типам обращаются атомарно ('ATOMIC_INT_LOCK_FREE' и т. Д.), Которые могут, например, тестироваться со статическим утверждением (что делает ваше первое утверждение сомнительным). – Olaf

Смежные вопросы