MOS Source Code
Loading...
Searching...
No Matches
run_test.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <sys/stat.h>
3#include <fcntl.h>
4#include <stdlib.h>
5#include <stdbool.h>
6#include <string.h>
7#include <stdio.h>
8#include <libgen.h>
9#include <simavr/sim_avr.h>
10#include <simavr/sim_gdb.h>
11#include <simavr/avr_ioport.h>
12#include <simavr/sim_elf.h>
13#include <simavr/avr_uart.h>
14
15static avr_t *g_avr;
16static avr_irq_t *g_uart_irq;
17
18static struct {
20 char args[3][16];
22static int g_args_idx;
23static bool g_uart_xon;
24static bool g_status_ok;
25
26static void uart_tx_hook(struct avr_irq_t * irq, uint32_t value, void * param)
27{
28 fputc(value, stdout);
29 fflush(stdout);
30}
31
32static bool stdin_can_read()
33{
34 struct timeval tv;
35 fd_set fds;
36 tv.tv_sec = 0;
37 tv.tv_usec = 0;
38 FD_ZERO(&fds);
39 FD_SET(STDIN_FILENO, &fds);
40 select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
41 return (FD_ISSET(0, &fds));
42}
43
44static void avr_logger(avr_t * avr, const int level, const char * format, va_list ap)
45{
46 if ((!avr && level <= LOG_WARNING) || (avr && avr->log >= level)) {
47 vfprintf(stderr , format, ap);
48 }
49}
50
51static void uart_xon_hook(struct avr_irq_t * irq, uint32_t value, void * param)
52{
53 g_uart_xon = true;
54 int v;
55
56 if (feof(stdin))
57 {
58 avr_raise_irq(&g_uart_irq[1], UART_INPUT_FE);
59 return;
60 }
61
62 while (g_uart_xon)
63 {
64 if (g_args_idx < sizeof(g_args))
65 {
66 v = ((char*)&g_args)[g_args_idx++];
67 }
68 else if (stdin_can_read())
69 {
70 v = fgetc(stdin);
71 }
72 else
73 {
74 break;
75 }
76
77 if (v != EOF)
78 {
79 avr_raise_irq(&g_uart_irq[1], v);
80 }
81 else
82 {
83 avr_raise_irq(&g_uart_irq[1], UART_INPUT_FE);
84 break;
85 }
86 }
87}
88
89static void uart_xoff_hook(struct avr_irq_t * irq, uint32_t value, void * param)
90{
91 g_uart_xon = false;
92}
93
95{
96 const char *irq_names[2] = {"8<uart_in", "8>uart_out"};
97 g_uart_irq = avr_alloc_irq(&g_avr->irq_pool, 0, 2, irq_names);
98 avr_irq_register_notify(&g_uart_irq[0], &uart_tx_hook, NULL);
99
100 uint32_t flags = 0;
101 avr_ioctl(g_avr, AVR_IOCTL_UART_GET_FLAGS('0'), &flags);
102 flags &= ~AVR_UART_FLAG_STDIO;
103 flags &= ~AVR_UART_FLAG_POLL_SLEEP;
104 avr_ioctl(g_avr, AVR_IOCTL_UART_SET_FLAGS('0'), &flags);
105
106 avr_irq_t *src = avr_io_getirq(g_avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_OUTPUT);
107 avr_irq_t *dst = avr_io_getirq(g_avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_INPUT);
108 avr_connect_irq(src, &g_uart_irq[0]);
109 avr_connect_irq(&g_uart_irq[1], dst);
110
111 avr_irq_t *xon = avr_io_getirq(g_avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_OUT_XON);
112 avr_irq_t *xoff = avr_io_getirq(g_avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_OUT_XOFF);
113 avr_irq_register_notify(xon, uart_xon_hook, NULL);
114 avr_irq_register_notify(xoff, uart_xoff_hook, NULL);
115}
116
117static void status_ok_hook(struct avr_irq_t * irq, uint32_t value, void * param)
118{
119 g_status_ok = value;
120}
121
122int main(int argc, char *argv[])
123{
124 avr_global_logger_set(&avr_logger);
125 g_avr = avr_make_mcu_by_name("atmega1284");
126 if (!g_avr)
127 {
128 fprintf(stderr, "avr_make_mcu_by_name failed\n");
129 return 1;
130 }
131
132 if (argc < 2)
133 {
134 fprintf(stderr, "Usage: %s [-g] binary [args ...]\n", argv[0]);
135 return 2;
136 }
137
138 const char *filename = argv[1];
139 bool enable_gdb = false;
140 int argc_offset = 2;
141
142 if (strcmp(filename, "-g") == 0)
143 {
144 enable_gdb = true;
145 argc_offset = 3;
146 filename = argv[2];
147 }
148
149 elf_firmware_t firmware = {};
150 elf_read_firmware(filename, &firmware);
151 avr_init(g_avr);
152 avr_load_firmware(g_avr, &firmware);
153 g_avr->frequency = 8000000;
154
155 if (enable_gdb)
156 {
157 g_avr->state = cpu_Stopped;
158 g_avr->gdb_port = 1234;
159 avr_gdb_init(g_avr);
160 }
161
162 init_uart();
163
164 avr_irq_register_notify(avr_io_getirq(g_avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 1), status_ok_hook, NULL);
165
166 // Pass the rest of arguments to application inside simulator
167 g_args.argc = argc - argc_offset;
168 if (g_args.argc > 3) g_args.argc = 3;
169 for (int i = 0; i < g_args.argc; i++)
170 {
171 strncpy(g_args.args[i], argv[i + argc_offset], 15);
172 }
173
174 while (1)
175 {
176 int state = avr_run(g_avr);
177 if (state == cpu_Done)
178 break;
179
180 if (state == cpu_Crashed)
181 {
182 fprintf(stderr, "CPU Crashed\n");
183 return 3;
184 }
185 }
186
187 if (g_status_ok)
188 {
189 return 0;
190 }
191 else
192 {
193 fprintf(stderr, "Received error status from simulation\n");
194 return 5;
195 }
196}
MOSAPI char * strncpy(char *__restrict dest, const char *__restrict src, size_t n)
Definition mos_string.c:202
MOSAPI s32 strcmp(const char *str1, const char *str2)
Definition mos_string.c:24
#define stdout
Definition mos_stdio.h:31
#define stderr
Definition mos_stdio.h:32
#define stdin
Definition mos_stdio.h:30
MOSAPI int fputc(int c, FILE *file)
MOSAPI const char *__restrict format
Definition mos_stdio.h:17
MOSAPI int vfprintf(FILE *__restrict file, const char *__restrict format, va_list ap)
MOSAPI int fgetc(FILE *file)
const char ** argv
Definition kmain.c:44
#define FD_SET(__fd, __set)
Definition ksyscall.c:434
#define FD_ISSET(__fd, __set)
Definition ksyscall.c:430
#define FD_ZERO(__set)
Definition ksyscall.c:438
#define NULL
Definition pb_syshdr.h:46
unsigned int uint32_t
Definition pb_syshdr.h:24
unsigned char uint8_t
Definition pb_syshdr.h:20
static bool stdin_can_read()
Definition run_test.c:32
static void uart_xon_hook(struct avr_irq_t *irq, uint32_t value, void *param)
Definition run_test.c:51
static void uart_tx_hook(struct avr_irq_t *irq, uint32_t value, void *param)
Definition run_test.c:26
static struct @32 g_args
static bool g_uart_xon
Definition run_test.c:23
static avr_t * g_avr
Definition run_test.c:15
static int g_args_idx
Definition run_test.c:22
static void uart_xoff_hook(struct avr_irq_t *irq, uint32_t value, void *param)
Definition run_test.c:89
static void status_ok_hook(struct avr_irq_t *irq, uint32_t value, void *param)
Definition run_test.c:117
static void avr_logger(avr_t *avr, const int level, const char *format, va_list ap)
Definition run_test.c:44
uint8_t argc
Definition run_test.c:19
void init_uart()
Definition run_test.c:94
static avr_irq_t * g_uart_irq
Definition run_test.c:16
static bool g_status_ok
Definition run_test.c:24
char args[3][16]
Definition run_test.c:20
int main()
Definition simple.cpp:6