summaryrefslogtreecommitdiffstats
path: root/emulator/subprocess.h
blob: 04791ef8615154cad37251bf526b2b37da704f97 (plain)
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_ */
bues.ch cgit interface