1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#ifndef AVREMU_SUBPROCESS_H_
#define AVREMU_SUBPROCESS_H_
#include "hardware.h"
#include "ipc.h"
#include "util.h"
#include <unistd.h>
/* 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_ */
|