โปรโตคอลการ จำกัด / การซิงโครไนซ์เทคนิคแบบอนุกรม


24

เนื่องจากการสื่อสารแบบซีเรียลแบบอะซิงโครนัสแพร่กระจายอย่างกว้างขวางในอุปกรณ์อิเล็กทรอนิกส์ทุกวันนี้ฉันเชื่อว่าพวกเราหลายคนได้พบคำถามเช่นนี้เป็นครั้งคราว พิจารณาอุปกรณ์อิเล็กทรอนิกส์Dและคอมพิวเตอร์PCที่เชื่อมต่อกับสายอนุกรม (RS-232 หรือคล้ายกัน) และจำเป็นต้องมีการแลกเปลี่ยนข้อมูลอย่างต่อเนื่อง Ie PCกำลังส่งเฟรมคำสั่งแต่ละเฟรมX msและDกำลังตอบกลับด้วยรายงานสถานะ / เฟรม telemetry แต่ละรายการY ms(สามารถส่งรายงานเป็นการตอบสนองต่อคำขอหรือเป็นอิสระ - ไม่สำคัญเลยที่นี่) กรอบการสื่อสารสามารถมีข้อมูลไบนารีใด ๆ โดยพลการ สมมติว่าเฟรมการสื่อสารเป็นแพ็กเก็ตที่มีความยาวคงที่

ปัญหา:

เนื่องจากโปรโตคอลมีความต่อเนื่องด้านการรับอาจหลุดการซิงโครไนซ์หรือเพียงแค่ "เข้าร่วม" ที่อยู่ตรงกลางของเฟรมที่ส่งต่อเนื่องดังนั้นมันจะไม่รู้ว่าจุดเริ่มต้นของเฟรม (SOF) นั้นอยู่ที่ไหน ข้อมูลมีความหมายที่แตกต่างกันไปตามตำแหน่งของ SOF ข้อมูลที่ได้รับจะเสียหายและอาจเกิดขึ้นตลอดไป

ทางออกที่ต้องการ

รูปแบบการลด / ประสานที่เชื่อถือได้ในการตรวจจับ SOF ด้วยเวลาการกู้คืนสั้น ๆ (เช่นไม่ควรใช้เวลามากกว่านั้นพูด 1 เฟรมเพื่อซิงโครไนซ์อีกครั้ง)

เทคนิคที่มีอยู่ฉันรู้ (และใช้บางส่วน) ของ:

1) ส่วนหัว / การตรวจสอบ - SOF เป็นค่าไบต์ที่กำหนดไว้ล่วงหน้า ตรวจสอบผลรวมในตอนท้ายของเฟรม

  • จุดเด่น:เรียบง่าย
  • ข้อด้อย:ไม่น่าเชื่อถือ เวลาฟื้นตัวที่ไม่รู้จัก

2) การบรรจุไบต์:

  • ข้อดี:การกู้คืนที่รวดเร็วและเชื่อถือได้สามารถใช้กับฮาร์ดแวร์ใด ๆ
  • ข้อด้อย:ไม่เหมาะสำหรับการสื่อสารด้วยเฟรมขนาดคงที่

3) การทำเครื่องหมายบิตที่ 9 - เพิ่มแต่ละไบต์ด้วยบิตเพิ่มเติมในขณะที่ SOF ที่ทำเครื่องหมายด้วย1และไบต์ข้อมูลจะถูกทำเครื่องหมายด้วย0:

  • จุดเด่น:การกู้คืนที่รวดเร็วและเชื่อถือได้
  • ข้อด้อย:ต้องการการสนับสนุนฮาร์ดแวร์ PCฮาร์ดแวร์และซอฟต์แวร์ส่วนใหญ่ไม่ได้รับการสนับสนุนโดยตรง

4) การทำเครื่องหมายบิตที่ 8 - ชนิดของการจำลองด้านบนในขณะที่ใช้บิตที่ 8 แทน 9 ซึ่งจะเหลือเพียง 7 บิตสำหรับแต่ละคำของข้อมูล

  • ข้อดี:การกู้คืนที่รวดเร็วและเชื่อถือได้สามารถใช้กับฮาร์ดแวร์ใด ๆ
  • ข้อด้อย:ต้องใช้รูปแบบการเข้ารหัส / ถอดรหัสจาก / ถึงการนำเสนอ 8 บิตแบบเดิมไปยัง / จากการเป็นตัวแทน 7 บิต ค่อนข้างสิ้นเปลือง

5) การหมดเวลาใช้งาน - สมมติว่า SOF เป็นไบต์แรกที่มาหลังจากเวลาว่างที่กำหนด

  • ข้อดี:ไม่มีข้อมูลค่าใช้จ่ายง่าย ๆ
  • ข้อด้อย:ไม่น่าเชื่อถือ จะไม่ทำงานได้ดีกับระบบจับเวลาที่ไม่ดีเช่น Windows PC ค่าโสหุ้ยการรับส่งข้อมูลที่อาจเกิดขึ้น

คำถาม: มีเทคนิค / วิธีแก้ไขอื่น ๆ ที่เป็นไปได้เพื่อแก้ไขปัญหาคืออะไร? คุณสามารถชี้ไปที่ข้อเสียในรายการด้านบนซึ่งสามารถใช้งานได้อย่างง่ายดายจึงลบออกได้หรือไม่ คุณ (หรือคุณ) ออกแบบระบบของคุณอย่างไร

serial  communication  protocol  brushless-dc-motor  hall-effect  hdd  scr  flipflop  state-machines  pic  c  uart  gps  arduino  gsm  microcontroller  can  resonance  memory  microprocessor  verilog  modelsim  transistors  relay  voltage-regulator  switch-mode-power-supply  resistance  bluetooth  emc  fcc  microcontroller  atmel  flash  microcontroller  pic  c  stm32  interrupts  freertos  oscilloscope  arduino  esp8266  pcb-assembly  microcontroller  uart  level  arduino  transistors  amplifier  audio  transistors  diodes  spice  ltspice  schmitt-trigger  voltage  digital-logic  microprocessor  clock-speed  overclocking  filter  passive-networks  arduino  mosfet  control  12v  switching  temperature  light  luminous-flux  photometry  circuit-analysis  integrated-circuit  memory  pwm  simulation  behavioral-source  usb  serial  rs232  converter  diy  energia  diodes  7segmentdisplay  keypad  pcb-design  schematics  fuses  fuse-holders  radio  transmitter  power-supply  voltage  multimeter  tools  control  servo  avr  adc  uc3  identification  wire  port  not-gate  dc-motor  microcontroller  c  spi  voltage-regulator  microcontroller  sensor  c  i2c  conversion  microcontroller  low-battery  arduino  resistors  voltage-divider  lipo  pic  microchip  gpio  remappable-pins  peripheral-pin-select  soldering  flux  cleaning  sampling  filter  noise  computers  interference  power-supply  switch-mode-power-supply  efficiency  lm78xx 

4 เป็น 1 / 8th เพียงสิ้นเปลืองมากกว่า 3
นิคจอห์นสัน

@ NickJohnson เห็นด้วย แต่มันเป็นเพียงการแนะนำให้ฉันเพิ่มสิ่งที่ "สิ้นเปลือง" ใน (3) เช่นกัน :)
Eugene Sh

ฉันไม่คิดว่าคุณจะอธิบายสมมติฐานของคุณอย่างครบถ้วนเกี่ยวกับข้อผิดพลาดในการสื่อสาร คุณสมมติว่าการสื่อสารนั้น 'สมบูรณ์แบบ' คือไม่มีข้อผิดพลาดหรือ 'สมบูรณ์แบบมากพอ' ที่ข้อผิดพลาดทั้งหมดถูกตรวจพบและระบุโดยฮาร์ดแวร์การสื่อสาร (เช่น comms ใช้แพริตีและเป็นบิตข้อผิดพลาดเดียวเท่านั้น)
gbulmer

Beceiver สามารถเข้าร่วมในช่วงกลางของไบต์และอาจตีความบิต 8 เป็นบิต 4 ดังนั้นการทำเครื่องหมายบิตที่ 9 จึงไม่น่าเชื่อถือ
ทิโมธีบอลด์วิน

@ gbulmer สมมติฐานดั้งเดิมคือช่องนี้สมบูรณ์แบบและปัญหาสามารถเกิดขึ้นได้เนื่องจากการซิงโครไนซ์เริ่มต้นเท่านั้น ภายใต้สมมติฐานเหล่านี้ "ความน่าเชื่อถือ" ฉันหมายถึงเกี่ยวข้องกับ resync เท่านั้น ในรายการด้านบนเทคนิคเหล่านี้ทั้งหมดรับประกันความสำเร็จ 100% ยกเว้นครั้งแรก แต่รูปแบบการตรวจสอบข้อผิดพลาดอาจและกรอบไม่ควรแยกเช่นนี้
ยูจีน Sh.

คำตอบ:


15

คุณ (หรือคุณ) ออกแบบระบบของคุณอย่างไร

จากประสบการณ์ของฉันทุกคนใช้เวลามากขึ้นในการแก้ไขข้อบกพร่องของระบบการสื่อสารมากกว่าที่คาดไว้ ดังนั้นฉันขอแนะนำอย่างยิ่งว่าเมื่อใดก็ตามที่คุณต้องการเลือกใช้โปรโตคอลการสื่อสารคุณจะต้องเลือกตัวเลือกใดก็ได้ที่ทำให้ระบบสามารถทำการดีบักได้ง่ายขึ้นหากเป็นไปได้

ฉันขอแนะนำให้คุณเล่นกับการออกแบบโปรโตคอลที่กำหนดเองไม่กี่ - มันสนุกและให้การศึกษามาก อย่างไรก็ตามฉันขอแนะนำให้คุณดูโปรโตคอลที่มีอยู่แล้ว หากฉันต้องการสื่อสารข้อมูลจากที่หนึ่งไปยังอีกที่หนึ่งฉันจะพยายามอย่างหนักที่จะใช้โปรโตคอลที่มีอยู่ก่อนซึ่งบางคนใช้เวลาในการดีบั๊กแล้ว

การเขียนโปรโตคอลการสื่อสารของคุณเองตั้งแต่เริ่มต้นมีแนวโน้มที่จะได้รับผลกระทบจากปัญหาทั่วไปหลาย ๆ ปัญหาที่ทุกคนมีเมื่อพวกเขาเขียนโปรโตคอลใหม่

มีโพรโทคอลระบบแบบฝังตัวหลายสิบรายการที่โพรโทคอลที่ใช้RS232ที่ดีสำหรับการสื่อสารแบบฝังตัวกับคอมพิวเตอร์ - ข้อใดที่ใกล้เคียงที่สุดกับความต้องการของคุณ

แม้ว่าบางกรณีทำให้มันเป็นไปไม่ได้ที่จะใช้โปรโตคอลที่มีอยู่แล้วฉันก็มีแนวโน้มที่จะทำให้บางสิ่งบางอย่างทำงานได้เร็วขึ้นโดยเริ่มต้นด้วยโปรโตคอลบางอย่างที่เกือบจะตรงกับข้อกำหนดแล้วจึงปรับแต่งมัน

ข่าวร้าย

อย่างที่ฉันได้พูดไปก่อนหน้านี้ :

น่าเสียดายที่เป็นไปไม่ได้ที่โปรโตคอลการสื่อสารใด ๆ จะมีคุณสมบัติที่ดีต่อการได้ทั้งหมด:

  • โปร่งใส: การสื่อสารข้อมูลมีความโปร่งใสและ "8 bit clean" - (a) ไฟล์ข้อมูลใด ๆ ที่เป็นไปได้สามารถส่งได้ (b) ลำดับไบต์ในไฟล์ที่จัดการเป็นข้อมูลเสมอและไม่ตีความผิดเป็นอย่างอื่นและ (c) ) ปลายทางได้รับไฟล์ข้อมูลทั้งหมดโดยไม่มีข้อผิดพลาดโดยไม่มีการเพิ่มหรือลบใด ๆ
  • คัดลอกง่าย: การสร้างแพ็กเก็ตนั้นง่ายที่สุดถ้าเราเพียงแค่คัดลอกข้อมูลจากแหล่งข้อมูลไปยังเขตข้อมูลของแพ็คเก็ตโดยไม่มีการเปลี่ยนแปลง
  • การเริ่มต้นที่ไม่ซ้ำกัน: สัญลักษณ์เริ่มแพ็คเก็ตนั้นง่ายต่อการจดจำเพราะเป็นไบต์คงที่ที่รู้จักซึ่งไม่เคยเกิดขึ้นที่อื่นในส่วนหัว, ส่วนหัว CRC, ส่วนของข้อมูลหรือข้อมูล CRC
  • 8 บิต: ใช้ 8 บิตเท่านั้น

ฉันจะแปลกใจและยินดีหากมีวิธีใดที่โปรโตคอลการสื่อสารจะมีคุณสมบัติเหล่านี้ทั้งหมด

ข่าวดี

มีเทคนิค / วิธีแก้ไขอื่น ๆ ที่เป็นไปได้เพื่อแก้ไขปัญหาคืออะไร?

บ่อยครั้งที่การดีบั๊กนั้นง่ายกว่ามากหากมนุษย์ที่เทอร์มินัลข้อความสามารถแทนที่อุปกรณ์สื่อสารใด ๆ ได้ สิ่งนี้ต้องใช้โปรโตคอลในการออกแบบให้มีเวลาค่อนข้างอิสระ (ไม่หมดเวลาระหว่างการหยุดที่ค่อนข้างนานระหว่างการกดแป้นพิมพ์ที่มนุษย์พิมพ์) นอกจากนี้โปรโตคอลดังกล่าวยัง จำกัด จำนวนไบต์ที่มนุษย์สามารถพิมพ์แล้วอ่านบนหน้าจอได้ง่าย

โพรโทคอลบางตัวอนุญาตให้ส่งข้อความในโหมด "text" หรือ "binary" (และต้องการให้ข้อความไบนารีที่เป็นไปได้ทั้งหมดมีข้อความ "ที่เทียบเท่า" ซึ่งหมายถึงสิ่งเดียวกัน) วิธีนี้จะช่วยให้การดีบักง่ายขึ้นมาก

บางคนคิดว่าการ จำกัด โปรโตคอลเพียงใช้ตัวอักษรที่พิมพ์ได้คือ "สิ้นเปลือง" แต่การประหยัดเวลาในการแก้ไขข้อบกพร่องมักทำให้คุ้มค่า

ตามที่คุณได้กล่าวไปแล้วถ้าคุณอนุญาตให้เขตข้อมูลมีไบต์ใดก็ได้รวมถึงจุดเริ่มต้นของส่วนหัวและส่วนท้ายของส่วนหัวเมื่อผู้รับเปิดใช้งานครั้งแรกเป็นไปได้ว่าตัวรับสัญญาณผิดพลาด สิ่งที่ดูเหมือนไบต์เริ่มต้นของส่วนหัว (SOH) ในเขตข้อมูลที่อยู่ตรงกลางของหนึ่งแพ็คเก็ต โดยปกติผู้รับจะได้รับการตรวจสอบที่ไม่ตรงกันในตอนท้ายของแพ็กเก็ตหลอก (ซึ่งโดยทั่วไปจะอยู่ครึ่งทางผ่านแพ็คเก็ตจริงที่สอง) มันเป็นเรื่องน่าดึงดูดอย่างมากที่จะทิ้งข้อความหลอกทั้งหมด (รวมถึงครึ่งแรกของแพ็คเก็ตที่สอง) ก่อนที่จะมองหา SOH ต่อไป - ด้วยเหตุนี้ผู้รับอาจไม่ซิงค์กับข้อความจำนวนมาก

ตามที่ alex.forencich ชี้ให้เห็นวิธีการที่ดีกว่าคือการที่ผู้รับจะทิ้งไบต์ที่จุดเริ่มต้นของบัฟเฟอร์จนถึง SOH ถัดไป สิ่งนี้ทำให้ผู้รับ (หลังจากทำงานผ่าน SOH หลายไบต์ในแพ็กเก็ตข้อมูลนั้น) เพื่อซิงโครไนซ์กับแพ็กเก็ตที่สองทันที

คุณสามารถชี้ไปที่ข้อเสียในรายการด้านบนซึ่งสามารถใช้งานได้ง่ายโดยการลบออก

ในขณะที่ Nicholas Clark ชี้ให้เห็นว่าการบรรจุข้อมูลแบบไบต์ค่าใช้จ่ายสม่ำเสมอ (COBS) มีค่าใช้จ่ายคงที่ที่ทำงานได้ดีกับเฟรมขนาดคงที่

เทคนิคหนึ่งที่มักถูกมองข้ามคือไบต์เครื่องหมายสิ้นสุดเฟรมเฉพาะ เมื่อผู้รับเปิดอยู่ตรงกลางของการส่งไบต์เครื่องหมายสิ้นสุดเฟรมโดยเฉพาะช่วยให้ตัวรับสัญญาณซิงโครไนซ์เร็วขึ้น

เมื่อผู้รับเปิดอยู่ตรงกลางของแพ็คเก็ตและเขตข้อมูลของแพ็คเก็ตที่เกิดขึ้นจะมีไบต์ที่ดูเหมือนจะเป็นจุดเริ่มต้นของแพ็คเก็ต (จุดเริ่มต้นของแพ็คเก็ตหลอก) เครื่องส่งสัญญาณสามารถแทรกชุด ของไบต์เครื่องหมายสิ้นสุดเฟรมหลังจากแพ็คเก็ตนั้นดังนั้นไบต์หลอกเริ่มต้นของแพ็คเก็ตในเขตข้อมูลไม่ยุ่งกับการซิงโครไนซ์ทันทีและถอดรหัสแพคเก็ตถัดไปได้อย่างถูกต้องแม้ว่าคุณโชคร้ายมากและการตรวจสอบ ของ pseudo-packet นั้นถูกต้อง

โชคดี.


คำตอบนี้ควรพิจารณาคำตอบที่ได้รับการยอมรับก่อนหน้านี้ (ขออภัย @DaveTweed) และบทความที่เชื่อมโยงนั้นเป็นสิ่งที่ต้องอ่านอย่างแน่นอนในหัวข้อนี้ ขอบคุณสำหรับการสละเวลาและเขียน
ยูจีน Sh.

1
ดีที่คุณชี้ค็อบดังนั้นผมจึงไม่ได้มีการเขียนคำตอบ :-)
นิลส์ Pipenbrinck

11

รูปแบบการบรรจุแบบไบต์ได้ผลดีมากสำหรับฉันในช่วงหลายปีที่ผ่านมา มันดีเพราะมันใช้งานง่ายในซอฟต์แวร์หรือฮาร์ดแวร์คุณสามารถใช้สายเคเบิล USB-to-UART มาตรฐานเพื่อส่งแพ็คเก็ตข้อมูลและคุณรับประกันว่าจะได้เฟรมคุณภาพดีโดยไม่ต้องกังวล หมดเวลาแลกเปลี่ยนร้อนหรืออะไรอย่างนั้น

ฉันจะสนับสนุนวิธีการบรรจุแบบไบต์รวมกับไบต์ความยาว (ความยาวแพ็คเก็ตโมดูโล 256) และ CRC ระดับแพ็คเก็ตแล้วใช้ UART ด้วยบิตพาริตี ความยาวไบต์ช่วยให้แน่ใจว่าการตรวจจับแบบหล่นไบต์ซึ่งทำงานได้ดีกับบิตพาริตี้ (เพราะ UART ส่วนใหญ่จะลดลงไบต์ใด ๆ ที่ล้มเหลวเสมอกัน) จากนั้น CRC ระดับแพ็กเก็ตจะช่วยเพิ่มความปลอดภัยให้คุณ

สำหรับค่าใช้จ่ายในการบรรจุไบต์คุณได้ดูโปรโตคอล COBS แล้วหรือยัง? เป็นวิธีที่ชาญฉลาดในการทำการบรรจุแบบไบต์ด้วยค่าใช้จ่ายคงที่ 1 ไบต์ต่อการส่ง 254 ครั้ง (รวมถึงการทำเฟรม CRC, LEN และอื่น ๆ )

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing


นี่เป็นวิธีที่ยอดเยี่ยมในการหลีกเลี่ยงการบรรจุข้อมูลลงใน 2x ในกรณีที่แย่ที่สุด ฉันใช้ชุดรูปแบบเฉพาะที่คล้ายกัน แต่มีรูปแบบเฉพาะแอปพลิเคชั่น แต่ก็เป็นเรื่องดีที่ได้เห็นสิ่งนี้อธิบายในลักษณะมาตรฐาน ฉันจะใช้ COBS ต่อจากนี้ไป ...
wjl

1
ขอบคุณจากฉันเช่นกันสำหรับการชี้ให้เห็น COBS - อัลกอริทึมที่เรียบร้อยมาก
Nick Johnson เมื่อ

6

ตัวเลือกของคุณ # 1, SOH รวมถึงการตรวจสอบมีความน่าเชื่อถือและจะกู้คืนในเฟรมถัดไปที่ไม่เสียหาย

ฉันสมมติว่าคุณทราบความยาวของข้อความอยู่แล้วหรือความยาวนั้นถูกเข้ารหัสเป็นไบต์ตาม SOH ทันที ไบต์ตรวจสอบจะปรากฏที่ท้ายข้อความ คุณต้องมีบัฟเฟอร์ด้านรับสำหรับข้อมูลที่อย่างน้อยตราบใดที่ข้อความที่ยาวที่สุดของคุณ

ทุกครั้งที่คุณเห็นไบต์ SOH ที่ส่วนหัวของบัฟเฟอร์มันอาจเป็นจุดเริ่มต้นของข้อความ คุณสแกนผ่านบัฟเฟอร์เพื่อคำนวณค่าการตรวจสอบสำหรับข้อความนั้นและดูว่าตรงกับไบต์ตรวจสอบในบัฟเฟอร์ ถ้าเป็นเช่นนั้นคุณทำเสร็จแล้ว; มิฉะนั้นคุณจะละทิ้งข้อมูลจากบัฟเฟอร์จนกว่าคุณจะไปยังไบต์ SOH ถัดไป

โปรดทราบว่าหากข้อความมีข้อผิดพลาดข้อมูลจริงอัลกอริธึมนี้จะถูกทิ้ง - แต่คุณอาจจะทำเช่นนั้นต่อไป หากอัลกอริทึมการตรวจสอบของคุณมีการแก้ไขข้อผิดพลาดไปข้างหน้าคุณสามารถตรวจสอบการจัดแนวข้อความที่เป็นไปได้สำหรับข้อผิดพลาดที่แก้ไข

หากข้อความมีความยาวคงที่คุณสามารถแจกจ่ายด้วยไบต์ SOH ทั้งหมด - เพียงแค่ทดสอบตำแหน่งเริ่มต้นที่เป็นไปได้ทุกค่าการตรวจสอบที่ถูกต้อง

คุณสามารถแจกจ่ายด้วยอัลกอริธึมการตรวจสอบและเก็บไบต์ SOH เท่านั้น แต่สิ่งนี้ทำให้อัลกอริธึมน้อยลง แนวคิดคือสำหรับการจัดแนวข้อความที่ถูกต้อง SOH จะปรากฏที่จุดเริ่มต้นของข้อความเสมอ หากคุณมีการจัดตำแหน่งที่ไม่ถูกต้องไบต์ถัดไปในสตรีมข้อมูลไม่น่าจะเป็น SOH อื่น (ขึ้นอยู่กับความถี่ที่ SOH ปรากฏในข้อมูลข้อความ) คุณสามารถเลือกไบต์ที่ถูกต้อง SOH บนพื้นฐานนี้เพียงอย่างเดียว (นี่เป็นวิธีการกำหนดกรอบการให้บริการโทรคมนาคมแบบซิงโครนัสอย่าง T1 และ E1)


ฉันเดาว่าความน่าเชื่อถือจะเป็นไปได้หรือไม่ ขึ้นอยู่กับความแรงของข้อผิดพลาดในการตรวจสอบ / แก้ไขรหัสเราอาจพบเฟรมที่ดูเหมือนถูกต้องในสตรีมไบต์แบบสุ่ม / สุ่ม
ยูจีน Sh.

แน่นอนว่าเป็นไปได้ แต่ในทางปฏิบัติมันค่อนข้างง่ายที่จะเลือกอัลกอริธึมการตรวจสอบที่แข็งแกร่งพอ
Dave Tweed

หากคุณมีอัตราภัณฑ์ของข้อผิดพลาดข้อมูลที่มีเสมอโอกาสภัณฑ์คุณจะยอมรับข้อความที่ไม่ถูกต้องอยู่แล้ว
นิคจอห์นสัน

@NickJohnson สมมติว่าช่องทางที่สะอาดสมบูรณ์แบบจะยังคงมีไม่ตรงกัน (ในทางทฤษฎี) ด้วยวิธีการนี้ แน่นอนน่าจะเป็นของพวกเขาเล็กน้อย
ยูจีน Sh.

1
ฉันรู้ว่าคุณรู้เรื่องนี้อยู่แล้วและพูดถึงมันผ่านไปแล้ว แต่เวอร์ชันที่คุณไม่ได้บัฟเฟอร์ข้อความทั้งหมดหรือเพียงขี้เกียจเกี่ยวกับวิธีการถอดรหัสของคุณมีความน่าเชื่อถือน้อยกว่า หากคุณซิงค์ที่ SOH ไบต์ถัดไปหลังจากเช็คซัมที่ไม่ตรงกันแทนที่จะเป็น SOH ไบต์ถัดไปหลังจาก SOH "เท็จ" คุณมีโอกาสดีมากที่จะทิ้งการเริ่มต้นข้อความจริงและไม่ซิงค์กับข้อความจำนวนมากหรือใน กรณีที่เลวร้ายที่สุดตลอดไป
ฮอบส์

5

ตัวเลือกหนึ่งที่ไม่ได้กล่าวถึง แต่ใช้กันอย่างแพร่หลาย (โดยเฉพาะอย่างยิ่งบนอินเทอร์เน็ต) คือการเข้ารหัส ASCII / การเข้ารหัสข้อความ (ที่จริงแล้วการใช้งานที่ทันสมัยส่วนใหญ่ถือว่า UTF-8) จากประสบการณ์ของฉันพวกฮาร์ดแวร์เกลียดที่จะทำสิ่งนี้ แต่คนซอฟท์แวร์มักจะชอบสิ่งนี้มากกว่าสิ่งอื่นใด (ส่วนใหญ่จะเป็นประเพณี Unix ที่ทำให้ข้อความทั้งหมดเป็นไปตาม)

ข้อดีของการเข้ารหัสข้อความคือคุณสามารถใช้อักขระที่ไม่สามารถพิมพ์ได้สำหรับการจัดเฟรม ตัวอย่างเช่นสิ่งที่ง่ายที่สุดคือใช้บางอย่างเช่น0x00เพื่อระบุจุดเริ่มต้นของเฟรมและ0xffจุดสิ้นสุดเฟรม

ฉันเห็นสองวิธีหลักในการเข้ารหัสข้อมูลเป็นข้อความ:

  1. เมื่อฮาร์ดแวร์ / ชุดประกอบถูกขอให้ทำสิ่งนี้มันจะถูกนำไปใช้เป็นการเข้ารหัสฐานสิบหก นี่เป็นการแปลงไบต์เป็นค่าฐานสิบหกใน ASCII ค่าใช้จ่ายมีขนาดใหญ่ โดยทั่วไปคุณจะส่งสองไบต์สำหรับทุกไบต์ข้อมูลจริง

  2. เมื่อคนที่แต่งตัวประหลาดซอฟต์แวร์ถูกขอให้ทำเช่นนี้มันอาจจะถูกนำไปใช้เป็นการเข้ารหัส base64 นี่เป็นการเข้ารหัสอินเทอร์เน็ตโดยแท้จริง ใช้สำหรับทุกอย่างตั้งแต่อีเมลไฟล์ MIME ไปจนถึงการเข้ารหัสข้อมูล URL ค่าใช้จ่ายอยู่ที่ 33% ดีกว่าการเข้ารหัส hex อย่างง่ายมาก

คุณสามารถละทิ้งข้อมูลไบนารีและส่งข้อความได้อย่างสมบูรณ์ ในกรณีนี้เทคนิคที่พบบ่อยที่สุดคือการกำหนดเขตข้อมูลด้วยการขึ้นบรรทัดใหม่ (เพียง"\n"หรือ"\r\n") คำสั่ง NMEA (GPS), Modem AT และเซ็นเซอร์ Adventech ADAM เป็นตัวอย่างที่พบได้บ่อยที่สุด

โปรโตคอล / กรอบข้อความเหล่านี้ทั้งหมดมีข้อดีและข้อเสียดังต่อไปนี้:

มือโปร:

  • ง่ายต่อการแก้ไขข้อบกพร่อง
  • ใช้งานง่ายในภาษาสคริปต์
  • สามารถทดสอบฮาร์ดแวร์ได้ง่ายๆโดยใช้ Hyperterminal / minicom
  • ใช้งานง่ายบนฮาร์ดแวร์ (ยกเว้นว่ามันเป็นไมโครขนาดเล็กมากเช่น PIC)
  • สามารถเป็นกรอบขนาดคงที่หรือขนาดแตกต่างกัน
  • คาดการณ์กรอบและเวลาการกู้คืนการซิงค์ที่รวดเร็ว (กู้คืนเมื่อสิ้นสุดเฟรมปัจจุบัน)

Con:

  • ค่าใช้จ่ายที่มีขนาดใหญ่มากเมื่อเทียบกับการส่งแบบไบนารี่บริสุทธิ์ (จากนั้นอีกครั้งข้อความ I / O ยังสามารถ "บีบอัด" ตัวเลขเช่นการส่งหนึ่งไบต์"0"(0x30) แทนที่จะเป็นสี่ไบต์ 0x00000000)
  • ไม่ค่อยสะอาดในการใช้งานกับไมโครที่มีขนาดเล็กมากเช่น PIC (ยกเว้นว่าห้องสมุดของคุณมีsprintf()ฟังก์ชั่นอยู่)

โดยส่วนตัวแล้วฉันมีข้อได้เปรียบที่หนักกว่าข้อเสียอย่างมาก ความง่ายในการดีบั๊กเพียงอย่างเดียวนับเป็น 5 คะแนน (เพื่อให้จุดเดียวเพียงอย่างเดียวนั้นมีค่ามากกว่าข้อเสียทั้งคู่)


จากนั้นก็มีวิธีแก้ปัญหาที่คิดไม่ออกอย่างรอบคอบซึ่งมาจากพวกซอฟต์แวร์: ส่งข้อมูลที่เข้ารหัสโดยไม่ต้องคิดเกี่ยวกับการทำเฟรม

ฉันต้องติดต่อกับฮาร์ดแวร์ที่ส่ง XML ดิบในอดีต XML คือกรอบทั้งหมดที่มีอยู่ โชคดีที่มันค่อนข้างง่ายที่จะกำหนดขอบเขตของกรอบด้วย<xml></xml>แท็ก ข้อเสียที่สำคัญสำหรับฉันคือมันใช้มากกว่าหนึ่งไบต์ในการกำหนดกรอบ นอกจากนี้การกำหนดกรอบเองอาจไม่ได้รับการแก้ไขเนื่องจากแท็กอาจมีแอททริบิวต์: <tag foo="bar"></tag>ดังนั้นคุณต้องกำหนดบัฟเฟอร์สำหรับกรณีที่แย่ที่สุดเพื่อหาจุดเริ่มต้นของเฟรม

เมื่อเร็ว ๆ นี้ฉันเคยเห็นผู้คนเริ่มส่ง JSON ออกจากพอร์ตอนุกรม ด้วยการวางกรอบ JSON เป็นการเดาที่ดีที่สุด คุณมีอักขระ"{"(หรือ"[") เพื่อตรวจจับเฟรม แต่ยังมีอยู่ในข้อมูล ดังนั้นคุณต้องมีตัวแยกวิเคราะห์แบบสืบเชื้อสายซ้ำ (หรืออย่างน้อยตัวนับรั้ง) เพื่อหาเฟรม อย่างน้อยก็เป็นเรื่องเล็กน้อยที่จะรู้ว่าเฟรมปัจจุบันสิ้นสุดก่อนกำหนด: "}{"หรือ"]["ผิดกฎหมายใน JSON และระบุว่าเฟรมเก่าได้สิ้นสุดลงแล้วและเฟรมใหม่เริ่มต้นขึ้น


สำหรับการเข้ารหัสข้อความนอกจากนี้ยังมีฐาน 85ซึ่งมีค่าใช้จ่าย 25% แทนที่จะเป็น 33%
Dave Tweed

ฉันจะพิจารณาว่าเป็นชุดย่อย / รูปแบบของวิธีที่ 4
ยูจีน Sh.

@EugeneSh: ในทางเทคนิคมันเป็นส่วนย่อยของการทดสอบ จากนั้นอีกครั้งเนื่องจากคุณพิจารณาว่าเป็นชุดย่อยของการทำเครื่องหมายบิตคุณสามารถเข้าใจได้ว่าทำไมความคลุมเครือนี้ทำให้หมวดหมู่ถูกต้อง นอกจากนี้คุณไม่สามารถพิจารณาการใช้งานส่วนใหญ่ของการเข้ารหัสข้อความเป็นชุดย่อยของการทำเครื่องหมายบิตเนื่องจากบิตการทำเครื่องหมายไม่เคยใช้ (ตัวอย่างเช่นฉันมักจะใช้<และ>เป็นตัวคั่นและฉันเชื่อว่าอีเมลใช้บรรทัดใหม่หมายเหตุ: ใช่อีเมลเป็นรูปแบบกรอบที่เหมาะสม ที่สามารถส่งผ่าน RS232 เพื่อนของฉันใช้ในการทำงานเซิร์ฟเวอร์กระจายอีเมลสำหรับบ้านของเขาโดยใช้ RS232).
slebetman

4

สิ่งที่คุณอธิบายว่า "การทำเครื่องหมาย Xth บิต" สามารถวางเป็นรหัสอื่น ๆ ที่มีคุณสมบัติในการขยายข้อมูลโดยใช้เศษส่วนคงที่ทำให้โค้ดบางตัวว่างที่จะใช้เป็นตัวคั่น บ่อยครั้งที่รหัสเหล่านี้ให้ประโยชน์อื่นเช่นกัน ซีดีใช้การมอดูเลตแบบแปดถึงสิบสี่ซึ่งรับประกันความยาวรันสูงสุด 0 บิตระหว่างแต่ละ 1 ตัวอย่างอื่น ๆ ได้แก่โค้ดบล็อกการแก้ไขข้อผิดพลาดไปข้างหน้าซึ่งใช้บิตเพิ่มเติมเพื่อเข้ารหัสการตรวจหาข้อผิดพลาดและข้อมูลการแก้ไขเช่นกัน

อีกระบบที่คุณไม่ได้กล่าวถึงคือการใช้ข้อมูลนอกแบนด์เช่นสายเลือกชิปเพื่อกำหนดขอบเขตธุรกรรมหรือแพ็คเก็ต


รหัสการแก้ไขข้อผิดพลาดเป็นคำถามเล็กน้อย พวกเขาควรจะถูกเพิ่มลงในแผนการเหล่านี้ใด ๆ "ข้อมูลนอกแบนด์" ที่คุณอ้างถึงนั้นเหมือนกับ "การควบคุมโฟลว์ฮาร์ดแวร์" ฉันเดาหรือไม่
ยูจีน Sh.

@EugeneSh - ที่จริงแล้วการใช้บิตตรวจสอบข้อผิดพลาดสำหรับการทำเฟรมนั้นใช้ได้อย่างสมบูรณ์แบบแม้ว่าจะมีราคาแพงในด้านการรับ คุณเพียงแค่ทำการคำนวณข้อผิดพลาดสำหรับการจัดตำแหน่งข้อมูลที่เป็นไปได้ทั้งหมดและสิ่งที่ประสบความสำเร็จคือการจัดตำแหน่งที่ถูกต้องในเฟรมที่ไม่เสียหาย แน่นอนถ้าเฟรมจะเสียหายคุณจะไม่พบมัน
Dave Tweed

@DaveTweed มันเป็นสิ่งที่ฉันหมายถึงโดยเทคนิคแรก หรือฉันเข้าใจคุณผิด
ยูจีน Sh.

ไม่คุณไม่ได้เข้าใจผิด นั่นคือสิ่งที่ฉันกำลังพูดถึง อย่างไรก็ตาม "การต่อต้าน" ของคุณนั้นผิด - มันน่าเชื่อถือและสามารถสร้างความแข็งแกร่งให้กับข้อผิดพลาดในการส่งสัญญาณได้เช่นกัน
Dave Tweed

@DaveTweed แล้วเวลากู้คืนล่ะ คุณมีตัวอย่างของวิธีการที่จะทำให้แข็งแกร่ง?
ยูจีน Sh.

3

อีกตัวเลือกหนึ่งคือสิ่งที่เป็นที่รู้จักในฐานะสายการเข้ารหัส การเข้ารหัสสายให้สัญญาณลักษณะทางไฟฟ้าบางอย่างที่ทำให้การส่งสัญญาณง่ายขึ้น (การรับประกันความสมดุล DC และความยาวการวิ่งสูงสุด) และสนับสนุนอักขระควบคุมสำหรับการกำหนดกรอบและการซิงโครไนซ์นาฬิกา รหัสบรรทัดใช้ในโปรโตคอลอนุกรมความเร็วสูงที่ทันสมัยทั้งหมด - 10M, 100M, 1G, และ 10G Ethernet, Serial ATA, FireWire, USB 3, PCIe, ฯลฯ รหัสบรรทัดทั่วไปคือ8b / 10b , 64b / 66bและ128b / 130b. นอกจากนี้ยังมีรหัสบรรทัดที่เรียบง่ายซึ่งไม่ได้ให้ข้อมูลการทำเฟรมเฉพาะยอดคงเหลือ DC และการซิงค์นาฬิกา ตัวอย่างของสิ่งเหล่านี้คือ Machester และ NRZ คุณอาจต้องการใช้ 8b / 10b ถ้าคุณต้องการซิงค์อย่างรวดเร็ว รหัสสายอื่นไม่ได้รับการออกแบบมาให้ซิงค์อย่างรวดเร็ว การใช้รหัสบรรทัดเช่นเดียวกับที่เสนอข้างต้นจะต้องใช้ฮาร์ดแวร์ที่กำหนดเองเพื่อส่งและรับ

สำหรับตัวเลือกของคุณ 5 อนุกรม RS232 มาตรฐานควรสนับสนุนการส่งและรับตัวแบ่งโดยที่สายไม่ได้ใช้งานสองสามครั้ง อย่างไรก็ตามสิ่งนี้อาจไม่รองรับในทุกระบบ

โดยทั่วไปวิธีการกำหนดกรอบที่ง่ายที่สุดและน่าเชื่อถือที่สุดคือตัวเลือกที่ 1 ของคุณเมื่อใช้ร่วมกับฟิลด์ความยาวและรูทีน CRC หรือการตรวจสอบอย่างง่าย รูทีนการถอดรหัสนั้นง่าย: ละทิ้งไบต์จนกว่าคุณจะได้รับไบต์เริ่มต้นอ่านฟิลด์ความยาวรอทั้งเฟรมตรวจสอบเช็คซัมเก็บไว้ถ้าดี หากการตรวจสอบไม่ดีเริ่มทิ้งไบต์จากบัฟเฟอร์จนกว่าคุณจะได้รับเริ่มต้นไบต์และทำซ้ำ ปัญหาหลักของเทคนิคนี้คือการหาจุดเริ่มต้นของเฟรมไบต์ซึ่งจริงๆแล้วไม่ใช่จุดเริ่มต้นของเฟรม เพื่อบรรเทาปัญหานี้เทคนิคหนึ่งคือการหลีกเลี่ยงไบต์ที่มีค่าเดียวกันกับการเริ่มต้นของเฟรมไบต์ด้วยอักขระควบคุมอื่นแล้วเปลี่ยนไบต์ที่หลบหนีดังนั้นจึงมีค่าที่แตกต่างกัน ในกรณีนี้คุณจะต้องทำสิ่งเดียวกันกับไบต์ควบคุมใหม่


นี่เป็นคำตอบเดียวกับของ Nick Johnson
Dave Tweed
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.