คลาส CAN -- โปรโตคอล Controller Area Network¶
CAN เป็นโปรโตคอลอนุกรมแบบสองสายที่ใช้สำหรับการส่งข้อความแบบเรียลไทม์ที่เชื่อถือได้ระหว่างโหนดหนึ่งโหนดขึ้นไปที่เชื่อมต่อกับบัสร่วมกัน CAN 2.0 ได้รับการกำหนดมาตรฐานใน ISO-11898 และปัจจุบันเป็นที่รู้จักในชื่อ CAN Classic
นอกจากนี้ยังมีโปรโตคอลใหม่กว่าที่เข้ากันได้แบบย้อนหลังชื่อว่า CAN FD (CAN with Flexible Data-Rate) ไดรเวอร์ machine.CAN ในปัจจุบันยังไม่รองรับฟีเจอร์ CAN FD หากต้องการ CAN FD ให้ใช้ pyb.CAN บน STM32
การรองรับ CAN ต้องการคอนโทรลเลอร์ (มักเป็นอุปกรณ์ต่อพ่วงภายในไมโครคอนโทรลเลอร์) และทรานซีฟเวอร์ภายนอกสำหรับปรับระดับสัญญาณลงบัส CAN
รองรับบน OpenMV Cam STM32 (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6 รวมถึงรุ่น Arduino ที่มีการต่อทรานซีฟเวอร์) ยังไม่รองรับบน OpenMV Cam RT1062 (พอร์ต mimxrt) หรือ OpenMV Cam AE3 (พอร์ต alif)
อินเทอร์เฟซ machine.CAN เป็นอินเทอร์เฟซการส่งข้อความ CAN ระดับต่ำพื้นฐานที่แยก CAN คอนโทรลเลอร์ออกเป็นคิวลำดับความสำคัญขาออกสำหรับส่งข้อความ คิวขาเข้าสำหรับรับข้อความ และกลไกสำหรับรายงานข้อผิดพลาด
Note
โมดูล can และ aiocan ของ micropython-lib ที่วางแผนไว้จะเป็นวิธีที่แนะนำสำหรับการใช้ CAN กับ MicroPython
คอนสตรักเตอร์¶
- class machine.CAN(id: int, *args, **kwargs)¶
สร้างออบเจ็กต์ CAN คอนโทรลเลอร์ด้วย id ที่กำหนด:
idระบุออบเจ็กต์ CAN คอนโทรลเลอร์เฉพาะ โดยขึ้นอยู่กับบอร์ดและพอร์ตอาร์กิวเมนต์อื่น ๆ ทั้งหมดจะถูกส่งไปยัง
CAN.init()ต้องระบุอาร์กิวเมนต์อย่างน้อยหนึ่งตัว (bitrate)
เวอร์ชันในอนาคตของคลาสนี้อาจยอมรับอาร์กิวเมนต์คีย์เวิร์ดเฉพาะพอร์ตที่นี่ซึ่งกำหนดค่าฮาร์ดแวร์ด้วย ปัจจุบันยังไม่มีการนำอาร์กิวเมนต์คีย์เวิร์ดดังกล่าวมาใช้
ตัวอย่าง¶
สร้างและเริ่มต้น CAN คอนโทรลเลอร์ 1 ด้วยบิตเรต 500kbps:
from machine import CAN can = CAN(1, 500_000)
เมธอด¶
- init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None¶
เริ่มต้น CAN บัสด้วยพารามิเตอร์ที่กำหนด:
bitrate คืออัตราบิตของบัสที่ต้องการในหน่วยบิตต่อวินาที
mode คือหนึ่งในค่าที่แสดงภายใต้ โหมด ซึ่งระบุโหมดการทำงานที่ต้องการ ค่าเริ่มต้นคือการทำงาน "normal" บนบัส
พารามิเตอร์ถัดไปเป็นตัวเลือกและเกี่ยวข้องกับการตั้งค่าเวลาบิต CAN ในกรณีส่วนใหญ่คุณสามารถปล่อยให้พารามิเตอร์เหล่านี้ตั้งเป็นค่าเริ่มต้นได้:
sample_point คือเปอร์เซ็นต์จำนวนเต็มของเวลาบิตข้อมูล ระบุตำแหน่งของตัวอย่างบิตเทียบกับเวลาบิตนามแฝงทั้งหมด ไดรเวอร์ CAN จะคำนวณพารามิเตอร์ตามนั้น พารามิเตอร์นี้จะถูกละเว้นหากตั้งค่า tseg1 และ tseg2
sjw คือความกว้างของการกระโดดซิงโครไนซ์ใหม่ในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง สามารถมีค่าระหว่าง 1 ถึง 4 (รวม) สำหรับ CAN แบบคลาสสิก
tseg1 กำหนดตำแหน่งของจุดตัวอย่างในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง สามารถมีค่าระหว่าง 1 ถึง 16 (รวม) สำหรับ CAN แบบคลาสสิก นี่คือผลรวมของเฟส
Prop_SegและPhase_Seg1ตามที่กำหนดในมาตรฐาน ISO-11898 หากตั้งค่านี้แล้ว tseg2 ต้องถูกตั้งค่าด้วยและ sample_point จะถูกละเว้นtseg2 กำหนดตำแหน่งของจุดส่งสัญญาณในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง สามารถมีค่าระหว่าง 1 ถึง 8 (รวม) สำหรับ CAN แบบคลาสสิก สอดคล้องกับ
Phase_Seg2ในมาตรฐาน ISO-11898 หากตั้งค่านี้แล้ว tseg1 ต้องถูกตั้งค่าด้วย
หากระบุอาร์กิวเมนต์เหล่านี้แล้ว CAN คอนโทรลเลอร์จะถูกกำหนดค่าอย่างถูกต้องสำหรับ bitrate ที่ต้องการและจำนวนควอนตัมเวลาทั้งหมดต่อบิตที่ระบุ ค่า tseg1 และ tseg2 จะแทนที่อาร์กิวเมนต์ sample_point หากระบุทั้งหมดนี้
Note
ฮาร์ดแวร์คอนโทรลเลอร์แต่ละตัวอาจมีข้อจำกัดเพิ่มเติมเกี่ยวกับค่าที่ถูกต้องสำหรับพารามิเตอร์เหล่านี้ และจะเรียก
ValueErrorหากค่าที่กำหนดไม่ได้รับการสนับสนุนNote
ฮาร์ดแวร์คอนโทรลเลอร์เฉพาะอาจยอมรับพารามิเตอร์คีย์เวิร์ดเสริมสำหรับฟีเจอร์เฉพาะฮาร์ดแวร์เช่นการโอเวอร์แซมปลิง
- set_filters(filters: list | tuple | None) None¶
ตั้งค่าตัวกรองรับในคอนโทรลเลอร์ CAN filters สามารถเป็น:
Noneเพื่อรับข้อความขาเข้าทั้งหมด หรือ[]หรือ()เพื่อปิดใช้งานการรับข้อความทั้งหมด หรืออิเทอเรเบิลของรายการหนึ่งรายการขึ้นไปที่กำหนดเกณฑ์ตัวกรอง แต่ละรายการควรเป็น tuple หรือ list ที่มีสามองค์ประกอบ:
identifierคือตัวระบุ CAN (int)bit_maskคือบิตมาสก์สำหรับบิตในฟิลด์ตัวระบุ CAN (int)flagsคือจำนวนเต็มที่มีบิตศูนย์หรือมากกว่าที่กำหนดใน แฟล็กข้อความ ถูกตั้งค่า ระบุคุณสมบัติที่ข้อความขาเข้าต้องตรงกัน ไม่ใช่ทุกคอนโทรลเลอร์ที่รองรับการกรองบนทุกแฟล็กValueErrorจะถูกเรียกหากมีการร้องขอแฟล็กที่ไม่รองรับ
ข้อความขาเข้าจะถูกยอมรับหากบิตที่มาสก์ใน
bit_maskตรงกันระหว่างตัวระบุข้อความและค่าidentifierของตัวกรอง และแฟล็กที่ตั้งค่าในตัวกรองตรงกับข้อความขาเข้าหากบิต
CAN.FLAG_EXT_IDถูกตั้งค่าในแฟล็ก ตัวกรองจะตรงกับ Extended CAN ID เท่านั้น หากบิตCAN.FLAG_EXT_IDไม่ได้ถูกตั้งค่า ตัวกรองจะตรงกับ Standard CAN ID เท่านั้นตัวกรองทั้งหมดจะถูก OR เข้าด้วยกันในคอนโทรลเลอร์ การส่ง list หรือ tuple ว่างสำหรับอาร์กิวเมนต์ filters หมายความว่าจะไม่มีการรับข้อความ
คอนโทรลเลอร์ CAN บางตัวกำหนดให้ตัวกรองแต่ละตัวต้องเชื่อมโยงกับ FIFO รับเพียงตัวเดียว ในกรณีเหล่านี้ รายการตัวกรองในอาร์กิวเมนต์จะถูกจัดสรรแบบ round-robin ให้กับ FIFO ที่มีอยู่ ไดรเวอร์นี้ไม่แยกความแตกต่างระหว่าง FIFO ใน IRQ รับ
Note
หากผู้เรียกส่งอิเทอเรเบิลที่มีรายการมากกว่า
CAN.FILTERS_MAXValueErrorจะถูกเรียกNote
หาก
identifierหรือbit_maskอยู่นอกช่วงสำหรับประเภท ID ที่ระบุValueErrorพร้อมเหตุผล "invalid id" จะถูกเรียกตัวอย่าง¶
รับข้อความขาเข้าทั้งหมด:
can.set_filters(None)รับเฉพาะข้อความที่มีค่า Standard ID 0x301 และ 0x700:
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
รับข้อความที่มีค่า Standard ID ในช่วง 0x300-0x3FF และค่า Extended ID 0x50700 เท่านั้น:
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
ค่าคงที่ที่อ่านจำนวนสูงสุดของตัวกรองรับที่รองรับสำหรับฮาร์ดแวร์คอนโทรลเลอร์นี้
โปรดทราบว่าคอนโทรลเลอร์บางตัวอาจมีข้อจำกัดฮาร์ดแวร์ที่ซับซ้อนมากขึ้นเกี่ยวกับจำนวนตัวกรองที่ใช้งาน (ตัวอย่างเช่น นับตัวกรอง Standard และ Extended ID แยกกัน) ในกรณีเหล่านี้
CAN.set_filtersอาจเรียกValueErrorแม้เมื่อไม่เกินขีดจำกัดFILTERS_MAX
- send(id: int, data: bytes, flags: int = 0) int | None¶
คัดลอกข้อความ CAN ใหม่ลงในคิวส่งฮาร์ดแวร์ของคอนโทรลเลอร์เพื่อส่งออกบัส คิวส่งคือคิวลำดับความสำคัญที่เรียงตามลำดับความสำคัญของตัวระบุ CAN (ตัวระบุตัวเลขน้อยกว่ามีลำดับความสำคัญสูงกว่า)
id คือค่าตัวระบุ CAN จำนวนเต็ม
data คือออบเจ็กต์ bytes (หรือคล้ายกัน) ที่มีข้อมูลข้อความ CAN หรืออธิบาย Remote Transmission Request (ดูด้านล่าง)
flags คือจำนวนเต็มที่มีบิตศูนย์หรือมากกว่าที่กำหนดใน แฟล็กข้อความ ถูกตั้งค่า ระบุคุณสมบัติของข้อความ CAN ขาออก (Extended ID, Remote Transmission Request เป็นต้น)
หากข้อความถูกจัดคิวเพื่อส่งออกบัสสำเร็จ ฟังก์ชันจะคืนค่าจำนวนเต็มในช่วง
0ถึงCAN.TX_QUEUE_LEN(ไม่รวม) ค่านี้คือดัชนีบัฟเฟอร์ส่งที่ข้อความถูกจัดคิวเพื่อส่ง และสามารถใช้โดยฟังก์ชันCAN.cancel_sendและในเหตุการณ์CAN.IRQ_TXหากคิวเต็มการส่งจะล้มเหลวและคืนค่า
Noneการส่งอาจล้มเหลวและคืนค่า
Noneด้วย หากค่า id ที่ให้มามีลำดับความสำคัญเท่ากับข้อความที่มีอยู่ในคิวส่งและฮาร์ดแวร์คอนโทรลเลอร์ CAN ไม่สามารถรับประกันว่าข้อความที่มี ID เดียวกันจะถูกส่งออกบัสในลำดับเดียวกันกับที่เพิ่มเข้าคิว หากต้องการจัดคิวข้อความไม่ว่าจะเป็นอย่างไร ให้ส่งค่าCAN.FLAG_UNORDEREDในอาร์กิวเมนต์ flags แฟล็กนี้ระบุว่าไม่เป็นไรที่จะส่งข้อความที่มี CAN ID เดียวกันออกบัสในลำดับใดก็ได้หากคอนโทรลเลอร์อยู่ในสถานะข้อผิดพลาด "Bus Off" หรือปิดใช้งาน การเรียกฟังก์ชันนี้จะเรียก
OSErrorNote
การนำไปใช้ระดับต่ำที่ตั้งใจนี้ออกแบบมาเพื่อให้ผู้เรียกสามารถสร้างคิวซอฟต์แวร์ของข้อความขาออกได้
Important
"คิวส่ง" CAN ไม่ใช่คิว FIFO แต่เรียงตามลำดับความสำคัญ และแม้ว่าจะสามารถรองรับได้ถึง
CAN.TX_QUEUE_LENรายการ อาจมีข้อจำกัดฮาร์ดแวร์อื่น ๆ เกี่ยวกับข้อความที่สามารถจัดคิวในเวลาเดียวกันได้Remote Transmission Request¶
หากบิต
CAN.FLAG_RTRถูกตั้งค่าในอาร์กิวเมนต์ flags คอนโทรลเลอร์จะส่ง Remote Transmission Request แทนข้อความ ในกรณีนี้เนื้อหาของอาร์กิวเมนต์ data จะถูกละเว้น คอนโทรลเลอร์จะส่งคำขอที่ฟิลด์ความยาวDLCเท่ากับความยาวของอาร์กิวเมนต์ dataตัวอย่าง¶
พยายามส่งข้อความที่มีเพย์โหลด 3 ไบต์
0a0b0cและ Standard ID 0x200:can.send(0x200, b"\x0a\x0b\x0c", 0)พยายามส่งข้อความที่มีเพย์โหลดว่างและ Extended ID 0x180008 ระบุว่าคอนโทรลเลอร์สามารถส่งข้อความที่มี ID นี้ในลำดับใดก็ได้ ในกรณีที่ข้อความอื่นถูกจัดคิวเพื่อส่งด้วย ID เดียวกันอยู่แล้ว:
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)พยายามส่ง Remote Transmission Request ที่มีความยาว 8 ไบต์และ Standard ID 0x555:
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
คืนค่าข้อความ CAN ที่ได้รับโดยคอนโทรลเลอร์ตามตัวกรองที่ตั้งค่าโดย
CAN.set_filters()ฟังก์ชันนี้รับอาร์กิวเมนต์เสริมหนึ่งตัว หากระบุแล้วต้องเป็น list ที่มีอย่างน้อย 4 องค์ประกอบที่องค์ประกอบที่สองเป็นออบเจ็กต์
memoryviewที่อ้างถึงbytearrayหรือออบเจ็กต์ที่คล้ายกันที่มีความจุเพียงพอสำหรับรับข้อความ CAN ใด ๆ (8 ไบต์สำหรับ CAN Classic, 64 ไบต์สำหรับ CAN FD) list ที่ให้มาจะถูกคืนค่าเป็นผลลัพธ์ที่สำเร็จ และหลีกเลี่ยงการจัดสรรหน่วยความจำภายในฟังก์ชันหาก CAN คอนโทรลเลอร์ไม่ได้รับข้อความ ฟังก์ชันนี้จะคืนค่า
NoneNote
ต้องเรียก
CAN.set_filtersก่อนที่คอนโทรลเลอร์จะรับข้อความได้ หากต้องการรับข้อความทั้งหมดให้เรียกset_filters(None)หาก CAN คอนโทรลเลอร์ได้รับข้อความ ฟังก์ชันนี้จะคืนค่า list ที่มี 4 องค์ประกอบ:
ดัชนี 0 คือ CAN ID ของข้อความที่ได้รับ เป็นจำนวนเต็ม
ดัชนี 1 คือ memoryview ที่ให้การเข้าถึงข้อมูลข้อความที่ได้รับ
หากไม่ได้ระบุ arg นี่คือ
memoryviewที่เก็บไบต์ที่ได้รับmemoryviewนี้ได้รับการสนับสนุนโดยbytearrayที่จัดสรรใหม่ซึ่งใหญ่พอที่จะรองรับข้อความ CAN ที่ได้รับ ซึ่งช่วยให้สามารถนำผลลัพธ์มาใช้ซ้ำเป็น arg ในอนาคตได้อย่างปลอดภัยเพื่อประหยัดการจัดสรรหน่วยความจำหากระบุ arg แล้ว
memoryviewที่ให้มาจะถูกปรับขนาดเพื่อเก็บไบต์ที่ได้รับเท่านั้น ผู้เรียกต้องรับผิดชอบในการตรวจสอบให้แน่ใจว่าออบเจ็กต์ที่รองรับmemoryviewสามารถรองรับข้อความ CAN ที่มีความยาวใด ๆ
ดัชนี 2 คือจำนวนเต็มที่มีบิตศูนย์หรือมากกว่าที่กำหนดใน แฟล็กข้อความ ถูกตั้งค่า ระบุข้อมูลเมตาดาต้าเกี่ยวกับข้อความที่ได้รับ
ดัชนี 3 คือจำนวนเต็มที่มีบิตศูนย์หรือมากกว่าที่กำหนดใน แฟล็กข้อผิดพลาดการรับ ถูกตั้งค่า ค่าที่ไม่ใช่ศูนย์ใด ๆ ระบุปัญหาที่อาจเกิดขึ้นเมื่อรับข้อความ CAN แฟล็กเหล่านี้จะถูกรีเซ็ตภายในคอนโทรลเลอร์ทุกครั้งที่ฟังก์ชันนี้คืนค่า
Remote Transmission Request¶
หาก Remote Transmission Request ถูกรับแล้วบิต
CAN.FLAG_RTRจะถูกตั้งค่าในดัชนี 2 และ memoryview ที่ดัชนี 1 จะมีศูนย์ทั้งหมด โดยมีความยาวเท่ากับฟิลด์DLCของคำขอที่ได้รับตัวอย่าง¶
can.set_filters(None) # receive all while True: res = can.recv() if res: can_id, data, flags, errs = res print("Received", hex(can_id), data.hex(), hex(flags), hex(errs)) else: time.sleep_ms(1) # not a good pattern, use the irq instead!
- irq(handler: Callable[[CAN], None] | None = None, trigger: int = 0, hard: bool = False) None¶
ตั้งค่าฟังก์ชัน handler อินเทอร์รัปต์ที่จะถูกเรียกเมื่อเกิดเหตุการณ์หนึ่งหรือมากกว่าที่ระบุใน trigger
handler คือฟังก์ชันที่จะถูกเรียกเมื่อเหตุการณ์อินเทอร์รัปต์ทริกเกอร์ ตัวจัดการต้องรับอาร์กิวเมนต์เพียงหนึ่งตัวซึ่งเป็นอินสแตนซ์
CANtrigger กำหนดค่าเหตุการณ์ที่สามารถสร้างอินเทอร์รัปต์ได้ ค่าที่เป็นไปได้คือมาสก์ของหนึ่งหรือมากกว่าของสิ่งต่อไปนี้:
เหตุการณ์
CAN.IRQ_RXเกิดขึ้นหลังจาก CAN คอนโทรลเลอร์ได้รับข้อความอย่างน้อยหนึ่งข้อความเข้า RX FIFO (หมายความว่าCAN.recv()จะคืนค่าสำเร็จ)เหตุการณ์
CAN.IRQ_TXเกิดขึ้นหลังจาก CAN คอนโทรลเลอร์ส่งข้อความออกบัส CAN สำเร็จหรือล้มเหลวในการส่งข้อความ ทริกเกอร์นี้มีข้อกำหนดเพิ่มเติมสำหรับตัวจัดการ ดู แฟล็ก IRQ สำหรับรายละเอียดเหตุการณ์
CAN.IRQ_STATEเกิดขึ้นเมื่อ CAN คอนโทรลเลอร์เปลี่ยนไปสู่สถานะข้อผิดพลาดที่รุนแรงยิ่งขึ้น เรียกCAN.state()เพื่อรับสถานะที่อัปเดต
hard หากเป็น True จะใช้อินเทอร์รัปต์แบบ hard ซึ่งช่วยลดความล่าช้าระหว่างเหตุการณ์ CAN คอนโทรลเลอร์และการเรียกตัวจัดการ ตัวจัดการอินเทอร์รัปต์แบบ hard อาจไม่จัดสรรหน่วยความจำ ดู การเขียนตัวจัดการอินเทอร์รัปต์
คืนค่าออบเจ็กต์ irq หากเรียกโดยไม่มีอาร์กิวเมนต์จะคืนค่าออบเจ็กต์ irq ที่กำหนดค่าไว้ก่อนหน้า
ดู แฟล็ก IRQ สำหรับตัวอย่าง
- cancel_send(index: int) bool¶
ร้องขอให้ CAN คอนโทรลเลอร์ยกเลิกการส่งข้อความออกบัส
อาร์กิวเมนต์ index ระบุบัฟเฟอร์ส่งเดี่ยว ควรเป็นจำนวนเต็มในช่วง
0ถึงCAN.TX_QUEUE_LEN(ไม่รวม) โดยทั่วไปนี่จะเป็นค่าที่CAN.send()คืนค่ามาก่อนหน้าผลลัพธ์คือ
Trueหากข้อความกำลังรอส่งในบัฟเฟอร์นี้และการส่งถูกยกเลิกผลลัพธ์คือ
Falseหากไม่เช่นนั้น (ไม่มีข้อความรอส่งในบัฟเฟอร์นี้ หรือการส่งสำเร็จแล้ว)ควรใช้เหตุการณ์ IRQ
CAN.IRQ_TXเพื่อตรวจสอบว่าข้อความถูกส่งแน่นอนหรือไม่ แต่โปรดทราบว่ามีเงื่อนไขการแย่งชิงที่อาจเกิดขึ้นหากการส่งถูกยกเลิกแล้วใช้บัฟเฟอร์เดียวกันในการส่งข้อความอื่น (โดยเฉพาะอย่างยิ่งหาก CAN คอนโทรลเลอร์ IRQ ไม่ใช่ "hard")
- state() int¶
คืนค่าจำนวนเต็มที่ระบุสถานะปัจจุบันของคอนโทรลเลอร์ ค่าจะเป็นหนึ่งในค่าที่กำหนดใน สถานะ
สถานะข้อผิดพลาดที่มีความรุนแรงน้อยกว่าอาจล้างโดยอัตโนมัติหากบัสฟื้นตัว แต่สถานะ
CAN.STATE_BUS_OFFสามารถกู้คืนได้โดยการเรียกCAN.restart()เท่านั้น
- get_counters(list: list | None = None, /) list¶
คืนค่าตัวนับข้อผิดพลาดของคอนโทรลเลอร์ ผลลัพธ์คือ list ของค่าแปดค่า หากระบุพารามิเตอร์ list เสริมแล้ว ออบเจ็กต์ list ที่ให้มาจะถูกอัปเดตและคืนค่าเป็นผลลัพธ์เพื่อหลีกเลี่ยงการจัดสรร
รายการ list ประกอบด้วย:
ค่า TEC (Transmit Error Counter)
ค่า REC (Receive Error Counter)
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Warning จากสถานะ Active
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Error Passive จากสถานะ Warning
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Bus Off จากสถานะ Error Passive
จำนวนทั้งหมดของข้อความ TX ที่รอในคิวฮาร์ดแวร์
จำนวนทั้งหมดของข้อความ RX ที่รอในคิวฮาร์ดแวร์
จำนวนครั้งที่เกิด RX overrun
Note
ขึ้นอยู่กับคอนโทรลเลอร์ ค่าเหล่านี้อาจล้นกลับเป็น 0 หลังจากค่าหนึ่ง
Note
หากคอนโทรลเลอร์ไม่รองรับตัวนับเฉพาะ จะคืนค่า
Noneสำหรับองค์ประกอบ list นั้น
- get_timings(list: list | None = None, /) list¶
คืนค่า list ขององค์ประกอบที่ระบุการตั้งค่าเวลาปัจจุบันที่กำหนดค่าใน CAN คอนโทรลเลอร์ ซึ่งสามารถใช้เพื่อตรวจสอบการตั้งค่าเวลาสำหรับการดีบัก ผลลัพธ์คือ list ของค่าหกค่า หากระบุพารามิเตอร์ list เสริมแล้ว ออบเจ็กต์ list ที่ให้มาจะถูกอัปเดตและคืนค่าเป็นผลลัพธ์เพื่อหลีกเลี่ยงการจัดสรร
รายการ list ประกอบด้วย:
บิตเรตที่แน่นอนที่ใช้โดยคอนโทรลเลอร์ อาจแตกต่างจากอาร์กิวเมนต์ bitrate ที่ส่งไปยัง
CAN.init()เนื่องจากการแบ่งปริมาณเพื่อให้ตรงตามข้อจำกัดฮาร์ดแวร์ความกว้างการกระโดดซิงโครไนซ์ใหม่ (SJW) ในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง มีความหมายเดียวกันกับพารามิเตอร์ sjw ของ
CAN.init()ตำแหน่งของจุดตัวอย่างในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง มีความหมายเดียวกันกับพารามิเตอร์ tseg1 ของ
CAN.init()ตำแหน่งของจุดส่งสัญญาณในหน่วยควอนตัมเวลาสำหรับบิตนามแฝง มีความหมายเดียวกันกับพารามิเตอร์ tseg2 ของ
CAN.init()ข้อมูลเวลา CAN FD
Noneสำหรับคอนโทรลเลอร์ที่ไม่รองรับ CAN FD หรือหาก CAN FD ไม่ได้เริ่มต้น มิฉะนั้นจะเป็น nested list ของสี่องค์ประกอบที่สอดคล้องกับรายการด้านบนแต่ใช้กับฟีเจอร์ CAN FD BRSข้อมูลเวลาเฉพาะคอนโทรลเลอร์เสริม ขึ้นอยู่กับคอนโทรลเลอร์ นี่จะเป็น
Noneหากคอนโทรลเลอร์ไม่รายงานใด ๆ หรือจะเป็น list ความยาวคงที่ที่มีองค์ประกอบเฉพาะกับฮาร์ดแวร์คอนโทรลเลอร์เฉพาะ
Note
หากยังไม่ได้เรียก
CAN.init()ฟังก์ชันนี้ยังคืนค่าผลลัพธ์อยู่ แต่ผลลัพธ์ขึ้นอยู่กับภายในคอนโทรลเลอร์และอาจไม่ถูกต้อง
- restart() None¶
ทำให้คอนโทรลเลอร์ออกจาก
STATE_BUS_OFFโดยไม่ล้างสถานะภายในอื่น ๆ และล้างตัวนับข้อผิดพลาดบางส่วน (จำนวนครั้งที่เข้าสู่สถานะข้อผิดพลาดแต่ละครั้งเสมอ และอาจรวม TEC และ REC ขึ้นอยู่กับคอนโทรลเลอร์)การเรียกฟังก์ชันนี้ยังยกเลิกข้อความที่รอส่งด้วย ไม่มีอินเทอร์รัปต์
IRQ_TXที่ถูกส่งสำหรับข้อความเหล่านี้โปรดทราบว่าฟังก์ชันนี้อาจหรืออาจไม่ทำให้คอนโทรลเลอร์ออกจากสถานะ "Error Passive" ขึ้นอยู่กับว่าฮาร์ดแวร์คอนโทรลเลอร์ล้าง TEC และ REC หรือไม่
- deinit() None¶
ยกเลิกการเริ่มต้นอินสแตนซ์ CAN ที่ใช้งานอยู่ก่อนหน้า ข้อความที่รอทั้งหมด (ส่งและรับ) จะถูกทิ้งและคอนโทรลเลอร์หยุดการโต้ตอบบนบัส หากต้องการใช้อินสแตนซ์นี้อีกครั้งให้เรียก
CAN.init()ไม่มีอินเทอร์รัปต์
IRQ_TXหรือIRQ_RXที่ถูกเรียกในการตอบสนองต่อการเรียกฟังก์ชันนี้ดูเพิ่มเติม
CAN.restart()
ค่าคงที่¶
- TX_QUEUE_LEN: int¶
จำนวนสูงสุดของข้อความ CAN ที่สามารถจัดคิวในคิวข้อความฮาร์ดแวร์ขาออกของคอนโทรลเลอร์ "ดัชนีบัฟเฟอร์ส่ง" ที่ใช้โดย
CAN.send(),CAN.cancel_send()และ แฟล็ก IRQ จะอยู่ในช่วงนี้
โหมด¶
ค่าเหล่านี้แสดงโหมดการทำงานของคอนโทรลเลอร์ ตามที่ส่งไปยัง
CAN.init()ไม่ใช่ทุกคอนโทรลเลอร์ที่รองรับทุกโหมดการเปลี่ยนโหมดของคอนโทรลเลอร์ที่กำลังทำงานอยู่ต้องเรียก
CAN.deinit()แล้วเรียกCAN.init()อีกครั้งด้วยโหมดใหม่- MODE_NORMAL: int¶
คอนโทรลเลอร์ทำงานเป็นโหนดเครือข่าย CAN มาตรฐาน (จะรับรองข้อความที่ถูกต้องและอาจส่งข้อผิดพลาดขึ้นอยู่กับ State ปัจจุบัน)
- MODE_SLEEP: int¶
CAN คอนโทรลเลอร์อยู่ในโหมดพลังงานต่ำ ขึ้นอยู่กับคอนโทรลเลอร์ อาจรองรับการปลุกคอนโทรลเลอร์และการเปลี่ยนไปยัง
CAN.MODE_NORMALหากได้รับสัญญาณ CAN
- MODE_LOOPBACK: int¶
โหมดทดสอบ CAN คอนโทรลเลอร์ยังคงเชื่อมต่อกับบัสภายนอก แต่จะรับข้อความที่ส่งออกของตัวเองด้วยและละเว้นข้อผิดพลาด ACK
สถานะ¶
ค่าเหล่านี้คืนค่าโดย
CAN.state()และสะท้อนสถานะข้อผิดพลาดของ CAN คอนโทรลเลอร์:- STATE_ACTIVE: int¶
คอนโทรลเลอร์ทำงานอยู่และตัวนับข้อผิดพลาด
TECและRECทั้งคู่อยู่ต่ำกว่าค่าขีดแบ่งการแจ้งเตือนที่ 96 ดูCAN.get_counters()
- STATE_WARNING: int¶
คอนโทรลเลอร์ทำงานอยู่แต่ตัวนับข้อผิดพลาด
TECและRECอย่างน้อยหนึ่งตัวอยู่ระหว่าง 96 และ 127 ดูCAN.get_counters()
- STATE_PASSIVE: int¶
คอนโทรลเลอร์อยู่ในสถานะ "Error Passive" หมายความว่าไม่ส่งข้อผิดพลาดแอ็คทีฟไปยังบัสอีกต่อไป แต่ยังคงทำงานได้ตามปกติ สถานะนี้เกิดขึ้นเมื่อตัวนับข้อผิดพลาด
TECหรือRECอย่างน้อยหนึ่งตัวเป็น 128 หรือมากกว่า แต่TECน้อยกว่า 255 ดูCAN.get_counters()
- STATE_BUS_OFF: int¶
คอนโทรลเลอร์อยู่ในสถานะ Bus-Off หมายความว่าตัวนับข้อผิดพลาด
TECมากกว่า 255 CAN คอนโทรลเลอร์จะไม่โต้ตอบกับบัสในสถานะนี้ และต้องรีสตาร์ทผ่านCAN.restart()เพื่อดำเนินการต่อ
แฟล็กข้อความ¶
ค่าเหล่านี้แสดงข้อมูลเมตาดาต้าเกี่ยวกับข้อความ CAN ฟังก์ชัน
CAN.send(),CAN.recv()และCAN.set_filters()รับหรือคืนค่าจำนวนเต็มที่ประกอบด้วยแฟล็กเหล่านี้ศูนย์หรือมากกว่า bitwise ORed เข้าด้วยกัน- FLAG_EXT_ID: int¶
หากตั้งค่า ระบุว่าตัวระบุข้อความเป็น Extended (29-bit) หากไม่ตั้งค่า ระบุว่าตัวระบุข้อความเป็น Standard (11-bit)
- FLAG_UNORDERED: int¶
หากตั้งค่าในอาร์กิวเมนต์
flagsของCAN.send()ระบุว่าไม่เป็นไรหากข้อความที่มี CAN ID เดียวกันถูกส่งในลำดับใดก็ได้บนบัสมิฉะนั้น การพยายามจัดคิวข้อความหลายรายการที่มี ID เดียวกันอาจส่งผลให้
CAN.send()ล้มเหลวหากฮาร์ดแวร์คอนโทรลเลอร์ไม่สามารถบังคับใช้การเรียงลำดับได้แฟล็กนี้ไม่เคยถูกตั้งค่าบนข้อความที่ได้รับ และถูกละเว้นโดย
CAN.set_filters()
แฟล็กข้อผิดพลาดการรับ¶
ผลลัพธ์ของ
CAN.recv()มีค่าจำนวนเต็มที่ประกอบด้วยแฟล็กเหล่านี้ศูนย์หรือมากกว่า bitwise ORed เข้าด้วยกัน หากตั้งค่า แฟล็กเหล่านี้ระบุปัญหาทั่วไปที่อาจเกิดขึ้นเมื่อรับข้อความ CANค่า IRQ¶
- IRQ_RX: int¶
ส่งไปยังอาร์กิวเมนต์
triggerของirq()เพื่อเรียกตัวจัดการทุกครั้งที่ CAN คอนโทรลเลอร์ได้รับข้อความสมบูรณ์เข้า RX FIFO ภายในตัวจัดการให้อ่านข้อความด้วยrecv()
- IRQ_TX: int¶
ส่งไปยังอาร์กิวเมนต์
triggerของirq()เพื่อเรียกตัวจัดการทุกครั้งที่ CAN คอนโทรลเลอร์จบความพยายามในการส่ง (สำเร็จหรือล้มเหลว) ภายในตัวจัดการให้ใช้บิตเพิ่มเติมด้านล่างเพื่อกู้คืนว่า mailbox ใดเสร็จสิ้นและล้มเหลวหรือไม่ -- ดู แฟล็ก IRQ
- IRQ_STATE: int¶
ส่งไปยังอาร์กิวเมนต์
triggerของirq()เพื่อเรียกตัวจัดการทุกครั้งที่คอนโทรลเลอร์เปลี่ยนระหว่างค่าSTATE_*(active / warning / passive / bus-off) ใช้state()ภายในตัวจัดการเพื่ออ่านสถานะใหม่
- IRQ_TX_FAILED: int¶
แฟล็กสถานะที่อาจถูกตั้งค่าใน
irq().flags()เมื่อเหตุการณ์IRQ_TXเกิดขึ้น ระบุว่าความพยายามในการส่งล้มเหลว (โดยทั่วไปเพราะcancel_send()ถูกเรียก หรือคอนโทรลเลอร์เข้าสู่สถานะข้อผิดพลาด)
- IRQ_TX_IDX_SHIFT: int¶
ตำแหน่งบิตของฟิลด์ transmit-mailbox-index ภายในค่า
irq().flags()ระหว่างเหตุการณ์IRQ_TXดัชนี mailbox ถูกแยกออกมาเป็น(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK
- IRQ_TX_IDX_MASK: int¶
บิตมาสก์ของฟิลด์ transmit-mailbox-index ภายในค่า
irq().flags()ระหว่างเหตุการณ์IRQ_TXดัชนีที่แยกออกมาตรงกับจำนวนเต็มที่คืนค่าโดยการเรียกsend()ที่สอดคล้องกัน (จำนวนเต็มในช่วง0ถึงTX_QUEUE_LEN)
แฟล็ก IRQ¶
การเรียก CAN.irq() ลงทะเบียนตัวจัดการอินเทอร์รัปต์ด้วยทริกเกอร์หนึ่งหรือมากกว่า CAN.IRQ_RX, CAN.IRQ_TX และ CAN.IRQ_STATE
ฟังก์ชันคืนค่าออบเจ็กต์ IRQ และการเรียกฟังก์ชัน flags() บนออบเจ็กต์นี้คืนค่าจำนวนเต็มที่ระบุว่าเหตุการณ์ทริกเกอร์ใดทริกเกอร์อินเทอร์รัปต์ ตัวจัดการ CAN IRQ ควรเรียกฟังก์ชัน flags() ซ้ำ ๆ จนกว่าจะคืนค่า 0
เมื่อฟังก์ชัน flags() คืนค่าพร้อมบิต CAN.IRQ_TX ถูกตั้งค่า ตัวจัดการยังสามารถตรวจสอบบิตแฟล็กต่อไปนี้ในผลลัพธ์สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์ TX:
บิต
CAN.IRQ_TX_FAILEDถูกตั้งค่าหากการส่งล้มเหลว โดยทั่วไปนี้จะเกิดขึ้นเฉพาะเมื่อมีการเรียกCAN.cancel_send()แม้ว่าอาจเกิดขึ้นหากคอนโทรลเลอร์เข้าสู่สถานะข้อผิดพลาดCAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTคือบริเวณ bitmasked ของค่า flags ที่เก็บดัชนีของบัฟเฟอร์ส่งที่สร้างเหตุการณ์ นี่จะเป็นจำนวนเต็มในช่วง0ถึงCAN.TX_QUEUE_LEN(ไม่รวม) และจะตรงกับผลลัพธ์ของการเรียกCAN.send()ก่อนหน้า
ตัวอย่าง IRQ_TX¶
from machine import CAN
def irq_send(can):
while flags := can.irq().flags():
if flags & can.IRQ_TX:
idx = (flags >> can.IRQ_TX_IDX_SHIFT) & can.IRQ_TX_IDX_MASK
success = not (flags & can.IRQ_TX_FAILED)
print("irq_send", idx, success)
can = CAN(1, 500_000)
can.irq(irq_send, trigger=can.IRQ_TX, hard=True)
Important
หากตั้งค่าทริกเกอร์ CAN.IRQ_TX ตัวจัดการ ต้อง เรียก flags() ซ้ำ ๆ จนกว่าจะคืนค่า 0 ดังที่แสดงในตัวอย่างนี้ มิฉะนั้น CAN อินเทอร์รัปต์อาจไม่ถูกเปิดใช้งานใหม่อย่างถูกต้อง