Introduce 'Uart::Session' interface

The new 'Uart::Session' interface is an extension of the
'Terminal::Session' interface that allows for configuring UART-specific
parameters, i.e., the baud rate.
This commit is contained in:
Norman Feske 2012-10-29 12:30:29 +01:00
parent 0c76bc9cfd
commit 5b4edeb031
12 changed files with 233 additions and 57 deletions

View File

@ -17,35 +17,37 @@
#include <terminal_session/client.h> #include <terminal_session/client.h>
#include <base/connection.h> #include <base/connection.h>
#include <base/printf.h>
namespace Terminal { namespace Terminal {
struct Connection : Genode::Connection<Session>, Session_client struct Connection : Genode::Connection<Session>, Session_client
{ {
Connection() /**
: * Wait for connection-established signal
Genode::Connection<Session>(session("ram_quota=%zd", 2*4096)), */
Session_client(cap()) static void wait_for_connection(Genode::Capability<Session> cap)
{ {
using namespace Genode; using namespace Genode;
/*
* Wait for connection-established signal
*/
/* create signal receiver, just for the single signal */ /* create signal receiver, just for the single signal */
Signal_context sig_ctx; Signal_context sig_ctx;
Signal_receiver sig_rec; Signal_receiver sig_rec;
Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx); Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
/* register signal handler */ /* register signal handler */
call<Rpc_connected_sigh>(sig_cap); cap.call<Rpc_connected_sigh>(sig_cap);
/* wati for signal */ /* wati for signal */
sig_rec.wait_for_signal(); sig_rec.wait_for_signal();
sig_rec.dissolve(&sig_ctx); sig_rec.dissolve(&sig_ctx);
} }
Connection()
:
Genode::Connection<Session>(session("ram_quota=%zd", 2*4096)),
Session_client(cap())
{
wait_for_connection(cap());
}
}; };
} }

View File

@ -0,0 +1,82 @@
/*
* \brief Client-side UART session interface
* \author Norman Feske
* \date 2012-10-29
*/
/*
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__UART_SESSION__CLIENT_H_
#define _INCLUDE__UART_SESSION__CLIENT_H_
/* Genode includes */
#include <uart_session/uart_session.h>
#include <terminal_session/client.h>
namespace Uart {
class Session_client : public Genode::Rpc_client<Session>
{
private:
Terminal::Session_client _terminal;
public:
Session_client(Genode::Capability<Session> cap)
:
Genode::Rpc_client<Session>(cap), _terminal(cap)
{ }
/********************
** UART interface **
********************/
void baud_rate(Genode::size_t bits_per_second)
{
call<Rpc_baud_rate>(bits_per_second);
}
/************************
** Terminal interface **
************************/
Size size() { return _terminal.size(); }
bool avail() { return _terminal.avail(); }
Genode::size_t read(void *buf, Genode::size_t buf_size)
{
return _terminal.read(buf, buf_size);
}
Genode::size_t write(void const *buf, Genode::size_t num_bytes)
{
return _terminal.write(buf, num_bytes);
}
void connected_sigh(Genode::Signal_context_capability cap)
{
_terminal.connected_sigh(cap);
}
void read_avail_sigh(Genode::Signal_context_capability cap)
{
_terminal.read_avail_sigh(cap);
}
Genode::size_t io_buffer_size() const
{
return _terminal.io_buffer_size();
}
};
}
#endif /* _INCLUDE__UART_SESSION__CLIENT_H_ */

View File

@ -0,0 +1,34 @@
/*
* \brief Connection to UART service
* \author Norman Feske
* \date 2012-10-29
*/
/*
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__UART_SESSION__CONNECTION_H_
#define _INCLUDE__UART_SESSION__CONNECTION_H_
#include <uart_session/client.h>
#include <terminal_session/connection.h>
namespace Uart {
struct Connection : Genode::Connection<Session>, Session_client
{
Connection()
:
Genode::Connection<Session>(session("ram_quota=%zd", 2*4096)),
Session_client(cap())
{
Terminal::Connection::wait_for_connection(cap());
}
};
}
#endif /* _INCLUDE__UART_SESSION__CONNECTION_H_ */

View File

@ -0,0 +1,45 @@
/*
* \brief UART session interface
* \author Norman Feske
* \date 2012-10-29
*
* The UART session interface is an extended Terminal session interface.
*/
/*
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__UART_SESSION__UART_SESSION_H_
#define _INCLUDE__UART_SESSION__UART_SESSION_H_
/* Genode includes */
#include <terminal_session/terminal_session.h>
namespace Uart {
using namespace Terminal;
struct Session : Terminal::Session
{
static const char *service_name() { return "Uart"; }
/**
* Set baud rate
*/
virtual void baud_rate(Genode::size_t bits_per_second) = 0;
/*******************
** RPC interface **
*******************/
GENODE_RPC(Rpc_baud_rate, void, baud_rate, Genode::size_t);
GENODE_RPC_INTERFACE_INHERIT(Terminal::Session, Rpc_baud_rate);
};
}
#endif /* _INCLUDE__UART_SESSION__UART_SESSION_H_ */

View File

@ -41,7 +41,10 @@ set config {
</start> </start>
<start name="uart_drv"> <start name="uart_drv">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides><service name="Terminal"/></provides> <provides>
<service name="Uart"/>
<service name="Terminal"/>
</provides>
<config> <config>
<policy label="test-uart1" uart="1"/> <policy label="test-uart1" uart="1"/>
<policy label="test-uart2" uart="2"/> <policy label="test-uart2" uart="2"/>

View File

@ -22,10 +22,10 @@
#include <io_port_session/connection.h> #include <io_port_session/connection.h>
/* local includes */ /* local includes */
#include "terminal_driver.h" #include "uart_driver.h"
class I8250 : public Terminal::Driver, public Genode::Irq_handler class I8250 : public Uart::Driver, public Genode::Irq_handler
{ {
private: private:
@ -84,7 +84,7 @@ class I8250 : public Terminal::Driver, public Genode::Irq_handler
_inb<MSR>(); _inb<MSR>();
} }
Terminal::Char_avail_callback &_char_avail_callback; Uart::Char_avail_callback &_char_avail_callback;
enum { IRQ_STACK_SIZE = 4096 }; enum { IRQ_STACK_SIZE = 4096 };
Genode::Irq_activation _irq_activation; Genode::Irq_activation _irq_activation;
@ -95,7 +95,7 @@ class I8250 : public Terminal::Driver, public Genode::Irq_handler
* Constructor * Constructor
*/ */
I8250(unsigned port_base, int irq_number, unsigned baud, I8250(unsigned port_base, int irq_number, unsigned baud,
Terminal::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
: :
_port_base(port_base), _port_base(port_base),
_io_port(port_base, 0xf), _io_port(port_base, 0xf),

View File

@ -18,7 +18,7 @@
#include <cap_session/connection.h> #include <cap_session/connection.h>
#include "i8250.h" #include "i8250.h"
#include "terminal_component.h" #include "uart_component.h"
int main(int argc, char **argv) int main(int argc, char **argv)
@ -28,9 +28,9 @@ int main(int argc, char **argv)
printf("--- i8250 UART driver started ---\n"); printf("--- i8250 UART driver started ---\n");
/** /**
* Factory used by 'Terminal::Root' at session creation/destruction time * Factory used by 'Uart::Root' at session creation/destruction time
*/ */
struct I8250_driver_factory : Terminal::Driver_factory struct I8250_driver_factory : Uart::Driver_factory
{ {
enum { UART_NUM = 4 }; enum { UART_NUM = 4 };
I8250 *created[UART_NUM]; I8250 *created[UART_NUM];
@ -62,15 +62,15 @@ int main(int argc, char **argv)
created[i] = 0; created[i] = 0;
} }
Terminal::Driver *create(unsigned index, Uart::Driver *create(unsigned index,
Terminal::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
{ {
/* /*
* We assume the underlying kernel uses UART0 and, therefore, start at * We assume the underlying kernel uses UART0 and, therefore, start at
* index 1 for the user-level driver. * index 1 for the user-level driver.
*/ */
if (index < 1 || index >= UART_NUM) if (index < 1 || index >= UART_NUM)
throw Terminal::Driver_factory::Not_available(); throw Uart::Driver_factory::Not_available();
I8250 *uart = created[index]; I8250 *uart = created[index];
@ -88,7 +88,7 @@ int main(int argc, char **argv)
return uart; return uart;
} }
void destroy(Terminal::Driver *driver) { /* TODO */ } void destroy(Uart::Driver *driver) { /* TODO */ }
} driver_factory; } driver_factory;
@ -96,7 +96,7 @@ int main(int argc, char **argv)
static Cap_connection cap; static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "uart_ep"); static Rpc_entrypoint ep(&cap, STACK_SIZE, "uart_ep");
static Terminal::Root uart_root(&ep, env()->heap(), driver_factory); static Uart::Root uart_root(&ep, env()->heap(), driver_factory);
env()->parent()->announce(ep.manage(&uart_root)); env()->parent()->announce(ep.manage(&uart_root));
sleep_forever(); sleep_forever();

View File

@ -20,7 +20,7 @@
/* local includes */ /* local includes */
#include "pl011.h" #include "pl011.h"
#include "terminal_component.h" #include "uart_component.h"
int main(int argc, char **argv) int main(int argc, char **argv)
@ -30,9 +30,9 @@ int main(int argc, char **argv)
printf("--- PL011 UART driver started ---\n"); printf("--- PL011 UART driver started ---\n");
/** /**
* Factory used by 'Terminal::Root' at session creation/destruction time * Factory used by 'Uart::Root' at session creation/destruction time
*/ */
struct Pl011_driver_factory : Terminal::Driver_factory struct Pl011_driver_factory : Uart::Driver_factory
{ {
Pl011 *created[PL011_NUM]; Pl011 *created[PL011_NUM];
@ -45,15 +45,15 @@ int main(int argc, char **argv)
created[i] = 0; created[i] = 0;
} }
Terminal::Driver *create(unsigned index, Uart::Driver *create(unsigned index,
Terminal::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
{ {
/* /*
* We assume the underlying kernel uses UART0 and, therefore, start at * We assume the underlying kernel uses UART0 and, therefore, start at
* index 1 for the user-level driver. * index 1 for the user-level driver.
*/ */
if (index < 1 || index >= PL011_NUM) if (index < 1 || index >= PL011_NUM)
throw Terminal::Driver_factory::Not_available(); throw Uart::Driver_factory::Not_available();
Pl011_uart *cfg = &pl011_uart[index]; Pl011_uart *cfg = &pl011_uart[index];
Pl011 *uart = created[index]; Pl011 *uart = created[index];
@ -71,7 +71,7 @@ int main(int argc, char **argv)
return uart; return uart;
} }
void destroy(Terminal::Driver *driver) { /* TODO */ } void destroy(Uart::Driver *driver) { /* TODO */ }
} driver_factory; } driver_factory;
@ -79,7 +79,7 @@ int main(int argc, char **argv)
static Cap_connection cap; static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "uart_ep"); static Rpc_entrypoint ep(&cap, STACK_SIZE, "uart_ep");
static Terminal::Root uart_root(&ep, env()->heap(), driver_factory); static Uart::Root uart_root(&ep, env()->heap(), driver_factory);
env()->parent()->announce(ep.manage(&uart_root)); env()->parent()->announce(ep.manage(&uart_root));
sleep_forever(); sleep_forever();

View File

@ -22,9 +22,9 @@
#include <os/attached_io_mem_dataspace.h> #include <os/attached_io_mem_dataspace.h>
/* local includes */ /* local includes */
#include "terminal_driver.h" #include "uart_driver.h"
class Pl011 : public Terminal::Driver, public Genode::Irq_handler class Pl011 : public Uart::Driver, public Genode::Irq_handler
{ {
private: private:
@ -78,7 +78,7 @@ class Pl011 : public Terminal::Driver, public Genode::Irq_handler
Genode::Attached_io_mem_dataspace _io_mem; Genode::Attached_io_mem_dataspace _io_mem;
Genode::uint32_t volatile *_base; Genode::uint32_t volatile *_base;
Terminal::Char_avail_callback &_char_avail_callback; Uart::Char_avail_callback &_char_avail_callback;
enum { IRQ_STACK_SIZE = 4096 }; enum { IRQ_STACK_SIZE = 4096 };
Genode::Irq_activation _irq_activation; Genode::Irq_activation _irq_activation;
@ -100,7 +100,7 @@ class Pl011 : public Terminal::Driver, public Genode::Irq_handler
*/ */
Pl011(Genode::addr_t mmio_base, Genode::size_t mmio_size, Pl011(Genode::addr_t mmio_base, Genode::size_t mmio_size,
unsigned ibrd, unsigned fbrd, int irq_number, unsigned ibrd, unsigned fbrd, int irq_number,
Terminal::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
: :
_io_mem(mmio_base, mmio_size), _io_mem(mmio_base, mmio_size),
_base(_io_mem.local_addr<unsigned volatile>()), _base(_io_mem.local_addr<unsigned volatile>()),

View File

@ -11,8 +11,8 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#ifndef _TERMINAL_COMPONENT_H_ #ifndef _UART_COMPONENT_H_
#define _TERMINAL_COMPONENT_H_ #define _UART_COMPONENT_H_
/* Genode includes */ /* Genode includes */
#include <base/rpc_server.h> #include <base/rpc_server.h>
@ -20,16 +20,16 @@
#include <os/session_policy.h> #include <os/session_policy.h>
#include <os/attached_ram_dataspace.h> #include <os/attached_ram_dataspace.h>
#include <root/component.h> #include <root/component.h>
#include <terminal_session/terminal_session.h> #include <uart_session/uart_session.h>
/* local includes */ /* local includes */
#include "terminal_driver.h" #include "uart_driver.h"
namespace Terminal { namespace Uart {
using namespace Genode; using namespace Genode;
class Session_component : public Rpc_object<Terminal::Session, class Session_component : public Rpc_object<Uart::Session,
Session_component> Session_component>
{ {
private: private:
@ -45,7 +45,7 @@ namespace Terminal {
/** /**
* Functor informing the client about new data to read * Functor informing the client about new data to read
*/ */
struct Char_avail_callback : Terminal::Char_avail_callback struct Char_avail_callback : Uart::Char_avail_callback
{ {
Genode::Signal_context_capability sigh; Genode::Signal_context_capability sigh;
@ -57,15 +57,15 @@ namespace Terminal {
} _char_avail_callback; } _char_avail_callback;
Terminal::Driver_factory &_driver_factory; Uart::Driver_factory &_driver_factory;
Terminal::Driver &_driver; Uart::Driver &_driver;
public: public:
/** /**
* Constructor * Constructor
*/ */
Session_component(Terminal::Driver_factory &driver_factory, Session_component(Uart::Driver_factory &driver_factory,
unsigned index) unsigned index)
: :
_io_buffer(Genode::env()->ram_session(), IO_BUFFER_SIZE), _io_buffer(Genode::env()->ram_session(), IO_BUFFER_SIZE),
@ -74,6 +74,16 @@ namespace Terminal {
{ } { }
/****************************
** Uart session interface **
****************************/
void baud_rate(Genode::size_t bits_per_second)
{
PWRN("Setting the baud rate is not supported.");
}
/******************************** /********************************
** Terminal session interface ** ** Terminal session interface **
********************************/ ********************************/
@ -174,4 +184,4 @@ namespace Terminal {
}; };
} }
#endif /* _TERMINAL_COMPONENT_H_ */ #endif /* _UART_COMPONENT_H_ */

View File

@ -11,10 +11,10 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#ifndef _TERMINAL_DRIVER_H_ #ifndef _UART_DRIVER_H_
#define _TERMINAL_DRIVER_H_ #define _UART_DRIVER_H_
namespace Terminal { namespace Uart {
/** /**
* Functor, called by 'Driver' when data is ready for reading * Functor, called by 'Driver' when data is ready for reading
@ -27,7 +27,7 @@ namespace Terminal {
struct Driver struct Driver
{ {
/** /**
* Write character to terminal * Write character to UART
*/ */
virtual void put_char(char c) = 0; virtual void put_char(char c) = 0;
@ -37,7 +37,7 @@ namespace Terminal {
virtual bool char_avail() = 0; virtual bool char_avail() = 0;
/** /**
* Read character from terminal * Read character from UART
*/ */
virtual char get_char() = 0; virtual char get_char() = 0;
}; };
@ -72,4 +72,4 @@ namespace Terminal {
} }
#endif /* _TERMINAL_DRIVER_H_ */ #endif /* _UART_DRIVER_H_ */

View File

@ -13,7 +13,7 @@
#include <base/snprintf.h> #include <base/snprintf.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <terminal_session/connection.h> #include <uart_session/connection.h>
using namespace Genode; using namespace Genode;
@ -22,14 +22,14 @@ int main()
{ {
printf("--- UART test started ---\n"); printf("--- UART test started ---\n");
static Timer::Connection timer; static Timer::Connection timer;
static Terminal::Connection terminal; static Uart::Connection uart;
for (unsigned i = 0; ; ++i) { for (unsigned i = 0; ; ++i) {
static char buf[100]; static char buf[100];
int n = snprintf(buf, sizeof(buf), "UART test message %d\n", i); int n = snprintf(buf, sizeof(buf), "UART test message %d\n", i);
terminal.write(buf, n); uart.write(buf, n);
timer.msleep(2000); timer.msleep(2000);
} }