1. Pascal / Говнокод #22024

    −49

    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
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    type
    TReadCoils = array [0..3] of word;
    
    CONST crctab: ARRAY[0..255] OF WORD = (
        $0000, $C0C1, $C181, $0140, $C301, $03C0, $0280, $C241,
        $C601, $06C0, $0780, $C741, $0500, $C5C1, $C481, $0440,
        $CC01, $0CC0, $0D80, $CD41, $0F00, $CFC1, $CE81, $0E40,
        $0A00, $CAC1, $CB81, $0B40, $C901, $09C0, $0880, $C841,
        $D801, $18C0, $1980, $D941, $1B00, $DBC1, $DA81, $1A40,
        $1E00, $DEC1, $DF81, $1F40, $DD01, $1DC0, $1C80, $DC41,
        $1400, $D4C1, $D581, $1540, $D701, $17C0, $1680, $D641,
        $D201, $12C0, $1380, $D341, $1100, $D1C1, $D081, $1040,
        $F001, $30C0, $3180, $F141, $3300, $F3C1, $F281, $3240,
        $3600, $F6C1, $F781, $3740, $F501, $35C0, $3480, $F441,
        $3C00, $FCC1, $FD81, $3D40, $FF01, $3FC0, $3E80, $FE41,
        $FA01, $3AC0, $3B80, $FB41, $3900, $F9C1, $F881, $3840,
        $2800, $E8C1, $E981, $2940, $EB01, $2BC0, $2A80, $EA41,
        $EE01, $2EC0, $2F80, $EF41, $2D00, $EDC1, $EC81, $2C40,
        $E401, $24C0, $2580, $E541, $2700, $E7C1, $E681, $2640,
        $2200, $E2C1, $E381, $2340, $E101, $21C0, $2080, $E041,
        $A001, $60C0, $6180, $A141, $6300, $A3C1, $A281, $6240,
        $6600, $A6C1, $A781, $6740, $A501, $65C0, $6480, $A441,
        $6C00, $ACC1, $AD81, $6D40, $AF01, $6FC0, $6E80, $AE41,
        $AA01, $6AC0, $6B80, $AB41, $6900, $A9C1, $A881, $6840,
        $7800, $B8C1, $B981, $7940, $BB01, $7BC0, $7A80, $BA41,
        $BE01, $7EC0, $7F80, $BF41, $7D00, $BDC1, $BC81, $7C40,
        $B401, $74C0, $7580, $B541, $7700, $B7C1, $B681, $7640,
        $7200, $B2C1, $B381, $7340, $B101, $71C0, $7080, $B041,
        $5000, $90C1, $9181, $5140, $9301, $53C0, $5280, $9241,
        $9601, $56C0, $5780, $9741, $5500, $95C1, $9481, $5440,
        $9C01, $5CC0, $5D80, $9D41, $5F00, $9FC1, $9E81, $5E40,
        $5A00, $9AC1, $9B81, $5B40, $9901, $59C0, $5880, $9841,
        $8801, $48C0, $4980, $8941, $4B00, $8BC1, $8A81, $4A40,
        $4E00, $8EC1, $8F81, $4F40, $8D01, $4DC0, $4C80, $8C41,
        $4400, $84C1, $8581, $4540, $8701, $47C0, $4680, $8641,
        $8201, $42C0, $4380, $8341, $4100, $81C1, $8081, $4040 );
    
     //ôóíêöèÿ íàõîæäåíèÿ êîíòðîëüíîé ñóììû
    function crc16(twoSym:array of Word; size:word):Word;
    var
     i:Integer;
     crc:Word;
    begin
      crc:=$FFFF;
    
      for i:=0 to ((size div 2) -1) do
    
      begin
        crc:=  (crc shr 8) xor CrcTab[(crc and $FF) xor twoSym[i]];
      end;
       Result:=(crc shr 8) or (crc shl 8);
    end;
    function ReadCoils(DeviceAddress: byte; StartingAddress:word; QuantityCoils : word): TReadCoils;
      var
    
        Datagramm: Array[0..3] of Word;
         ToPort: Array[0..5] of word;
    begin
        Datagramm[0]:=TwoBytesToWord(DeviceAddress,$3);
        Datagramm[1]:=TwoBytesToWord(hi(StartingAddress),lo(StartingAddress));
        Datagramm[2]:=TwoBytesToWord(hi(QuantityCoils),lo(QuantityCoils));
         ToPort[0]:=hi(datagramm[0]);
         ToPort[1]:=lo(datagramm[0]);
         ToPort[2]:=hi(datagramm[1]);
         ToPort[3]:=lo(datagramm[1]);
         ToPort[4]:=hi(datagramm[2]);
         ToPort[5]:=lo(datagramm[2]);
         Datagramm[3]:=crc16(toport,12);
    end;

    Вот такими костылями заставляем вычисляться CRC-16 для Modbus в Readcoils

    Запостил: untitled_001, 23 Января 2017

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

    • когда увидел начало подумал "эй, кто там мои исходники выложил". отпустило когда до Datagramm дочитал.
      Ну а так - да, в Modbus используется internet byte order, надо просто по байтам а не словам заполнять.
      Ответить
      • а всякую htons() к вам не завезли?

        и почему коммент в CP866? Это что, под дос писано?
        Ответить
        • почему дос?
          win-1252 обычный
          Ответить
          • да, ты прав

            это текст в 1251 выведенный в 1252

            я налажал
            Ответить
            • Это баг Delphi7 и всех компилируемых ею приложений
              Ответить
              • не понял
                баг дельфи заставляет тебя писать калменты на русском?

                или дельфи не умеет utf-8 просто и конпелятор ломается?
                Ответить
                • Борленд Дельфи 7 не умеет. Калменты на русской кодировке отображаюься норм. Но при коприпасте выходит шняга, если при вставке из клипборда раскладка клавы отличается
                  Ответить
                  • >>Delphi 7 (August 2002)
                    это правда?

                    ну тогда это позор
                    в 2002м году уже XP была, довольно очевидно было что будущее за уникодом
                    Ответить
                    • Ты помнишь как всё начиналос, всё было впервые и вновь....
                      Ответить
                      • Боюсь что эта песенка старше паскаля;)
                        Ответить
              • Это баг любых не юникодных приложений в венде, проверь.

                Если приложение не юникодное и выбрана не та раскладка - копируется вот такая хуита. Венда, походу, по раскладке пытается кодировку клипборда угадать... Эвристика, мать её.
                Ответить
                • >>эвристика
                  ну?

                  https://msdn.microsoft.com/en-us/library/windows/desktop/ff729168(v=vs.85).aspx

                  if it (клипборд) contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input language. You can use the CF_LOCALE format to associate a different locale with the clipboard text.

                  Note that the clipboard does not support plain text in multiple character sets. To achieve this, use a formatted text data type such as RTF instead.
                  The system uses the code page associated with CF_LOCALE to implicitly convert from CF_TEXT to CF_UNICODETEXT. Therefore, the correct code page table is used for the conversion.
                  Ответить
                  • > to the current input language
                    Ну эвристика же :)
                    Ответить
                    • На самом деле однобайтовая кодировка в винде выставляется в regional settings, причем там она называется не по номеру кодовой страницы, а по названию страны (внезапно). ну типа Russia -- Win1251.

                      https://s30.postimg.org/3sroucaht/loc.png

                      зы: однобайтовые кодировки надо обоссцать и сжечь уже лет 10 как
                      Ответить
                      • > выставляется в regional settings
                        Ага. Вот только если прога не указала CF_LOCALE, то почему-то используется не она, а именно эвристика через current input language. Костыль какой-то.
                        Ответить
        • есть swap, но я не вижу смысла страдать перестановками байтов в словах если можно просто записывать в буфер побайтово.
          Ответить
          • > просто записывать в буфер побайтово
            Угу. И насчитывать CRC на собранный в буфере пакет, а не ебаться с этим в каждой функции.
            Ответить
      • Modbus protocol reference - такой редкочитаемый мануал, где смешались в кучу байты, ворды, биг ендианы. Весьма вазелиновое занятие программировать такую муру.
        Ответить
        • Хм, прочитал главу о фрейминге в этом мануале. Нормальная спека, тащемта, вроде всё понятно.
          Ответить
        • Там на один день прочитать и реализовать. Ну может на два. И не надо никаких shl shr, сделай функцию которая пишет в буфер слово и которая пишет байт, и вызывай не думая больше о порядке байтов.
          Ответить
          • Кстати, в спеке во всех командах тупо расписано куда ложить hi а куда lo. И никаких "смешались в кучу байты, ворды, биг ендианы" я там не нашёл...

            > сделай функцию которая пишет в буфер слово и которая пишет байт
            +1

            З.Ы. Почему-то функция называется Read Coils (команда 1), а формирует Read Holding Registers (команда 3).
            Ответить
          • > сделай функцию которая пишет в буфер слово и которая пишет байт

            +1

            К слову о стандартных библиотеках https://golang.org/pkg/encoding/binary/
            https://github.com/roman-kashitsyn/encoding-binary
            Ответить
          • Оформить пакет не беда. А дальше инициализация глюкаво-корявого dcb, запихивания этого говна в поток, синхронизация данных потока с контролами gui. Вкусно, очень вкусно...
            Ответить
            • Ну не так страшен dcb, как его малюют. Если rs-232 - можно об второй комп с какой-нибудь putty подебажиться.

              Остальное тоже терпимо, даже в делфи.
              Ответить
              • Цепляюсь к железке через конвертер rs-485, данные мониторю через hhd serial monitor. Всё бы хорошо, но формирование фрейма мне периодически спать не даёт. Уже раз пять кардинально рефакторил эту часть кода. Дураков работа любит.
                Ответить
        • Я когда впервые с модбас встретился это таким облегчением было - мы сначала пытались железкой (частотником) рекомендованных способом управлять, через opc server, и так там медленно работало что прям бооль. В какой-то момент от отчаяния стали смотреть какие ещё есть варианты управления - http, ftp, о, а это что за незнакомое слово - modbus tcp. И с ним просто летать стало. В следующих проектах правда и на модбас забили, просто свой протокол по rs485 со стороны частотника реализовали.
          Короче это простой протокол.

          То ли дело ethercat/profinet - я сколько не читал, ничего не понял. Сначала какие-то абстракции вводят, потом абстракции поверх них, ни разу до конкретных байтов не доходил.
          Ответить
          • Ну modbus tcp это совершенно отдельная песня. Писал прогу управления регистрами ПЛК(который был слейвом) и на дельфе, и на php мутил типа умного дома.
            Потом руководство заставило заняться SLMP протоколом от фирмы Mitsubishi. Так там вообще всё проще этих ваших модбасов. На транспортном уровне тот же TCP, а сообщение шлётся в стандартный TCP-сокет безо всяких контролек в натуральном ascii виде типа 500000FF03FF000018000004010001X*00000000 08, а в ответ приходит что-то типа D00000FF03FF00000C000010000000. Остаётся только разложить эту лабуду и вытащить состояние запрашиваемых битов. А Modbus RTU продолжаю заниматься по причине того, что в нашем бедном регионе промоборудование дешёвых китайских брендов и брать контроллер типа Семёна за 150 тыщ с ихними profibus и AS-interface никто не станет.
            Ответить
          • > просто свой протокол по rs485 со стороны частотника реализовали
            а могли остаться на модбасе и облегчить жизнь потенциальным интеграторам, желающим вашего девайса
            Ответить
            • >а могли остаться на модбасе и облегчить жизнь потенциальным интеграторам, желающим вашего девайса
              в век Стухнета и прочих червей никому доверять нельзя. Надо создавать свой протокол, с покером и блудницами
              Ответить
              • Как тупейший транспортный протокол (не реализация) с дохуядесятилетней историей может являться точкой уязвимости. Я бы поверил, что нестандартный протокол больше имеет шансов на проблемы.
                Ответить
            • оверхед очень большой. По своему протоколу только то что надо передаем, можно всякую там синхронизацию сделать, а по модбас и длина посылки ограничена, и пауза между посылками нужна, и на строне частотника потом регистры туда-сюда переставлять. Хотя мы в то время теми еще неосиляторами были, возможно и на модбас можно хорошей скорости достичь.
              Ответить
            • Ну и там все равно не поинтегрируешь, поверх модбаса безумный велосипед, да и девайс не на продажу а под объект. мы в театре систему управления декорациями делали.
              Ответить
          • >В следующих проектах правда и на модбас забили, просто свой протокол по rs485 со стороны частотника реализовали.
            Дайте свангую: Частотник а-ля Овен-Веспер? Они любят такой халабудой заниматься. Ну еще Вакон был, но его кагбе "поглотили"
            Ответить
    • Первый раз вижу, чтобы crc считали по словам, а не по байтам.

      З.Ы. А, тьфу, его по байтам и считают.
      Ответить

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