1 /* Code to manage the interface between the simulator and the kernel.
2 Copyright (C) 2005-2008, Jonathan Bachrach, Jacob Beal, and contributors
3 listed in the AUTHORS file in the MIT Proto distribution's top directory.
5 This file is part of MIT Proto, and is distributed under the terms of
6 the GNU General Public License, with a linking exception, as described
7 in the file LICENSE in the MIT Proto distribution's top directory. */
10 #include "spatialcomputer.h"
12 /*****************************************************************************
13 * SIMULATED HARDWARE *
14 *****************************************************************************/
15 // globals managed by set_vm_context
16 SimulatedHardware
* hardware
=NULL
;
19 SimulatedHardware::SimulatedHardware() {
20 for(int i
=0;i
<NUM_HARDWARE_FNS
;i
++) patch_table
[i
]=&base
;
23 void SimulatedHardware::patch(HardwarePatch
* p
, HardwareFunction fn
) {
27 // The kernel lives in C on a single device
28 // This function sets the globals that connect it to a simulated device.
29 void SimulatedHardware::set_vm_context(Device
* d
) {
33 is_debugging_val
= is_kernel_debug
&& d
->debug();
34 is_tracing_val
= is_kernel_trace
&& d
->debug();
35 is_script_debug_val
= is_kernel_debug_script
&& d
->debug();
38 /*****************************************************************************
39 * DEBUGGING INFORMATION *
40 *****************************************************************************/
41 // The kernel uses these to decide what information to post
42 // debug_id specifies which node is being debugged.
43 int debug_id
= -1; // -1 means all: we'll set it there and modulate is_X
44 int is_debugging_val
= 0;
45 int is_tracing_val
= 0;
46 int is_script_debug_val
= 0;
49 /*****************************************************************************
50 * KERNEL HARDWARE CALLOUTS *
51 *****************************************************************************/
53 void reinitHardware(void) { return; }
55 void mov (VEC_VAL
*val
)
56 { hardware
->patch_table
[MOV_FN
]->mov(val
); }
57 void flex (NUM_VAL val
)
58 { hardware
->patch_table
[FLEX_FN
]->flex(val
); }
59 NUM_VAL
cam_get (int k
)
60 { return hardware
->patch_table
[CAM_GET_FN
]->cam_get(k
); }
61 NUM_VAL
radius_get (VOID
)
62 { return hardware
->patch_table
[RADIUS_GET_FN
]->radius_get(); }
63 NUM_VAL
radius_set (NUM_VAL val
)
64 { return hardware
->patch_table
[RADIUS_SET_FN
]->radius_set(val
); }
65 void die (NUM_VAL val
)
66 { hardware
->patch_table
[DIE_FN
]->die(val
); }
67 void clone_machine (NUM_VAL val
)
68 { hardware
->patch_table
[CLONE_MACHINE_FN
]->clone_machine(val
); }
69 void set_r_led (NUM_VAL val
)
70 { hardware
->patch_table
[SET_R_LED_FN
]->set_r_led(val
); }
71 void set_g_led (NUM_VAL val
)
72 { hardware
->patch_table
[SET_G_LED_FN
]->set_g_led(val
); }
73 void set_b_led (NUM_VAL val
)
74 { hardware
->patch_table
[SET_B_LED_FN
]->set_b_led(val
); }
75 void set_probe (DATA
* d
, uint8_t p
)
76 { hardware
->patch_table
[SET_PROBE_FN
]->set_probe(d
,p
); }
78 void set_dt (NUM_VAL dt
)
79 { hardware
->patch_table
[SET_DT_FN
]->set_dt(dt
);}
81 void set_is_folding (BOOL val
, int k
)
82 { hardware
->patch_table
[SET_IS_FOLDING_FN
]->set_is_folding(val
,k
); }
83 BOOL
read_fold_complete (int val
)
84 { return hardware
->patch_table
[READ_FOLD_COMPLETE_FN
]->
85 read_fold_complete(val
); }
87 NUM_VAL
set_channel (NUM_VAL diffusion
, int k
)
88 { return hardware
->patch_table
[SET_CHANNEL_FN
]->set_channel(diffusion
,k
); }
89 NUM_VAL
read_channel (int k
)
90 { return hardware
->patch_table
[READ_CHANNEL_FN
]->read_channel(k
); }
91 NUM_VAL
drip_channel (NUM_VAL val
, int k
)
92 { return hardware
->patch_table
[DRIP_CHANNEL_FN
]->drip_channel(val
,k
); }
93 VEC_VAL
*grad_channel (int k
)
94 { return hardware
->patch_table
[GRAD_CHANNEL_FN
]->grad_channel(k
); }
95 NUM_VAL
read_radio_range (VOID
)
96 { return hardware
->patch_table
[READ_RADIO_RANGE_FN
]->read_radio_range(); }
97 NUM_VAL
read_light_sensor (VOID
)
98 { return hardware
->patch_table
[READ_LIGHT_SENSOR_FN
]->read_light_sensor(); }
99 NUM_VAL
read_microphone (VOID
)
100 { return hardware
->patch_table
[READ_MICROPHONE_FN
]->read_microphone(); }
101 NUM_VAL
read_temp (VOID
)
102 { return hardware
->patch_table
[READ_TEMP_FN
]->read_temp(); }
103 NUM_VAL
read_short (VOID
)
104 { return hardware
->patch_table
[READ_SHORT_FN
]->read_short(); }
105 NUM_VAL
read_sensor (uint8_t n
)
106 { return hardware
->patch_table
[READ_SENSOR_FN
]->read_sensor(n
); }
107 VEC_VAL
*read_coord_sensor (VOID
)
108 { return hardware
->patch_table
[READ_COORD_SENSOR_FN
]->read_coord_sensor(); }
109 VEC_VAL
*read_mouse_sensor (VOID
)
110 { return hardware
->patch_table
[READ_MOUSE_SENSOR_FN
]->read_mouse_sensor(); }
111 VEC_VAL
*read_ranger (VOID
)
112 { return hardware
->patch_table
[READ_RANGER_FN
]->read_ranger(); }
113 NUM_VAL
read_bearing (VOID
)
114 { return hardware
->patch_table
[READ_BEARING_FN
]->read_bearing(); }
115 NUM_VAL
read_speed (VOID
)
116 { return hardware
->patch_table
[READ_SPEED_FN
]->read_speed(); }
117 NUM_VAL
read_bump (VOID
)
118 { return hardware
->patch_table
[READ_BUMP_FN
]->read_bump(); }
119 NUM_VAL
read_button (uint8_t n
)
120 { return hardware
->patch_table
[READ_BUTTON_FN
]->read_button(n
); }
121 NUM_VAL
read_slider (uint8_t ikey
, uint8_t dkey
, NUM_VAL init
, NUM_VAL incr
,
122 NUM_VAL min
, NUM_VAL max
) {
123 return hardware
->patch_table
[READ_SLIDER_FN
]->
124 read_slider(ikey
,dkey
,init
,incr
,min
,max
);
126 void set_speak (NUM_VAL period
)
127 { hardware
->patch_table
[SET_SPEAK_FN
]->set_speak(period
); }
129 int radio_send_export (uint8_t version
, uint8_t timeout
, uint8_t n
,
130 uint8_t len
, COM_DATA
*buf
) {
131 return hardware
->patch_table
[RADIO_SEND_EXPORT_FN
]->
132 radio_send_export(version
,timeout
,n
,len
,buf
);
134 int radio_send_script_pkt (uint8_t version
, uint16_t n
, uint8_t pkt_num
,
136 return hardware
->patch_table
[RADIO_SEND_SCRIPT_PKT_FN
]->
137 radio_send_script_pkt(version
,n
,pkt_num
,script
);
139 int radio_send_digest (uint8_t version
, uint16_t script_len
, uint8_t *digest
) {
140 return hardware
->patch_table
[RADIO_SEND_DIGEST_FN
]->
141 radio_send_digest(version
,script_len
,digest
);
144 extern void my_platform_operation(uint8_t op
);
145 void platform_operation(uint8_t op
) { my_platform_operation(op
); }
147 /*****************************************************************************
148 * MEMORY MANAGEMENT *
149 *****************************************************************************/
150 // the simulator grants only a fixed-size block of memory to each machine
151 int MAX_MEM_SIZE
= 4*4096;
152 uint8_t* MEM_CONS(MACHINE
*m
) {
153 m
->memlen
= MAX_MEM_SIZE
;
154 m
->membuf
= (uint8_t*)calloc(m
->memlen
,1);
155 if(m
->membuf
==NULL
) uerror("Malloc failed for membuf!");
156 m
->saved_memptr
= m
->memptr
= 0;
159 void MEM_GROW (MACHINE
*m
) { uerror("OUT OF MEM"); }
161 MACHINE
* allocate_machine() {
162 MACHINE
* vm
= (MACHINE
*)calloc(1,sizeof(MACHINE
));
166 void deallocate_machine(MACHINE
** vm
) {
167 FREE(&(*vm
)->membuf
);
171 /*****************************************************************************
173 *****************************************************************************/
174 void post_data_to2 (char *str
, DATA
*d
, int verbosity
) {
176 if (d
->is_dead
) { // Note: we should never see "DEAD" markers
177 sprintf(buf
, "(DEAD "); strcat(str
, buf
);
181 sprintf(buf
, "%.2f", NUM_GET(d
)); strcat(str
, buf
); break; }
182 case FUN_TAG
: { // Note: a function is just an ID
183 sprintf(buf
, "F%d", FUN_GET(d
)); strcat(str
, buf
); break; }
186 VEC_VAL
*v
= VEC_GET(d
);
187 if(verbosity
>0) strcat(str
, "[");
188 for (i
= 0; i
< v
->n
; i
++) {
189 if (i
!= 0) strcat(str
, " ");
190 post_data_to2(str
, &v
->elts
[i
], verbosity
);
192 if(verbosity
>0) strcat(str
, "]");
196 sprintf(buf
, ")"); strcat(str
, buf
);
200 void post_stripped_data_to (char *str
, DATA
*d
) {
202 post_data_to2(str
, d
, 0);
205 void post_data_to (char *str
, DATA
*d
) {
207 post_data_to2(str
, d
, 1);
210 void post_data (DATA
*d
) {
212 post_data_to(buf
, d
);