3.25. พื้นฐาน CAN bus

CAN (Controller Area Network) ได้รับการออกแบบโดย Bosch ในทศวรรษ 1980 เพื่อเชื่อมต่อหน่วยควบคุมอิเล็กทรอนิกส์ทั้งหมดในรถยนต์เข้ากับบัสร่วมสายเดียวที่สั้น ปัจจุบันยังคงครองตลาดสายไฟในรถยนต์ แต่ความทนทาน พฤติกรรมแบบเรียลไทม์ และการออกแบบแบบ multi-master ทำให้มันกลายเป็น field bus มาตรฐานในระบบอัตโนมัติ หุ่นยนต์ อุปกรณ์การเกษตร และอุตสาหกรรมทุกประเภท

CAN ไม่มี "controller" เพียงตัวเดียวและชุด "peripherals" เหมือน SPI และ I2C ทุกโหนดบนบัสเป็น peer และโหนดใดก็ตามสามารถส่งข้อมูลได้เมื่อบัสว่างอยู่ สิ่งที่ทำให้ระบบนี้ขยายขนาดได้คือการออกแบบแบบ broadcast-with-arbitration

3.25.1. การ Broadcast พร้อมการจัดลำดับความสำคัญ (Priority Arbitration)

ทุกข้อความบน CAN bus มี identifier -- 11 บิตสำหรับ standard frame แบบ classic และ 29 บิตสำหรับ extended variant โดย identifier ไม่ใช่ address แต่เป็นการระบุว่าข้อความนั้น เกี่ยวกับ อะไร (รอบต่อนาทีของเครื่องยนต์ ตำแหน่งแป้นเบรก แรงดันแบตเตอรี เป็นต้น) เมื่อโหนดต้องการส่งค่า มันจะ broadcast ค่านั้นพร้อม identifier ที่เหมาะสม และทุกโหนดบนบัสจะรับสัญญาณ broadcast นั้นได้ แต่ละ receiver จะกรองบัสด้วยฮาร์ดแวร์เพื่อเลือกเฉพาะ ID ที่ต้องการ

หากสองโหนดพยายามส่งข้อมูลพร้อมกัน การออกแบบทางไฟฟ้าของบัสจะทำให้ข้อความที่มี identifier ตัวเลข ต่ำกว่า ชนะโดยไม่สูญเสียบิตใดเลย

กลไกนี้อาศัยสองสถานะทางไฟฟ้าของบัส: dominant (ค่าลอจิก 0) และ recessive (ค่าลอจิก 1) สายไฟ CAN ถูกดึงขึ้นสูง (recessive) ด้วยตัวต้านทาน termination เมื่อไม่มีโหนดสื่อสาร โหนดใดก็ตามสามารถดึงสายลงต่ำ (dominant) โดยให้กระแสไหลผ่าน transceiver ผลลัพธ์คือ wired-AND: หากโหนดใดโหนดหนึ่งขับบัสเป็น dominant สายจะอ่านค่า dominant และจะอ่านค่า recessive เมื่อทุกโหนดปล่อยสายแล้วเท่านั้น Dominant ชนะเสมอ (บางเอกสารเรียกการจัดเรียงเดียวกันนี้ว่า wired-OR โดยถือว่า dominant คือสัญญาณ asserted แทนที่จะเป็น AND ของบิต recessive -- พฤติกรรมทางกายภาพเหมือนกันทั้งสองแบบ)

A single bus line held high by a termination resistor to Vcc. Three nodes (A, B, C) hang off the bus. Each node's output stage is a diode in series with a switch to ground -- the diode points from the bus down to the switch, so closing the switch pulls the bus low through the diode but no node can drive the bus high.

แนวคิด wired-AND ในรูปแบบทั่วไป CAN จริงใช้ลอจิกเดียวกันนี้กับ differential pair (CAN_H / CAN_L) โดยมี transceiver และตัวต้านทาน termination แยกกันสองสาย แต่กฎบนบัสเหมือนกัน: โหนดใดก็ตามสามารถดึง dominant ได้ และจะอ่านค่า recessive เฉพาะเมื่อทุกโหนดปล่อยสายแล้วเท่านั้น

Arbitration ใช้ความไม่สมมาตรนี้โดยตรง ทุกโหนดที่กำลังส่งจะส่ง ID ของมันทีละบิต โดยเริ่มจาก MSB ก่อน และตรวจสอบบัส ขณะ ที่ส่ง โหนดที่วางบิต recessive ลงบนสาย แต่อ่านกลับมาได้ dominant รู้ว่ามีโหนดอื่นที่มี ID ต่ำกว่ากำลังส่งในเวลาเดียวกันและชนะในตำแหน่งบิตนั้น จึงหยุดขับบัสทันทีและเปลี่ยนเป็นฟัง โหนดที่ชนะในทางกลับกันเห็นบิตของตัวเองออกไปโดยไม่เปลี่ยนแปลง -- จากมุมมองของมันไม่มีอะไรผิดปกติเกิดขึ้น ID ที่มีหมายเลขต่ำกว่าชนะเพราะบิต dominant ของมันแทนที่บิต recessive ที่ ID ที่มีหมายเลขสูงกว่าจะส่งในตำแหน่งเดียวกัน

ผู้แพ้จะรอให้บัสว่างแล้วลองส่งใหม่โดยอัตโนมัติ ไม่มีการชนกัน ไม่มีข้อความสูญหาย -- มีเพียงการจัดลำดับความสำคัญแบบกำหนดแน่นอนเท่านั้น

นี่คือรูปแบบ publish/subscribe ที่ทำให้ CAN ทำงานได้ในระดับขนาดใหญ่: ทุกคนสามารถพูด ทุกคนสามารถฟัง และ ID ทำให้การส่งต่อเป็นแบบ implicit

3.25.2. บัสทางกายภาพ

MCU CAN controller ไม่ขับบัสโดยตรง มันเปิดเผยเพียงสองพิน CMOS 3.3 V -- TX (บิตที่ต้องการส่ง) และ RX (บิตที่เห็นบนบัส) -- และพินเหล่านั้นต่อไปยังชิปแยกที่เรียกว่า CAN transceiver หรือ PHY transceiver ตั้งอยู่ระหว่าง controller และสาย CAN จริง มันรู้วิธีสื่อสารกับบัส

บัสเองเป็น differential pair 5 V:

  • CAN_H -- สาย "สูง" ของ pair

  • CAN_L -- สาย "ต่ำ"

ในสถานะ recessive ทั้งสองสายอยู่ที่ประมาณ 2.5 V (จุดกึ่งกลางของแหล่งจ่าย 5 V ของบัส) ในสถานะ dominant transceiver จะดึง CAN_H ขึ้นไปประมาณ 3.5 V และดึง CAN_L ลงมาประมาณ 1.5 V สร้าง differential ประมาณ 2 V ระหว่าง pair ตัวรับสัญญาณจะสุ่มตัวอย่าง ความต่าง ระหว่างสองสาย ซึ่งทำให้สัญญาณไม่ได้รับผลกระทบจาก common-mode noise ที่เกิดขึ้นตลอดสายเคเบิลยาว

หน้าที่สองทางของ transceiver:

  • ด้าน TX มันอ่านพิน TX single-ended 3.3 V ของ controller และขับ CAN_H กับ CAN_L ให้ห่างกันสำหรับ dominant หรือปล่อยทั้งคู่สำหรับ recessive

  • ด้าน RX มันอ่าน differential pair CAN_H / CAN_L และรายงานระดับ single-ended 3.3 V บนพิน RX กลับไปยัง controller

ตัวต้านทาน termination 120 โอห์มสองตัว หนึ่งตัวที่แต่ละปลายทางกายภาพของสาย จะดึงบัสไว้ที่จุดกึ่งกลาง recessive เมื่อไม่มีโหนดขับและลด reflection ที่จะทำให้สัญญาณ differential เสียหายในการเดินสายยาว

3.25.3. data frame

standard CAN data frame มีลักษณะดังนี้บนสาย:

Eight fields drawn in sequence: SOF (1 bit), ID (11 bits), RTR (1 bit), control (6 bits), data (0 -- 8 bytes), CRC (16 bits), ACK (2 bits), and EOF (7 bits).

standard CAN data frame: ฟิลด์ SOF, ID, RTR, control, data, CRC, ACK และ EOF

แต่ละฟิลด์มีหน้าที่เฉพาะ:

  • SOF (start of frame) หนึ่งบิต dominant ที่บอกว่าเฟรมใหม่กำลังเริ่มต้นและซิงโครไนซ์นาฬิกาบิตของทุกโหนด

  • ID (identifier) identifier 11 บิตที่บัสใช้สำหรับ arbitration ตัวเลขต่ำกว่า = ความสำคัญสูงกว่า

  • RTR (remote transmission request) ตั้งค่าบน คำขอ สำหรับข้อมูล แทนที่จะเป็น การส่ง ข้อมูล receiver ที่มี ID ตรงกันจะตอบสนองโดยการส่งข้อมูลเอง

  • Control ฟิลด์ 6 บิตที่เข้ารหัสความยาวข้อมูล (DLC) และบิตจัดการบ้านบางส่วน

  • Data payload 0 ถึง 8 ไบต์ (CAN Classic; CAN FD ขยายเป็น 64 ไบต์)

  • CRC รวม 16 บิต: CRC 15 บิตเหนือฟิลด์ก่อนหน้าบวก CRC delimiter 1 บิต

  • ACK รวม 2 บิต ในบิตแรก -- ACK slot -- ผู้ส่งปล่อยสายและโหนดใดก็ตามที่ได้รับเฟรมอย่างถูกต้องจะดึงลงต่ำ บิตที่สองเป็น recessive delimiter การไม่มี ACK บอกให้ผู้ส่งรู้ว่าไม่มีโหนดใดรับเฟรมได้และควรลองใหม่

  • EOF (end of frame) เจ็ดบิต recessive ปิดท้ายเฟรม

ทั้งหมดนี้ถูกสร้างและถอดรหัสโดย CAN controller ในฮาร์ดแวร์ ซอฟต์แวร์เห็นเพียง ID ข้อมูล และแฟล็กบางส่วนเท่านั้น

3.25.4. ตำแหน่งของ CAN

การออกแบบของ CAN กำหนดช่องทางการใช้งานของมัน:

  • ทนทาน การส่งสัญญาณแบบ differential บน twisted pair การตรวจจับข้อผิดพลาดในตัว การ arbitration ลำดับความสำคัญแบบกำหนดแน่นอน และการลองส่งใหม่อัตโนมัติ ทำให้ CAN ทนทานต่อสภาพแวดล้อมที่มีสัญญาณรบกวนทางไฟฟ้า ซึ่ง UART และ SPI จะเสียข้อมูล

  • Multi-master โหนดใดก็ตามสามารถสื่อสารได้ตลอดเวลา ไม่จำเป็นต้องมี controller กลาง และไม่มีโหนดใดเป็น single point of failure

  • จำกัดแบนด์วิดท์ CAN Classic มีขีดสูงสุดประมาณ 1 Mbit/s; CAN FD ขยายค่านี้ CAN เป็นคำตอบที่ถูกต้องเมื่อลิงก์อยู่ ระหว่าง บอร์ดหรือโมดูล มักผ่านสายเคเบิลหลายเมตร โดยมีความน่าเชื่อถือเป็นลำดับความสำคัญ

  • โปรโตคอลชั้นสูง CAN bus เปล่าไม่ได้บอกว่า ID มีความหมายว่าอะไรหรือวิธีแบ่งข้อความยาวเป็น fragment โปรโตคอลชั้น application -- CANopen, J1939, ISO-TP/UDS, NMEA 2000 -- เพิ่มกฎเหล่านั้นไว้ด้านบน สิ่งที่ควรรู้เพิ่มเติมคือไฟล์ DBC: รูปแบบข้อความเฉพาะของผู้จำหน่ายที่บันทึกว่า ID ใดบรรจุสัญญาณระดับบิตใดในยานพาหนะหรือระบบเฉพาะ ไฟล์ DBC เป็นรูปแบบ metadata ที่อธิบาย message layout ของบัสหนึ่ง ไม่ใช่โปรโตคอลของตัวเอง

ไดรเวอร์ใน CAN bus ในโค้ด จัดการ CAN frame ระดับสาย การแมป ID กับความหมายเป็นหน้าที่ของ application