ПредишенСледващото

запознат със следните ситуации във вашия C или C ++ код, вградени системи ли сте?

• Кодът работи добре - докато не бъдат решени чрез оптимизация на компилатор.
• Кодът работи добре - докато не активирате прекъсва.
• бясно тичане на драйверите.
• RTOS задачи работят добре в изолация - докато се генерира някаква друга задача.

Ако отговорът е "да" на някой от тези въпроси, то е вероятно, че не се използва тази променлива. Но вие не сте сами. Малко програмисти разбира как да се използва летлив. За съжаление, много книги, посветени на езика за програмиране на C обръщат малко внимание на квалификациите летлив.

Ключова дума летлив език C е квалификант, който се добавя към декларацията на променливата (тип променлива квалификант, като CONST на квалификант). В него се разказва компилаторът, че стойността на променлива може да бъде променяна по всяко време - без никаква видима за действие за код компилатор, променливата на средата. Последиците от това са доста сериозни. Въпреки това, преди да се справим с това, нека да погледнем на синтаксиса.

[Синтаксис ключова дума летливи]

За да се декларира променлива като летлив, добавете летлив ключова дума, преди или след типа на данните в променливата определение. Например, по-долу са еквивалентни като определяне променлива Фу число с имота летливи:

Същото важи и за начина на летливи-променливи, особено свързани с паметта картирани регистри, вход / изход (памет картирани I / O регистри). И двете от тези декларации са еднакво решена импрегниран bezznakoe като указател към 8-битово число на (байт) с имота летливи:

Летливи указатели към не-летливи данни са много редки, но трябва да се отбележи все пак, и синтаксиса е възможно:

И само за пълнота, ако изведнъж наистина трябва да получим указател на летливи енергонезависима-променлива, а след това го пиша по този начин:

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

[Правилното използване на летливите дума]

Променливата трябва да бъдат декларирани като летлив, когато му е възможно неочаквана промяна. На практика това може да е само на 3 вида променливи:

1. паметта картирани регистри на процесора или периферно устройство (памет-картирани периферни апарати).
2. Глобалните променливи модифицирани в кода за прекъсване манипулатор (прекъсват рутинна услуга, ISR).
3. Глобални променливи, които са достъпни чрез различни задачи в многонишковите приложения (обикновено се отнася до различни теми RTOS).

Нека да обсъдим всеки един от тези три случая.

Обикновено този код, ще причини грешка, веднага след като включите оптимизация на компилатор, че с оптимизиране включен ще генерира код като този:

Сега, кода на асемблер ще бъде, както следва:

Той постига желаното поведение на програмата.

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

Прекъсването на манипулатори. Прекъсване манипулатори (съчетания прекъсване на услуги, ISR) често определени променливи, които са тествани в основния код (бягане е прекъсната) или друго прекъсване в кода. Например, ISR да проверите серийния порт всеки получен символ за появата на ETX характер (най-вероятно се посочва в края на съобщението). Ако се срещна символ ETX, на ISR да зададете глобален флаг. Неправилно прилагане може да бъде, както следва:

Когато оптимизиране съставител е изключен (както обикновено се прави, когато отстраняване на грешки), кодът може да работи. Въпреки това, почти всяка по-голяма или по-малко приличен оптимизатор "ще разбие" кода. Проблемът е, че компилаторът няма информация, че etx_rcvd променлива може да бъде променена в ISR. Докато компилаторът мисли така, за него израз! Ext_rcvd винаги е вярно, така че примката никога няма да бъде завършена. Следователно, всички на кода след оптимизатор линия тяло може лесно да се отстрани чрез оптимизатор. Ако имате късмет, компилаторът ще се оплаква за това. Ако си нещастен (или все още не са се научили да се обърне внимание на съставител на съобщения), а след това код също ще се провали. Естествено, виното ще бъде веднага възлага на "отвратителен оптимизатор".

Решение в тази ситуация би било да се декларира променлива като etx_rcvd летлив. Тогава всичките си проблеми (или поне на проблемите, свързани с този случай) ще изчезнат.

Многонишкова приложения. Въпреки наличието на опашки (опашки), канали (тръби) и други механизми за обмен в многонишкова среда (RTOS), все още остава обичайна практика за обмен на информация между двата потока чрез общата памет (глобална променлива). Дори когато добавяте проектанта изместване в кода си в компилатора все още няма данни, че контекста на работната смяна, и че това може да се случи. В този случай, когато друга задача е променил общата глобална променлива, същото като с прекъсващ оператор може да се случи, както е описано по-горе. Както и в предишния пример, общата променлива трябва да се декларира като летлив. Например, може да има проблем в кода, когато достъп до споделения променлива CNTR на различни задачи:

Този код не е вероятно да се работи, когато оптимизация е активирана. Обявяването CNTR като летлив ще бъде най-добрият начин за решаване на проблема.

Достъпът до регистрите картографирани в паметта (памет картирани регистър, или MMR) се осъществява с помощта на указатели. Ето още един пример, където имаше проблеми с липсата на C код дума за PIC микроконтролер. Код, за да направи пермутация на съдържанието на двете периферни регистри:

Някои компилатори позволяват да изрично да декларират всички променливи като летлив. Не се поддаде на това изкушение, защото тя е по същество disaccustoms мислене (както и оптимизация и изключване). Също така е възможно в резултат на по-малко оптимизиран код.

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

Ако бяха дадени, за да се определи код бъги глупаво следват Впиши работа по текстовете на изходния код в ключова дума за търсене на летливи. Ако изхода на Впиши да са празни, представените тук примери дават добра отправна точка за отстраняване на неизправности.

[А какво да кажем на структурите? ]

Как да се използва летлив с конструкции и указатели към структурата? Трябва ли да се дефинира указател към структура, която е летливо или дали всеки отделен елемент от структурата да се определи колко летливи или енергонезависима? Може би за някои периферни регистри не е нужно да се използва летлив, защото тяхната стойност не се променя, но статутът на маската на прекъсване, приемащият буфер, и така нататък. Г. Подлежи на промяна и следователно трябва да се определи като летлив?

Къде да поставя летлив ключовата дума в това определение, с цел правилно да се използва структурата с моя индекс?

В този пример, най-добрата практика е следната структура определение регистрира с I / O MMR:

Свързани статии

Подкрепете проекта - споделете линка, благодаря!