lib/edge_ai/api.txt แสดงรายการฟังก์ชัน API 40 ตัว และ ไม่มี printf หรือ puts archive ตัวนี้ไม่ได้นิยามทั้งสองตัว (overridable.txt ว่าง) หน้านี้อธิบายว่าทั้งสองตัวบน CM55 มาจากไหน เพราะผลของมันกระทบโค้ดที่ผู้อ่านเขียนขึ้นเอง
- variant ที่ใช้ได้
- mtb-mpy และ mtb-only
printf
int printf(const char *fmt, ...);
ข้อกำหนดการเรียกใช้ proj_cm55/bento_cm55_stdio.c ซึ่งเป็นซอร์สเปิดที่อ่านและแก้ได้ นิยาม printf เป็น no-op แบบ weak ผลที่ตามมาสำหรับโค้ด CM55 มีดังนี้:
- printf ในโค้ด CM55 ที่เขียนขึ้นเองจะไม่พิมพ์อะไรออกมาโดยค่าตั้งต้น การเรียกสำเร็จและคืนค่า 0
- เหตุที่ต้องปิดเสียง CM55 ไม่มีคอนโซล UART เป็นของ CM33_NS (proj_cm55/main.c:9-10) และ cy_retarget_io_init() ไม่เคยถูกเรียกบนคอร์นี้ newlib stdio จึงจะไปจับ mutex ที่ไม่เคยถูกเตรียมไว้แล้วหยุดคอร์ ทั้งที่ ML middleware, TFLite-Micro และไดรเวอร์ Ethos-U ที่นำเข้ามาต่างก็เรียก printf บนเส้นทางที่โครงการนี้ควบคุมไม่ได้
- ทางเลือก (1) นิยาม printf()/puts() ของตนเองที่ใดก็ได้ในแอปพลิเคชัน ซึ่งเป็น strong จึงชนะในขั้นลิงก์โดยไม่ต้องแก้ไฟล์นี้ (2) ส่งข้อมูลวินิจฉัยของ CM55 ผ่าน IPC ไปยังคอนโซลของ CM33_NS ซึ่งเป็นสิ่งที่เฟิร์มแวร์ BENTO ทำ (3) build ด้วย DEFINES+=BENTO_CM55_MUTE_STDIO=0 เพื่อใช้ printf ของ newlib จริง ซึ่งต้องเรียก cy_retarget_io_init() บน CM55 และให้ UART ของคอร์นี้เองด้วย
- สิ่งที่สังเกตได้บน CM55 โดยค่าตั้งต้นจึงเป็นรหัส LED และหน้าจอ ซึ่งมีทั้งสอง variant บวกกับ ui._diag() บน mtb-mpy (หรือ ipc_ui_platform_diag() จาก C บน mtb-only)
puts
ข้อกำหนดการเรียกใช้ เหมือนกับ printf: เป็น no-op แบบ weak ในไฟล์เดียวกัน และจำเป็นต้องมีคู่กัน เพราะ GCC เขียน printf("literal\n") ใหม่ให้เป็น puts("literal") build ที่ปิดเสียงเฉพาะ printf จึงยังไปถึง newlib ได้ผ่านข้อความวินิจฉัยแบบข้อความคงที่ทุกตัว หากนิยาม printf ของตนเอง ให้นิยาม puts ด้วย