Skip to content

Commit

Permalink
Optimize memory access + add Linux build script + add computer simula…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
raspiduino committed Jul 2, 2024
1 parent 19da996 commit eb13613
Show file tree
Hide file tree
Showing 9 changed files with 1,115 additions and 80 deletions.
10 changes: 5 additions & 5 deletions build.bat
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
@echo off
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst -std=gnu99 main.c -o main.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdcard.lst -std=gnu99 sdcard.c -o sdcard.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdprint.lst -std=gnu99 sdprint.c -o sdprint.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=spi.lst -std=gnu99 spi.c -o spi.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart.lst -std=gnu99 uart.c -o uart.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst -std=gnu99 main.c -o main.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdcard.lst -std=gnu99 sdcard.c -o sdcard.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdprint.lst -std=gnu99 sdprint.c -o sdprint.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=spi.lst -std=gnu99 spi.c -o spi.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart.lst -std=gnu99 uart.c -o uart.o
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-gcc -mmcu=atmega328p -I. -DF_CPU=16000000UL -O3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 main.o sdcard.o sdprint.o spi.o uart.o --output main.elf -Wl,-Map=main.map,--cref
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-objcopy -O ihex -R .eeprom main.elf main.hex
C:\Users\mmb\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-size -A -d main.elf
Expand Down
49 changes: 49 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

avr() {
echo "Building for AVR"
avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst -std=gnu99 main.c -o main.o
avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdcard.lst -std=gnu99 sdcard.c -o sdcard.o
avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sdprint.lst -std=gnu99 sdprint.c -o sdprint.o
avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=spi.lst -std=gnu99 spi.c -o spi.o
avr-gcc -c -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart.lst -std=gnu99 uart.c -o uart.o
avr-gcc -mmcu=atmega328p -I. -DF_CPU=16000000UL -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 main.o sdcard.o sdprint.o spi.o uart.o --output main.elf -Wl,-Map=main.map,--cref
avr-objcopy -O ihex -R .eeprom main.elf main.hex
avr-size -A -d main.elf
echo "Done! Now flash the hex to your device (maybe using avrdude)"
}

sim() {
echo "Building for simulation (debug)"
gcc -I. -g3 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 main_sim.c if_sim.c -o sim
}

sim_opt() {
echo "Building for simulation (release)"
gcc -I. -march=native -Ofast -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 main_sim.c if_sim.c -o sim
}

# Check for help flag
if [[ "$1" == "-h" || "$1" == "--help" || "$1" == "help" ]]; then
echo "Usage: $0 (sim|sim_opt|avr)"
echo " sim: (Debug) Build computer simulation (exact same logic, only interfaces changed)"
echo " sim_opt: (Release) Build computer simulation (exact same logic, only interfaces changed)"
echo " avr: (Release) Build for AVR"
exit 0
fi

# Check for arguments
if [[ "$1" == "sim" ]]; then
sim
else
if [[ "$1" == "sim_opt" ]]; then
sim_opt
else
if [[ "$1" == "avr" ]]; then
avr
else
echo "Invalid argument: '$1'"
exit 1
fi
fi
fi
160 changes: 160 additions & 0 deletions if_sim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/time.h>

#include "if_sim.h"

uint8_t mem[RAM_SIZE];

// UART
const char hex_digits[] = "0123456789ABCDEF";
static int is_eofd;

void UART_init()
{
return; // Do literally nothing
}

void UART_putc(const unsigned char data)
{
putchar(data);
}

void UART_puts(const char* charString)
{
// iterate through string
while(*charString > 0)
// print character
UART_putc(*charString++);
}

void UART_puthex8(uint8_t val)
{
// extract upper and lower nibbles from input value
uint8_t upperNibble = (val & 0xF0) >> 4;
uint8_t lowerNibble = val & 0x0F;

// convert nibble to its ASCII hex equivalent
upperNibble += upperNibble > 9 ? 'A' - 10 : '0';
lowerNibble += lowerNibble > 9 ? 'A' - 10 : '0';

// print the characters
UART_putc(upperNibble);
UART_putc(lowerNibble);
}

unsigned char UART_getc(void)
{
if( is_eofd ) return 0xffffffff;
char rxchar = 0;
int rread = read(fileno(stdin), (char*)&rxchar, 1);

if( rread > 0 ) // Tricky: getchar can't be used with arrow keys.
return rxchar;
else
return -1;
}

unsigned char UART_available(void)
{
if( is_eofd ) return -1;
int byteswaiting;
ioctl(0, FIONREAD, &byteswaiting);
if( !byteswaiting && write( fileno(stdin), 0, 0 ) != 0 ) { is_eofd = 1; return -1; } // Is end-of-file for
return !!byteswaiting;
}

void UART_puthex32(unsigned long value) {
UART_puts("0x");
char x[9];
unsigned char i, c;

x[8] = '\0';

for (i = 0; i < 8; i++) {
c = value & 0x0F;
value >>= 4;
c = (c >= 10) ? (c + 'A' - 10) : (c + '0');
x[7 - i] = c;
}

UART_puts(x);
}

void UART_putdec32(unsigned long value) {

char x[16];
unsigned char i, c;

x[sizeof(x) - 1] = 0;

for(i = 0; i < sizeof(x) - 1; i++){

c = (value % 10) + '0';
value /= 10;
x[sizeof(x) - 2 - i] = c;
if(!value) break;
}

UART_puts(x + sizeof(x) - 2 - i);
}

// SPI
void SPI_init(uint16_t initParams) {
// Do literally nothing
}

// SD
void SD_printDataErrToken(uint8_t token) {
// Literally impossible in a simulation, but just in case
printf("SD error: %x", token);
}

uint8_t SD_init() {
// Open and read RAM file to memory array
FILE *fp = fopen("rv32.bin", "rb");
if (fp == NULL) {
perror("fopen");
return 1;
}

// Check if file size matches expected size
fseek(fp, 0, SEEK_END); // Seek to the end of the file
long actual_size = ftell(fp); // Get the file size
rewind(fp); // Rewind to the beginning for reading

if (actual_size != RAM_SIZE) {
fprintf(stderr, "Warning: File size (%ld bytes) does not match expected size (%d bytes)\n", actual_size, RAM_SIZE);
}

// Read the entire file into the buffer
size_t bytes_read = fread(mem, 1, RAM_SIZE, fp);
if (bytes_read != RAM_SIZE) {
fprintf(stderr, "fread error: %zu bytes read (expected %d)\n", bytes_read, RAM_SIZE);
fclose(fp);
return 1;
}

return 0; // Success
}

uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token) {
// Read
memcpy(buf, mem + (addr * SD_BLOCK_LEN), 512);

// Read success
*token = 0xFF;
}

uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *res) {
// Write
memcpy(mem + (addr * SD_BLOCK_LEN), buf, 512);

// Write success
*res = 0xFF;
}

// Misc
void _delay_ms(unsigned int ms) {
usleep(ms * 1000);
}
17 changes: 17 additions & 0 deletions if_sim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "types.h"

// Config
#define RAM_SIZE 16777216UL // Minimum RAM amount (in bytes), just tested (may reduce further by custom kernel)
#define DTB_SIZE 1536 // DTB size (in bytes), must recount manually each time DTB changes
#define INSTRS_PER_FLIP 1024 // Number of instructions executed before checking status. See loop()
#define TIME_DIVISOR 2
#define SD_BLOCK_LEN 512

void _delay_ms(uint32_t ms);
Loading

0 comments on commit eb13613

Please sign in to comment.