13 avr_cycle_count_t tests_cycle_count = 0;
14 int tests_disable_stdout = 1;
16 static char *test_name = "(uninitialized test)";
17 static FILE *orig_stderr = NULL;
18 static int finished = 0;
20 static void atexit_handler(void) {
22 _fail(NULL, 0, "Test exit without indicating success.");
25 void tests_success(void) {
28 fprintf(stderr, "OK: %s\n", test_name);
32 void tests_init(int argc, char **argv) {
33 test_name = strdup(argv[0]);
34 atexit(atexit_handler);
37 static avr_cycle_count_t
38 cycle_timer_longjmp_cb(struct avr_t *avr, avr_cycle_count_t when, void *param) {
40 longjmp(*jmp, LJR_CYCLE_TIMER);
43 static jmp_buf *special_deinit_jmpbuf = NULL;
45 static void special_deinit_longjmp_cb(struct avr_t *avr) {
46 if (special_deinit_jmpbuf)
47 longjmp(*special_deinit_jmpbuf, LJR_SPECIAL_DEINIT);
50 static int my_avr_run(avr_t * avr)
52 if (avr->state == cpu_Stopped)
55 uint16_t new_pc = avr->pc;
57 if (avr->state == cpu_Running)
58 new_pc = avr_run_one(avr);
60 // if we just re-enabled the interrupts...
61 // double buffer the I flag, to detect that edge
62 if (avr->sreg[S_I] && !avr->i_shadow)
64 avr->i_shadow = avr->sreg[S_I];
66 // run the cycle timers, get the suggested sleep time
67 // until the next timer is due
68 avr_cycle_count_t sleep = avr_cycle_timer_process(avr);
72 if (avr->state == cpu_Sleeping) {
73 if (!avr->sreg[S_I]) {
74 printf("simavr: sleeping with interrupts off, quitting gracefully\n");
76 fail("Test case error: special_deinit() returned?");
80 * try to sleep for as long as we can (?)
82 // uint32_t usec = avr_cycles_to_usec(avr, sleep);
83 // printf("sleep usec %d cycles %d\n", usec, sleep);
85 avr->cycle += 1 + sleep;
87 // Interrupt servicing might change the PC too, during 'sleep'
88 if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
89 avr_service_interrupts(avr);
91 // if we were stepping, use this state to inform remote gdb
96 avr_t *tests_init_avr(const char *elfname) {
97 tests_cycle_count = 0;
98 if (tests_disable_stdout) {
104 if (elf_read_firmware(elfname, &fw))
105 fail("Failed to read ELF firmware \"%s\"", elfname);
106 avr_t *avr = avr_make_mcu_by_name(fw.mmcu);
108 fail("Creating AVR failed.");
110 avr_load_firmware(avr, &fw);
114 int tests_run_test(avr_t *avr, unsigned long run_usec) {
116 fail("Internal test error: avr == NULL in run_test()");
117 // register a cycle timer to fire after 100 seconds (simulation time);
118 // assert that the simulation has not finished before that.
120 special_deinit_jmpbuf = &jmp;
121 avr->special_deinit = special_deinit_longjmp_cb;
122 avr_cycle_timer_register_usec(avr, run_usec,
123 cycle_timer_longjmp_cb, &jmp);
124 int reason = setjmp(jmp);
125 tests_cycle_count = avr->cycle;
127 // setjmp() returned directly, run avr
130 } else if (reason == 1) {
131 // returned from longjmp(); cycle timer fired
133 } else if (reason == 2) {
134 // returned from special deinit, avr stopped
137 fail("Error in test case: Should never reach this.");
141 int tests_init_and_run_test(const char *elfname, unsigned long run_usec) {
142 avr_t *avr = tests_init_avr(elfname);
143 return tests_run_test(avr, run_usec);
146 struct output_buffer {
153 /* static void buf_output_cb(avr_t *avr, avr_io_addr_t addr, uint8_t v, */
155 static void buf_output_cb(struct avr_irq_t *irq, uint32_t value, void *param) {
156 struct output_buffer *buf = param;
158 fail("Internal error: buf == NULL in buf_output_cb()");
159 if (buf->currlen > buf->alloclen-1)
160 fail("Internal error");
161 if (buf->alloclen == 0)
162 fail("Internal error");
163 if (buf->currlen == buf->alloclen-1) {
165 buf->str = realloc(buf->str, buf->alloclen);
167 buf->str[buf->currlen++] = value;
168 buf->str[buf->currlen] = 0;
171 static void init_output_buffer(struct output_buffer *buf) {
172 buf->str = malloc(128);
179 void tests_assert_uart_receive(const char *elfname,
180 unsigned long run_usec,
181 const char *expected,
183 avr_t *avr = tests_init_avr(elfname);
184 struct output_buffer buf;
185 init_output_buffer(&buf);
187 avr_irq_register_notify(avr_io_getirq(avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUTPUT),
188 buf_output_cb, &buf);
189 enum tests_finish_reason reason = tests_run_test(avr, run_usec);
190 if (reason == LJR_CYCLE_TIMER) {
191 if (strcmp(buf.str, expected) == 0) {
192 _fail(NULL, 0, "Simulation did not finish within %lu simulated usec. "
193 "UART output is correct and complete.", run_usec);
195 _fail(NULL, 0, "Simulation did not finish within %lu simulated usec. "
196 "UART output so far: \"%s\"", run_usec, buf.str);
198 if (strcmp(buf.str, expected) != 0)
199 _fail(NULL, 0, "UART outputs differ: expected \"%s\", got \"%s\"", expected, buf.str);
202 void tests_assert_cycles_at_least(unsigned long n) {
203 if (tests_cycle_count < n)
204 _fail(NULL, 0, "Program ran for too few cycles (%"
205 PRI_avr_cycle_count " < %lu)", tests_cycle_count, n);
208 void tests_assert_cycles_at_most(unsigned long n) {
209 if (tests_cycle_count > n)
210 _fail(NULL, 0, "Program ran for too many cycles (%"
211 PRI_avr_cycle_count " > %lu)", tests_cycle_count, n);
214 void tests_assert_cycles_between(unsigned long min, unsigned long max) {
215 tests_assert_cycles_at_least(min);
216 tests_assert_cycles_at_most(max);
219 void _fail(const char *filename, int linenum, const char *fmt, ...) {
221 stderr = orig_stderr;
224 fprintf(stderr, "%s:%d: ", filename, linenum);
226 fprintf(stderr, "Test ");
228 fprintf(stderr, "%s ", test_name);
229 fprintf(stderr, "FAILED.\n");
232 fprintf(stderr, "%s:%d: ", filename, linenum);
236 vfprintf(stderr, fmt, va);