|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:36 am
Защитени променливи в ембедед програмирането
| Автор |
Съобщение |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
 Защитени променливи в ембедед програмирането
Възниква следният проблем: основния цикъл на програмата и някакво прекъсване трябва да споделят обща съставна променлива, т.е. такава, която е по-голяма от разредността на ядрото. Например, 32 битова променлива тип long в 8 битов процесор. Задачата за решаване е следната: Основния цикъл започва да работи с тази променлива, например да я копира на друго място, стига до 2-рия байт и в това време се генерира прекъсването, което записва съвсем друга стойност и когато управлението се върне обратно в цикъла, копирането на последните 2 байта създава неприятна боза.
Най-простото нещо, което ползвам (друго не се сетих), е просто да правя полу-семафор и да заключвам променливата, преди да започна да я обработвам. Прекъсването проверява дали е заключена, и ако е, не я пипа. Да, но тук възникват 2 основни момента, за които нямам решение.
1. При неприятно стечение на обстоятелствата, прекъсването може да изпадне в резонанс с основния цикъл и моментът на възникването му да съвпада винаги с момента, в който променливата се обработва и, съответно, е заключена. По този начин променливата никога няма да се опреснява.
2. Ако опресняването е критично, т.е. не можем да пропускаме обработката в прекъсването, то, очевидно заключващия механизъм няма смисъл.
Ще ви бъда благодарен, ако пуснете някакви линкове по въпроса, или споделите нещо, което сте измислили сами. 
|
| Пон Яну 22, 2007 10:36 am |
|
 |
|
evc
Ранг: Напреднал
Регистриран на: Пет Окт 21, 2005 8:45 am Мнения: 499
|
 Re: Защитени променливи в ембедед програмирането
Отложи (забрани) си прекъсването до края на операцията с тази променлива в основния цикъл. В началото на копирането забраняваш всички прекъсвания, в края на копирането - разрешаваш. Ако по време на обработката възникне irq, веднага след разрешаване на прекъсванията, ще влезеш в обработка. Ако пък е критично прекъсването да се обработи веднага след постъпване на irq, направи си дублираща променлива и в комбинация с флага, който ползваш за "заключване", ще ползваш или едната или другата променлива, в зависимост от състоянието на флага, т.е. нещо като стек.
_________________ Простотията е Божи дар, но човек не бива да парадира с подаръците си!
|
| Пон Яну 22, 2007 11:07 am |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
Може да направиш обратното. Когато прекъсването опресни променливата да дигне един флаг. В главната програма преди копирането на всеки байт ще проверяваш този флаг и ако установиш, че се е промени по време на копиране връщаш цикъла отначало за да прочете отново всички байтове, като преди това естествено нулираш флага.
|
| Пон Яну 22, 2007 11:13 am |
|
 |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
 Re: Защитени променливи в ембедед програмирането
Ами отлагането чисто хардуерно не знам дали е взъможно. В смисъл, в доста от системите, особено тия, дето са само с 1 вектор на прекъсване, май събитието се губи, ако в този момент са ти забранени прекъсванията.
Другото е добро, наистина ще работи, но трябва да има 2 флага - коя променлива е заключена и коя е последно обновена. Ще се усложни обработката, но ще работи (направо ще си трябва библиотека). Мерси! 
|
| Пон Яну 22, 2007 11:32 am |
|
 |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
Ами това си го мислех, но трябва да си пиша цялата ф-я по прехвърлянето на асм (не съм фен). 
|
| Пон Яну 22, 2007 11:36 am |
|
 |
|
Цецо
Ранг: Форумен бог
Регистриран на: Пон Сеп 27, 2004 9:22 am Мнения: 15501 Местоположение: София
|
Едва ли ще намериш процесор, на който прекъсването да не се "запомня". Това си е стандарт, флага за прекъсване се вдига, даже и прекъсването да е забранено и когато го разрешиш, то се активира "моментало", ако междувременно не си нулирал флага насила.
То това му е и идеята на тоя механизъм, да се "запомнят" прекъсванията и да се обработят, било то и с малко закъснение.
_________________ "Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.
|
| Пон Яну 22, 2007 11:57 am |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Точно с забраняване на прекъсванията е начина. Не съм имал случай когато забавянето на прекъсването с 4-5 такта да е проблем.
Погледни ако искаш как е в ембедед OS-ите.
там забраняването на прекъсванията е доста често. Много операции се правят точно в такъв режим.
Там механизнма обикновенно е следния
Това са функциите на freeRtos за забраняване и разрешаване на прекъсванията.
|
| Пон Яну 22, 2007 1:12 pm |
|
 |
|
bkulev
Ранг: Популярен
Регистриран на: Сря Яну 25, 2006 12:47 pm Мнения: 305 Местоположение: Varna
|
Рек има и трети начин - променливата я пипаш само на едно място (ти си реши къде, дали irq или другаде), а в местата където сега я модифицират само даваш заявка(вдигаш флаг).
Ама и това е според зависи... 
|
| Пон Яну 22, 2007 1:14 pm |
|
 |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
Да, това си е класически семафор/критична секция.
Аз поради няква причина останах с впечатлението, че доста системи не си "помнят" прекъсванията, за това възникна въпроса.
|
| Пон Яну 22, 2007 1:48 pm |
|
 |
|
plameniv
Ранг: Форумен бог
Регистриран на: Нед Окт 10, 2004 9:55 am Мнения: 1718
|
 Hm
Какъв е проблема важния ти цикъл да си работи с 2 променливи негова и друга идваща от прекъсване , просто проверяваш в основния цикъл дали има имат разлика и ако има нужда основния цикъл я променя с новата .
Просто прекъсването винаги ще си пише на 1 място което си е негова променлива а не обща.
|
| Пон Яну 22, 2007 1:53 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
Комбинации има много на тая тема... Въпреки че повечето се споменаха ще се пробвам да ги обобщя:
1) Ако бачкаш на С компилатор, повечето имат __monitor опции за функции. Правиш си функциите които четат/пишат защитената променлива с тая опция и оставаш на компилатора да му мисли...
2) Ако нямаш вложени извиквания на критични секции, може просто:
__disable_interrupt();
// бачкаш си защитената променлива
__enable_interrupt();
3) Ако имаш вложени критични секции и битови операции на процесора с достъп до флага за прекъсвания, може по следния начин:
bit old_flag;
old_flag = int_flag;
int_enable_flag = DISABLE;
// бачкаш си защитената променлива
int_enable_flag = old_flag;
4) Друг вариант е да броиш колко пъти си искал да забраниш прекъсванията - както е показал Никола...
5) Когато прекъсването само чете защитената променлива, а отдолу се променя, можеш да направиш две копия на променливата и един флаг който показва кое е валидното копие. В основната програма променяш "невалидното копие" и сменяш флага (с атомична операция). Така никога не забраняваш прекъсванията.
6) Когато само прекъсването пипа променливата, ти трябва едно копие на променливата и един флаг. Просто прекъсването винаги като пипне променливата вдига и флага. Отдолу, за да изчетеше променливата правиш цикъл в който първо сваляш флага, правиш си копие и проверяваш дали междувременно не се е вдигнал флага. Ако се е вдигнал зацикляш, докато успееш да прочетеш без да е имало прекъсване...
7) Ако променливата се променя от много места и не искаш да забраняваш прекъсванията може и по-сложен алгоритъм да се направи. Тук зависи дали имаш атомични операции, примерно на ARM може да нямаш и тогава семафорите стават една красива работа....
|
| Пон Яну 22, 2007 2:22 pm |
|
 |
|
Ки4о
Ранг: Форумен бог
Регистриран на: Съб Юли 22, 2006 9:50 pm Мнения: 1638
|
Рек това което казваш ти но използваш приоритетни прекъсвания - прекъсването с по-голям приоритет заменя стойността,а това с по-нисък- не я пипа.
|
| Пон Яну 22, 2007 4:01 pm |
|
 |
|
trm_only_for_work
Ранг: Минаващ
Регистриран на: Пон Яну 15, 2007 8:47 pm Мнения: 59
|
 |  |  |  | Nikola Kirov написа: Точно с забраняване на прекъсванията е начина. Не съм имал случай когато забавянето на прекъсването с 4-5 такта да е проблем. Погледни ако искаш как е в ембедед OS-ите. там забраняването на прекъсванията е доста често. Много операции се правят точно в такъв режим. Там механизнма обикновенно е следния Това са функциите на freeRtos за забраняване и разрешаване на прекъсванията. |  |  |  |  |
Цецо и Никола добре го казаха, отделн оче го пише и в datasheet на PIC,ARM , значи и в док. на AVR трябва да го пише.
Проблема не е дори, когато имаш някокло прекъсваня (а ако имаш и приоритети на прекъсванята хептен).
Пробелма е, когато може едно прекъсване да бъде задействано от две или повече неща/ситуации.
Примерно вързал си 4,8пина с int_on_statechange и става страшно , ако го забавиш.
Ако ползваш един външен int за няколко събития (примерно IC подава int_out към главното mcu< но това е знак само за събитие, но не и кое точно събтие).
И ако възникнат две събития в IC-то ,дали IC-то така ще е у-но , че да "помни" предишното състояние или препокривя ~"STATUS" регистъра (применро).
Може и със флагове , но софтуерно. Въпреки че в твоят случей ще е дървено така:
т.е
critical_point:
bsf MYSTATUS,CP ; critical point execution flag set
do
do
do
do
____int_ ->>>
do
do
do
bsf MYSTATUS,CP ; critical point execution done
return ; to main or whatever is in STACK
...
int:
btfsc MYSTATUS,CP
goto ... Или нещо друго
do_int
--- в твоя случей да опзлваш софтуерни флагове , за да следиш къде ти е програмата хич не е това, което искаш , но пак е вариант, макар и не добър.
_________________ @HCL: "Авторьт не поема отговорност в случай на некоректна или непьлна информация. "
(1)всеки има право на мнение, но това не означава че всеки е прав
(3)не сте длъжен да сте съгласен с неговото мнение.
Защо трябва да Ви се напомня ?
|
| Пон Яну 22, 2007 5:24 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
маниак,пооправил си си наистина съобщенията но още малко ще трябва. След едно прочитане не разбрах какво искаш да кажеш. Не смятам да го чета пак и да гадая.
Още малко по смислено и си ОК 
|
| Пон Яну 22, 2007 5:55 pm |
|
 |
|
Ки4о
Ранг: Форумен бог
Регистриран на: Съб Юли 22, 2006 9:50 pm Мнения: 1638
|
Маниак,идеята на приоритетните прекъсвания е че ти сам задаваш приоритета,демек знаеш къде кво правиш
При прекъсвания в прекъсването се запазват статуси,работни регистри,програмни броячи,.....но явно още не си стигнал до тези неща или кат си ги чел си ги попрескочил.
|
| Пон Яну 22, 2007 10:13 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 3 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|