How do I make a port of MicroPython for Casio calculators?

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
Zezombye
Posts: 34
Joined: Mon Jul 30, 2018 8:29 pm

How do I make a port of MicroPython for Casio calculators?

Post by Zezombye » Mon Jul 30, 2018 8:45 pm

Hi everyone,

I'd like to make a port of MicroPython for Casio calculators. Like TI calculators, they have their own filesystem, and ways to program an editor in C.

I managed to compile MPy for SH3 (architecture of Casio calculators), using the minimal port. To make a successful port, I need to :
- Initialize Micropython (I obviously need to call the main() method in main.c, but do I call it once when the user launches my editor, or do I call it every time the user runs the program?)
- Send code to micropython (as I understand, it is done with the uart_code.c file, using the mp_hal_stdin_rx_chr() function; does this function execute periodically, do I need to do anything for this function to execute periodically?)
- Receive print() statements from python code (also done with the uart_code.c file, using mp_hal_stdout_tx_strn() function)
- Receive input() interrupts (no idea how to do this)
- Override import statement to use Casio-specific functions, as the filesystem is different (no idea either; I guess it is in the builtinimport.c file, but I can't find anything I need to modify)

Any idea of how to do these things? I'd appreciate help a lot as there is a lot of source code. Thanks in advance :)

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by jickster » Tue Jul 31, 2018 8:48 pm

Zezombye wrote:
Mon Jul 30, 2018 8:45 pm
ways to program an editor in C.
What does that mean?
Zezombye wrote:
Mon Jul 30, 2018 8:45 pm
Send code to micropython (as I understand, it is done with the uart_code.c file, using the mp_hal_stdin_rx_chr() function; does this function execute periodically, do I need to do anything for this function to execute periodically?)
Please clarify your overall architecture. Your questions imply a certain architecture but it's unclear:

Will micropython be only code running or does Casio have some sort of OS on-top of which you'll be running your executable?

Add some more details about the sw architecture of your environment.

Zezombye
Posts: 34
Joined: Mon Jul 30, 2018 8:29 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by Zezombye » Wed Aug 01, 2018 9:20 am

What does that mean?
Basically you can make (graphical) apps in C, there's an SDK available.
Will micropython be only code running or does Casio have some sort of OS on-top of which you'll be running your executable?
Yes: Casio has an OS, and I'm running my executable on top.

Anyway, in the meantime I figured out how to make the shell working (input/output):
Image

For output, I replaced the mp_hal_stdout_tx_strn() function so that it calls my custom print() function.
For input, the "serial" way of reading wasn't the way I wanted, because it would be better performance-wise if I completely interrupted the program while waiting for input, rather than putting the read loop in a timer, and the input loop in the other. Also, I needed some keys to input strings instead of simply chars (for example, the "^" key inputs "**").
So I didn't replace mp_hal_stdin_rx_chr(), but the readline() loop in /lib/mp-readline/readline.c :

Code: Select all

int readline(vstr_t *line, const char *prompt) {
    readline_init(line, prompt);
    for (;;) {
		char str[10] = {0};
		
		waitForKey(str);
		
		for (int i = 0; str[i]; i++) {
			int c = str[i];
			int r = readline_process_char(c);
			if (r >= 0) {
				return r;
			}
		}
    }
}
And as for initializing MicroPython, I will initialize it each time I need to run a program (the startup time is almost instantaneous so it makes little difference).

Now, I still need help for input() and import :
- The input() function throws a "name not defined" error; I apparently need to import sys. How do I do that ("import sys" does not work)? And why does print() works but not input()?
Image
As for the input() interrupts, I guess there's not actually interrupts, but that MicroPython simply enters the read loop and calls the read function on its own, so I've got little to nothing to do on my side (only listen when the read function is called, and display cursor).

- As for import, how do I add modules such as math or urandom (or sys)?

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by jickster » Wed Aug 01, 2018 2:45 pm

Zezombye wrote:
Wed Aug 01, 2018 9:20 am
As for import, how do I add modules such as math or urandom (or sys)?
In micropython code, search for "MP_QSTR_sys".
You'll see several entries, each of which is surrounded by #if MICROPY_PY_SYS #endif
If you have your IDE indexing set up correctly, the code will appear as not included in compilation.

In mpconfig.h, you'll see all the macros that are used to include or exclude code in compilation.
In mpconfigport.h, you enable whichever macros you need.

To include "sys", in mpconfigport.h you add
#define MICROPY_PY_SYS (1)

Follow same process for any other module: math, urandom, etc

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by jickster » Wed Aug 01, 2018 2:56 pm

Zezombye wrote:
Wed Aug 01, 2018 9:20 am
And as for initializing MicroPython, I will initialize it each time I need to run a program (the startup time is almost instantaneous so it makes little difference).
I'm not surprised it's instantaneous: initialization merely zeros out the heap you pass in and sets up the state variable.

The state of micropython is contained in two items:
the heap that you allocate and pass in to gc_init()
and
the state mp_state_ctx_t mp_state_ctx;

With respect to saving/restoring state, the question you need to answer is whether anything you're planning to do will NECESSITATE saving/restoring the state since this is only possible with extreme restrictions; see viewtopic.php?f=3&t=4855 and https://github.com/micropython/micropython/issues/3833

Zezombye
Posts: 34
Joined: Mon Jul 30, 2018 8:29 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by Zezombye » Sun Aug 05, 2018 9:34 am

Thanks; I set MICROPY_PY_SYS to 1, and now I can "import sys" without a "module not found" error, however I still have the same "name not defined" for the input() function. Is there anything more I have to do? I also defined MICROPY_PY_IO.

Edit: nevermind, I had to define MICROPY_PY_BUILTINS_INPUT in mpconfig.h.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by jickster » Sun Aug 05, 2018 7:44 pm

Zezombye wrote:
Sun Aug 05, 2018 9:34 am
Edit: nevermind, I had to define MICROPY_PY_BUILTINS_INPUT in mpconfig.h.
You could define it there but you should do it in mpconfigport.h

Zezombye
Posts: 34
Joined: Mon Jul 30, 2018 8:29 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by Zezombye » Tue Aug 07, 2018 2:33 pm

I am currently trying to implement floats. I defined MICROPY_FLOAT_IMPL as MICROPY_FLOAT_IMPL_DOUBLE, however when I do anything involving floats (even typing "1.1" into the shell) the system crashes with a null pointer exception.

As the SDK for Casio only supports C89, I had to implement some functions: nan(), nearbyint(), copysign(), feholdexcept() and fesetenv(). The problem could come from these functions, but I honestly doubt that as I put print statements at the beginning of each of these functions, and nothing is printed. So that mean it's something else.

What functions are used when python handles anything related to doubles (no calculations, as I simply type a number into the shell)?

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

How do I make a port of MicroPython for Casio calculators?

Post by jickster » Tue Aug 07, 2018 3:11 pm

Zezombye wrote:I am currently trying to implement floats. I defined MICROPY_FLOAT_IMPL as MICROPY_FLOAT_IMPL_DOUBLE, however when I do anything involving floats (even typing "1.1" into the shell) the system crashes with a null pointer exception.

As the SDK for Casio only supports C89, I had to implement some functions: nan(), nearbyint(), copysign(), feholdexcept() and fesetenv(). The problem could come from these functions, but I honestly doubt that as I put print statements at the beginning of each of these functions, and nothing is printed. So that mean it's something else.

What functions are used when python handles anything related to doubles (no calculations, as I simply type a number into the shell)?
Put a breakpoint in the big switch-statement in vm.c and you’ll see which bytecodes and functions are executed and where the crash occurs.

Zezombye
Posts: 34
Joined: Mon Jul 30, 2018 8:29 pm

Re: How do I make a port of MicroPython for Casio calculators?

Post by Zezombye » Thu Aug 09, 2018 4:40 am

I can't put breakpoints so I did the "manual" method with good old print().

Anyway, I put print statements everywhere (beginning of mp_execute_bytecode, before for loop, beginning of for loop, beginning of switch...): when I type an integer, all print statements are executed, however when I type a double it crashes before it even prints anything.

So I guess the crash occurs before the execution of mp_execute_bytecode() :/

Post Reply