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