الفئة CAN -- بروتوكول شبكة منطقة التحكم (Controller Area Network)¶
CAN هو بروتوكول تسلسلي ثنائي الأسلاك يُستخدم لتوصيل الرسائل في الوقت الفعلي بشكل موثوق بين عقدة واحدة أو أكثر متصلة بناقل مشترك. تم توحيد CAN 2.0 في المعيار ISO-11898، وهو معروف الآن أيضًا باسم CAN Classic.
يوجد أيضًا بروتوكول أحدث ومتوافق مع الإصدارات السابقة يُسمى CAN FD (أي CAN بمعدل بيانات مرن). لا يدعم برنامج التشغيل machine.CAN حاليًا ميزات CAN FD؛ استخدم pyb.CAN على STM32 إذا كنت بحاجة إلى CAN FD.
يتطلب دعم CAN وحدة تحكم (غالبًا ما تكون طرفية داخلية للمتحكم الدقيق)، ومرسلًا مستقبلًا خارجيًا لمعايرة مستوى الإشارات على ناقل CAN.
متوفر على كاميرات OpenMV المعتمدة على STM32 (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6، إضافة إلى المتغيرات التي تحمل علامة Arduino التجارية والتي تتضمن مرسلًا مستقبلًا). غير مدعوم بعد على OpenMV Cam RT1062 (منفذ mimxrt) أو OpenMV Cam AE3 (منفذ alif).
واجهة machine.CAN هي واجهة منخفضة المستوى وأساسية لتبادل رسائل CAN تجرّد وحدة تحكم CAN على هيئة طابور أولوية صادر لإرسال الرسائل، وطابور وارد لاستقبال الرسائل، وآليات للإبلاغ عن الأخطاء.
ملاحظة
ستكون وحدتا micropython-lib المخططتان can و aiocan هما الطريقة الموصى بها لاستخدام CAN مع MicroPython.
المُنشئ¶
- class machine.CAN(id: int, *args, **kwargs)¶
إنشاء كائن وحدة تحكم CAN بالمعرّف المحدد:
يحدد
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 هو إحدى القيم الموضحة تحت الأوضاع، ويشير إلى وضع التشغيل المطلوب. الوضع الافتراضي هو التشغيل "العادي" على الناقل.
المعطيات التالية اختيارية وتتعلق بتوقيتات بت 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 إذا تم توفير كل هذه القيم.
ملاحظة
قد يكون لعتاد وحدة التحكم الفردي قيود إضافية على القيم الصالحة لهذه المعطيات، وسيُطلق
ValueErrorإذا لم تكن قيمة معينة مدعومة.ملاحظة
قد يقبل عتاد وحدة تحكم معين وسائط مفتاحية اختيارية إضافية لميزات خاصة بالعتاد مثل الإفراط في أخذ العينات.
- set_filters(filters: list | tuple | None) None¶
ضبط مرشحات الاستقبال في وحدة تحكم CAN. يمكن أن تكون filters:
Noneلقبول جميع الرسائل الواردة، أو[]أو()لتعطيل استقبال جميع الرسائل، أوكائن قابل للتكرار يحتوي على عنصر واحد أو أكثر تحدد معايير المرشح. ينبغي أن يكون كل عنصر صفًا (tuple) أو قائمة بثلاثة عناصر:
identifierهو معرّف CAN (عدد صحيح).bit_maskهو قناع بت للبتات في حقل معرّف CAN (عدد صحيح).flagsهو عدد صحيح يحتوي على صفر أو أكثر من البتات المعرّفة في أعلام الرسائل. يحدد هذا الخصائص التي تحتاج الرسالة الواردة إلى مطابقتها. لا تدعم جميع وحدات التحكم التصفية على جميع الأعلام، ويُطلقValueErrorإذا طُلب علم غير مدعوم.
تُقبل الرسائل الواردة إذا تطابقت البتات المقنّعة في
bit_maskبين معرّف الرسالة وقيمةidentifierللمرشح، وتطابقت الأعلام المضبوطة في المرشح مع الرسالة الواردة.إذا كان البت
CAN.FLAG_EXT_IDمضبوطًا في الأعلام، فإن المرشح يطابق معرّفات CAN الموسّعة فقط. وإذا لم يكن البتCAN.FLAG_EXT_IDمضبوطًا، فإن المرشح يطابق معرّفات CAN القياسية فقط.تُدمج جميع المرشحات معًا بعملية OR في وحدة التحكم. يعني تمرير قائمة أو صف فارغ لوسيطة المرشحات أنه لن يتم استقبال أي رسائل.
تتطلب بعض وحدات تحكم CAN أن يرتبط كل مرشح بطابور استقبال FIFO واحد فقط. في هذه الحالات، تُوزَّع عناصر المرشح في الوسيطة بالتناوب (round-robin) على طوابير FIFO المتاحة. لا يميّز برنامج التشغيل هذا بين طوابير FIFO في مقاطعة الاستقبال (IRQ).
ملاحظة
إذا مرّر المستدعي كائنًا قابلًا للتكرار يحتوي على عناصر أكثر من
CAN.FILTERS_MAX، فسيُطلقValueError.ملاحظة
إذا كان أي من
identifierأوbit_maskخارج النطاق لنوع المعرّف المحدد، فسيُطلقValueErrorبالسبب "invalid id".أمثلة¶
استقبال جميع الرسائل الواردة:
can.set_filters(None)استقبال الرسائل ذات قيم المعرّف القياسي 0x301 و 0x700 فقط:
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
استقبال الرسائل ذات قيم المعرّف القياسي في النطاق 0x300-0x3FF، وقيمة المعرّف الموسّع 0x50700 فقط:
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
قيمة ثابتة تقرأ العدد الأقصى لمرشحات الاستقبال المدعومة لوحدة التحكم العتادية هذه.
لاحظ أن بعض وحدات التحكم قد يكون لها قيود عتادية أكثر تعقيدًا على عدد المرشحات قيد الاستخدام (على سبيل المثال، عدّ مرشحات المعرّف القياسي والموسّع بشكل مستقل.) في هذه الحالات قد يُطلق
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 الصادرة (معرّف موسّع، طلب إرسال عن بُعد، إلخ.)
إذا تمت إضافة الرسالة بنجاح إلى طابور الإرسال على الناقل، فإن الدالة تُرجع عددًا صحيحًا في النطاق من
0إلىCAN.TX_QUEUE_LEN(غير شامل). هذه القيمة هي فهرس مخزن الإرسال المؤقت حيث أُضيفت الرسالة للإرسال، ويمكن استخدامها بواسطة دالةCAN.cancel_sendوفي أحداثCAN.IRQ_TX.إذا كان الطابور ممتلئًا فسيفشل الإرسال ويُرجَع
None.قد يفشل الإرسال أيضًا ويُرجِع
Noneإذا كانت قيمة id المقدمة ذات أولوية مساوية لرسالة موجودة في طابور الإرسال ولم يستطع عتاد وحدة تحكم CAN ضمان إرسال الرسائل ذات المعرّف نفسه على الناقل بنفس الترتيب الذي أُضيفت به إلى الطابور. لإضافة الرسالة إلى الطابور على أي حال، مرّر العلمCAN.FLAG_UNORDEREDفي الوسيطة flags. يشير هذا العلم إلى أنه لا بأس بإرسال الرسائل ذات معرّف CAN نفسه على الناقل بأي ترتيب.إذا كانت وحدة التحكم في حالة الخطأ "Bus Off" أو معطّلة فإن استدعاء هذه الدالة سيُطلق
OSError.ملاحظة
صُمِّم هذا التنفيذ منخفض المستوى عمدًا بحيث يستطيع المستدعي إنشاء طابور برمجي للرسائل الصادرة.
مهم
"طابور إرسال" CAN ليس طابور FIFO، بل هو مرتب وفق الأولوية، ورغم أنه يمكن أن يحمل حتى
CAN.TX_QUEUE_LENعنصرًا فقد توجد قيود عتادية أخرى على الرسائل التي يمكن إضافتها إلى الطابور في الوقت نفسه.طلبات الإرسال عن بُعد (Remote Transmission Requests)¶
إذا كان البت
CAN.FLAG_RTRمضبوطًا في الوسيطة flags فإن وحدة التحكم سترسل طلب إرسال عن بُعد بدلًا من رسالة. في هذه الحالة يُتجاهل محتوى الوسيطة data. سترسل وحدة التحكم طلبًا يكون فيه حقل الطولDLCمساويًا لطول الوسيطة data.أمثلة¶
محاولة إرسال رسالة بحمولة من ثلاثة بايتات
0a0b0cومعرّف قياسي 0x200:can.send(0x200, b"\x0a\x0b\x0c", 0)محاولة إرسال رسالة بحمولة فارغة ومعرّف موسّع 0x180008. الإشارة إلى أن وحدة التحكم يمكنها إرسال الرسائل بهذا المعرّف بأي ترتيب، في حال وجود رسائل أخرى مضافة للإرسال بنفس المعرّف:
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)محاولة إرسال طلب إرسال عن بُعد بطول 8 بايتات ومعرّف قياسي 0x555:
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
إرجاع رسالة CAN التي استقبلتها وحدة التحكم، وفقًا للمرشحات المضبوطة بواسطة
CAN.set_filters().تأخذ هذه الدالة وسيطة اختيارية واحدة، إذا قُدِّمت فيجب أن تكون قائمة من 4 عناصر على الأقل يكون فيها العنصر الثاني كائن
memoryviewيشير إلىbytearrayأو كائن مشابه بسعة كافية لاحتواء أي رسالة CAN مستقبَلة (8 بايتات لـ CAN Classic، 64 بايتًا لـ CAN FD). ستُرجَع القائمة المقدمة كنتيجة ناجحة، وهو ما يتجنب تخصيص الذاكرة داخل الدالة.إذا لم تستقبل وحدة تحكم CAN أي رسائل، فإن هذه الدالة تُرجع
None.ملاحظة
يجب استدعاء
CAN.set_filtersقبل أن تتمكن وحدة التحكم من استقبال أي رسائل. لاستقبال جميع الرسائل، استدعِset_filters(None).إذا استقبلت وحدة تحكم CAN رسالة، فإن هذه الدالة تُرجع قائمة من 4 عناصر:
الفهرس 0 هو معرّف CAN للرسالة المستقبَلة، كعدد صحيح.
الفهرس 1 هو memoryview يتيح الوصول إلى بيانات الرسالة المستقبَلة.
إذا لم يُقدَّم arg فهذا
memoryviewيحمل البايتات التي تم استقبالها. يستند هذاmemoryviewإلىbytearrayمخصص حديثًا بحجم كافٍ لاحتواء أي رسالة CAN مستقبَلة. يتيح هذا إعادة استخدام النتيجة بأمان كـ arg مستقبلي، لتوفير عمليات تخصيص الذاكرة.إذا قُدِّم arg فسيُعاد تحجيم
memoryviewالمقدَّم ليحمل تمامًا البايتات التي تم استقبالها. يتحمل المستدعي مسؤولية التأكد من أن الكائن الداعم لـmemoryviewيمكنه احتواء رسالة CAN بأي طول.
الفهرس 2 هو عدد صحيح يحتوي على صفر أو أكثر من البتات المعرّفة في أعلام الرسائل. ويشير إلى بيانات وصفية حول الرسالة المستقبَلة.
الفهرس 3 هو عدد صحيح يحتوي على صفر أو أكثر من البتات المعرّفة في أعلام أخطاء الاستقبال. أي قيمة غير صفرية تشير إلى مشكلات محتملة عند استقبال رسائل CAN. تُعاد هذه الأعلام إلى وضعها الأصلي داخل وحدة التحكم في كل مرة تُرجع فيها هذه الدالة.
طلبات الإرسال عن بُعد (Remote Transmission Requests)¶
إذا تم استقبال طلب إرسال عن بُعد فسيُضبط البت
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 هي دالة تُستدعى عند تحفيز حدث المقاطعة. يجب أن يأخذ المعالج وسيطة واحدة بالضبط هي مثيل
CAN.trigger يكوّن الحدث (أو الأحداث) الذي يمكن أن يولّد مقاطعة. القيم الممكنة هي قناع لواحد أو أكثر مما يلي:
يقع حدث
CAN.IRQ_RXبعد أن تكون وحدة تحكم CAN قد استقبلت رسالة واحدة على الأقل في طابور RX FIFO الخاص بها (مما يعني أنCAN.recv()سيُرجِع بنجاح).يقع حدث
CAN.IRQ_TXبعد أن تكون وحدة تحكم CAN قد أرسلت رسالة بنجاح على ناقل CAN أو فشلت في إرسال رسالة. لهذا المُحفِّز متطلبات إضافية على المعالج، انظر أعلام IRQ للتفاصيل.يقع حدث
CAN.IRQ_STATEعندما تنتقل وحدة تحكم CAN إلى حالة خطأ أكثر خطورة. استدعِCAN.state()للحصول على الحالة المحدّثة.
hard إذا كانت True، تُستخدم مقاطعة صلبة (hard). يقلل هذا التأخير بين حدث وحدة تحكم CAN واستدعاء المعالج. قد لا تخصص معالجات المقاطعة الصلبة ذاكرة؛ انظر كتابة معالجات المقاطعات.
يُرجِع كائن irq. إذا استُدعيت بدون وسائط فسيُرجَع كائن irq مكوّن مسبقًا.
انظر أعلام IRQ للحصول على مثال.
- cancel_send(index: int) bool¶
طلب وحدة تحكم CAN إلغاء إرسال رسالة على الناقل.
تحدد الوسيطة index مخزن إرسال مؤقت واحدًا. ينبغي أن تكون عددًا صحيحًا في النطاق من
0إلىCAN.TX_QUEUE_LEN(غير شامل). عمومًا ستكون هذه قيمة أرجعتها سابقًاCAN.send().تكون النتيجة
Trueإذا كانت هناك رسالة في انتظار الإرسال في هذا المخزن المؤقت وتم إلغاء الإرسال.تكون النتيجة
Falseخلاف ذلك (إما لم تكن هناك رسالة في انتظار الإرسال في هذا المخزن المؤقت، أو نجح الإرسال بالفعل).ينبغي استخدام حدث المقاطعة
CAN.IRQ_TXلتحديد ما إذا كانت الرسالة قد أُرسلت بالتأكيد أم لا، لكن لاحظ وجود حالات تسابق محتملة إذا أُلغي إرسال ثم استُخدم المخزن المؤقت نفسه لإرسال رسالة أخرى (خاصة إذا لم تكن مقاطعة وحدة تحكم CAN "صلبة").
- state() int¶
يُرجِع قيمة عددية صحيحة تشير إلى الحالة الراهنة لوحدة التحكم. ستكون القيمة إحدى القيم المعرّفة في الحالات.
قد تُمسح حالات الخطأ الأقل خطورة تلقائيًا إذا تعافى الناقل، لكن الحالة
CAN.STATE_BUS_OFFلا يمكن التعافي منها إلا باستدعاءCAN.restart().
- get_counters(list: list | None = None, /) list¶
يُرجِع قيم عدّادات الأخطاء لوحدة التحكم. النتيجة هي قائمة من ثماني قيم. إذا حُدِّد المعطى الاختياري list فسيُحدَّث كائن القائمة المقدَّم ويُرجَع كنتيجة، لتجنب عملية تخصيص.
عناصر القائمة هي:
قيمة TEC (عدّاد أخطاء الإرسال)
قيمة REC (عدّاد أخطاء الاستقبال)
عدد المرات التي دخلت فيها وحدة التحكم في حالة التحذير من حالة النشاط.
عدد المرات التي دخلت فيها وحدة التحكم في حالة الخطأ السلبي من حالة التحذير.
عدد المرات التي دخلت فيها وحدة التحكم في حالة Bus Off من حالة الخطأ السلبي.
العدد الإجمالي لرسائل TX المعلّقة في الطابور العتادي.
العدد الإجمالي لرسائل RX المعلّقة في الطابور العتادي.
عدد المرات التي حدث فيها تجاوز سعة RX.
ملاحظة
حسب وحدة التحكم، قد تتجاوز هذه القيم السعة وتعود إلى 0 بعد قيمة معينة.
ملاحظة
إذا لم تدعم وحدة التحكم عدّادًا معينًا، فستُرجِع
Noneلعنصر القائمة ذاك.
- get_timings(list: list | None = None, /) list¶
يُرجِع قائمة من العناصر تشير إلى التوقيتات المكوّنة حاليًا في وحدة تحكم CAN. يمكن استخدام هذا للتحقق من التوقيتات لأغراض تصحيح الأخطاء. النتيجة هي قائمة من ست قيم. إذا حُدِّد المعطى الاختياري list فسيُحدَّث كائن القائمة المقدَّم ويُرجَع كنتيجة، لتجنب عملية تخصيص.
عناصر القائمة هي:
معدل البت الدقيق المستخدم من قبل وحدة التحكم. قد يختلف عن وسيطة bitrate الممرَّرة إلى
CAN.init()بسبب التكميم لتلبية قيود العتاد.عرض قفزة إعادة المزامنة (SJW) بوحدات كميات الزمن للبتات الاسمية. له المعنى نفسه للمعطى sjw في
CAN.init().موضع نقطة العينة بوحدات كميات الزمن للبتات الاسمية. له المعنى نفسه للمعطى tseg1 في
CAN.init().موضع نقطة الإرسال بوحدات كميات الزمن للبتات الاسمية. له المعنى نفسه للمعطى tseg2 في
CAN.init().معلومات توقيت CAN FD. تكون
Noneلوحدات التحكم التي لا تدعم CAN FD، أو إذا لم تُهيَّأ CAN FD. وإلا فستكون قائمة متداخلة من أربعة عناصر مقابلة للعناصر أعلاه لكنها تنطبق على ميزة CAN FD BRS.معلومات توقيت اختيارية خاصة بوحدة التحكم. حسب وحدة التحكم ستكون إما
Noneإذا لم تُبلّغ وحدة التحكم عن أي منها، أو ستكون قائمة ثابتة الطول عناصرها خاصة بوحدة تحكم عتادية معينة.
ملاحظة
إذا لم يتم استدعاء
CAN.init()فإن هذه الدالة لا تزال تُرجِع نتيجة، لكن النتيجة تعتمد على بنية وحدة التحكم الداخلية وقد لا تكون دقيقة.
- restart() None¶
يجعل وحدة التحكم تخرج من
STATE_BUS_OFFدون مسح أي حالة داخلية أخرى. يمسح أيضًا بعض عدّادات الأخطاء (دائمًا عدد المرات التي دُخلت فيها كل حالة خطأ، وربما TEC و REC حسب وحدة التحكم.)يؤدي استدعاء هذه الدالة أيضًا إلى إلغاء أي رسائل في انتظار الإرسال. لا يتم تسليم أي مقاطعات
IRQ_TXلهذه الرسائل.لاحظ أن هذه الدالة قد تتسبب أو لا تتسبب في خروج وحدة التحكم من حالة "الخطأ السلبي"، حسب ما إذا كان عتاد وحدة التحكم يصفّر 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¶
وحدة التحكم في حالة "الخطأ السلبي" مما يعني أنها لم تعد ترسل أخطاء نشطة إلى الناقل، لكنها بخلاف ذلك تعمل. تُدخَل هذه الحالة عندما يكون واحد على الأقل من عدّادي الأخطاء
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()أو تُرجِع قيمة عددية صحيحة مكوّنة من صفر أو أكثر من هذه الأعلام مدموجة معًا بعملية OR بتية.- FLAG_EXT_ID: int¶
إذا ضُبط، يشير إلى أن معرّف الرسالة موسّع (29 بت). وإذا لم يُضبط، يشير إلى أن معرّف الرسالة قياسي (11 بت).
- FLAG_UNORDERED: int¶
إذا ضُبط في وسيطة
flagsلـCAN.send()، يشير إلى أنه لا بأس بإرسال الرسائل ذات معرّف CAN نفسه بأي ترتيب على الناقل.وإلا فإن محاولة إضافة رسائل متعددة بالمعرّف نفسه إلى الطابور قد تؤدي إلى فشل
CAN.send()إذا لم يستطع عتاد وحدة التحكم فرض الترتيب.لا يُضبط هذا العلم أبدًا على الرسائل المستقبَلة، ويُتجاهل من قبل
CAN.set_filters().
أعلام أخطاء الاستقبال¶
تتضمن نتيجة
CAN.recv()قيمة عددية صحيحة مكوّنة من صفر أو أكثر من هذه الأعلام مدموجة معًا بعملية OR بتية. إذا ضُبطت، تشير هذه الأعلام إلى مشكلات عامة محتملة في استقبال رسائل 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_*(نشط / تحذير / سلبي / bus-off). استخدمstate()داخل المعالج لقراءة الحالة الجديدة.
- IRQ_TX_FAILED: int¶
علم حالة قد يُضبط في
irq().flags()عند تحفيز حدثIRQ_TX. يشير إلى أن محاولة الإرسال فشلت (عادةً لأنcancel_send()قد استُدعي، أو لأن وحدة التحكم دخلت في حالة خطأ).
- IRQ_TX_IDX_SHIFT: int¶
موضع البت لحقل فهرس صندوق بريد الإرسال ضمن قيمة
irq().flags()أثناء حدثIRQ_TX. يُستخرَج فهرس صندوق البريد على هيئة(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.
- IRQ_TX_IDX_MASK: int¶
قناع البت لحقل فهرس صندوق بريد الإرسال ضمن قيمة
irq().flags()أثناء حدثIRQ_TX. يطابق الفهرس المستخرَج العدد الصحيح الذي أرجعه استدعاءsend()المقابل (عدد صحيح في النطاق من0إلىTX_QUEUE_LEN).
أعلام IRQ¶
يسجّل استدعاء CAN.irq() معالج مقاطعة بواحد أو أكثر من المُحفِّزات CAN.IRQ_RX و CAN.IRQ_TX و CAN.IRQ_STATE.
تُرجِع الدالة كائن IRQ، ويُرجِع استدعاء دالة flags() على هذا الكائن عددًا صحيحًا يشير إلى حدث (أو أحداث) المُحفِّز الذي حفّز المقاطعة. ينبغي لمعالج IRQ الخاص بـ CAN استدعاء دالة flags() بشكل متكرر حتى تُرجِع 0.
عندما تُرجِع دالة flags() والبت CAN.IRQ_TX مضبوط، يمكن للمعالج أيضًا فحص بتات الأعلام التالية في النتيجة للحصول على معلومات إضافية حول حدث TX:
يُضبط البت
CAN.IRQ_TX_FAILEDإذا فشل الإرسال. عادةً لن يحدث هذا إلا إذا استُدعيCAN.cancel_send()، رغم أنه قد يحدث أيضًا إذا دخلت وحدة التحكم في حالة خطأ.CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTهو منطقة مقنّعة بتيًا من قيمة الأعلام تحمل فهرس مخزن الإرسال المؤقت الذي ولّد الحدث. سيكون هذا عددًا صحيحًا في النطاق من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)
مهم
إذا كان مُحفِّز CAN.IRQ_TX مضبوطًا فإن المعالج يجب أن يستدعي flags() بشكل متكرر حتى تُرجِع 0، كما هو موضح في هذا المثال. وإلا فقد لا يُعاد تمكين مقاطعات CAN بشكل صحيح.