subsys: console: Switch to POSIX-like read/write interface

Tty device gets only read/write calls, but console retains
getchar/putchar for convenience.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2018-10-23 21:15:46 +03:00 committed by Anas Nashif
commit 6203020bfd
3 changed files with 136 additions and 20 deletions

View file

@ -7,6 +7,7 @@
#ifndef ZEPHYR_INCLUDE_CONSOLE_H_
#define ZEPHYR_INCLUDE_CONSOLE_H_
#include <sys/types.h>
#include <zephyr/types.h>
#include <kernel.h>
@ -79,24 +80,31 @@ static inline void tty_set_tx_timeout(struct tty_serial *tty, s32_t timeout)
}
/**
* @brief Input a character from a tty device.
* @brief Read data from a tty device.
*
* @param tty tty device structure
* @return >=0, an input character
* <0, an error (e.g. -EAGAIN if timeout expired)
* @param buf buffer to read data to
* @param size maximum number of bytes to read
* @return >0, number of actually read bytes (can be less than size param)
* =0, for EOF-like condition (e.g., break signalled)
* <0, in case of error (e.g. -EAGAIN if timeout expired). errno
* variable is also set.
*/
int tty_getchar(struct tty_serial *tty);
ssize_t tty_read(struct tty_serial *tty, void *buf, size_t size);
/**
* @brief Output a character from to tty device.
* @brief Write data to tty device.
*
* @param tty tty device structure
* @param c character to output
* @return 0 if ok, <0 if error
* @param buf buffer containg data
* @param size maximum number of bytes to write
* @return =>0, number of actually written bytes (can be less than size param)
* <0, in case of error (e.g. -EAGAIN if timeout expired). errno
* variable is also set.
*/
int tty_putchar(struct tty_serial *tty, u8_t c);
ssize_t tty_write(struct tty_serial *tty, const void *buf, size_t size);
/** @brief Initialize console_getchar()/putchar() calls.
/** @brief Initialize console device.
*
* This function should be called once to initialize pull-style
* access to console via console_getchar() function and buffered
@ -108,6 +116,31 @@ int tty_putchar(struct tty_serial *tty, u8_t c);
*/
void console_init(void);
/**
* @brief Read data from console.
*
* @param dummy ignored, present to follow read() prototype
* @param buf buffer to read data to
* @param size maximum number of bytes to read
* @return >0, number of actually read bytes (can be less than size param)
* =0, in case of EOF
* <0, in case of error (e.g. -EAGAIN if timeout expired). errno
* variable is also set.
*/
ssize_t console_read(void *dummy, void *buf, size_t size);
/**
* @brief Write data to console.
*
* @param dummy ignored, present to follow write() prototype
* @param buf buffer to write data to
* @param size maximum number of bytes to write
* @return =>0, number of actually written bytes (can be less than size param)
* <0, in case of error (e.g. -EAGAIN if timeout expired). errno
* variable is also set.
*/
ssize_t console_write(void *dummy, const void *buf, size_t size);
/** @brief Get next char from console input buffer.
*
* Return next input character from console. If no characters available,
@ -118,16 +151,17 @@ void console_init(void);
* Zephyr callback-based console input processing, shell subsystem,
* or console_getline().
*
* @return A character read, including control characters.
* @return 0-255: a character read, including control characters.
* <0: error occured.
*/
u8_t console_getchar(void);
int console_getchar(void);
/** @brief Output a char to console (buffered).
*
* Puts a character into console output buffer. It will be sent
* to a console asynchronously, e.g. using an IRQ handler.
*
* @return -1 on output buffer overflow, otherwise 0.
* @return <0 on error, otherwise 0.
*/
int console_putchar(char c);

View file

@ -13,15 +13,36 @@ static struct tty_serial console_serial;
static u8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE];
static u8_t console_txbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE];
int console_putchar(char c)
ssize_t console_write(void *dummy, const void *buf, size_t size)
{
return tty_putchar(&console_serial, (u8_t)c);
ARG_UNUSED(dummy);
return tty_write(&console_serial, buf, size);
}
u8_t console_getchar(void)
ssize_t console_read(void *dummy, void *buf, size_t size)
{
/* Console works in blocking mode, so we don't expect an error here */
return (u8_t)tty_getchar(&console_serial);
ARG_UNUSED(dummy);
return tty_read(&console_serial, buf, size);
}
int console_putchar(char c)
{
return tty_write(&console_serial, &c, 1);
}
int console_getchar(void)
{
u8_t c;
int res;
res = tty_read(&console_serial, &c, 1);
if (res < 0) {
return res;
}
return c;
}
void console_init(void)

View file

@ -69,7 +69,7 @@ static int tty_irq_input_hook(struct tty_serial *tty, u8_t c)
return 1;
}
int tty_putchar(struct tty_serial *tty, u8_t c)
static int tty_putchar(struct tty_serial *tty, u8_t c)
{
unsigned int key;
int tx_next;
@ -87,7 +87,7 @@ int tty_putchar(struct tty_serial *tty, u8_t c)
}
if (tx_next == tty->tx_get) {
irq_unlock(key);
return -1;
return -ENOSPC;
}
tty->tx_ringbuf[tty->tx_put] = c;
@ -98,7 +98,37 @@ int tty_putchar(struct tty_serial *tty, u8_t c)
return 0;
}
int tty_getchar(struct tty_serial *tty)
ssize_t tty_write(struct tty_serial *tty, const void *buf, size_t size)
{
const u8_t *p = buf;
size_t out_size = 0;
int res = 0;
while (size--) {
res = tty_putchar(tty, *p++);
if (res < 0) {
/* If we didn't transmit anything, return the error. */
if (out_size == 0) {
errno = -res;
return res;
}
/*
* Otherwise, return how much we transmitted. If error
* was transient (like EAGAIN), on next call user might
* not even get it. And if it's non-transient, they'll
* get it on the next call.
*/
return out_size;
}
out_size++;
}
return out_size;
}
static int tty_getchar(struct tty_serial *tty)
{
unsigned int key;
u8_t c;
@ -119,6 +149,37 @@ int tty_getchar(struct tty_serial *tty)
return c;
}
ssize_t tty_read(struct tty_serial *tty, void *buf, size_t size)
{
u8_t *p = buf;
size_t out_size = 0;
int res = 0;
while (size--) {
res = tty_getchar(tty);
if (res < 0) {
/* If we didn't transmit anything, return the error. */
if (out_size == 0) {
errno = -res;
return res;
}
/*
* Otherwise, return how much we transmitted. If error
* was transient (like EAGAIN), on next call user might
* not even get it. And if it's non-transient, they'll
* get it on the next call.
*/
return out_size;
}
*p++ = (u8_t)res;
out_size++;
}
return out_size;
}
void tty_init(struct tty_serial *tty, struct device *uart_dev,
u8_t *rxbuf, u16_t rxbuf_sz,
u8_t *txbuf, u16_t txbuf_sz)