Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

MicroPython for Microcontrollers Module 9

Packages, .mpy files and custom firmware interview questions

Interview questions on packages, .mpy files and custom firmware: warm-ups, then what each harder question tests and how a good answer starts.

15 questions: 4 warm-ups and 11 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher

    Why can't you pip install a package onto a Pico, and what do you use instead?

    Answered in the lesson Libraries with mip and micropython-lib

  2. Fresher

    What is an .mpy file, and what does a board gain when it imports one instead of the .py file?

    Answered in the lesson Precompile to .mpy with mpy-cross

  3. Fresher

    What is the difference between a frozen module and an .mpy file in /lib?

    Answered in the lesson Frozen modules, manifests and ROMFS

  4. Fresher

    What is the difference between a natmod and a user C module in MicroPython?

    Answered in the lesson Native modules in C: natmods and user C modules

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Mid to senior

    Forty Pico W boards installed umqtt.simple with mip.install("umqtt.simple") over three months, and some now behave differently when the broker drops the connection. How do you tell what each board runs, and how do you make the next installs the same everywhere?

    What it tests
    Knowing that an install without a version takes the newest one, reading what a board holds, and pinning versions of packages and their dependencies for a fleet.
    First step
    Start from how the boards were installed: with no version, each install asked the index for latest.json, the newest version on that day, so boards installed months apart can hold different code. Compare the files on the boards, their SHA-256 against the hashes of each version's package file, before changing anything.
    Follow-ups

    From the lesson Libraries with mip and micropython-lib

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  2. Fresher to mid

    A teammate's package installs with mpremote mip install github:team/sensor on their computer. On yours it prints Package may be partially installed and the import fails. How do you find the cause, and what do you change so it cannot happen again?

    What it tests
    Reading mip's messages, the format of package.json (pairs, relative sources, forward slashes), how sources are rewritten with a version, and checking a package before you publish it.
    First step
    Read the line before the warning: mip names what failed, Package not found for the package file, File not found with the path for one file, or an error with an HTTP status. Then compare the two installs: the same version or branch, the same package.json, and what is already in /lib on each board.
    Follow-ups

    From the lesson Libraries with mip and micropython-lib

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  3. Mid to senior

    After a fleet of Picos moves from MicroPython 1.22 to 1.29.0, every .mpy module in /lib still imports except one, which fails with ValueError: incompatible .mpy file. What is different about that one, and how do you fix the fleet and the build?

    What it tests
    Knowing that bytecode files check only the .mpy version while machine-code files also check the sub-version, reading a header, and pinning the cross-compiler to the firmware.
    First step
    Read the headers of a module that loads and of the one that fails. The bytecode files start 4d 06 00 1f: version 6, which 1.29.0 still reads. The failing one is likely machine code, third byte 0x12: sub-version 2, the format of 1.22, while 1.29.0 requires 3 for any file with machine code.
    Follow-ups

    From the lesson Precompile to .mpy with mpy-cross

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  4. Mid to senior

    One repository feeds Pico, Pico W and ESP32 boards, and some modules use @micropython.native. Design the build and deploy steps so that a board can never be sent an .mpy file it cannot import.

    What it tests
    Splitting bytecode from machine-code modules, deriving -march from each board's _mpy, pinning mpy-cross, and a pre-flight check of headers before anything is copied.
    First step
    Group the targets by what their firmware reads, not by product name: the Pico and the Pico W share one sys.implementation._mpy, 4870, armv6m, and the ESP32 reports 11014, xtensawin. Bytecode modules build once for all; each machine-code module builds once per architecture. Then decide where the check goes.
    Follow-ups

    From the lesson Precompile to .mpy with mpy-cross

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Fresher to mid

    A Pico app with 25 modules in /lib raises MemoryError during its imports at start, but runs once the largest module is removed. Would precompiling everything to .mpy help, and what would you measure before and after?

    What it tests
    Telling the compiler's RAM at import from the bytecode's RAM afterwards, measuring with gc and micropython.mem_info, and knowing when freezing or ROMFS is the next step.
    First step
    Separate two costs. While a .py module imports, the board's compiler needs RAM of its own on top of the bytecode it makes; an .mpy file removes that cost, but its bytecode still lands in RAM. Measure gc.mem_free() after a gc.collect() at points through the imports, to see which cost runs out.
    Follow-ups

    From the lesson Precompile to .mpy with mpy-cross

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Mid to senior

    Your Pico firmware freezes the app's station package. A bug in it is found after 300 boards ship, and a teammate copies a fixed station to /lib on a test board, but the bug is still there. Explain why, and how you would ship the fix and design the next firmware.

    What it tests
    The order of sys.path with frozen modules and ROMFS, what a frozen module's __file__ shows, and designing firmware that can be fixed in the field.
    First step
    Check which copy runs before touching code: import station, then print(station.__file__). On the rp2 port sys.path is '', '.frozen', then /lib, so the frozen copy is found first and the file in /lib is never read. The fix cannot reach the boards as a file in /lib.
    Follow-ups

    From the lesson Frozen modules, manifests and ROMFS

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  7. Fresher to mid

    After flashing a custom Pico firmware built with FROZEN_MANIFEST, the board starts at the prompt, main.py on its flash never runs, and import asyncio fails. The stock firmware works. What went wrong in the build, and how do you check a manifest before flashing?

    What it tests
    That a manifest replaces the board's manifest, what the rp2 port freezes (_boot.py, asyncio, drivers), and checking a manifest's output before it reaches a board.
    First step
    Both symptoms point at the port's own frozen modules. The rp2 port's _boot.py mounts the flash filesystem at each start, and asyncio is frozen by the port's board manifest. Look at the first lines of the manifest: without include("$(PORT_DIR)/boards/manifest.py"), none of them is in the firmware.
    Follow-ups

    From the lesson Frozen modules, manifests and ROMFS

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  8. Senior to staff

    A fleet of 200 Pico W boards runs out of RAM, and its app changes about once a month. You can ship one new firmware now, and only over USB at a service visit. Would you freeze the app, move it to ROMFS, or keep .mpy files in /lib? Defend the choice.

    What it tests
    Weighing RAM, update cost and risk for frozen code, ROMFS and files; partitions set at build time; sys.path order; and planning the one firmware build well.
    First step
    Write down what each change will cost in the field. Frozen code saves the RAM, but a monthly change becomes a firmware flash over USB at a visit. .mpy files in /lib change easily but keep the bytecode in RAM, which is what runs short. ROMFS runs from flash and changes with a new image, if the firmware has a partition.
    Follow-ups

    From the lesson Frozen modules, manifests and ROMFS

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  9. Mid to senior

    A Modbus gateway on ESP32 boards with stock firmware spends most of its time computing CRC-16 over 256-byte frames in Python. Would you use viper, a natmod or a user C module, and how would you prove the change is correct and worth it?

    What it tests
    Choosing between viper, natmods and user C modules from constraints, measuring before and after, and proving equality with a reference and known check values.
    First step
    Start from the constraints. Stock firmware rules out a user C module. A 256-byte frame costs 2,048 shift steps in the bitwise CRC, each several bytecode instructions in Python; measure the time per frame on the board first, with time.ticks_us() around the call, so the gain can be shown in numbers.
    Follow-ups

    From the lesson Native modules in C: natmods and user C modules

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  10. Mid to senior

    You port a C library to a natmod. It compiles and passes its tests on your computer, but the natmod build fails, pointing at the library's lookup tables and a global counter. What do natmods not support, and how do you change the C without changing its results?

    What it tests
    Knowing which kinds of C data a natmod's loader accepts, changing a library to fit without changing its results, and testing the changed C against the original.
    First step
    Read the error, then the natmod page's list of what its loader supports. Sort the library's globals by the section the compiler puts each in: code, read-only data, data with initial values, or zeroed data. Note how each table and the counter are declared, const or not, static or not, with a value or not, before changing a line.
    Follow-ups

    From the lesson Native modules in C: natmods and user C modules

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  11. Senior to staff

    Your product ships a natmod for Pico, ESP32 and ESP32-C3 boards, with a Python fallback. Design the tests and the CI that keep every natmod and the fallback in agreement, and make a board that runs the fallback visible.

    What it tests
    Testing a C core and a Python reference together, building per architecture, a loader that survives a missing or a wrong file, and making silent fallbacks observable in the field.
    First step
    Make one set of test vectors the source of truth: known check values, such as 0x4B37 for "123456789" in CRC-16/MODBUS, edge cases, and random frames with a fixed seed. Run them against the Python reference and against the plain C core on the CI machine before any cross-compiler runs.
    Follow-ups

    From the lesson Native modules in C: natmods and user C modules

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes

All MicroPython for Microcontrollers interview questions · The MicroPython for Microcontrollers track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.