Отговори на тема  [ 30 мнения ]  Отиди на страница 1, 2  Следваща
Стабилно работеща програма за MCU ??? 
Автор Съобщение
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Нед Окт 19, 2008 7:26 pm
Мнения: 673
Мнение Стабилно работеща програма за MCU ???
Има ли някакъв универсален подход за писане на програма, която при неочакван външен фактор, да не отива на кучето в г--а.
Написах една дълга програма(2025 реда на С), е за повечето от вас това никак не е много, но за мен е неприятно дълга, но нямаше начин.
Хванах се че при използване на кучето, го ресетвам така че никога да не се препълва ( усетих се че е грешка). Условията за вземане на решения са много, използвам около 50 флага (1 бит променливи). Например, при следене на напрежението на захранващата батерия използвам един флаг за прага на включване и прага на изключване, за да имам нещо като хистерезис, и така нататък. Добро решение ли ще е да доусложня нещата, като добавя, едно паралелно следене на процесите, още променливи специално за текущото състояние на системата, и на базата на тях да се вземе решение, има ли проблем, от къде и как да се излезе от нокаута.

_________________
Вниманиене съмвишист....ИЙ.


Сря Ное 04, 2009 9:25 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Яну 30, 2006 2:48 am
Мнения: 1248
Местоположение: София
Мнение 
На мен ми е известен само един - слагаш втори процесор паралелно, и го натоварваш с контрола на основния. На основния пък, се задава да проверява контролния


Сря Ное 04, 2009 9:41 pm
Профил WWW
Ранг: Популярен
Ранг: Популярен

Регистриран на: Чет Ное 29, 2007 2:22 pm
Мнения: 309
Местоположение: Vratsa
Мнение 
Оптимизираш важния код и товариш едното проц само с него , останалото в друг проц. Иначе си стръва само ако може с малко допълнителен код да следиш защо се е стигнало до кучето .


Сря Ное 04, 2009 11:08 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Яну 10, 2006 2:40 pm
Мнения: 2258
Мнение Re: Стабилно работеща програма за MCU ???
RM написа:
Има ли някакъв универсален подход за писане на програма, която при неочакван външен фактор, да не отива на кучето в г--а.
Написах една дълга програма(2025 реда на С), е за повечето от вас това никак не е много, но за мен е неприятно дълга, но нямаше начин.
Хванах се че при използване на кучето, го ресетвам така че никога да не се препълва ( усетих се че е грешка). Условията за вземане на решения са много, използвам около 50 флага (1 бит променливи). Например, при следене на напрежението на захранващата батерия използвам един флаг за прага на включване и прага на изключване, за да имам нещо като хистерезис, и така нататък. Добро решение ли ще е да доусложня нещата, като добавя, едно паралелно следене на процесите, още променливи специално за текущото състояние на системата, и на базата на тях да се вземе решение, има ли проблем, от къде и как да се излезе от нокаута.


ползваш RTOS, структурираш си тасковете и приоритетите и не се разпиляваш в 2000 реда код


Чет Ное 05, 2009 12:56 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

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


Чет Ное 05, 2009 8:41 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
Е зайфоде, ти пък, при по големи РС програми може и да е така, но в контролерите специално не виждам причина да има програми без бъг, особенно такива по 1000-2000 реда. Друг е въпроса за случаите когато се получава бъг, или по скоро неработоспособност в резултат на външен фактор, бъг не би трбявало да има, защото външните фактори може да са много, но въздействията в-у процесора са краен брой, и то не много ако се обобщят, какво може да стане :
- ресет, по някаква причина, проблем с захранване или нещо друго
- счупване на променлива, т.е. проблем в рама
- счупване на кода, т.е. еепром или друго от сорта
- всякакви "непредвидени" ситуации по входове / изходи, такива принципно не трбява да има, примерно ако имаш два крайни изключватели еидн срещу друг, не може да предполагаш че винаги ще е натиснат само единя, дори да няма физически начин да се натиснат и двата.

Значи, проблема от ресета в зависимостот контролера, но най-добре е да караш по стандартна процедура, т.е. да не разчиташ че стека ще е в същото състояние и т.н., дори да е казно че при ресета който си получил е така.
чупенето на променливи, просто ги пишеш по два или три пъти, ако искаш им пишеш и чексума някъде, но дали ще е чек сума или ще я имаш още веднъж същата работа, или почти ... е ако чексумата е 8 бита а променливата 32 може да спестиш място, ама тогава има анс да се счупи така че да и излезе чексумата, нищо обаче не пречи да я пишеш веднъж инвертирана, при ресет може да се случи да имаш само 0 в паметта, и ако я нямаш инвертирана ще приемеш че е вярна, щото ще имащш само нули, но ако я имаш инвертирана това няма как да стане. това решава 99.9% от чупенето на променливи, останалите 0.1% е трудно да ги орпавиш, но се случват твърде рядко.

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

За непредвидените входно изходни състояния говорихме, не трябва да има такива.

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

За WDT позлвай го задължително, това му е идеята, да те ресетне ако зациклиш. Също така ако може да не позлваш while ще е най-добре, или в най-лошия случай навсякъде предвиждай начин да излезеш, по тайм оут, или просто не зареждай WTD вътре ... не мое да имаш while по дълъг от 100-200 мс ... не е правилно де, поне споредмен, и това е прекалено дълъг, всичко по дълго просто си го полираш переодично, или го слагаш на прекъсване ... та ако не зареждаш wdt това автоматично ще те изкара ако забиеш в някой такъв цикъл ... но пак по добре просто си сложи таймоут.


Чет Ное 05, 2009 3:39 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
и от къде нататък тони вече няма сигурност - до 2000 реда може, а над това не може? :)


Чет Ное 05, 2009 4:04 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
Ами и при 5 може да има, и при 10 ... но ако имаш 1 млн реда сорс, вероятноста да намямаш бъг е доста малка, в момента кода на един наш продукт може би е 200-300 хил реда, може би и повече хищника трябва да каже колко са точо, и съвсем нормално излизат бъгове, някои от тях са такива че се появяват само в определени случаи.
Но при писане на код, особенно 1000-2000 реда, не е никак нормално да има бъгове, още повече ако говорим за контролер. При РС е друго, в тия 2000 реда може да се окаже че зависиш от още един куп неща, ОС, драйвери с които работиш и т.н. неша извън твоя контрол, и неща чието поведение не можеш да предвидиш.
При контролерите не е така, там всички е ясно, или би трябвало да е, грешките, състоянията на периферията и т.н. съответно добре написан софтуер се предполага че не трябва да има бъгове, а разни неустановени състояния трябва да са сведени до минимум, би трябвлао да е ясно в кой момент каво трябва да се случи, без значение дали това е номинален режим или не.


Чет Ное 05, 2009 9:04 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Нед Окт 19, 2008 7:26 pm
Мнения: 673
Мнение 
При стабилни условия, без неочаквани прекъсвания на комуникациите, програмата работи стабилно месеци, и никога не прави проблеми. Но когато по време на приемане на дани прекъсна комуникацията за момент, и нещата се объркат, би трябвало сама да си въстанови работоспособноста.
Системата приема дани . Разпознаването на данните съм го организирал нещо подобно на AT команди. Получава се едно огромно дърво от разклонения
Код:
switch (getchar()){
  case 0x00:break;
  case 'A': switch (getchar()){
                                            case 0x00:break;
                                            case 'B': ............
                                            case 'C': ...........   
                                            default:break;

                                           };



  case 'B': ...............
  case 'C': ................

                           };

За да не забива във функцията на getchar() , при чакане на символ над определено време, връща 0х00, и излиза от switch (getchar()){...};
След определено време праща още един 0х00, излиза от още един switch ... и така нататък докато излезе от тези разклонения.
Има ли друг начин за подобна комуникация освен със switch , case.
От всички цикли, съм направил процедури за сигурно излизане от тях, при забиване на комуникацията, или при появата на грешки.
И единственото което се получи, е работа на всички прекъсвания, процесора не заспива, по голямя част от процесите работят, но някой не. WDT не ресетира чипа (не се препълва). Получава се така че Работи перфектно когато всичко е наред, но случили се нещо всичките защити дето съм мислил че ще оправят нещата не работят така както се очаква.

_________________
Вниманиене съмвишист....ИЙ.


Чет Ное 05, 2009 9:20 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Ами след като пишеш по зле от първия човек как очакваш програмата ти да работи ;) Обикновенно комуникацията се прави с state mashine. При нормално написан код имаш само едно място където извикваш getchar. А сега просто изтрии всичко дето си го натворил и го пренапиши според тия указания и ще видиш че няма да имаш нужда от нещо повече от WD и то не за да ти покрива бозата която си сътворил ами да ресетва процесора ако нещо се ошашка от смущения.


Чет Ное 05, 2009 9:31 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
Как така WD не те рестартва .... за да не те рестартва WD значи го полираш, не виждам друг начин WD да не те рестартне, или пък ако изобщо не е включен. Не знам какъв е процесора, примерно при пиковете WDT се разрешава през конфиг думата.
Но като цяло това което си направил не ми изглежда много добре. Не знам как са ти организирани данните, защо не работиш с пакети? Като гледам правиш нещо като приемане и обработка в реално време, и то по доста извратен начин. Този getchar () не знам как е написан при теб, ама ако се не лъжа в CCS за пикове е написан с while без никакъв изход, и освен това нулира WDT така че ако влезеш там и нищо не даойде на порта си зависваш во веки веков.

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


Чет Ное 05, 2009 9:35 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Нед Окт 19, 2008 7:26 pm
Мнения: 673
Мнение 
В този случай, ползвам Mega8 с CVAVR , напълнил съм го до 98%. Почти изцяло съм заел EEPROM-а и RAM-a. управлявам един модул от Мобифон
преправен за комуникация на 433 с LMX2335 , зареждането на приемника и предавателя и настройката на 22-битовите регистри-броячи N и R правя с контролера, настройките на нивата на звука , тоналното разпознаване , пароли, следене на напрежение на батерии, охрана на помещението, .... През RS 232 от PC настройвам честотите, получавам нивата на звика, задавам много параметри за начина на работа на PLL синтезатора, стъпките на настроики, начина на работа на фазовите детектори-поляритет .... автоматична смяна на честоти при зашумяване ... Това мога да го управлявам и настроивам от компютър, като пращам команди, дани, чакам отговори. Това си го правя единствено за мен, и когато имам свободно време си го доусъвършенствам, колкото мога.
getchar() съм допълнил, за да не зависва в while() :D
Не претендирам че е добро, като изпълнение но"криво лево" бачка, а и не се занимавам професионално с това, само през свободното си време.
State Machine като вариант отпада категорично (не разбирам, и не мога), ако може някаква насока за по добър начин, за организиране и приемане на подобни команди в реално време :oops:

_________________
Вниманиене съмвишист....ИЙ.


Чет Ное 05, 2009 10:54 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
state machine не е сложно, много попросто и прегледно ще стане дори и по най-елементарният начин който ще прилича малко на твоя. Но иначе аз предпочитам да си чакам пакета, съдейки по това което правиш, много вероятно комуникацията ти да е или null терминирана или с /n /r, в този случай имаш елементарен начин пълниш си буфера докато получиш терминатора, след това проверяваш какво е дошло. Изобщо доста варианти има а ти си избрал най-неподходящия.

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


Чет Ное 05, 2009 11:10 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
То много лесно да кажеш не мога. Някакси неволно се сещам за "Врачански ....". Постъпи като нормален човек. Като не знаеш,четеш и после знаеш. State Mashine е от основните похвати в програмирането.

Привеждам ти за пример от прост код който реализира протокол за обмен чрез state mashine. Макар че ако малко се напънеш и пуснеш търсене в Google ще намериш доста инфо и примери.

Код:
void com_Serve(void)
{
    u8 i,b;
    static union
    {
        u16 crc_recv16;
        u8 crc_recv[2];
    };

    if ( recv_f(&b)  )
    {
        switch(_state)          // Read byte
        {
        case 0: // Wait Start
            if ( b == '\n')
                _state ++;
        break;

        case 1: // Wait Command
            if ( b >= (u8)CMD_END_CMD_LIST )
                _state = 0;
            else
            {
                _cmd = b;
                _state ++;
            }
        break;

        case 2:   // Wait Length
            _length = b;
            _state++;
        break;

        case 3: // Wait command control sum //
            if ( b != ( _cmd + _length + 1 ) )
                goto rst;

            _cript_flag = 0;

            if ( _length == 0 )
            {
                if ( _cmd == CMD_STARTUP_DONGLE )
                {
                    _set_key_to_default();
                    _send_dev_info();
                }

                if ( _program_enable )
                {
                    if ( _cmd==CMD_READ_DATA )       // No Data Argument commands
                        _read_data();
                    if ( _cmd==CMD_ERASE_PAGE )
                        _erase_page();
                    if ( _cmd==CMD_GET_KEY_NAMES )
                        _get_key_names();
                }
                goto rst;
            }
            _state ++;
            break;

        case 4: // Wait Data

        ...........................
        ...........................


Чет Ное 05, 2009 11:59 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
RM, разликата между това което си написал и стейт машината не е кой знае каква и това че нещата ти се объркват няма отношение към нея струва ми се.
значи аз не видях никъде в обясненията ти каква ти е концепцията за синхронизация на протокола при прекъсване в комуникацията. викаш ще излезе от дървото по таймаут, това не спасява нищо. нали когато комуникацията се оправи, не се знае от къде ще почне и пак ще получаваш безсмислени команди. същия проблем го има и стейтмашината - прекъсне ли се комуникацията, изтърваме команди които ще ни преместят в графа на състоянията, после като се оправи почваме да скачаме по съвсем измислени клонове.
доколкото схващам пращаш някакви текстови команди. заеби цялото това дърво (май си чел някаква книга за компилатори, или се бъркам?) и просто си направи функция ReceiveString.
нещо такова
Код:
char str[32];
char arg[32];
while(1){
  int res=ReceiveString(str);
  if(!res){
        Прави тука каквото трябва при загуба на комуникация
        continue;
  }
  ExtractArg(str,arg);// ако командите имат аргументи, тук ги разделяш в отделен стринг
  if(!cmpstr(str,"com1"){OnCom1(arg);continue;}
  if(!cmpstr(str,"com2"){OnCom2(arg);continue;}
.................................

}



Пет Ное 06, 2009 10:26 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 30 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

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


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

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