What causes the simulator to generate this error? The code works in the board hardware fine


I suspect it’s because I have to use the Micro:Bit Card Edge extension to enable PIN functions, yet my board is a RP2040 based custom board and the pin functions actually work with the GPIO as I’m using it…

1 Like

This means that the API isn’t defined in the simulator.

A more detailed explanation

When a project is compiled in MakeCode, we first convert the TypeScript of the project into an intermediate representation. This representation is either sent to the binary compiler to produce machine code (a UF2 file), or sent to the simulator compiler to produce a JavaScript file that mimics our C++ runtime. You can actually see this file if you switch to JavaScript and look at the “built” tab in the file explorer underneath the simulator, it’s called binary.js. That takes care of all of the TS code from the user and their added extensions, but the C++ code from extensions is not compiled and run in the browser. Instead, we implement “shim” functions that mimic the behavior of the C++ functions.

For example, the drawImage function in pxt-arcade is implemented in C++ inside the screen extension in pxt-common-packages here.

When we compile that extension, we generate a shims.d.ts file that contains a TS typing for that API here. This is the typing that is used by the compiler to check the user code, but it is just a typing with no implementation.

If we look at the binary.js for an arcade program that references this API, you’ll see something like this:

case 25:
    r0 = s.retval;
    s.dw___9800 = (r0);
    r0 = s.arg0.fields["img"];
    s.tmp_0 = r0;
    r0 = pxsim_ImageMethods.drawImage(globals.screen___1829, s.tmp_0, s.rxl___9790, s.ry___9702);
    r0 = (s.rxl___9790 + s.dw___9800);
    s.tmp_0 = r0;
    r0 = (s.tmp_0 % s.w___9680);
    s.rxl___9790 = (r0);

that call to pxsim_ImageMethods.drawImage will end up calling this function which is defined inside of the sim folder of screen extension. This function is written by hand and mimics the same C++ function but using APIs in the browser rather than C++.

If you’re writing a C++ extension, the APIs you add will not work in the simulator. We don’t allow third-party extensions to contribute code to the simulator for security reasons; the code does not pass through our compiler so we cannot guarantee that it is not malicious in some way. This is why we generally recommend that all APIs be written in TypeScript whenever possible.

If you aren’t writing a C++ extension and just happened to hit this when calling some API from pxt-arcade or one of the recommended extensions, you should open an issue since this is most likely a bug!

2 Likes

I am ONLY using Typescript/blockly. I’m able to do this because of the RP2040 support that’s been added by Michal recently. I’m using the final public test build editor.

So what could be causing this? I guess it’s safe to ignore while things work on the board but it does mean I have no debug capability…

can you share some code? my guess is it’s a bug on makecode’s side. if you can share a project that reproduces this error than I can take a look

I’ve published to the following repo:

thanks @xjordanx, that is definitely a makecode bug. looks like it isn’t generating a declaration for that particular pin for some reason. sorry for the inconvenience!

in the meantime, you can work around it like so:

if (control.deviceDalVersion() !== "sim") {
    pins.P23.setPull(PinPullMode.PullDown)
    pins.P24.setPull(PinPullMode.PullDown)
}
1 Like