Bugfixes for serial read rpc. Using kernel sys_getchar for dummy terminal read. Added silly shell to hello.c
This commit is contained in:
parent
8e5760627e
commit
62af3cbd65
@ -145,4 +145,34 @@ struct aos_rpc *aos_rpc_get_process_channel(void);
|
|||||||
*/
|
*/
|
||||||
struct aos_rpc *aos_rpc_get_serial_channel(void);
|
struct aos_rpc *aos_rpc_get_serial_channel(void);
|
||||||
|
|
||||||
|
// MARKER SHELL: remove these temprorary functions
|
||||||
|
static inline size_t dummy_terminal_write(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
err = sys_print(buf, len);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
static inline size_t dummy_terminal_read(char *buf, size_t len)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
// we need this for now cause sys_getchar is blocking and not even allowing other processes to run
|
||||||
|
if(len > 1) len = 1;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < len; ++i) {
|
||||||
|
err = sys_getchar(&buf[i]);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _LIB_BARRELFISH_AOS_MESSAGES_H
|
#endif // _LIB_BARRELFISH_AOS_MESSAGES_H
|
||||||
|
|||||||
@ -146,8 +146,10 @@ aos_rpc_serial_write(struct aos_rpc *rpc, const char *buf, size_t buf_len) {
|
|||||||
NULL, NULL, &written_bytes, NULL
|
NULL, NULL, &written_bytes, NULL
|
||||||
);
|
);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "Failed to write the full buffer");
|
||||||
return total_bytes;
|
return total_bytes;
|
||||||
}
|
}
|
||||||
|
assert(written_bytes <= chunk_len);
|
||||||
|
|
||||||
total_bytes += written_bytes;
|
total_bytes += written_bytes;
|
||||||
|
|
||||||
@ -176,13 +178,15 @@ aos_rpc_serial_read(struct aos_rpc *rpc, char *buf, size_t buf_len) {
|
|||||||
|
|
||||||
size_t read_bytes;
|
size_t read_bytes;
|
||||||
err = do_aos_rpc(
|
err = do_aos_rpc(
|
||||||
rpc, RPC_MTYPE_SERIAL_WRITE,
|
rpc, RPC_MTYPE_SERIAL_READ,
|
||||||
NULL_CAP, 0, chunk_len, 0,
|
NULL_CAP, 0, chunk_len, 0,
|
||||||
NULL, NULL, &read_bytes, NULL
|
NULL, &read_bytes, NULL, NULL
|
||||||
);
|
);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "Failed to read the full buffer");
|
||||||
return total_bytes;
|
return total_bytes;
|
||||||
}
|
}
|
||||||
|
assert(read_bytes <= chunk_len);
|
||||||
|
|
||||||
memcpy(buf, rpc->shared_mem, read_bytes);
|
memcpy(buf, rpc->shared_mem, read_bytes);
|
||||||
total_bytes += read_bytes;
|
total_bytes += read_bytes;
|
||||||
|
|||||||
@ -64,24 +64,24 @@ static void libc_assert(const char *expression, const char *file,
|
|||||||
sys_print(buf, len < sizeof(buf) ? len : sizeof(buf));
|
sys_print(buf, len < sizeof(buf) ? len : sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((__used__))
|
// __attribute__((__used__))
|
||||||
static size_t syscall_terminal_write(const char *buf, size_t len)
|
// static size_t syscall_terminal_write(const char *buf, size_t len)
|
||||||
{
|
// {
|
||||||
if(len) {
|
// if(len) {
|
||||||
errval_t err = sys_print(buf, len);
|
// errval_t err = sys_print(buf, len);
|
||||||
if (err_is_fail(err)) {
|
// if (err_is_fail(err)) {
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return len;
|
// return len;
|
||||||
}
|
// }
|
||||||
|
|
||||||
__attribute__((__used__))
|
// __attribute__((__used__))
|
||||||
static size_t dummy_terminal_read(char *buf, size_t len)
|
// static size_t dummy_terminal_read(char *buf, size_t len)
|
||||||
{
|
// {
|
||||||
debug_printf("Terminal read NYI!\n");
|
// debug_printf("Terminal read NYI!\n");
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static void handle_init_recv(void *arg)
|
static void handle_init_recv(void *arg)
|
||||||
{
|
{
|
||||||
@ -101,7 +101,6 @@ static void handle_init_recv(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rueegges: allow partial write
|
|
||||||
static size_t aos_terminal_write(const char *buf, size_t len)
|
static size_t aos_terminal_write(const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
if(len == 0) return 0;
|
if(len == 0) return 0;
|
||||||
@ -115,7 +114,6 @@ static size_t aos_terminal_write(const char *buf, size_t len)
|
|||||||
return aos_rpc_serial_write(rpc, buf, len);
|
return aos_rpc_serial_write(rpc, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rueegges: make more efficient?
|
|
||||||
static size_t aos_terminal_read(char *buf, size_t len)
|
static size_t aos_terminal_read(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
if(len == 0) return 0;
|
if(len == 0) return 0;
|
||||||
@ -136,10 +134,10 @@ void barrelfish_libc_glue_init(void)
|
|||||||
// what we need for that
|
// what we need for that
|
||||||
// TODO: change these to use the user-space serial driver if possible
|
// TODO: change these to use the user-space serial driver if possible
|
||||||
// TODO: set these functions
|
// TODO: set these functions
|
||||||
// MARKER SHELL: replace functions for init domain or UART driver with non-remote calls
|
// MARKER SHELL: init should also print through the UART driver
|
||||||
if(init_domain) {
|
if(init_domain) {
|
||||||
_libc_terminal_read_func = dummy_terminal_read;
|
_libc_terminal_read_func = dummy_terminal_read;
|
||||||
_libc_terminal_write_func = syscall_terminal_write;
|
_libc_terminal_write_func = dummy_terminal_write;
|
||||||
} else {
|
} else {
|
||||||
_libc_terminal_read_func = aos_terminal_read;
|
_libc_terminal_read_func = aos_terminal_read;
|
||||||
_libc_terminal_write_func = aos_terminal_write;
|
_libc_terminal_write_func = aos_terminal_write;
|
||||||
|
|||||||
@ -146,7 +146,7 @@ static errval_t handle_rpc_serial_getchar(
|
|||||||
// MARKER SHELL: Replace with UART call
|
// MARKER SHELL: Replace with UART call
|
||||||
*ret0 = getchar();
|
*ret0 = getchar();
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_serial_putchar(
|
static errval_t handle_rpc_serial_putchar(
|
||||||
@ -170,12 +170,8 @@ static errval_t handle_rpc_serial_write(
|
|||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
// MARKER SHELL: Replace with UART call
|
// MARKER SHELL: Replace with UART call
|
||||||
for (size_t i = 0; i < arg_size; ++i){
|
|
||||||
putchar(((char *)rpc->shared_mem)[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the number of characters written. Important for UART for early return when the buffer is full
|
// return the number of characters written. Important for UART for early return when the buffer is full
|
||||||
*ret0 = arg_size;
|
*ret0 = dummy_terminal_write((char *)rpc->shared_mem, arg_size);
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
@ -186,12 +182,8 @@ static errval_t handle_rpc_serial_read(
|
|||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
// MARKER SHELL: Replace with UART call
|
// MARKER SHELL: Replace with UART call
|
||||||
for (size_t i = 0; i < arg_size; ++i){
|
|
||||||
((char *)rpc->shared_mem)[i] = getchar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the number of characters read. Important for UART for early return when the buffer is empty
|
// return the number of characters read. Important for UART for early return when the buffer is empty
|
||||||
*ret0 = arg_size;
|
*ret_size = dummy_terminal_read((char *)rpc->shared_mem, arg0);
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,8 @@
|
|||||||
#define HELLO_CATCH_COMMAND "catch"
|
#define HELLO_CATCH_COMMAND "catch"
|
||||||
#define HELLO_SPAWN_COMMAND "spawn"
|
#define HELLO_SPAWN_COMMAND "spawn"
|
||||||
|
|
||||||
|
#define HELLO_CMDLINE_READ_LEN 100
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
@ -43,10 +45,39 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// try to spawn a child using rpc
|
// try to spawn a child using rpc
|
||||||
if (argc > 1 && !strncmp(argv[1], HELLO_SPAWN_COMMAND, sizeof(HELLO_SPAWN_COMMAND))) {
|
if (argc > 1 && !strncmp(argv[1], HELLO_SPAWN_COMMAND, sizeof(HELLO_SPAWN_COMMAND))) {
|
||||||
|
debug_printf("Waiting for 1s before showing shell because kernel getchar blocks everything!\n");
|
||||||
|
barrelfish_usleep(1000000);
|
||||||
|
|
||||||
|
debug_printf("# ");
|
||||||
|
// try to read cmdline from the terminal (a very very primitive shell)
|
||||||
|
char cmdline[HELLO_CMDLINE_READ_LEN+1];
|
||||||
|
for(int i = 0; i < HELLO_CMDLINE_READ_LEN; ++i) {
|
||||||
|
char c = getchar();
|
||||||
|
if(c == '\r') {
|
||||||
|
printf("\n");
|
||||||
|
cmdline[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(c == 0x7f) {
|
||||||
|
if (i > 0) {
|
||||||
|
printf("\b \b"); fflush(stdout);
|
||||||
|
}
|
||||||
|
--i;
|
||||||
|
if(i >= 0) --i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdline[i] = c;
|
||||||
|
printf("%c", c); fflush(stdout);
|
||||||
|
}
|
||||||
|
cmdline[HELLO_CMDLINE_READ_LEN] = '\0';
|
||||||
|
|
||||||
|
printf("Got command line: %s\n", cmdline);
|
||||||
|
|
||||||
// start process
|
// start process
|
||||||
domainid_t pid;
|
domainid_t pid;
|
||||||
rpc = aos_rpc_get_process_channel();
|
rpc = aos_rpc_get_process_channel();
|
||||||
err = aos_rpc_process_spawn(rpc, "hello Aurel Jan Sandro", 0, &pid);
|
err = aos_rpc_process_spawn(rpc, cmdline, 0, &pid);
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process");
|
||||||
printf("Started a new process!\n");
|
printf("Started a new process!\n");
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user