1. Си / Говнокод #12908

    +131

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    ////выполнение полного сброса, конфигурирования и проверки того что записано в регистрах
    ////0 - проверка неудачная
    ////1 - все нормально
    BYTE ADE7758::Full_Check(void)
    {
        OS_DI();
        
        if(Check())//проверка состояний регистров
            return 1;//все нормально
        else
        {
            
            Configure();
            OS_Delay(1);//ждем пока нестабильность пройдет
            if(Check())//проверка состояний регистров
                return 1;//все нормально
            else //после переконфигурации не все нормально - значит делаем ресет
            {
                OS_Delay(100);//ждем пока нестабильность пройдет
                Reset();	//полный сброс
                OS_Delay(10);//ждем еще чуть-чуть для завершения пересброса (на всякий случай)
                Configure();//переконфигурация
                //OS_Delay(500);//ждем пока нестабильность пройдет		
                if(Check())//снова проверка состояний регистров
                    return 1;//после пересброса все нормально
                else
                {
                    OS_Delay(500);//ждем пока нестабильность пройдет
                    Reset();	//полный сброс
                    Configure();//переконфигурация
                    OS_Delay(500);//ждем пока нестабильность пройдет
                    if(Check())//снова проверка состояний регистров
                    {
                        return 1;//после пересброса все нормально
                    }
                    else
                    {
                        return 0;//все проверки неудачные - выход с ошибкой
                    }
                }
            }
        }	
    }

    "Нельзя доверять никому. Совсем никому. Даже самому себе."
    Разумеется это вызывается в прерывании 200 раз в секунду.
    1 тик OS_Delay() = 10мс.
    Разрешение прерываний после сделает "дядя Вася".
    Зато знаем классы и умеем их писать.

    Запостил: apparato, 18 Апреля 2013

    Комментарии (17) RSS

    • > BYTE ADE7758::Full_Check(void)

      и где здесь си?
      Ответить
      • Проект сишный, но для взрослости пару классов заведено. Предыдущий мною размещенный говнокод из этого же проекта.
        Вот ещё такая штука стрелилась:
        ...
        if( (!(ADE_MODE.SYNCHRONIZATION) && (IRQ_timeout_A>=ADE_TIMEOUT) && (IRQ_timeout_B>=ADE_TIMEOUT) && (IRQ_timeout_C>=ADE_TIMEOUT)) ||
        (!(ADE_MODE.SYNCHRONIZATION) && ( (ADE_ZXA_COUNTER==0) || ( ADE_ZXB_COUNTER==0) || (ADE_ZXC_COUNTER==0) ) ) ||
        ( (ADE_MODE.SYNCHRONIZATION) && (ADE_ZXA_COUNTER==0) && ( ADE_ZXB_COUNTER==0) && (ADE_ZXC_COUNTER==0) )
        )
        {
        ...

        P.S. Как такового C++ и его фичей нет. Не хотелось авторский текст портить.
        Ответить
    • Фигня. Смотрите, как надо:
      BYTE ADE7758::Full_Check(void)
      {
          OS_DI();
      
          int delay = 10;        
      
          while (!Check()) {   //проверка состояний регистров
              OS_Delay(delay); //ждем пока нестабильность пройдет
              Reset();	 //полный сброс
              OS_Delay(delay); //ждем еще чуть-чуть для завершения пересброса (на всякий случай)
              Configure();     //переконфигурация
              OS_Delay(delay); //ждем пока нестабильность пройдет		
      	delay *= 2;	    
          }
          return 1; //все нормально
      }
      Ответить
    • Чем дальше, тем интересней.
      Дополнение 1 для полноты картины.

      void ADE7758::Configure(void)
      {
      ...    
          WriteRegister (AVRMSOS,2, K::u1_off[datch]);	//записываем коэффициент смещения
          WriteRegister (BVRMSOS,2, K::u2_off[datch]);	//записываем коэффициент смещения
          WriteRegister (CVRMSOS,2, K::u3_off[datch]);	//записываем коэффициент смещения
          
          WriteRegister (AIRMSOS,2, K::i1_off[datch]);	//записываем коэффициент смещения
          WriteRegister (BIRMSOS,2, K::i2_off[datch]);	//записываем коэффициент смещения
          WriteRegister (CIRMSOS,2, K::i3_off[datch]);	//записываем коэффициент смещения
          
          WriteRegister (AWATTOS,  2,K::p1_off[datch]);	//в регистр смещения мощности записываем нулевое значение
          WriteRegister (BWATTOS,  2,K::p2_off[datch]);
          WriteRegister (CWATTOS,  2,K::p3_off[datch]);
      ...
      Ответить
    • Дополнение 2:

      ////проверка состояния всех регистров, если хоть один регитр отличается от того что должно быть то
      //// 0 - проверка неудачная
      //// 1 - все регистры содержат то что там должно быть
      BYTE ADE7758::Check(char mod)//проверка регистров 0-частичная, 1-проверяются все регистры
      {
      ...
          //если нужна полная проверка регистров то идем дальше
          if(ReadRegister (AVRMSOS,2)		!= (WORD)K::u1_off[datch])	return 0;	//записываем коэффициент смещения
          if(ReadRegister (BVRMSOS,2)		!= (WORD)K::u2_off[datch])	return 0;	//записываем коэффициент смещения
          if(ReadRegister (CVRMSOS,2)		!= (WORD)K::u3_off[datch])	return 0;	//записываем коэффициент смещения
          
          if(ReadRegister (AIRMSOS,2)		!= (WORD)K::i1_off[datch])	return 0;	//записываем коэффициент смещения
          if(ReadRegister (BIRMSOS,2)		!= (WORD)K::i2_off[datch])	return 0;	//записываем коэффициент смещения
          if(ReadRegister (CIRMSOS,2)		!= (WORD)K::i3_off[datch])	return 0;	//записываем коэффициент смещения
          
          if(ReadRegister (AWATTOS,2)		!= (WORD)K::i1_off[datch])	return 0;	//в регистр смещения мощности записываем нулевое значение
          if(ReadRegister (BWATTOS,2)		!= (WORD)K::i2_off[datch])	return 0;
          if(ReadRegister (CWATTOS,2)		!= (WORD)K::i3_off[datch])	return 0;
      ...
      Ответить
      • это криво в прикладухе - но это нормально для системщины.

        когда у тебя железо подвисает, иногда удается узнать где, на какой строчке, что и как подвисло.

        я в свое время пытался тоже красиво писать, а потом забил: во время bring-up'а код, "хороший" по стандартам прикладного программирования, просто не катит. десяток прямых доступов к регистрам намного проще чем цикл.
        Ответить
        • Если внимательно посмотреть на Дополнение 1 и Дополнение 2, то можно увидеть, что в Configure() записываются в регистры смещения: мощности калибровочные значения
          K::p[123]_off[datch].
          А в Check() проверяются немного чуть другие:
          K::i[123]_off[datch].
          Поэтому результат Full_Check() равный 1 (всё Ок!) будет истинен только для K::p[123]_off[datch] = K::[b]i[.b][123]_off[datch].
          Это разгадка на жалобу "почему-то до калибровки работает, а после нет."
          Ответить
          • без контекста такое невозможно узнать.

            один из первых девайсов который я программировал (моушн контроллер), из-за крюков реализации memio у ISA-to-PCI контроллера, писать нужно было под одному аддресу, а читать по другому.
            Ответить
    • гы-гы. в некоторой степени напоминает код который пытается на/с NFS файлы "надежно" читать: попробуй три раза, если все еще не работает поспать, потом еще раз попробовать пару раз.

      а так, на самом деле, без ковыряния datasheet очень сложно сказать говно это или нет, потому что эта процедура может быть сделана согласно официальной доке. в свое время траханины с заморачками и багами дешевых сетевых адаптеров насмотрелся (или хорошый адаптер c криво привинченым gmac'ом). для одного девайса, в драйвере треть кода была посвящена воркараундам всевозможных багов.

      PS http://www.analog.com/en/analog-to-digital-converters/energy-measurement/ade7758/products/product.html - интересно что вы там делаете...
      Ответить
      • Это трудится в контроллере управления генераторной установки.

        У AD есть проблемы в реализации некоторых чипов, особенно семейства 77, причем это верно не только для ade77xx, но и для АЦП ad77xx. Вероятность сбоев зависимости от кривизны рук и лени электронщика. Сбои заключаются в самопроизвольном (некоторые говорят "мистическом") изменении значений настроечных регистров. Единственным противодействием является проверка значений регистров. Для полной надёги нужно проверять все настроечные регистры. В данной мыкросхеме регистров что-то около 256 (всего, и настроечных, и значений). Просто проверка в каждом цикле чтения значений займет убийственное время.
        В данной реализации Check(mod) проверяется 6 регистров для mod=0,
        а для mod=1 ещё дополнительно 18 регистров. Вероятность обнаружения сбоя желающие могут посчитать.
        Ответить
        • "Просто проверка в каждом цикле чтения значений займет убийственное время."

          кривое железо вездесуще. но без кривого железа, было бы меньше работы :)
          Ответить
        • "В данной реализации Check(mod) проверяется 6 регистров для mod=0,
          а для mod=1 ещё дополнительно 18 регистров."

          к слову. по теме memory mapped io. если есть возможность, можно потрясти железячников что бы они эти регистры в железе рядом замапили. тогда можно будет делать проверку одним memcpy(). например: PCI32 может передавать 32bit слова. если регистры байтовые, то так можно будет съэкономить на количестве операций ввода/вывода, читая 4 регистра за раз.
          Ответить
    • код микроконтроллерный обыкновенный
      Ответить
      • Это ГОВНОкод микроконтроллерный редкостный.
        Ответить
      • Внимательно приглядываемся к прототипу BYTE ADE7758::Check(char mod).
        И видим наличие параметра mod.
        После смотрим на реализацию Full_Check().
        О-о! Лулзы!
        Ответить
    • Мелочь, но приятно:
      #define i_-   		_g	                  //g


      И везде полностью халяльный стиль:
      ...
      #define   i_0	  _a|_b|_c|_d|_e|_f     //a,b,c,d,e,f
      #define   i_1	  _b|_c                 //b,c
      ...


      И ещё:
      typedef struct TMCHAR
      {
          U8 data1;
          U8 data2;
          U8 data3;
          U8 data4;
      };
      Ответить
    • //ждем пока нестабильность пройдет

      незнал что путен кодит
      Ответить

    Добавить комментарий