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:
parent
9d3b48fd48
commit
6203020bfd
3 changed files with 136 additions and 20 deletions
|
@ -7,6 +7,7 @@
|
||||||
#ifndef ZEPHYR_INCLUDE_CONSOLE_H_
|
#ifndef ZEPHYR_INCLUDE_CONSOLE_H_
|
||||||
#define ZEPHYR_INCLUDE_CONSOLE_H_
|
#define ZEPHYR_INCLUDE_CONSOLE_H_
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <kernel.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
|
* @param tty tty device structure
|
||||||
* @return >=0, an input character
|
* @param buf buffer to read data to
|
||||||
* <0, an error (e.g. -EAGAIN if timeout expired)
|
* @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 tty tty device structure
|
||||||
* @param c character to output
|
* @param buf buffer containg data
|
||||||
* @return 0 if ok, <0 if error
|
* @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
|
* This function should be called once to initialize pull-style
|
||||||
* access to console via console_getchar() function and buffered
|
* 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);
|
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.
|
/** @brief Get next char from console input buffer.
|
||||||
*
|
*
|
||||||
* Return next input character from console. If no characters available,
|
* 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,
|
* Zephyr callback-based console input processing, shell subsystem,
|
||||||
* or console_getline().
|
* 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).
|
/** @brief Output a char to console (buffered).
|
||||||
*
|
*
|
||||||
* Puts a character into console output buffer. It will be sent
|
* Puts a character into console output buffer. It will be sent
|
||||||
* to a console asynchronously, e.g. using an IRQ handler.
|
* 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);
|
int console_putchar(char c);
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,36 @@ static struct tty_serial console_serial;
|
||||||
static u8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE];
|
static u8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE];
|
||||||
static u8_t console_txbuf[CONFIG_CONSOLE_PUTCHAR_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 */
|
ARG_UNUSED(dummy);
|
||||||
return (u8_t)tty_getchar(&console_serial);
|
|
||||||
|
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)
|
void console_init(void)
|
||||||
|
|
|
@ -69,7 +69,7 @@ static int tty_irq_input_hook(struct tty_serial *tty, u8_t c)
|
||||||
return 1;
|
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;
|
unsigned int key;
|
||||||
int tx_next;
|
int tx_next;
|
||||||
|
@ -87,7 +87,7 @@ int tty_putchar(struct tty_serial *tty, u8_t c)
|
||||||
}
|
}
|
||||||
if (tx_next == tty->tx_get) {
|
if (tx_next == tty->tx_get) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
return -1;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty->tx_ringbuf[tty->tx_put] = c;
|
tty->tx_ringbuf[tty->tx_put] = c;
|
||||||
|
@ -98,7 +98,37 @@ int tty_putchar(struct tty_serial *tty, u8_t c)
|
||||||
return 0;
|
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;
|
unsigned int key;
|
||||||
u8_t c;
|
u8_t c;
|
||||||
|
@ -119,6 +149,37 @@ int tty_getchar(struct tty_serial *tty)
|
||||||
return c;
|
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,
|
void tty_init(struct tty_serial *tty, struct device *uart_dev,
|
||||||
u8_t *rxbuf, u16_t rxbuf_sz,
|
u8_t *rxbuf, u16_t rxbuf_sz,
|
||||||
u8_t *txbuf, u16_t txbuf_sz)
|
u8_t *txbuf, u16_t txbuf_sz)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue