zephyr: Re-implement the Zephyr console in non-blocking mode.
The standard Zephyr console implementation doesn't make use of `tty_set_rx_timeout()` and therefore all the functions to receive characters block indefinitely until data is received (including `console_read()`). This commit also releases the GIL where it applies, e.g. the REPL and the time sleep functions. Signed-off-by: danicampora <danicampora@gmail.com>
This commit is contained in:
parent
6833f3dda9
commit
d68d8fcf90
@ -51,12 +51,15 @@ void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) {
|
|||||||
k_poll_event_init(&wait_events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, sem);
|
k_poll_event_init(&wait_events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, sem);
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
mp_handle_pending(true);
|
||||||
|
MP_THREAD_GIL_EXIT();
|
||||||
k_timeout_t wait;
|
k_timeout_t wait;
|
||||||
if (timeout_ms == (uint32_t)-1) {
|
if (timeout_ms == (uint32_t)-1) {
|
||||||
wait = K_FOREVER;
|
wait = K_FOREVER;
|
||||||
} else {
|
} else {
|
||||||
uint32_t dt = mp_hal_ticks_ms() - t0;
|
uint32_t dt = mp_hal_ticks_ms() - t0;
|
||||||
if (dt >= timeout_ms) {
|
if (dt >= timeout_ms) {
|
||||||
|
MP_THREAD_GIL_ENTER();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wait = K_MSEC(timeout_ms - dt);
|
wait = K_MSEC(timeout_ms - dt);
|
||||||
@ -65,9 +68,9 @@ void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) {
|
|||||||
if (wait_events[0].state == K_POLL_STATE_SIGNALED) {
|
if (wait_events[0].state == K_POLL_STATE_SIGNALED) {
|
||||||
wait_events[0].signal->signaled = 0;
|
wait_events[0].signal->signaled = 0;
|
||||||
wait_events[0].state = K_POLL_STATE_NOT_READY;
|
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) {
|
} else if (sem && wait_events[1].state == K_POLL_STATE_SEM_AVAILABLE) {
|
||||||
wait_events[1].state = K_POLL_STATE_NOT_READY;
|
wait_events[1].state = K_POLL_STATE_NOT_READY;
|
||||||
|
MP_THREAD_GIL_ENTER();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -269,6 +269,7 @@ int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
|
|||||||
|
|
||||||
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
|
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
|
||||||
k_sem_give(&mutex->handle);
|
k_sem_give(&mutex->handle);
|
||||||
|
k_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_thread_deinit(void) {
|
void mp_thread_deinit(void) {
|
||||||
|
|||||||
@ -50,14 +50,16 @@ static int console_irq_input_hook(uint8_t ch) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t zephyr_getchar(void) {
|
int zephyr_getchar(void) {
|
||||||
mp_hal_wait_sem(&uart_sem, -1);
|
mp_hal_wait_sem(&uart_sem, 0);
|
||||||
k_sem_take(&uart_sem, K_FOREVER);
|
if (k_sem_take(&uart_sem, K_MSEC(0)) == 0) {
|
||||||
unsigned int key = irq_lock();
|
unsigned int key = irq_lock();
|
||||||
uint8_t c = uart_ringbuf[i_get++];
|
int c = (int)uart_ringbuf[i_get++];
|
||||||
i_get &= UART_BUFSIZE - 1;
|
i_get &= UART_BUFSIZE - 1;
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
return c;
|
return c;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zephyr_getchar_init(void) {
|
void zephyr_getchar_init(void) {
|
||||||
|
|||||||
@ -17,4 +17,4 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void zephyr_getchar_init(void);
|
void zephyr_getchar_init(void);
|
||||||
uint8_t zephyr_getchar(void);
|
int zephyr_getchar(void);
|
||||||
|
|||||||
@ -24,14 +24,14 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include <zephyr/zephyr.h>
|
#include <zephyr/zephyr.h>
|
||||||
#include <zephyr/console/console.h>
|
|
||||||
#include "zephyr_getchar.h"
|
#include "zephyr_getchar.h"
|
||||||
|
|
||||||
int real_main(void);
|
int real_main(void);
|
||||||
|
int mp_console_init(void);
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
#ifdef CONFIG_CONSOLE_SUBSYS
|
#ifdef CONFIG_CONSOLE_SUBSYS
|
||||||
console_init();
|
mp_console_init();
|
||||||
#else
|
#else
|
||||||
zephyr_getchar_init();
|
zephyr_getchar_init();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -25,10 +25,28 @@
|
|||||||
*/
|
*/
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
#include "src/zephyr_getchar.h"
|
#include "src/zephyr_getchar.h"
|
||||||
// Zephyr headers
|
// Zephyr headers
|
||||||
#include <zephyr/drivers/uart.h>
|
#include <zephyr/zephyr.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/console/console.h>
|
#include <zephyr/console/console.h>
|
||||||
|
#include <zephyr/console/tty.h>
|
||||||
|
#include <zephyr/drivers/uart.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONSOLE_SUBSYS
|
||||||
|
|
||||||
|
static int mp_console_putchar(char c);
|
||||||
|
static int mp_console_getchar(void);
|
||||||
|
|
||||||
|
|
||||||
|
static struct tty_serial mp_console_serial;
|
||||||
|
|
||||||
|
static uint8_t mp_console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE];
|
||||||
|
static uint8_t mp_console_txbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE];
|
||||||
|
|
||||||
|
#endif // CONFIG_CONSOLE_SUBSYS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core UART functions to implement for a port
|
* Core UART functions to implement for a port
|
||||||
@ -36,11 +54,18 @@
|
|||||||
|
|
||||||
// Receive single character
|
// Receive single character
|
||||||
int mp_hal_stdin_rx_chr(void) {
|
int mp_hal_stdin_rx_chr(void) {
|
||||||
#ifdef CONFIG_CONSOLE_SUBSYS
|
for (;;) {
|
||||||
return console_getchar();
|
int _chr;
|
||||||
#else
|
#ifdef CONFIG_CONSOLE_SUBSYS
|
||||||
return zephyr_getchar();
|
_chr = mp_console_getchar();
|
||||||
#endif
|
#else
|
||||||
|
_chr = zephyr_getchar();
|
||||||
|
#endif
|
||||||
|
if (_chr >= 0) {
|
||||||
|
return _chr;
|
||||||
|
}
|
||||||
|
MICROPY_EVENT_POLL_HOOK
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send string of given length
|
// Send string of given length
|
||||||
@ -49,8 +74,8 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
|||||||
#ifdef CONFIG_CONSOLE_SUBSYS
|
#ifdef CONFIG_CONSOLE_SUBSYS
|
||||||
while (len--) {
|
while (len--) {
|
||||||
char c = *str++;
|
char c = *str++;
|
||||||
while (console_putchar(c) == -1) {
|
while (mp_console_putchar(c) == -1) {
|
||||||
k_msleep(1);
|
MICROPY_EVENT_POLL_HOOK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -63,3 +88,58 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
|||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONSOLE_SUBSYS
|
||||||
|
|
||||||
|
int mp_console_init(void) {
|
||||||
|
|
||||||
|
const struct device *uart_dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
|
||||||
|
if (!device_is_ready(uart_dev)) {
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tty_init(&mp_console_serial, uart_dev);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks device driver supports for interrupt driven data transfers. */
|
||||||
|
if (CONFIG_CONSOLE_GETCHAR_BUFSIZE + CONFIG_CONSOLE_PUTCHAR_BUFSIZE) {
|
||||||
|
const struct uart_driver_api *api =
|
||||||
|
(const struct uart_driver_api *)uart_dev->api;
|
||||||
|
if (!api->irq_callback_set) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_set_tx_buf(&mp_console_serial, mp_console_txbuf, sizeof(mp_console_txbuf));
|
||||||
|
tty_set_rx_buf(&mp_console_serial, mp_console_rxbuf, sizeof(mp_console_rxbuf));
|
||||||
|
|
||||||
|
tty_set_rx_timeout(&mp_console_serial, 0);
|
||||||
|
tty_set_tx_timeout(&mp_console_serial, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mp_console_putchar(char c) {
|
||||||
|
return tty_write(&mp_console_serial, &c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mp_console_getchar(void) {
|
||||||
|
uint8_t c;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = tty_read(&mp_console_serial, &c, 1);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_CONSOLE_SUBSYS
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user