forked from M-Labs/artiq
corecom: exception support
This commit is contained in:
parent
0c9f05dc80
commit
3de24619b2
@ -70,4 +70,4 @@ class Core:
|
||||
binary = get_runtime_binary(self.runtime_env, func_def)
|
||||
self.core_com.load(binary)
|
||||
self.core_com.run(func_def.name)
|
||||
self.core_com.serve(rpc_map)
|
||||
self.core_com.serve(rpc_map, exception_map)
|
||||
|
@ -25,9 +25,14 @@ class CoreCom:
|
||||
def run(self, kname):
|
||||
print("RUN: "+kname)
|
||||
|
||||
def serve(self, rpc_map):
|
||||
def serve(self, rpc_map, exception_map):
|
||||
print("================")
|
||||
print(" RPC map")
|
||||
print("================")
|
||||
for k, v in sorted(rpc_map.items(), key=itemgetter(0)):
|
||||
print(str(k)+" -> "+str(v))
|
||||
print("================")
|
||||
print(" Exception map")
|
||||
print("================")
|
||||
for k, v in sorted(exception_map.items(), key=itemgetter(0)):
|
||||
print(str(k)+" -> "+str(v))
|
||||
|
@ -31,8 +31,9 @@ class _D2HMsgType(Enum):
|
||||
CRC_FAILED = 6
|
||||
OBJECT_UNRECOGNIZED = 7
|
||||
KERNEL_FINISHED = 8
|
||||
KERNEL_STARTUP_FAILED = 9
|
||||
RPC_REQUEST = 10
|
||||
KERNEL_EXCEPTION = 9
|
||||
KERNEL_STARTUP_FAILED = 10
|
||||
RPC_REQUEST = 11
|
||||
|
||||
|
||||
def _write_exactly(f, data):
|
||||
@ -141,12 +142,10 @@ class CoreCom:
|
||||
_write_exactly(self.port, struct.pack("b", ord(c)))
|
||||
logger.debug("running kernel: {}".format(kname))
|
||||
|
||||
def serve(self, rpc_map):
|
||||
def serve(self, rpc_map, exception_map):
|
||||
while True:
|
||||
msg = self._get_device_msg()
|
||||
if msg == _D2HMsgType.KERNEL_FINISHED:
|
||||
return
|
||||
elif msg == _D2HMsgType.RPC_REQUEST:
|
||||
if msg == _D2HMsgType.RPC_REQUEST:
|
||||
rpc_num, n_args = struct.unpack(">hb",
|
||||
_read_exactly(self.port, 3))
|
||||
args = []
|
||||
@ -160,5 +159,11 @@ class CoreCom:
|
||||
_write_exactly(self.port, struct.pack(">l", r))
|
||||
logger.debug("rpc service: {} ({}) == {}".format(
|
||||
rpc_num, args, r))
|
||||
elif msg == _D2HMsgType.KERNEL_EXCEPTION:
|
||||
(exception_num, ) = struct.unpack(">l",
|
||||
_read_exactly(self.port, 4))
|
||||
raise exception_map[exception_num]
|
||||
elif msg == _D2HMsgType.KERNEL_FINISHED:
|
||||
return
|
||||
else:
|
||||
raise IOError("Incorrect request from device: "+str(msg))
|
||||
|
@ -1,8 +1,14 @@
|
||||
#ifndef __CORECOM_H
|
||||
#define __CORECOM_H
|
||||
|
||||
enum {
|
||||
KERNEL_RUN_FINISHED,
|
||||
KERNEL_RUN_EXCEPTION,
|
||||
KERNEL_RUN_STARTUP_FAILED
|
||||
};
|
||||
|
||||
typedef int (*object_loader)(void *, int);
|
||||
typedef int (*kernel_runner)(const char *);
|
||||
typedef int (*kernel_runner)(const char *, int *);
|
||||
|
||||
void corecom_serve(object_loader load_object, kernel_runner run_kernel);
|
||||
int corecom_rpc(int rpc_num, int n_args, ...);
|
||||
|
@ -25,6 +25,7 @@ enum {
|
||||
MSGTYPE_OBJECT_UNRECOGNIZED,
|
||||
|
||||
MSGTYPE_KERNEL_FINISHED,
|
||||
MSGTYPE_KERNEL_EXCEPTION,
|
||||
MSGTYPE_KERNEL_STARTUP_FAILED,
|
||||
|
||||
MSGTYPE_RPC_REQUEST,
|
||||
@ -114,7 +115,7 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
|
||||
int length;
|
||||
int i;
|
||||
char kernel_name[256];
|
||||
int r;
|
||||
int r, eid;
|
||||
|
||||
length = receive_int();
|
||||
if(length > (sizeof(kernel_name)-1)) {
|
||||
@ -125,8 +126,22 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
|
||||
kernel_name[i] = receive_char();
|
||||
kernel_name[length] = 0;
|
||||
|
||||
r = run_kernel(kernel_name);
|
||||
send_char(r ? MSGTYPE_KERNEL_FINISHED : MSGTYPE_KERNEL_STARTUP_FAILED);
|
||||
r = run_kernel(kernel_name, &eid);
|
||||
switch(r) {
|
||||
case KERNEL_RUN_FINISHED:
|
||||
send_char(MSGTYPE_KERNEL_FINISHED);
|
||||
break;
|
||||
case KERNEL_RUN_EXCEPTION:
|
||||
send_char(MSGTYPE_KERNEL_EXCEPTION);
|
||||
send_int(eid);
|
||||
break;
|
||||
case KERNEL_RUN_STARTUP_FAILED:
|
||||
send_char(MSGTYPE_KERNEL_STARTUP_FAILED);
|
||||
break;
|
||||
default:
|
||||
corecom_log("BUG: run_kernel returned unexpected value '%d'", r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void corecom_serve(object_loader load_object, kernel_runner run_kernel)
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "corecom.h"
|
||||
#include "elf_loader.h"
|
||||
#include "exceptions.h"
|
||||
#include "services.h"
|
||||
#include "rtio.h"
|
||||
#include "dds.h"
|
||||
@ -64,19 +65,28 @@ static int load_object(void *buffer, int length)
|
||||
|
||||
typedef void (*kernel_function)(void);
|
||||
|
||||
static int run_kernel(const char *kernel_name)
|
||||
static int run_kernel(const char *kernel_name, int *eid)
|
||||
{
|
||||
kernel_function k;
|
||||
struct exception_env ee;
|
||||
int exception_occured;
|
||||
|
||||
k = find_symbol(symtab, kernel_name);
|
||||
if(k == NULL) {
|
||||
corecom_log("Failed to find kernel entry point '%s' in object", kernel_name);
|
||||
return 0;
|
||||
return KERNEL_RUN_STARTUP_FAILED;
|
||||
}
|
||||
|
||||
exception_occured = exception_catch(&ee, eid);
|
||||
if(exception_occured)
|
||||
return KERNEL_RUN_EXCEPTION;
|
||||
else {
|
||||
rtio_init();
|
||||
flush_cpu_icache();
|
||||
k();
|
||||
exception_pop();
|
||||
return KERNEL_RUN_FINISHED;
|
||||
}
|
||||
rtio_init();
|
||||
flush_cpu_icache();
|
||||
k();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void blink_led(void)
|
||||
|
Loading…
Reference in New Issue
Block a user