micropython --- truy cập và kiểm soát nội bộ MicroPython¶
Hàm¶
- micropython.const(expr: int) int¶
Dùng để khai báo rằng biểu thức là hằng số để trình biên dịch có thể tối ưu hóa nó. Cách sử dụng hàm này như sau:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
Các hằng số được khai báo theo cách này vẫn có thể truy cập như biến toàn cục từ bên ngoài module mà chúng được khai báo. Mặt khác, nếu một hằng số bắt đầu bằng dấu gạch dưới thì nó bị ẩn, không khả dụng như biến toàn cục, và không chiếm bộ nhớ trong quá trình thực thi.
Hàm
constnày được MicroPython parser nhận ra trực tiếp và được cung cấp như một phần của modulemicropythonchủ yếu để các tập lệnh có thể được viết chạy trên cả CPython và MicroPython, bằng cách tuân theo mẫu trên.
- micropython.opt_level(level: int | None = None) int | None¶
Nếu level được cung cấp thì hàm này đặt mức độ tối ưu hóa cho việc biên dịch tập lệnh tiếp theo và trả về
None. Ngược lại, nó trả về mức độ tối ưu hóa hiện tại.Mức độ tối ưu hóa kiểm soát các tính năng biên dịch sau:
Assertions: ở mức 0, các câu lệnh assertion được bật và biên dịch vào bytecode; ở mức 1 và cao hơn, assertion không được biên dịch.
Biến nội tích
__debug__: ở mức 0 biến này mở rộng thànhTrue; ở mức 1 và cao hơn nó mở rộng thànhFalse.Số dòng mã nguồn: ở mức 0, 1 và 2, số dòng mã nguồn được lưu cùng với bytecode để các ngoại lệ có thể báo cáo số dòng xảy ra; ở mức 3 và cao hơn, số dòng không được lưu.
Mức độ tối ưu hóa mặc định thường là mức 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
Cấp phát size byte RAM cho bộ đệm ngoại lệ khẩn cấp (kích thước tốt là khoảng 100 byte). Bộ đệm được dùng để tạo ngoại lệ trong trường hợp cấp phát RAM thông thường thất bại (ví dụ: trong interrupt handler) và do đó cung cấp thông tin traceback hữu ích trong các tình huống này.
Cách tốt để sử dụng hàm này là đặt nó ở đầu tập lệnh chính (ví dụ:
boot.pyhoặcmain.py) và sau đó bộ đệm ngoại lệ khẩn cấp sẽ hoạt động cho tất cả mã tiếp theo.
- micropython.mem_info(verbose: Any | None = None) None¶
In thông tin về bộ nhớ hiện đang được sử dụng. Nếu đối số verbose được cung cấp thì thông tin bổ sung sẽ được in.
Thông tin được in phụ thuộc vào triển khai, nhưng hiện tại bao gồm lượng stack và heap đang được sử dụng. Trong chế độ verbose, nó in toàn bộ heap cho biết các khối nào đang được sử dụng và khối nào rảnh.
- micropython.qstr_info(verbose: Any | None = None) None¶
In thông tin về các chuỗi đã được intern. Nếu đối số verbose được cung cấp thì thông tin bổ sung sẽ được in.
Thông tin được in phụ thuộc vào triển khai, nhưng hiện tại bao gồm số lượng chuỗi đã được intern và lượng RAM chúng sử dụng. Trong chế độ verbose, nó in ra tên của tất cả chuỗi đã được intern trong RAM.
- micropython.stack_use() int¶
Trả về một số nguyên biểu thị lượng stack hiện đang được sử dụng. Giá trị tuyệt đối của nó không đặc biệt hữu ích, thay vào đó nó nên được dùng để tính toán sự chênh lệch mức sử dụng stack tại các điểm khác nhau.
- micropython.heap_lock() None¶
Khóa heap. Khi bị khóa, không thể thực hiện cấp phát bộ nhớ và
MemoryErrorsẽ được raise nếu có bất kỳ cấp phát heap nào được thử.Các khóa được lồng nhau: gọi
heap_lock()nhiều lần sẽ tăng độ sâu khóa. Heap vẫn bị khóa cho đến khiheap_unlock()được gọi cùng số lần.Nếu REPL trở nên hoạt động khi heap đang bị khóa thì nó sẽ bị mở khóa cưỡng bức.
- micropython.heap_unlock() int¶
Giảm độ sâu khóa heap đi một và trả về độ sâu mới dưới dạng số nguyên không âm. Giá trị trả về là
0có nghĩa là heap không còn bị khóa và việc cấp phát được phép trở lại.
- micropython.heap_locked() int¶
Trả về độ sâu khóa heap hiện tại dưới dạng số nguyên không âm;
0có nghĩa là heap không bị khóa.Lưu ý: hàm này không khả dụng trên OpenMV Cam.
- micropython.kbd_intr(chr: int) None¶
Đặt ký tự sẽ raise ngoại lệ
KeyboardInterrupt. Theo mặc định, giá trị này được đặt là 3 trong quá trình thực thi tập lệnh, tương ứng với Ctrl-C. Truyền -1 vào hàm này sẽ vô hiệu hóa việc bắt Ctrl-C, và truyền 3 sẽ khôi phục lại.Hàm này có thể được dùng để ngăn việc bắt Ctrl-C trên luồng ký tự đến thường được sử dụng cho REPL, trong trường hợp luồng đó được sử dụng cho mục đích khác.
- micropython.schedule(func: Callable[[Any], Any], arg: Any) None¶
Lên lịch hàm func để được thực thi "rất sớm". Hàm được truyền giá trị arg làm đối số duy nhất. "Rất sớm" có nghĩa là MicroPython runtime sẽ cố gắng tốt nhất để thực thi hàm sớm nhất có thể, cho rằng nó cũng đang cố gắng hiệu quả, và các điều kiện sau đây được thỏa mãn:
Một hàm đã được lên lịch sẽ không bao giờ chiếm quyền ưu tiên của một hàm đã lên lịch khác.
Các hàm đã được lên lịch luôn được thực thi "giữa các opcode" có nghĩa là tất cả các phép toán Python cơ bản (chẳng hạn như thêm vào danh sách) được đảm bảo là nguyên tử.
Một cổng nhất định có thể định nghĩa "vùng quan trọng" mà trong đó các hàm đã lên lịch sẽ không bao giờ được thực thi. Các hàm có thể được lên lịch trong vùng quan trọng nhưng chúng sẽ không được thực thi cho đến khi vùng đó được thoát. Ví dụ về vùng quan trọng là interrupt handler chiếm quyền ưu tiên (IRQ).
Bên trong các hàm native code, các hàm đã lên lịch không được gọi trừ khi native code gọi một hàm cụ thể thực hiện điều đó.
Một số hàm nhất định bao gồm
poll.poll,poll.ipoll,time.sleepvàtime.sleep_ms(bao gồm cả sleep thời gian không) sẽ gọi các hàm đã lên lịch.
Một cách sử dụng hàm này là lên lịch hàm gọi lại từ một IRQ chiếm quyền ưu tiên. IRQ như vậy đặt ra hạn chế đối với mã chạy trong IRQ (ví dụ heap có thể bị khóa) và việc lên lịch một hàm để gọi sau sẽ gỡ bỏ những hạn chế đó.
Trên các cổng đa luồng, hành vi của hàm đã lên lịch phụ thuộc vào việc Global Interpreter Lock (GIL) có được bật cho cổng cụ thể đó không:
Nếu GIL được bật, hàm có thể chiếm quyền ưu tiên của bất kỳ luồng nào và chạy trong ngữ cảnh của nó.
Nếu GIL bị tắt, hàm sẽ chỉ chiếm quyền ưu tiên của luồng chính và chạy trong ngữ cảnh của nó.
Lưu ý: Nếu
schedule()được gọi từ IRQ chiếm quyền ưu tiên, khi việc cấp phát bộ nhớ không được phép và hàm gọi lại được truyền vàoschedule()là một bound method, việc truyền trực tiếp sẽ thất bại. Điều này là do tạo tham chiếu đến bound method gây ra cấp phát bộ nhớ. Giải pháp là tạo tham chiếu đến method trong constructor của lớp và truyền tham chiếu đó vàoschedule(). Vấn đề này được thảo luận chi tiết ở đây tài liệu tham khảo trong phần "Tạo các đối tượng Python".Có một hàng đợi có giới hạn để giữ các hàm đã lên lịch và
schedule()sẽ raiseRuntimeErrornếu hàng đợi đầy.
Lớp¶
- class micropython.RingIO(size: int)¶
- class micropython.RingIO(buffer: bytes | bytearray | memoryview)
Cung cấp ringbuffer có kích thước cố định cho các byte với giao diện stream. Có thể được coi là biến thể FIFO-queue của
io.BytesIO. Hai dạng constructor chỉ khác nhau ở cách cung cấp bộ đệm nền:RingIO(size)cấp phát bộ đệm nền trong nội bộ. Thuật toán ringbuffer cổ điển dự trữ một byte để theo dõi, vì vậy bộ đệm được cấp phát lớn hơnsizemột byte và thực thể có thể giữ đủsizebyte dữ liệu. Ví dụ:RingIO(16)cấp phát bộ đệm 17 byte và giữ 16 byte dữ liệu.RingIO(buffer)sử dụngbufferđược cung cấp tại chỗ thay vì cấp phát một cái. Vì một byte được dự trữ để theo dõi, thực thể có thể giữlen(buffer) - 1byte dữ liệu. Ví dụ:RingIO(bytearray(16))giữ 15 byte dữ liệu.
Thực thể RingIO an toàn với IRQ/luồng khi được sử dụng để truyền dữ liệu theo một hướng (ví dụ: được ghi từ IRQ và đọc từ hàm không phải IRQ, hoặc ngược lại). Điều này không đúng nếu một thực thể được ghi từ cả ngữ cảnh IRQ và không phải IRQ, điều này thường gây ra hỏng dữ liệu.
- read(nbytes: int | None = None) bytes¶
Đọc các ký tự có sẵn. Đây là hàm không chặn. Nếu
nbytesđược chỉ định thì đọc tối đa nhiều byte đó, ngược lại đọc nhiều dữ liệu nhất có thể.Giá trị trả về: đối tượng bytes chứa các byte đã đọc. Sẽ là đối tượng bytes có độ dài không nếu không có dữ liệu.
- readline(nbytes: int | None = None) bytes¶
Đọc một dòng, kết thúc bằng ký tự xuống dòng hoặc trả về nếu tồn tại trong bộ đệm, ngược lại trả về các byte có sẵn trong bộ đệm. Nếu
nbytesđược chỉ định thì đọc tối đa nhiều byte đó.Giá trị trả về: đối tượng bytes chứa dòng đã đọc.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Đọc các byte có sẵn vào
bufđược cung cấp. Nếunbytesđược chỉ định thì đọc tối đa nhiều byte đó. Ngược lại, đọc tối đalen(buf)byte.Giá trị trả về: Số nguyên đếm số byte đã đọc vào
buf.
- write(buf: bytes | bytearray | memoryview) int¶
Ghi không chặn các byte từ
bufvào ringbuffer, bị giới hạn bởi không gian có sẵn trong ringbuffer.Giá trị trả về: Số nguyên đếm số byte đã ghi.