zephyr: Run scheduled callbacks at REPL and during mp_hal_delay_ms.
And ctrl-C can now interrupt a time.sleep call. This uses Zephyr's k_poll API to wait efficiently for an event signal, and an optional semaphore. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
916c3fd23f
commit
d120859857
@ -46,6 +46,7 @@ set(MICROPY_SOURCE_PORT
|
||||
modutime.c
|
||||
modzephyr.c
|
||||
modzsensor.c
|
||||
mphalport.c
|
||||
uart_core.c
|
||||
zephyr_storage.c
|
||||
)
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
@ -123,6 +124,7 @@ int real_main(void) {
|
||||
mp_stack_set_limit(CONFIG_MAIN_STACK_SIZE - 512);
|
||||
|
||||
init_zephyr();
|
||||
mp_hal_init();
|
||||
|
||||
#ifdef TEST
|
||||
static const char *argv[] = {"test"};
|
||||
|
@ -96,6 +96,9 @@
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
|
||||
|
||||
void mp_hal_signal_event(void);
|
||||
#define MICROPY_SCHED_HOOK_SCHEDULED mp_hal_signal_event()
|
||||
|
||||
#define MICROPY_PY_SYS_PLATFORM "zephyr"
|
||||
|
||||
#ifdef CONFIG_BOARD
|
||||
|
74
ports/zephyr/mphalport.c
Normal file
74
ports/zephyr/mphalport.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
static struct k_poll_signal wait_signal;
|
||||
static struct k_poll_event wait_events[2] = {
|
||||
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&wait_signal),
|
||||
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
NULL, 0),
|
||||
};
|
||||
|
||||
void mp_hal_init(void) {
|
||||
k_poll_signal_init(&wait_signal);
|
||||
}
|
||||
|
||||
void mp_hal_signal_event(void) {
|
||||
k_poll_signal_raise(&wait_signal, 0);
|
||||
}
|
||||
|
||||
void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) {
|
||||
mp_uint_t t0 = mp_hal_ticks_ms();
|
||||
if (sem) {
|
||||
k_poll_event_init(&wait_events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, sem);
|
||||
}
|
||||
for (;;) {
|
||||
k_timeout_t wait;
|
||||
if (timeout_ms == (uint32_t)-1) {
|
||||
wait = K_FOREVER;
|
||||
} else {
|
||||
uint32_t dt = mp_hal_ticks_ms() - t0;
|
||||
if (dt >= timeout_ms) {
|
||||
return;
|
||||
}
|
||||
wait = K_MSEC(timeout_ms - dt);
|
||||
}
|
||||
k_poll(wait_events, sem ? 2 : 1, wait);
|
||||
if (wait_events[0].state == K_POLL_STATE_SIGNALED) {
|
||||
wait_events[0].signal->signaled = 0;
|
||||
wait_events[0].state = K_POLL_STATE_NOT_READY;
|
||||
mp_handle_pending(true);
|
||||
} else if (sem && wait_events[1].state == K_POLL_STATE_SEM_AVAILABLE) {
|
||||
wait_events[1].state = K_POLL_STATE_NOT_READY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
#include <zephyr.h>
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
void mp_hal_init(void);
|
||||
void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms);
|
||||
|
||||
static inline mp_uint_t mp_hal_ticks_us(void) {
|
||||
return k_cyc_to_ns_floor64(k_cycle_get_32()) / 1000;
|
||||
}
|
||||
@ -21,7 +24,7 @@ static inline void mp_hal_delay_us(mp_uint_t delay) {
|
||||
}
|
||||
|
||||
static inline void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
k_msleep(delay);
|
||||
mp_hal_wait_sem(NULL, delay);
|
||||
}
|
||||
|
||||
static inline uint64_t mp_hal_time_ns(void) {
|
||||
|
@ -13,6 +13,7 @@ CONFIG_CONSOLE_PUTCHAR_BUFSIZE=128
|
||||
CONFIG_NEWLIB_LIBC=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_MAIN_STACK_SIZE=4736
|
||||
CONFIG_POLL=y
|
||||
|
||||
# Enable sensor subsystem (doesn't add code if not used).
|
||||
# Specific sensors should be enabled per-board.
|
||||
|
@ -1,6 +1,7 @@
|
||||
CONFIG_NEWLIB_LIBC=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
CONFIG_POLL=y
|
||||
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||
CONFIG_CONSOLE_SUBSYS=y
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
extern int mp_interrupt_char;
|
||||
void mp_sched_keyboard_interrupt(void);
|
||||
void mp_hal_signal_event(void);
|
||||
void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms);
|
||||
|
||||
static struct k_sem uart_sem;
|
||||
#define UART_BUFSIZE 256
|
||||
@ -36,6 +38,7 @@ static int console_irq_input_hook(uint8_t ch)
|
||||
return 1;
|
||||
}
|
||||
if (ch == mp_interrupt_char) {
|
||||
mp_hal_signal_event();
|
||||
mp_sched_keyboard_interrupt();
|
||||
return 1;
|
||||
} else {
|
||||
@ -49,6 +52,7 @@ static int console_irq_input_hook(uint8_t ch)
|
||||
}
|
||||
|
||||
uint8_t zephyr_getchar(void) {
|
||||
mp_hal_wait_sem(&uart_sem, -1);
|
||||
k_sem_take(&uart_sem, K_FOREVER);
|
||||
unsigned int key = irq_lock();
|
||||
uint8_t c = uart_ringbuf[i_get++];
|
||||
|
Loading…
Reference in New Issue
Block a user