### Prepare system
```sh
-$ sudo apt install gcc make gcc-avr avr-libc
+$ sudo apt install gcc make gcc-avr avr-libc git
$ sudo apt install libelf-dev
$ sudo apt install freeglut3 freeglut3-dev
-$ sudo apt install libncurses3
+$ sudo apt install libncurses5 libncurses5-dev
```
### Clone repository
* i386: `obj-i686-linux-gnu`
* amd64: `obj-x86_64-linux-gnu`
* arm64: `obj-aarch64-linux-gnu`
+* armhf: `arm-linux-gnueabihf`
* ...
Project examples available in folder `examples`
-
dist/**
build/**
-dpkg/**/*.deb
-dpkg/**/usr/share/htl-simuc/simuc
-dpkg/**/usr/share/htl-simuc/simavr
-dpkg/**/DEBIAN/control
**/*.vcd
--- /dev/null
+{
+ "configurations": [
+ {
+ "name": "Linux",
+ "includePath": ["${workspaceFolder}/**", "${workspaceFolder}/include" ],
+ "defines": [],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "c11",
+ "cppStandard": "c++17",
+ "intelliSenseMode": "clang-x64"
+ }
+ ],
+ "version": 4
+}
"request": "launch",
"program": "${workspaceFolder}/dist/simuc",
"args": [],
- "stopAtEntry": false,
+ "stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
+ "miDebuggerPath": "/usr/bin/gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ],
"preLaunchTask": "build"
}
]
"atmega",
"avcc",
"avrsim",
+ "ddra",
"ddrb",
"eeprom",
"eesize",
"lfcrlf",
"lockbits",
"megaavr",
+ "microcontroller",
+ "Microcontrollers",
"millis",
"mmcu",
"picocom",
+ "porta",
"PORTB",
"ramend",
"simavr",
"simuc",
"slavename",
"SRAM",
- "sreg"
+ "sreg",
+ "UART"
]
}
\ No newline at end of file
PRJ="simuc"
$(PRJ): dist/simuc
-start2: $(PRJ)
- LD_LIBRARY_PATH=$(pwd);dist/simuc
-
start: $(PRJ)
dist/simuc
-CFLAGS = -Os -Wall
#X_CFLAGS = -O0 -g -Wall
-X_CFLAGS = -Os -g -Wall
-
+CFLAGS = -Os -Wall -g
+CFLAGS += -isystem ./include
+#CFLAGS += -isystem ./include/parts
dist/simuc: build/main.o build/sim.o build/simavr.o build/error.o build/uart_pty.o ../../simavr/obj-$(shell gcc -dumpmachine)/libsimavr.a
#g++ -o $@ -g -Wall -gdwarf-2 $^ -Wl,-rpath,$(CURDIR) -L$(CURDIR) -lsimavr -lpthread -lutil
g++ -o $@ -g -Wall -gdwarf-2 $^ -lelf -lpthread -lutil
-
-#dist/libsim.so: build/sim.o build/simavr.o build/error.o build/uart_pty.o
-# gcc -o $@ $(CFLAGS) -shared $^
-
build/sim.o: src/sim/sim.cpp src/sim/sim.h src/sim/error.h src/simavr/simavr.h
gcc -o $@ $(CFLAGS) -fPIC -c $<
gcc -o $@ $(CFLAGS) -Wno-unused-result -fPIC -c $<
build/main.o: src/main.cpp src/sim/sim.h src/simavr/simavr.h
- g++ -o $@ $(X_CFLAGS) -c $<
+ g++ -o $@ $(CFLAGS) -c $<
# ############################################
# Debian Packet for htl-simuc_version_arch.deb
# ############################################
-ARCH := $(shell arch)
-ifeq ($(ARCH), x86_64)
+ARCH := $(shell gcc -dumpmachine)
+ifeq ($(ARCH), x86_64-linux-gnu)
DEBARCH="amd64"
OBJARCH=""
endif
-ifeq ($(ARCH), x86_32)
+ifeq ($(ARCH), i686_64-linux-gnu)
DEBARCH="i386"
endif
-ifeq ($(ARCH), aarch64)
+ifeq ($(ARCH), aarch64-linux-gnu)
DEBARCH="arm64"
endif
+ifeq ($(ARCH), arm-linux-gnueabihf)
+ DEBARCH="armhf"
+endif
-DEBVERSION := 0.0.1~1
+DEBVERSION := 0.0.2~1
DEBNAME := dpkg/htl-simuc_version_arch
DEBSRC := dpkg/htl-simuc_version_arch
+DEBARCH := $(shell dpkg --print-architecture)
DEB := $(DEBNAME:%version=%$(DEBVERSION),%arch=%$(DEBARCH).deb)
+LIBC_NAME := libc6
+LIBC_VERSION := $(shell dpkg --list | grep ${LIBC_NAME}:${DEBARCH} | tr -s ' ' | cut -d" " -f 3 | cut -d"-" -f 1)
+LIBCXX_NAME := libstdc++6
+LIBCXX_VERSION := $(shell dpkg --list | grep ${LIBCXX_NAME}:${DEBARCH} | tr -s ' ' | cut -d" " -f 3 | cut -d"-" -f 1)
+LIBELF_NAME := libelf1
+LIBELF_VERSION := $(shell dpkg --list | grep ${LIBELF_NAME}:${DEBARCH} | tr -s ' ' | cut -d" " -f 3 | cut -d"-" -f 1)
+
deb: dpkg $(DEBSRC)/DEBIAN/control $(DEBSRC)/usr/share/doc/htl-simuc/readme
@dpkg-deb --root-owner-group --build $(DEBSRC) ${DEB}
+ @mv $(DEBSRC)/*.deb dpkg/
+ @chmod 644 dpkg/*.deb
.PHONY: $(DEBSRC)/DEBIAN/control $(DEBSRC)/usr/share/doc/htl-simuc/readme
$(DEBSRC)/DEBIAN/control:
- echo "Package: htl-simuc" > $@
- echo "Version:" ${DEBVERSION} >> $@
+ @test -n "${LIBC_NAME}" && test -n "${LIBC_VERSION}"
+ @test -n "${LIBCXX_NAME}" && test -n "${LIBCXX_VERSION}"
+ @test -n "${LIBELF_NAME}" && test -n "${LIBELF_VERSION}"
+ @echo "Package: htl-simuc" > $@
+ @echo "Version:" ${DEBVERSION} >> $@
@echo "Section: devel" >> $@
- echo "Architecture:" $(DEBARCH) >> $@
- @echo "Depends: libelf1" >> $@
+ @echo "Architecture:" $(DEBARCH) >> $@
+ @echo "Depends:" ${LIBELF_NAME} "(>=" ${LIBELF_VERSION}")," ${LIBC_NAME} "(>=" ${LIBC_VERSION}")," ${LIBCXX_NAME} "(>=" ${LIBCXX_VERSION}")" >> $@
@echo "Recommends: gcc-avr, avr-libc, gdb-avr, binutils-avr, avrdude" >> $@
- echo "Installed-Size:" $(shell du -s $(DEBSRC) | cut -f1) >> $@
+ @echo "Installed-Size:" $(shell du -s $(DEBSRC) | cut -f1) >> $@
@echo "Priority: optional" >> $@
@echo "Maintainer: Manfred Steiner <sx@htl-kaindorf.at>" >> $@
@echo "Description: megaavr microcontroller simulation" >> $@
@echo >> $@
@echo "$ git clone https://git.htl-mechatronik.at/public/sx/simavr.git" >> $@
@echo "$ git checkout $(shell git rev-parse HEAD)" >> $@
+ @echo >> $@
+ @echo "git diff:" >> $@
+ @git diff >> $@
@chmod 644 $@
dpkg: $(PRJ)
@find $(DEBSRC) -type d -exec chmod 755 {} \;
@find $(DEBSRC)/usr/share/htl-simuc/ -type f -exec chmod 644 {} \;
@chmod 755 $(DEBSRC)/usr/share/htl-simuc/simuc/simuc
+ ln -sf ../doc/htl-simuc/readme $(DEBSRC)/usr/share/htl-simuc/readme
@touch $(DEBSRC)
# #####################################################################
* Stack pointer SP and stack content
Commands available via standard input (keyboard):
-* *Enter* print current cycles and elapsed time
+* *Enter* print current cycles, elapsed time and LED status
* `interrupt`: stop cpu
* `continue`: continue cpu run
* `stack`: print complete stack content on standard output
$ sudo apt install gcc make gcc-avr avr-libc
$ sudo apt install libelf-dev
$ sudo apt install freeglut3 freeglut3-dev
-$ sudo apt install libncurses3
+$ sudo apt install libncurses5 libncurses5-dev
```
### Clone repository
```sh
user@host:~ $ git clone https://git.htl-mechatronik.at/public/sx/simavr.git
-user@host:~ $ cd simavr/examples/simuc
-user@host:~/simavr/examples/simuc $
```
+### Make complete simavr
+
+```sh
+user@host:~ $ cd ~/simavr
+user@host:~/simavr/ $ make
+```
+
### Make simuc executable
```sh
+user@host:~ $ cd ~/simavr/examples/simuc
+user@host:~/simavr/examples/simuc $
user@host:~/simavr/examples/simuc $ make
```
### Make debian packet `htl-simuc`
```sh
+user@host:~ $ cd ~/simavr/examples/simuc
user@host:~/simavr/examples/simuc $ make deb
```
--- /dev/null
+**/*.deb
+**/usr/share/doc/htl-simuc/readme
+**/usr/share/htl-simuc/simuc
+**/usr/share/htl-simuc/simavr
+**/DEBIAN/control
+++ /dev/null
-created: So 27 Nov 2022 16:21:49 CET
-https://git.htl-mechatronik.at/public/?p=sx/simavr.git;a=home
-
-git clone https://git.htl-mechatronik.at/public/sx/simavr.git
-git checkout 0a12726a5335284495e557078a73381dc5fc8599
--- /dev/null
+../../parts
\ No newline at end of file
--- /dev/null
+../../../simavr/sim
\ No newline at end of file
#include "simavr/simavr.h"
void printHelp () {
- printf("simuc V1.0.0 (%s,%s)\n", __DATE__, __TIME__);
+ printf("simuc V0.0.2 (%s,%s)\n", __DATE__, __TIME__);
printf("usage: simuc [options] elf-file\n\n");
printf(" available options:\n");
printf(" --board ... set board (arduino, sure, evws1)\n");
}
int main (int argc, char **argv) {
- struct StartParameters params = {
- filename: NULL,
- gdbPort: -1,
- frequency: -1,
- mmcu: NULL,
- board: BoardUnknown,
- vcc: -1,
- avcc: -1,
- aref: -1
- };
+ struct StartParameters params;
+ memset((void *)¶ms, 0, sizeof(params));
+ params.filename = NULL;
+ params.gdbPort = -1;
+ params.frequency = -1;
+ params.mmcu = NULL;
+ params.board = BoardUnknown;
+ params.vcc = -1;
+ params.avcc = -1;
+ params.aref = -1;
+
if (argc <= 1) {
printHelp();
if (errno == 1) {
return 1;
}
+ printf("available commands: i (interrupt), c (continue), s (stack)\n");
+ printf("----------------------------------------------------------\n");
printf("init done - press key to start\n");
getchar();
+ printf("----------------------------------------------------------\n");
start();
// int cnt = 0;
throw std::logic_error(error(AT, "waitForEvent() fails caused by mutex error"));
}
try {
- struct SimAvrEvent rv = { epochMillis: 0, event: EventUnknown };
+ struct SimAvrEvent rv = { 0, EventUnknown };
struct SimAvrEvent *p = NULL;
if (events.size() > 0) {
p = events.front();
printf("cycle %" PRIu64 " = %ds %03dms %03dµs %03dns", avr->cycle, seconds, millis, micros, nanos);
}
+bool SimAvr::sprintfLedStatus (char *s, size_t size, bool onlyOnChange) {
+ bool rv = false;
+ if (s != NULL && size > 0 && startParameters != NULL) {
+ s[0] = 0;
+ switch (startParameters->board) {
+ case BoardNano: {
+ static int8_t ledL = -1; // pin floating
+ uint8_t ddrb = avr->data[0x24];
+ uint8_t portb = avr->data[0x25];
+ int8_t nextLedL = -1;
+ if (ddrb & 0x20) {
+ nextLedL = portb & 0x20 ? 1 : 0;
+ }
+ if (!onlyOnChange || nextLedL != ledL) {
+ ledL = nextLedL;
+ snprintf(s, size, "LED L = %c", ledL ? 'X' : '.');
+ rv = true;
+ }
+ break;
+ }
+ case BoardSure: {
+ static int8_t led[4] = { -1, -1, -1, -1 }; // pin floating
+ uint8_t ddra = avr->data[0x3a];
+ uint8_t porta = avr->data[0x3b];
+ int change = 0;
+ for (int i = 0; i < 4; i++) {
+ int8_t nextLed = -1;
+ if (ddra & (1 << i)) {
+ nextLed = porta & (1 << i) ? 0 : 1;
+ }
+ if (nextLed != led[i]) {
+ change = 1;
+ led[i] = nextLed;
+ }
+ }
+ if (!onlyOnChange || change) {
+ int n = snprintf(s, size, "LED PA[3210] =");
+ for (int i = 3; i >= 0; i--) {
+ n += snprintf(s + n, size - n, " %c", led[i] ? 'X' : '.');
+ }
+ rv = true;
+ }
+ break;
+ }
+ case BoardEWS1: {
+ static int8_t led = -1; // pin floating
+ uint8_t ddrb = avr->data[0x24];
+ uint8_t portb = avr->data[0x25];
+ int8_t nextLed = -1;
+ if (ddrb & 0x01) {
+ nextLed = portb & 0x01 ? 1 : 0;
+ }
+ if (!onlyOnChange || nextLed != led) {
+ led = nextLed;
+ snprintf(s, size, "LED1 (PB0) = %c", led ? 'X' : '.');
+ rv = true;
+ }
+ break;
+ }
+ default: break;
+ }
+ }
+ return rv;
+}
+
+
void SimAvr::avrRun () {
long cnt = 0;
int lastAvrState = -1;
_avr_sp_set(avr, 0);
+ char led[80];
while (1) {
try {
+ if (sprintfLedStatus(led, sizeof(led), true)) {
+ printCyclesAndElapsedTime();
+ printf(": %s\n", led);
+ }
+
if (avr->state != lastAvrState) {
switch (avr->state) {
case cpu_Stopped: {
}
printf(printHeader ? "\n" : "\n");
-
- printf(" Arduino LED L: ");
- printf((avr->data[0x24] & 0x20) && (avr->data[0x25] & 0x20) ? "ON\n" : "OFF\n");
-
- printf("\n");
+ char s[20];
+ sprintfLedStatus(s, sizeof(s), false);
+ printf(" %s\n", s);
break;
}
case cpu_Sleeping: printf("cpu enter sleep mode at cycle %" PRIu64 "\n", avr->cycle); break;
lastAvrState = avr->state;
}
- if (startParameters != NULL) {
- switch (startParameters->board) {
- case BoardNano: {
- static int8_t ledL = -1; // pin floating
- uint8_t ddrb = avr->data[0x24];
- uint8_t portb = avr->data[0x25];
- int8_t nextLedL = -1;
- if (ddrb & 0x20) {
- nextLedL = portb & 0x20 ? 1 : 0;
- }
- if (nextLedL != ledL) {
- ledL = nextLedL;
- printCyclesAndElapsedTime();
- printf(": LED L = %c\n", ledL ? 'X' : '.');
- }
- break;
- }
- case BoardSure: {
- static int8_t led[4] = { -1, -1, -1, -1 }; // pin floating
- uint8_t ddra = avr->data[0x3a];
- uint8_t porta = avr->data[0x3b];
- int change = 0;
- for (int i = 0; i < 4; i++) {
- int8_t nextLed = -1;
- if (ddra & (1 << i)) {
- nextLed = porta & (1 << i) ? 0 : 1;
- }
- if (nextLed != led[i]) {
- change = 1;
- led[i] = nextLed;
- }
- }
- if (change) {
- printCyclesAndElapsedTime(); printf(": ");
- printf(" LED PA[3210] =");
- for (int i = 3; i >= 0; i--) {
- printf(" %c", led[i] ? 'X' : '.');
- }
- printf("\n");
- }
- break;
- }
- case BoardEWS1: {
- static int8_t led = -1; // pin floating
- uint8_t ddrb = avr->data[0x24];
- uint8_t portb = avr->data[0x25];
- int8_t nextLed = -1;
- if (ddrb & 0x01) {
- nextLed = portb & 0x01 ? 1 : 0;
- }
- if (nextLed != led) {
- led = nextLed;
- printCyclesAndElapsedTime();
- printf(": LED1 (PB0) = %c\n", led ? 'X' : '.');
- }
- break;
- }
- default: break;
- }
- }
-
if (cnt <= 0) {
// usleep(10000);
if (pthread_mutex_lock(&lock)) {
switch (command) {
case CommandStatus: {
printCyclesAndElapsedTime();
- printf("\n");
+ char s[80];
+ sprintfLedStatus(s, sizeof(s), false);
+ printf(" %s\n", s);
break;
}
case CommandInterrupt: {
Semaphore eventCount;
uart_pty_t *uartPty[2] = { NULL, NULL };
void printCyclesAndElapsedTime ();
+ bool sprintfLedStatus (char *s, size_t size, bool onlyOnChange);
};