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

Почти всеки вградени приложения използва прекъсва, и много - многозадачност и многонишково. Тези заявления трябва да бъдат приложени като се вземе предвид факта, че контекста на изпълнение може да се промени по всяко време. Например, произтичащи прекъсване предизвиква Scheduler, който изпълнява контекст преминаване към по-висок приоритет задача. Какво се случва, ако задачите и функциите се използват споделени променливи? С висока степен на вероятност можем да предположим, че една катастрофа - един от проблемите, ще се развали данните на друга задача. Прибл. Превод: Разбира се, същото може да се каже и за общите променливи и прекъсване на основната линия в конвенционални, единична задача програми.

В вградени системи свят входящ функция, трябва да отговарят на следните правила:

Правило 1. Функцията атомната достъп до глобални променливи или променлива се създава за всяка функция повикване

Правило 2: Функцията не причинява не-риентри функции

Правило 3. Функцията използва атомно достъпа до периферните устройства

Правилата 1 и 3, думата "атомна", който се основава на гръцката дума, означаваща "неделим". В програмирането, терминът "атомен" се използва за операции, които не могат да бъдат прекъснати. Помислете за следното твърдение:

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

В първата част на член 1, изисква използване на атомната глобални променливи. Нека двете функции споделят една и съща глобална променлива Foobar. Ако функцията съдържа код

това не е входящ, защото достъп до променлива Foobar не е атомна, защото се използва за промяна на Foobar три стъпки, а не един. Този код може да прекъсне прекъсване при които функцията се нарича В, която също така изпълнява някои действия с Foobar. След завръщането от прекъсване стойност температура може да не съответства на действителния Foobar стойност.

Налице е конфликт, на самолетни катастрофи и стотици хора, които викаха: "Защо този шибан програмист никой не научи да използва повторно навлизаща функции.". Въпреки това, предполагам, че функция изглежда по различен начин:

Сега атомна операция, за прекъсване няма да спре по средата на операция на Foobar, конфликтът няма да възникне, така че тази операция е входящ.

Чакай ... Знаете ли наистина, че си компилатор ще генерира за тази операция? На x86 процесор, този код може да изглежда като вас следващия път:

което разбира се не е атомна работа на, следователно експресия Foobar + = 1; Това не е входящ. Атомното версия ще изглежда така:

Поуката от това: да бъдат много внимателни относно предположенията, компилаторът генерира атомната код. В противен случай, може да откриете, репортерите на програма "Максимум" под вратата й - "Кой е отговорен за повреда на спирачката в мотопед Филип Киркоров". По принцип, винаги трябва да се предположи, че компилаторът винаги генерира код за не-атомни изрази като

Във втората част на член 1 казва, че ако една функция използва neatormany достъп, трябва да се създаде данните за всяко извикване на функция. В "Предизвикателството" имаме предвид, незабавно изпълнение на функцията. Функцията за многозадачна работа може да се нарече едновременно от множество задачи.

Да разгледаме следния код:

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

C и C ++ може да ни предпази от тази опасност. Ние използваме локална променлива. Т.е. Ние определяме Foo в рамките на функцията. В този случай, всяко повикване some_function () ще използвате променлива разпределени в стека (това е, разбира се, не се отнася за PIC16 и PIC18. С последното е вярно, можете да използвате компилатор Microchip C18, което може да се приложи софтуер стека и по този начин входящ. Но, ако е необходимо тя е там?).

Друг вариант може да бъде използването на динамично разпределение на паметта. Въпреки това, в същото време трябва да се уверите, че много динамична библиотека разпределение функции обратния вход. Обикновено не. Както е случаят с локалните променливи за всяко обаждане ще се генерират от едно парче памет - по този начин се решава основния проблем reentrancy.

Правило 2 казва, че обаждащият се наследява не входящ в призванието. Това е, ако пристанището на данни в функция B която е била причинена от функция, да се говори за входящия А безсмислено.

Komilyatory използващи езици от високо ниво, които сме осъзнали срещу коварна проблем. Сигурни ли сте, - наистина сигурен - че обратния вход на съставител библиотека? Очевидно е, че низ (в C, това не е така) и други сложни операции предизвикват функциите на библиотеката компилатор. Повечето от компилатора генерира разговори с библиотечните функции за математически операции, дори и за тривиален умножение и деление на цели числа.

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

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

Какво е най-добрият начин да се направи функция входящ? Разбира се, за да се избегне използването на глобални променливи.

Като цяло, глобални променливи значително усложнява отстраняване на грешки код и да причини леки грешки. Опитайте се да използвате локални променливи и динамично разпределение на паметта.

Въпреки това, глобални променливи е най-бързият начин за прехвърляне на данни. Като правило, напълно да се отървете от глобалните променливи във вградените системи в реално време е невъзможно. Ето защо, когато се използват споделени ресурси (глобални променливи или периферни), ние трябва да се използват различни методи, за да се гарантира, валентност.

Най-разпространеният начин - деактивиране прекъсва за периода на не-входящ код. Ако прекъсва са изключени от системата за многозадачна работа се превръща в една задача. В действителност това не е така - това, което не позволява превключване на контекста, след забраната за прекъсване причина RTOS услуга? Изключване прекъсва, направете без входящ част от кода, нека ме прекъсвай. Доста често, е, както следва:

Въпреки това, този код е опасно! Ако do_something () - глобално въвеждане функция, която се нарича от различни места, а след това в един момент тя може да се дължи, когато е забранено да прекъсва. И преди да са разрешени, завръщащи се прекъсва, контекстът се променя. А много опасен начин, който може да доведе до сериозни проблеми.

И не използвате стария извинение: "Да, но когато пишете код, аз съм много внимателен аз наричам тази функция, само когато сте сигурни, че прекъсва са активирани.". Програмистът, който ще ви (и с такива оправдания това може да се случи много бързо) замени може да не е наясно с този сериозен ограничения (особено след като е малко вероятно да го има в документацията).

Много по-добре изглежда следната функция:

Забрана на прекъсванията се увеличи времето за реакция на системата за външни събития (често просто неприемливо). По-лек начин да се осигури reentrancy е да се използват семафори. показва ресурс заетост. Semaphore - това е проста бинарна индикатор тип "включване-изключване", който може да бъде достъпен с атомна. А семафор се използва като се даде възможност на знамето, за задача запазване на празен ход, докато необходимите ресурси е зает.

Почти всички търговски видове синхронизация са RTOS обект "семафор" (често семафор реализира защита мутекс наречена едновременен достъп; мутекс има допълнителни свойства). Ако използвате най-семафори RTOS - това е вашият начин да се осигури reentrancy. Не използвайте RTOS? Често виждам програми, които използват променлива флаг за защита на ресурса:

Тя изглежда семпло и елегантно, но този код е опасно!

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