checkpoint-arch.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "contiki.h"
00041 #include "lib/checkpoint.h"
00042
00043 #include "sys/rtimer.h"
00044 #include "sys/mt.h"
00045 #include "cfs/cfs.h"
00046 #include "cfs/cfs-coffee.h"
00047 #include "dev/leds.h"
00048 #include "dev/watchdog.h"
00049
00050 #include <io.h>
00051 #include <signal.h>
00052 #include <stdio.h>
00053
00054 #define DEBUG 1
00055 #if DEBUG
00056 #define PRINTF(...) printf(__VA_ARGS__)
00057 #else
00058 #define PRINTF(...)
00059 #endif
00060
00061 #define COMMAND_ROLLBACK 1
00062 #define COMMAND_CHECKPOINT 2
00063 #define COMMAND_TBR 3
00064
00065 #define DATA_AS_HEX 0
00066
00067 #define INCLUDE_RAM 1
00068 #define INCLUDE_TIMERS 1
00069 #define INCLUDE_LEDS 1
00070
00071
00072 #define RAM_START 0x1100
00073 #define RAM_END 0x30FF
00074
00075 #define STOP_TIMERS() TACTL &= ~(MC1); TBCTL &= ~(MC1); watchdog_stop();
00076 #define START_TIMERS() watchdog_start(); TACTL |= MC1; TBCTL |= MC1;
00077
00078 static struct mt_thread checkpoint_thread;
00079 static uint8_t preset_cmd;
00080 static int preset_fd;
00081
00082 typedef union {
00083 unsigned char u8[2];
00084 unsigned short u16;
00085 } word_union_t;
00086
00087
00088 static void
00089 write_byte(int fd, uint8_t c)
00090 {
00091 #if DATA_AS_HEX
00092 uint8_t hex[2];
00093 sprintf(hex, "%02x", c);
00094 if(cfs_write(fd, hex, 2) != 2) {
00095 printf("err #1\n");
00096 }
00097 #else
00098 if(cfs_write(fd, &c, 1) != 1) {
00099 printf("err #2\n");
00100 }
00101 #endif
00102 }
00103 #if 0
00104 static void
00105 write_array(int fd, unsigned char *mem, uint16_t len)
00106 {
00107 #if DATA_AS_HEX
00108 int i;
00109 for(i = 0; i < len; i++) {
00110 write_byte(fd, mem[i]);
00111 }
00112 #else
00113 cfs_write(fd, mem, len);
00114 #endif
00115 }
00116 #endif
00117
00118 static void
00119 write_word(int fd, uint16_t w)
00120 {
00121 word_union_t tmp;
00122 tmp.u16 = w;
00123 write_byte(fd, tmp.u8[0]);
00124 write_byte(fd, tmp.u8[1]);
00125 }
00126
00127 static uint8_t
00128 read_byte(int fd)
00129 {
00130 #if DATA_AS_HEX
00131 uint8_t hex[2];
00132
00133 cfs_read(fd, hex, 2);
00134
00135 if(hex[0] >= 'A' && hex[0] <= 'F') {
00136 hex[0] = (hex[0] - 'A' + 0xa);
00137 } else if(hex[0] >= 'a' && hex[0] <= 'f') {
00138 hex[0] = (hex[0] - 'a' + 0xa);
00139 } else {
00140 hex[0] = (hex[0] - '0');
00141 }
00142 if(hex[1] >= 'A' && hex[1] <= 'F') {
00143 hex[1] = (hex[1] - 'A' + 0xa);
00144 } else if(hex[1] >= 'a' && hex[1] <= 'f') {
00145 hex[1] = (hex[1] - 'a' + 0xa);
00146 } else {
00147 hex[1] = (hex[1] - '0');
00148 }
00149 return (uint8_t)((hex[0]<<4)&0xf0) | (hex[1]&0x0f);
00150 #else
00151 uint8_t c;
00152 cfs_read(fd, &c, 1);
00153 return c;
00154 #endif
00155 }
00156
00157 static uint16_t
00158 read_word(int fd)
00159 {
00160 word_union_t tmp;
00161 tmp.u8[0] = read_byte(fd);
00162 tmp.u8[1] = read_byte(fd);
00163 return tmp.u16;
00164 }
00165
00166 static void
00167 thread_checkpoint(int fd)
00168 {
00169 #if INCLUDE_RAM
00170 unsigned char *addr;
00171 uint16_t size = 0;
00172 unsigned char *thread_mem_start = (unsigned char *)&checkpoint_thread.thread.stack;
00173 unsigned char *thread_mem_end = thread_mem_start + sizeof(checkpoint_thread.thread.stack) - 1;
00174 unsigned char *coffee_mem_start = cfs_coffee_get_protected_mem(&size);
00175 unsigned char *coffee_mem_end = coffee_mem_start + size - 1;
00176 #endif
00177
00178
00179
00180
00181
00182 #if INCLUDE_RAM
00183 for(addr = (unsigned char *)RAM_START;
00184 addr < (unsigned char *)RAM_END;
00185 addr++) {
00186
00187 if((addr >= thread_mem_start && addr <= thread_mem_end)) {
00188
00189
00190 continue;
00191 }
00192
00193 if((addr >= coffee_mem_start && addr <= coffee_mem_end)) {
00194
00195
00196 continue;
00197 }
00198
00199
00200 write_byte(fd, *addr);
00201
00202 if(((int)addr % 512) == 0) {
00203 PRINTF(".");
00204 }
00205 }
00206
00207 #endif
00208
00209
00210 #if INCLUDE_TIMERS
00211 write_word(fd, TACTL);
00212 write_word(fd, TACCTL1);
00213 write_word(fd, TACCR1);
00214 write_word(fd, TAR);
00215
00216 write_word(fd, TBCTL);
00217 write_word(fd, TBCCTL1);
00218 write_word(fd, TBCCR1);
00219 write_word(fd, TBR);
00220 #endif
00221
00222
00223 #if INCLUDE_LEDS
00224 write_byte(fd, leds_arch_get());
00225 #endif
00226
00227
00228
00229
00230
00231 write_byte(fd, -1);
00232 }
00233
00234 static void
00235 thread_rollback(int fd)
00236 {
00237 #if INCLUDE_RAM
00238 unsigned char *addr;
00239 uint16_t size = 0;
00240 unsigned char *thread_mem_start = (unsigned char *)&checkpoint_thread.thread.stack;
00241 unsigned char *thread_mem_end = thread_mem_start + sizeof(checkpoint_thread.thread.stack) - 1;
00242 unsigned char *coffee_mem_start = cfs_coffee_get_protected_mem(&size);
00243 unsigned char *coffee_mem_end = coffee_mem_start + size - 1;
00244 #endif
00245
00246
00247
00248
00249
00250 #if INCLUDE_RAM
00251 for(addr = (unsigned char *)RAM_START;
00252 addr < (unsigned char *)RAM_END;
00253 addr++) {
00254 if((addr >= thread_mem_start && addr <= thread_mem_end)) {
00255
00256
00257 continue;
00258 }
00259
00260 if((addr >= coffee_mem_start && addr <= coffee_mem_end)) {
00261
00262
00263 continue;
00264 }
00265
00266 *addr = read_byte(fd);
00267
00268 if(((int)addr % 512) == 0) {
00269 PRINTF(".");
00270 }
00271 }
00272
00273 #endif
00274
00275
00276 #if INCLUDE_TIMERS
00277 TACTL = read_word(fd);
00278 TACCTL1 = read_word(fd);
00279 TACCR1 = read_word(fd);
00280 TAR = read_word(fd);
00281
00282 TBCTL = read_word(fd);
00283 TBCCTL1 = read_word(fd);
00284 TBCCR1 = read_word(fd);
00285 TBR = read_word(fd);
00286 #endif
00287
00288
00289 #if INCLUDE_LEDS
00290 leds_arch_set(read_byte(fd));
00291 #endif
00292
00293
00294
00295
00296
00297 read_byte(fd);
00298 }
00299
00300 static void
00301 thread_loop(void *data)
00302 {
00303 uint8_t cmd;
00304 int fd;
00305
00306 while(1) {
00307
00308 cmd = preset_cmd;
00309 fd = preset_fd;
00310
00311
00312 if(cmd == COMMAND_ROLLBACK) {
00313 PRINTF("Rolling back");
00314 thread_rollback(fd);
00315 PRINTF(" done!\n");
00316 } else if(cmd == COMMAND_CHECKPOINT) {
00317 PRINTF("Checkpointing");
00318 thread_checkpoint(fd);
00319 PRINTF(" done!\n");
00320 } else if(cmd == COMMAND_TBR) {
00321 PRINTF("Writing TBR");
00322 write_word(fd, TBR);
00323 PRINTF(" done!\n");
00324 } else {
00325 printf("Error: unknown command: %u\n", cmd);
00326 }
00327
00328
00329 mt_yield();
00330 }
00331 }
00332
00333 int
00334 checkpoint_arch_size()
00335 {
00336 return 10258;
00337 }
00338
00339 void
00340 checkpoint_arch_checkpoint(int fd)
00341 {
00342 STOP_TIMERS();
00343
00344 preset_cmd = COMMAND_CHECKPOINT;
00345 preset_fd = fd;
00346 mt_exec(&checkpoint_thread);
00347
00348 START_TIMERS();
00349 }
00350
00351 void
00352 checkpoint_arch_rollback(int fd)
00353 {
00354 STOP_TIMERS();
00355
00356 preset_cmd = COMMAND_ROLLBACK;
00357 preset_fd = fd;
00358 mt_exec(&checkpoint_thread);
00359
00360 START_TIMERS();
00361 }
00362
00363 void
00364 checkpoint_arch_init(void)
00365 {
00366 mt_init();
00367 mt_start(&checkpoint_thread, thread_loop, NULL);
00368
00369
00370
00371 }
00372