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);
41 return 0; // clear warning
44 static jmp_buf *special_deinit_jmpbuf = NULL;
46 static void special_deinit_longjmp_cb(struct avr_t *avr) {
47 if (special_deinit_jmpbuf)
48 longjmp(*special_deinit_jmpbuf, LJR_SPECIAL_DEINIT);
51 static int my_avr_run(avr_t * avr)
53 if (avr->state == cpu_Stopped)
56 uint16_t new_pc = avr->pc;
58 if (avr->state == cpu_Running)
59 new_pc = avr_run_one(avr);
61 // if we just re-enabled the interrupts...
62 // double buffer the I flag, to detect that edge
63 if (avr->sreg[S_I] && !avr->i_shadow)
64 avr->interrupts.pending_wait++;
65 avr->i_shadow = avr->sreg[S_I];
67 // run the cycle timers, get the suggested sleep time
68 // until the next timer is due
69 avr_cycle_count_t sleep = avr_cycle_timer_process(avr);
73 if (avr->state == cpu_Sleeping) {
74 if (!avr->sreg[S_I]) {
75 printf("simavr: sleeping with interrupts off, quitting gracefully\n");
77 fail("Test case error: special_deinit() returned?");
81 * try to sleep for as long as we can (?)
83 // uint32_t usec = avr_cycles_to_usec(avr, sleep);
84 // printf("sleep usec %d cycles %d\n", usec, sleep);
86 avr->cycle += 1 + sleep;
88 // Interrupt servicing might change the PC too, during 'sleep'
89 if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
90 avr_service_interrupts(avr);
92 // if we were stepping, use this state to inform remote gdb
97 avr_t *tests_init_avr(const char *elfname) {
98 tests_cycle_count = 0;
99 if (tests_disable_stdout) {
100 orig_stderr = stderr;
105 if (elf_read_firmware(elfname, &fw))
106 fail("Failed to read ELF firmware \"%s\"", elfname);
107 avr_t *avr = avr_make_mcu_by_name(fw.mmcu);
109 fail("Creating AVR failed.");
111 avr_load_firmware(avr, &fw);
115 int tests_run_test(avr_t *avr, unsigned long run_usec) {
117 fail("Internal test error: avr == NULL in run_test()");
118 // register a cycle timer to fire after 100 seconds (simulation time);
119 // assert that the simulation has not finished before that.
121 special_deinit_jmpbuf = &jmp;
122 avr->special_deinit = special_deinit_longjmp_cb;
123 avr_cycle_timer_register_usec(avr, run_usec,
124 cycle_timer_longjmp_cb, &jmp);
125 int reason = setjmp(jmp);
126 tests_cycle_count = avr->cycle;
128 // setjmp() returned directly, run avr
131 } else if (reason == 1) {
132 // returned from longjmp(); cycle timer fired
134 } else if (reason == 2) {
135 // returned from special deinit, avr stopped
138 fail("Error in test case: Should never reach this.");
142 int tests_init_and_run_test(const char *elfname, unsigned long run_usec) {
143 avr_t *avr = tests_init_avr(elfname);
144 return tests_run_test(avr, run_usec);
147 struct output_buffer {
154 /* static void buf_output_cb(avr_t *avr, avr_io_addr_t addr, uint8_t v, */
156 static void buf_output_cb(struct avr_irq_t *irq, uint32_t value, void *param) {
157 struct output_buffer *buf = param;
159 fail("Internal error: buf == NULL in buf_output_cb()");
160 if (buf->currlen > buf->alloclen-1)
161 fail("Internal error");
162 if (buf->alloclen == 0)
163 fail("Internal error");
164 if (buf->currlen == buf->alloclen-1) {
166 buf->str = realloc(buf->str, buf->alloclen);
168 buf->str[buf->currlen++] = value;
169 buf->str[buf->currlen] = 0;
172 static void init_output_buffer(struct output_buffer *buf) {
173 buf->str = malloc(128);
180 void tests_assert_uart_receive_avr(avr_t *avr,
181 unsigned long run_usec,
182 const char *expected,
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_uart_receive(const char *elfname,
203 unsigned long run_usec,
204 const char *expected,
206 avr_t *avr = tests_init_avr(elfname);
208 tests_assert_uart_receive_avr(avr,
214 void tests_assert_cycles_at_least(unsigned long n) {
215 if (tests_cycle_count < n)
216 _fail(NULL, 0, "Program ran for too few cycles (%"
217 PRI_avr_cycle_count " < %lu)", tests_cycle_count, n);
220 void tests_assert_cycles_at_most(unsigned long n) {
221 if (tests_cycle_count > n)
222 _fail(NULL, 0, "Program ran for too many cycles (%"
223 PRI_avr_cycle_count " > %lu)", tests_cycle_count, n);
226 void tests_assert_cycles_between(unsigned long min, unsigned long max) {
227 tests_assert_cycles_at_least(min);
228 tests_assert_cycles_at_most(max);
231 void _fail(const char *filename, int linenum, const char *fmt, ...) {
233 stderr = orig_stderr;
236 fprintf(stderr, "%s:%d: ", filename, linenum);
238 fprintf(stderr, "Test ");
240 fprintf(stderr, "%s ", test_name);
241 fprintf(stderr, "FAILED.\n");
244 fprintf(stderr, "%s:%d: ", filename, linenum);
248 vfprintf(stderr, fmt, va);