#ifndef AVREMU_SUBPROCESS_H_ #define AVREMU_SUBPROCESS_H_ #include "hardware.h" #include "ipc.h" #include "util.h" #include /* Instance of an emulated device on the controlling host process. */ struct avremu_host_instance { /* Type of microcontroller we are emulating. */ enum avr_setup_type type; /* PID of the device process. */ pid_t device_pid; /* Is the device subprocess running? */ bool device_running; struct ipc_tx msg_to_device; struct ipc_rx msg_from_device; struct ipc_rx status_from_device; }; /* Instance of an emulated device. * This is the process running the actual code. */ struct avremu_device_instance { /* Type of microcontroller we are emulating. */ enum avr_setup_type type; struct ipc_tx msg_to_host; struct ipc_rx msg_from_host; struct ipc_tx status_to_host; }; int avremu_instance_create(struct avremu_host_instance *host, enum avr_setup_type type); void avremu_instance_destroy(struct avremu_host_instance *host); enum avrmsg_to_device_type { DEVMSG_LOADFLASH, /* Load a binary flash image. */ DEVMSG_RESET, /* Reset the microcontroller. */ }; struct avrmsg_to_device { enum avrmsg_to_device_type msg; union { uint16_t size; }; }; static inline int sendmsg_to_device(struct avremu_host_instance *host, const struct avrmsg_to_device *msg) { return ipc_message_send(&host->msg_to_device, msg, sizeof(*msg), 1); } static inline int sendnotify_to_device(struct avremu_host_instance *host, enum avrmsg_to_device_type msg) { struct avrmsg_to_device m = { .msg = msg, }; return sendmsg_to_device(host, &m); } static inline int pollmsg_from_host(struct avremu_device_instance *dev, struct avrmsg_to_device *msg) { return ipc_message_poll(&dev->msg_from_host, msg, sizeof(*msg)); } enum avrmsg_to_host_type { HOSTMSG_READY, /* Initialization complete. */ HOSTMSG_EXIT, /* The device process exited. */ }; struct avrmsg_to_host { enum avrmsg_to_host_type msg; }; static inline int sendmsg_to_host(struct avremu_device_instance *dev, const struct avrmsg_to_host *msg, bool read_result) { return ipc_message_send(&dev->msg_to_host, msg, sizeof(*msg), read_result); } static inline int sendnotify_to_host(struct avremu_device_instance *dev, enum avrmsg_to_host_type msg) { struct avrmsg_to_host m = { .msg = msg, }; return sendmsg_to_host(dev, &m, 0); } static inline int pollmsg_from_device(struct avremu_host_instance *host, struct avrmsg_to_host *msg) { return ipc_message_poll(&host->msg_from_device, msg, sizeof(*msg)); } #endif /* AVREMU_SUBPROCESS_H_ */