1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

examples/micropython: initial micropython example application

This commit is contained in:
Kaspar Schleiser 2019-07-16 15:58:29 +02:00
parent 042786b835
commit b5743cab40
6 changed files with 223 additions and 0 deletions

View File

@ -0,0 +1,30 @@
# name of your application
APPLICATION = micropython
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# select MicroPython package
USEPKG += micropython
# include boot.py as header
BLOBS += boot.py
# configure MicroPython's heap size
MP_RIOT_HEAPSIZE ?= 8192U
# MicroPython needs a larger stack
CFLAGS += '-DTHREAD_STACKSIZE_MAIN=THREAD_STACKSIZE_DEFAULT*4'
# use miniterm (instead of the default pyterm) in order to support control
# characters (CTRL-D ...)
RIOT_TERMINAL ?= miniterm
# enable modmachine support for peripherals if available
FEATURES_OPTIONAL += periph_adc
FEATURES_OPTIONAL += periph_spi
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,25 @@
BOARD_INSUFFICIENT_MEMORY := \
blackpill \
bluepill \
calliope-mini \
i-nucleo-lrwan1 \
microbit \
nrf51dongle \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f070rb \
nucleo-f072rb \
nucleo-f302r8 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l031k6 \
nucleo-l053r8 \
opencm904 \
saml10-xpro \
saml11-xpro \
stm32f0discovery \
spark-core \
stm32f030f4-demo \
stm32l0538-disco \
#

View File

@ -0,0 +1,6 @@
# Overview
WARNING: RIOT's MicroPython port is currently quite incomplete!
This application provides an example on how to use MicroPython with RIOT.
Please see the documentation of pkg/micropython.

View File

@ -0,0 +1 @@
print("boot.py: MicroPython says hello!")

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2019 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief micropython example application
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
#include <stdio.h>
#include "thread.h"
#include "micropython.h"
#include "py/stackctrl.h"
#include "lib/utils/pyexec.h"
#include "blob/boot.py.h"
static char mp_heap[MP_RIOT_HEAPSIZE];
int main(void)
{
int coldboot = 1;
/* let MicroPython know the top of this thread's stack */
uint32_t stack_dummy;
mp_stack_set_top((char*)&stack_dummy);
/* Make MicroPython's stack limit somewhat smaller than actual stack limit */
mp_stack_set_limit(THREAD_STACKSIZE_MAIN - MP_STACK_SAFEAREA);
while (1) {
/* configure MicroPython's heap */
mp_riot_init(mp_heap, sizeof(mp_heap));
/* execute boot.py
*
* MicroPython's test suite gets confused by extra output, so only do
* this the first time after the node boots up, not on following soft
* reboots.
*/
if (coldboot) {
puts("-- Executing boot.py");
mp_do_str((const char *)boot_py, boot_py_len);
puts("-- boot.py exited. Starting REPL..");
coldboot = 0;
}
/* loop over REPL input */
while (1) {
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
if (pyexec_raw_repl() != 0) {
break;
}
} else {
if (pyexec_friendly_repl() != 0) {
break;
}
}
}
puts("soft reboot");
}
return 0;
}

View File

@ -0,0 +1,84 @@
#!/usr/bin/env python3
import sys
from testrunner import run
def testfunc(child):
def get_time():
child.sendline('utime.time()')
child.readline()
res = int(child.readline().rstrip())
child.expect_exact('>>>')
return res
child.expect_exact('boot.py: MicroPython says hello!')
child.expect_exact('>>>')
child.sendline('print("echo this! " * 4)')
child.expect_exact('echo this! echo this! echo this! echo this!')
child.expect_exact('>>>')
# test riot.thread_getpid()
child.sendline('import riot')
child.sendline('print(riot.thread_getpid())')
child.expect_exact('2')
child.expect_exact('>>>')
#
# test xtimer integration
#
child.sendline('import utime')
child.expect_exact('>>>')
# testing timing over serial using the REPL is very inaccurate, thus
# we allow a *large* overshoot (100 by default).
def test_sleep(t, slack=100):
before = get_time()
child.sendline('utime.sleep_ms(%s)' % t)
child.expect_exact('>>>')
duration = get_time() - before
print("test_sleep(%s, %s): slept %sms" % (t, slack, duration))
assert duration > t and duration < (t + slack)
return duration
# get overhead from sleeping 0ms, add 10 percent
slack = int(test_sleep(0, 1000) * 1.1)
test_sleep(50, slack)
test_sleep(250, slack)
test_sleep(500, slack)
# test setting timers
child.sendline('import xtimer')
child.expect_exact('>>>')
child.sendline('a = 0')
child.expect_exact('>>>')
child.sendline('def inc_a(): global a; a+=1')
child.expect_exact('...')
child.sendline('')
child.expect_exact('>>>')
child.sendline('t = xtimer.xtimer(inc_a)')
child.expect_exact('>>>')
before = get_time()
child.sendline('t.set(500000)')
child.expect_exact('>>>')
child.sendline('while a==0: pass')
child.expect_exact('...')
child.sendline('')
child.expect_exact('>>>')
duration = get_time() - before
assert duration > 500
print("[TEST PASSED]")
if __name__ == "__main__":
sys.exit(run(testfunc))