Отговори на тема  [ 44 мнения ]  Отиди на страница 1, 2, 3  Следваща
Глобални променливи и прекъсвания 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Вто Ное 16, 2004 3:29 pm
Мнения: 108
Местоположение: София
Мнение Глобални променливи и прекъсвания
Чудя се ако декларирам глобална променлива която е 16 или повече бита за
PIC18 процесор и използвам C18 компилатор, то няма ли да има проблем
ако ползвам променливата в нормална функция и прекъсване.

За пример следния код:

volatile int g_p;

void main() {
int l_p;
...

l_p = g_p;

...
}

isr...
void isr() {
...
g_p = 0xFF40;
...
}

...

Проблема който виждам е че присвояването на l_p = g_p не е атомарно.
Дали има инструкции на PIC18, които могат да го направят атомарно от гледна
точка на прекъсването?


Сря Дек 09, 2009 10:58 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Не. Ако ползваш едни и същи обекти които не са атомични (бит и байт при PIC18) в прекъсване и основната програма - твоя е грижата да синхронизираш достъпа до тях.

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

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Сря Дек 09, 2009 11:26 am
Профил ICQ
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Вто Ное 16, 2004 3:29 pm
Мнения: 108
Местоположение: София
Мнение 
Хм и аз така предложих, но немога да измисля нещо по-добро
от това с кратко забраняване на прекъсванията някой да има идеи?


Сря Дек 09, 2009 11:55 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
както каза цецо, забраната за прекъсване в общия случай не е решение. става когато времето на защитената операция е некритично като закъснение за прекъсването, но ако е по-голямо от критичното, не става. тогава си трябва синхронизиращ примитив, нямам идея в 18ките има ли такива. но само за четене на един инт, става си и със забрана на прекъсването.


Сря Дек 09, 2009 11:57 am
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Вто Ное 16, 2004 3:29 pm
Мнения: 108
Местоположение: София
Мнение 
Аз имам идея да ползвам допълнително един байт за синхронизация.
Ако е вдигнат тоя байт/бит няма да пипам стойността от прекъсването.
Ако не е променям.

Слагам флага преди да прочета глобалната променлива и го свалям след края.


Сря Дек 09, 2009 12:21 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Специално в случая който излагаш, забраната на прекъсванията е най-оптималния вариант.

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

Виж ако защитената секция е по голяма по размер и се налага преоритет (или последователност) при обработката и т.н.... тогава вече трябва да мислиш за нещо по сложно... Всъщност тогава вече е време да почнеш да четеш "що е то RTOS" :):):)

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Сря Дек 09, 2009 1:09 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Ето ви едно извращение - C++ за микроконтролери. :D Това е защитена променлива, която не налага забраната на прекъсванията.


Прикачени файлове:
svar.h [562 Байта]
251 пъти
Сря Дек 09, 2009 9:37 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Вто Ное 16, 2004 3:29 pm
Мнения: 108
Местоположение: София
Мнение 
:) това е безсмислен код :) или трябва да ти обяснят подробно,
къде им е трябвало това чудо на програмирането


Чет Дек 10, 2009 10:13 am
Профил WWW
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Яну 18, 2009 1:28 pm
Мнения: 110
Мнение 
i_dachev написа:
:) това е безсмислен код :) или трябва да ти обяснят подробно,
къде им е трябвало това чудо на програмирането


кода си е напълно смислен (за теб е явно прекалено сложен) !

някой ден (след 10г примерно), когато почне да пишеш мнооого по-сложни/големи неща ще схванеш идеята която е: четене на коректни данни които не са в процес на модифициране!

PS: това че е c++ няма никакво значение - само е по удобно!


Чет Дек 10, 2009 10:34 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
i_dachev написа:
Аз имам идея да ползвам допълнително един байт за синхронизация.
Ако е вдигнат тоя байт/бит няма да пипам стойността от прекъсването.
Ако не е променям.

Слагам флага преди да прочета глобалната променлива и го свалям след края.

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


Чет Дек 10, 2009 10:34 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Реконструктор написа:
Ето ви едно извращение - C++ за микроконтролери. :D Това е защитена променлива, която не налага забраната на прекъсванията.


Добре, а какво ще стане ако при рефрешването на m_Shadow(между байтовете, нали то също не е атомик), дойде прекъсване,в което се ползва CShadowVar::Get().
Ето тук:
Код:
void RefreshShadow()
   {
      do
      {
         m_bRefreshing = 0;
         m_Shadow = m_Original;  // <-------- Тук
      }
      while(m_bRefreshing);   
   }


Или този код е само за случаите в които Get() се ползва само от основната нишка, а Set() асинхронно в прекъсване...

_________________
Най-опасният враг на истината и свободата е мнозинството.


Чет Дек 10, 2009 10:53 am
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 2:45 am
Мнения: 263
Мнение 
Най-добре си забрани прекъсванията и си копирай променливата. За 16-битова променлива копирането би трябвало да отнеме 4 цикъла + евентуално 1 за превключване на банката, което не е болка за умиране.


Чет Дек 10, 2009 11:16 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Zdrav написа:
Реконструктор написа:
Ето ви едно извращение - C++ за микроконтролери. :D Това е защитена променлива, която не налага забраната на прекъсванията.


Добре, а какво ще стане ако при рефрешването на m_Shadow(между байтовете, нали то също не е атомик), дойде прекъсване,в което се ползва CShadowVar::Get().
Ето тук:
Код:
void RefreshShadow()
   {
      do
      {
         m_bRefreshing = 0;
         m_Shadow = m_Original;  // <-------- Тук
      }
      while(m_bRefreshing);   
   }



Или този код е само за случаите в които Get() се ползва само от основната нишка, а Set() асинхронно в прекъсване...


Ще се дигне m_bRefreshing и цикъла ще се повтори. Това е целия смисъл.


Чет Дек 10, 2009 1:14 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Реконструктор погледни сорса който си приложил. При викане на Get() не се вдига m_bRefreshing!!!
Аз предлагам ето така:
Код:
#ifndef __SVAR_H__
#define __SVAR_H__

#include <stdint.h>

// Shadow variable definition

template <typename T>
class CShadowVar
{
private:
   T         m_Original;
   T         m_Shadow;


public:
   CShadowVar()
   {
      m_Original = 0;
      m_Shadow = 0;
   }

   void Set(T NewVal)
   {
      m_Original = NewVal;
   }

   T Get()
   {
      do
      {
         m_Shadow = m_Original;
      }
      while(m_Shadow != m_Original);
      return m_Shadow;
   }
};

#endif



Разбира се ако латентноста на прекъсванията е толкова критична. Ако не е и аз съм за варианта със забраняване/разрешаване на прекъсванията.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Чет Дек 10, 2009 1:48 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Апр 17, 2006 1:44 pm
Мнения: 291
Мнение 
Винаги може да се омаже кода и не мисля, че по този начин може да се реши проблема точно защото и след като излезне от while цикъла, преди да върне метода, респективно да се ползва стойността може да бъде променена.
Само решение с някаква опашка и dispatcher може да помогне, където всяка операция се поставя в опашка и винаги се изпълнява серийно.


Чет Дек 10, 2009 4:54 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 44 мнения ]  Отиди на страница 1, 2, 3  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни