Addded basic profiling and fixed sd card init status being inverted
This commit is contained in:
parent
2aa48f3871
commit
e49b0e6cc3
@ -53,7 +53,7 @@ Retro-Go is a launcher and framework to run emulators on the ODROID-GO. It comes
|
||||
Note: If you are stuck in an emulator, hold MENU while powering up the device to return to the launcher.
|
||||
|
||||
|
||||
# Game covers
|
||||
# Game covers
|
||||
The preferred cover art format is 8bit PNG with a resolution of 168x168 and I recommend post-processing
|
||||
with [pngquant](https://pngquant.org/). Retro-Go is also backwards-compatible with the official RAW565
|
||||
Go-Play romart pack that you may already have.
|
||||
@ -88,14 +88,13 @@ The official esp-idf version 3.3 or 4.0 is required and it is recommended to app
|
||||
sdcard-fix patch located in the tools folder. Both make and cmake are supported.
|
||||
|
||||
## Build everything and generate .fw:
|
||||
1. `python rg_tool.py release` or `python rg_tool.py release --use-make` (legacy make system)
|
||||
1. `python rg_tool.py build-fw` or `python rg_tool.py build-fw --use-make` (legacy make system)
|
||||
|
||||
For a smaller build you can also specify which apps you want, for example the launcher + nes/gameboy only:
|
||||
1. `python rg_tool.py release retro-go nofrendo-go gnuboy-go`
|
||||
1. `python rg_tool.py build-fw retro-go nofrendo-go gnuboy-go`
|
||||
|
||||
## Build, flash, and monitor individual apps for faster development:
|
||||
1. Build app: `python rg_tool.py build nofrendo-go`
|
||||
2. Then flash and monitor: `python rg_tool.py --offset=0x100000 --port=COM3 flashmon nofrendo-go`
|
||||
1. `python rg_tool.py run nofrendo-go --offset=0x100000 --port=COM3`
|
||||
* Offset is required only if you use my multi-firmware, in which case it is displayed in the boot menu.
|
||||
|
||||
|
||||
|
||||
10
base.cmake
10
base.cmake
@ -13,3 +13,13 @@ if(NOT PROJECT_VER)
|
||||
string(TIMESTAMP TODAY "%Y.%m.%d")
|
||||
set(PROJECT_VER "${TODAY}-nogit")
|
||||
endif()
|
||||
|
||||
if($ENV{ENABLE_NETPLAY})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_NETPLAY")
|
||||
set(ENABLE_NETPLAY 1)
|
||||
endif()
|
||||
|
||||
if($ENV{ENABLE_PROFILING})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_PROFILING")
|
||||
set(ENABLE_PROFILING 1)
|
||||
endif()
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
/* GIMP RGBA C-Source image dump (hourglass_empty_black_48dp.c) */
|
||||
/* This image is taken from https://icons8.de/icon/49923/sanduhr and is free license. */
|
||||
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[48 * 48 * 2 + 1];
|
||||
} image_hourglass_empty_black_48dp = {
|
||||
} image_hourglass = {
|
||||
48, 48, 2,
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
1
components/odroid/bitmaps/image_logo.h
Normal file
1
components/odroid/bitmaps/image_logo.h
Normal file
@ -0,0 +1 @@
|
||||
#pragma once
|
||||
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/* GIMP RGBA C-Source image dump (Untitled.c) */
|
||||
/* This image is based on a free icon from https://icons8.com/icons/set/micro-sd */
|
||||
|
||||
@ -6,7 +8,7 @@ static const struct {
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[48 * 48 * 2 + 1];
|
||||
} image_sdcard_red_48dp = {
|
||||
} image_sdcard = {
|
||||
48, 48, 2,
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377}\377Y\376\266\375\226\375\226\375\226\375\226\375"
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#include "odroid_system.h"
|
||||
#include "odroid_display.h"
|
||||
#include "odroid_image_hourglass.h"
|
||||
#include "bitmaps/image_hourglass.h"
|
||||
|
||||
#define SCREEN_WIDTH ODROID_SCREEN_WIDTH
|
||||
#define SCREEN_HEIGHT ODROID_SCREEN_HEIGHT
|
||||
@ -1102,11 +1102,11 @@ void odroid_display_clear(uint16_t color)
|
||||
|
||||
void odroid_display_show_hourglass()
|
||||
{
|
||||
odroid_display_write((SCREEN_WIDTH / 2) - (image_hourglass_empty_black_48dp.width / 2),
|
||||
(SCREEN_HEIGHT / 2) - (image_hourglass_empty_black_48dp.height / 2),
|
||||
image_hourglass_empty_black_48dp.width,
|
||||
image_hourglass_empty_black_48dp.height,
|
||||
(uint16_t*)image_hourglass_empty_black_48dp.pixel_data);
|
||||
odroid_display_write((SCREEN_WIDTH / 2) - (image_hourglass.width / 2),
|
||||
(SCREEN_HEIGHT / 2) - (image_hourglass.height / 2),
|
||||
image_hourglass.width,
|
||||
image_hourglass.height,
|
||||
(uint16_t*)image_hourglass.pixel_data);
|
||||
}
|
||||
|
||||
void odroid_display_deinit()
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "bitmaps/font_basic.h"
|
||||
#include "odroid_system.h"
|
||||
#include "odroid_font8x8.h"
|
||||
#include "odroid_overlay.h"
|
||||
|
||||
static uint16_t *overlay_buffer = NULL;
|
||||
|
||||
125
components/odroid/odroid_profiler.c
Normal file
125
components/odroid/odroid_profiler.c
Normal file
@ -0,0 +1,125 @@
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "odroid_system.h"
|
||||
#include "odroid_profiler.h"
|
||||
|
||||
// Note this profiler might be inaccurate because of:
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=28205
|
||||
|
||||
static profile_t *profile;
|
||||
static volatile bool profile_lock;
|
||||
|
||||
NO_PROFILE static inline profile_frame_t *find_frame(void *this_fn, void *call_site)
|
||||
{
|
||||
for (int i = 0; i < 512; ++i)
|
||||
{
|
||||
profile_frame_t *frame = &profile->frames[i];
|
||||
|
||||
if (frame->func_ptr == 0)
|
||||
{
|
||||
profile->total_frames = MAX(profile->total_frames, i + 1);
|
||||
frame->func_ptr = this_fn;
|
||||
frame->caller_ptr = call_site;
|
||||
}
|
||||
|
||||
if (frame->func_ptr == this_fn && frame->caller_ptr == call_site)
|
||||
{
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
|
||||
RG_PANIC("Profile memory exhausted!");
|
||||
}
|
||||
|
||||
NO_PROFILE void rg_profiler_init(void)
|
||||
{
|
||||
printf("%s: Initializing profile...\n", __func__);
|
||||
profile = rg_alloc(sizeof(profile_t), MEM_SLOW);
|
||||
profile->time_started = get_elapsed_time();
|
||||
}
|
||||
|
||||
NO_PROFILE void rg_profiler_free(void)
|
||||
{
|
||||
// free(call_stack);
|
||||
free(profile);
|
||||
profile = NULL;
|
||||
}
|
||||
|
||||
NO_PROFILE static int list_comparator(const void *p, const void *q)
|
||||
{
|
||||
return ((profile_frame_t*)q)->run_time - ((profile_frame_t*)p)->run_time;
|
||||
}
|
||||
|
||||
NO_PROFILE void rg_profiler_print(void)
|
||||
{
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
// xSemaphoreTake(profile_lock, pdMS_TO_TICKS(10000));
|
||||
profile_lock = true;
|
||||
|
||||
uint32_t time_running = get_elapsed_time_since(profile->time_started);
|
||||
|
||||
// probably should use a mutex here
|
||||
qsort(profile->frames, profile->total_frames, sizeof(profile_frame_t), list_comparator);
|
||||
|
||||
for (int i = 0; i < profile->total_frames; ++i)
|
||||
{
|
||||
profile_frame_t *frame = &profile->frames[i];
|
||||
|
||||
printf(
|
||||
"%p\t%p\t%d\t%d\t%.0f%%\n",
|
||||
frame->caller_ptr,
|
||||
frame->func_ptr,
|
||||
frame->num_calls,
|
||||
frame->run_time,
|
||||
(float)frame->run_time / time_running * 100
|
||||
);
|
||||
}
|
||||
|
||||
printf("Profile frames: %d, total time: %d\n", profile->total_frames, time_running);
|
||||
|
||||
profile_lock = false;
|
||||
}
|
||||
|
||||
NO_PROFILE void rg_profiler_push(char *section_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NO_PROFILE void rg_profiler_pop(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NO_PROFILE void __cyg_profile_func_enter(void *this_fn, void *call_site)
|
||||
{
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
while (profile_lock);
|
||||
|
||||
profile_frame_t *fn = find_frame(this_fn, call_site);
|
||||
|
||||
// Recursion
|
||||
if (fn->enter_time != 0)
|
||||
fn->run_time += get_elapsed_time_since(fn->enter_time);
|
||||
|
||||
fn->enter_time = get_elapsed_time();
|
||||
fn->num_calls++;
|
||||
}
|
||||
|
||||
NO_PROFILE void __cyg_profile_func_exit(void *this_fn, void *call_site)
|
||||
{
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
while (profile_lock);
|
||||
|
||||
profile_frame_t *fn = find_frame(this_fn, call_site);
|
||||
|
||||
fn->run_time += get_elapsed_time_since(fn->enter_time);
|
||||
fn->enter_time = 0;
|
||||
}
|
||||
40
components/odroid/odroid_profiler.h
Normal file
40
components/odroid/odroid_profiler.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *func_ptr;
|
||||
void *caller_ptr;
|
||||
uint32_t enter_time;
|
||||
uint32_t num_calls;
|
||||
uint32_t run_time;
|
||||
} profile_frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t time_started;
|
||||
uint64_t time_stopped;
|
||||
uint32_t total_frames;
|
||||
uint32_t locked;
|
||||
profile_frame_t frames[512];
|
||||
} profile_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void rg_profiler_init(void);
|
||||
void rg_profiler_free(void);
|
||||
void rg_profiler_start(void);
|
||||
void rg_profiler_stop(void);
|
||||
void rg_profiler_print(void);
|
||||
void rg_profiler_push(char *section_name);
|
||||
void rg_profiler_pop(void);
|
||||
|
||||
void __cyg_profile_func_enter(void *this_fn, void *call_site);
|
||||
void __cyg_profile_func_exit(void *this_fn, void *call_site);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define NO_PROFILE __attribute((no_instrument_function))
|
||||
@ -16,7 +16,8 @@
|
||||
static bool sdcardOpen = false;
|
||||
|
||||
#define SDCARD_ACCESS_BEGIN() { \
|
||||
if (!sdcardOpen) RG_PANIC("SD Card not initialized"); \
|
||||
/* if (!sdcardOpen) RG_PANIC("SD Card not initialized"); */ \
|
||||
if (!sdcardOpen) { printf("SD Card not initialized\n"); return -1; } \
|
||||
odroid_system_spi_lock_acquire(SPI_LOCK_SDCARD); \
|
||||
}
|
||||
#define SDCARD_ACCESS_END() odroid_system_spi_lock_release(SPI_LOCK_SDCARD)
|
||||
@ -61,9 +62,10 @@ int odroid_sdcard_open()
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
printf("odroid_sdcard_open: esp_vfs_fat_sdmmc_mount failed (%d)\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (ret == ESP_OK) ? 0 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int odroid_sdcard_close()
|
||||
@ -146,7 +148,7 @@ int odroid_sdcard_unzip_file(const char* path, void* buf, size_t buf_size)
|
||||
return count;
|
||||
}
|
||||
|
||||
int odroid_sdcard_list(const char* path, char *out_files, size_t *out_count)
|
||||
int odroid_sdcard_list(const char* path, char **out_files, size_t *out_count)
|
||||
{
|
||||
SDCARD_ACCESS_BEGIN();
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ int odroid_sdcard_open();
|
||||
int odroid_sdcard_close();
|
||||
int odroid_sdcard_mkdir(const char *path);
|
||||
int odroid_sdcard_unlink(const char* path);
|
||||
int odroid_sdcard_list(const char* path, char *out_files, size_t *out_count);
|
||||
int odroid_sdcard_list(const char* path, char **out_files, size_t *out_count);
|
||||
int odroid_sdcard_read_file(const char* path, void* buf, size_t buf_size);
|
||||
int odroid_sdcard_unzip_file(const char* path, void* buf, size_t buf_size);
|
||||
int odroid_sdcard_write_file(const char* path, void* buf, size_t buf_size);
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "odroid_image_sdcard.h"
|
||||
#include "bitmaps/image_sdcard.h"
|
||||
#include "odroid_system.h"
|
||||
|
||||
// This is a direct pointer to rtc slow ram which isn't cleared on
|
||||
@ -70,7 +70,7 @@ void odroid_system_init(int appId, int sampleRate)
|
||||
|
||||
// sdcard init must be before odroid_display_init()
|
||||
// and odroid_settings_init() if JSON is used
|
||||
bool sd_init = odroid_sdcard_open();
|
||||
bool sd_init = (odroid_sdcard_open() == 0);
|
||||
|
||||
odroid_settings_init();
|
||||
odroid_overlay_init();
|
||||
@ -96,11 +96,11 @@ void odroid_system_init(int appId, int sampleRate)
|
||||
if (!sd_init)
|
||||
{
|
||||
odroid_display_clear(C_WHITE);
|
||||
odroid_display_write((ODROID_SCREEN_WIDTH - image_sdcard_red_48dp.width) / 2,
|
||||
(ODROID_SCREEN_HEIGHT - image_sdcard_red_48dp.height) / 2,
|
||||
image_sdcard_red_48dp.width,
|
||||
image_sdcard_red_48dp.height,
|
||||
(uint16_t*)image_sdcard_red_48dp.pixel_data);
|
||||
odroid_display_write((ODROID_SCREEN_WIDTH - image_sdcard.width) / 2,
|
||||
(ODROID_SCREEN_HEIGHT - image_sdcard.height) / 2,
|
||||
image_sdcard.width,
|
||||
image_sdcard.height,
|
||||
(uint16_t*)image_sdcard.pixel_data);
|
||||
odroid_system_halt();
|
||||
}
|
||||
|
||||
@ -111,6 +111,11 @@ void odroid_system_init(int appId, int sampleRate)
|
||||
|
||||
panicTrace->magicWord = 0;
|
||||
|
||||
#ifdef ENABLE_PROFILING
|
||||
printf("%s: Profiling has been enabled at compile time!\n", __func__);
|
||||
rg_profiler_init();
|
||||
#endif
|
||||
|
||||
printf("%s: System ready!\n\n", __func__);
|
||||
}
|
||||
|
||||
@ -425,8 +430,9 @@ void odroid_system_set_led(int value)
|
||||
static void odroid_system_monitor_task(void *arg)
|
||||
{
|
||||
runtime_counters_t current;
|
||||
bool led_state = false;
|
||||
bool letState = false;
|
||||
float tickTime = 0;
|
||||
uint loops = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -476,13 +482,13 @@ static void odroid_system_monitor_task(void *arg)
|
||||
|
||||
if (statistics.battery.percentage < 2)
|
||||
{
|
||||
led_state = !led_state;
|
||||
odroid_system_set_led(led_state);
|
||||
letState = !letState;
|
||||
odroid_system_set_led(letState);
|
||||
}
|
||||
else if (led_state)
|
||||
else if (letState)
|
||||
{
|
||||
led_state = false;
|
||||
odroid_system_set_led(led_state);
|
||||
letState = false;
|
||||
odroid_system_set_led(letState);
|
||||
}
|
||||
|
||||
printf("HEAP:%d+%d (%d+%d), BUSY:%.4f, FPS:%.4f (SKIP:%d, PART:%d, FULL:%d), BATTERY:%d\n",
|
||||
@ -497,7 +503,15 @@ static void odroid_system_monitor_task(void *arg)
|
||||
current.fullFrames,
|
||||
statistics.battery.millivolts);
|
||||
|
||||
#ifdef ENABLE_PROFILING
|
||||
if ((loops % 30) == 0)
|
||||
{
|
||||
rg_profiler_print();
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
loops++;
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
@ -524,7 +538,7 @@ IRAM_ATTR void odroid_system_spi_lock_acquire(spi_lock_res_t owner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (xSemaphoreTake(spiMutex, 10000 / portTICK_RATE_MS) == pdPASS)
|
||||
else if (xSemaphoreTake(spiMutex, pdMS_TO_TICKS(10000)) == pdPASS)
|
||||
{
|
||||
spiMutexOwner = owner;
|
||||
}
|
||||
@ -551,29 +565,30 @@ void *rg_alloc(size_t size, uint32_t caps)
|
||||
|
||||
if (!(caps & MALLOC_CAP_32BIT))
|
||||
{
|
||||
caps |= MALLOC_CAP_8BIT;
|
||||
caps |= MALLOC_CAP_8BIT;
|
||||
}
|
||||
|
||||
ptr = heap_caps_calloc(1, size, caps);
|
||||
|
||||
printf("RG_ALLOC: SIZE: %u [SPIRAM: %u; 32BIT: %u; DMA: %u] PTR: %p\n",
|
||||
size, (caps & MALLOC_CAP_SPIRAM) != 0, (caps & MALLOC_CAP_32BIT) != 0,
|
||||
(caps & MALLOC_CAP_DMA) != 0, ptr);
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
size_t availaible = heap_caps_get_largest_free_block(caps);
|
||||
size_t availaible = heap_caps_get_largest_free_block(caps);
|
||||
|
||||
// Loosen the caps and try again
|
||||
ptr = heap_caps_calloc(1, size, caps & ~(MALLOC_CAP_SPIRAM|MALLOC_CAP_INTERNAL));
|
||||
if (!ptr)
|
||||
{
|
||||
RG_PANIC("Memory allocation failed!");
|
||||
}
|
||||
// Loosen the caps and try again
|
||||
ptr = heap_caps_calloc(1, size, caps & ~(MALLOC_CAP_SPIRAM|MALLOC_CAP_INTERNAL));
|
||||
if (!ptr)
|
||||
{
|
||||
printf("RG_ALLOC: ^-- Allocation failed! (available: %d)\n", availaible);
|
||||
RG_PANIC("Memory allocation failed!");
|
||||
}
|
||||
|
||||
printf("RG_ALLOC: *** CAPS not fully met (req: %d, available: %d) ***\n", size, availaible);
|
||||
printf("RG_ALLOC: ^-- CAPS not fully met! (available: %d)\n", availaible);
|
||||
}
|
||||
|
||||
printf("RG_ALLOC: SIZE: %u [SPIRAM: %u; 32BIT: %u; DMA: %u] PTR: %p\n",
|
||||
size, (caps & MALLOC_CAP_SPIRAM) != 0, (caps & MALLOC_CAP_32BIT) != 0,
|
||||
(caps & MALLOC_CAP_DMA) != 0, ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
@ -14,8 +14,9 @@
|
||||
#include "odroid_audio.h"
|
||||
#include "odroid_display.h"
|
||||
#include "odroid_input.h"
|
||||
#include "odroid_overlay.h"
|
||||
#include "odroid_netplay.h"
|
||||
#include "odroid_overlay.h"
|
||||
#include "odroid_profiler.h"
|
||||
#include "odroid_sdcard.h"
|
||||
#include "odroid_settings.h"
|
||||
|
||||
@ -187,6 +188,12 @@ static inline uint get_elapsed_time_since(uint start)
|
||||
#undef MAX
|
||||
#define MAX(a,b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b);_a > _b ? _a : _b; })
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C
|
||||
#endif
|
||||
|
||||
#define RG_PANIC(x) odroid_system_panic(x, __FUNCTION__, __FILE__)
|
||||
|
||||
#define MEM_ANY 0
|
||||
@ -199,9 +206,3 @@ static inline uint get_elapsed_time_since(uint start)
|
||||
|
||||
void *rg_alloc(size_t size, uint32_t caps);
|
||||
void rg_free(void *ptr);
|
||||
|
||||
void rg_perf_init(void);
|
||||
void rg_perf_reset(void);
|
||||
void rg_perf_print(void);
|
||||
void rg_perf_func_enter(void *func_ptr, char *func_name);
|
||||
void rg_perf_func_leave(void);
|
||||
|
||||
@ -3,3 +3,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
set(COMPONENT_REQUIRES "odroid")
|
||||
register_component()
|
||||
component_compile_options(-O3 -DIS_LITTLE_ENDIAN)
|
||||
|
||||
if(DEFINED ENABLE_PROFILING)
|
||||
component_compile_options(-finstrument-functions)
|
||||
endif()
|
||||
|
||||
@ -3,3 +3,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
set(COMPONENT_REQUIRES "odroid")
|
||||
register_component()
|
||||
component_compile_options(-O3 -Wall -Wno-comment -Wno-error=comment)
|
||||
|
||||
if(DEFINED ENABLE_PROFILING)
|
||||
component_compile_options(-finstrument-functions)
|
||||
endif()
|
||||
|
||||
@ -3,3 +3,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ". includes engine netplay")
|
||||
set(COMPONENT_REQUIRES "odroid")
|
||||
register_component()
|
||||
component_compile_options(-O3 -Wno-all -Wno-error -Wno-sequence-point)
|
||||
|
||||
if(DEFINED ENABLE_PROFILING)
|
||||
component_compile_options(-finstrument-functions)
|
||||
endif()
|
||||
|
||||
@ -3,3 +3,7 @@ set(COMPONENT_ADD_INCLUDEDIRS "cpu nes mappers .")
|
||||
set(COMPONENT_REQUIRES "odroid")
|
||||
register_component()
|
||||
component_compile_options(-O3 -Wno-error=char-subscripts -Wno-error=attributes)
|
||||
|
||||
if(DEFINED ENABLE_PROFILING)
|
||||
component_compile_options(-finstrument-functions)
|
||||
endif()
|
||||
|
||||
@ -120,7 +120,7 @@ void emulator_init(retro_emulator_t *emu)
|
||||
sprintf(path, ODROID_BASE_PATH_ROMS "/%s", emu->dirname);
|
||||
odroid_sdcard_mkdir(path);
|
||||
|
||||
if (odroid_sdcard_list(path, &files, &count) == 0)
|
||||
if (odroid_sdcard_list(path, &files, &count) == 0 && count > 0)
|
||||
{
|
||||
emu->roms.files = rg_alloc(count * sizeof(retro_emulator_file_t), MEM_ANY);
|
||||
emu->roms.count = 0;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# Important: This file is now exec() in the global scope
|
||||
# Notes:
|
||||
# - Enabling netplay in an emulator increases its size by ~350KB
|
||||
# - Enabling profiling in an emulator increases its size by ~50KB
|
||||
# - Keep at least 32KB free in a partition for future updates
|
||||
# - Partitions must be 64K aligned
|
||||
|
||||
|
||||
35
rg_tool.py
35
rg_tool.py
@ -94,7 +94,7 @@ def monitor_app(target, port):
|
||||
|
||||
parser = argparse.ArgumentParser(description="Retro-Go build tool")
|
||||
parser.add_argument(
|
||||
"command", choices=["build", "clean", "release", "mkfw", "flash", "flashmon", "monitor"],
|
||||
"command", choices=["build-fw", "build", "clean", "flash", "monitor", "run"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"targets", nargs="*", default="all", choices=["all"] + list(PROJECT_APPS.keys())
|
||||
@ -102,6 +102,12 @@ parser.add_argument(
|
||||
parser.add_argument(
|
||||
"--use-make", action="store_const", const=True, help="Use legacy make build system"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--profile", action="store_const", const=True, help="Build with profiling enabled"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug", action="store_const", const=True, help="Build with debugging enabled"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port", default="COM3", help="Serial port to use for flash and monitor"
|
||||
)
|
||||
@ -113,26 +119,35 @@ parser.add_argument(
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
command = args.command
|
||||
targets = args.targets if not "all" in args.targets else PROJECT_APPS.keys()
|
||||
|
||||
if command == "clean" or command == "release":
|
||||
|
||||
if command == "build-fw":
|
||||
for target in targets:
|
||||
clean_app(target)
|
||||
build_app(target, args.use_make)
|
||||
build_firmware(targets)
|
||||
|
||||
if command == "build" or command == "release":
|
||||
if command == "build":
|
||||
for target in targets:
|
||||
build_app(target, args.use_make)
|
||||
|
||||
if command == "release" or command == "mkfw":
|
||||
build_firmware(targets)
|
||||
|
||||
if command == "flash" or command == "flashmon":
|
||||
if command == "clean":
|
||||
for target in targets:
|
||||
offset = find_app(target, args.offset, args.app_offset)
|
||||
flash_app(target, args.port, offset)
|
||||
clean_app(target)
|
||||
|
||||
if command == "monitor" or command == "flashmon":
|
||||
if command == "flash":
|
||||
for target in targets:
|
||||
flash_app(target, args.port, find_app(target, args.offset, args.app_offset))
|
||||
|
||||
if command == "monitor":
|
||||
monitor_app(targets[0], args.port)
|
||||
|
||||
if command == "run":
|
||||
build_app(targets[0], args.use_make)
|
||||
flash_app(targets[0], args.port, find_app(targets[0], args.offset, args.app_offset))
|
||||
monitor_app(targets[0], args.port)
|
||||
|
||||
|
||||
|
||||
@ -3,3 +3,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ". cpu sound")
|
||||
set(COMPONENT_REQUIRES "odroid")
|
||||
register_component()
|
||||
component_compile_options(-O3 -DIS_LITTLE_ENDIAN)
|
||||
|
||||
if(DEFINED ENABLE_PROFILING)
|
||||
component_compile_options(-finstrument-functions)
|
||||
endif()
|
||||
|
||||
@ -5,7 +5,7 @@ def readfile(filepath):
|
||||
with open(filepath, "rb") as f: return f.read()
|
||||
|
||||
if len(sys.argv) < 4:
|
||||
exit("usage: mkfw.py output_file description tile <type subtype length label binary> [, ...]")
|
||||
exit("usage: mkfw.py output_file description tile <type subtype length label binfile> [, ...]")
|
||||
|
||||
fw_name = sys.argv[1]
|
||||
|
||||
@ -31,7 +31,7 @@ while pos < len(sys.argv):
|
||||
|
||||
size = max(length, math.ceil(len(data) / 0x10000) * 0x10000)
|
||||
if size > length:
|
||||
print(" > WARNING: Partition will be expanded by %d bytes" % (size - length))
|
||||
print(" > WARNING: Partition smaller than file (+%d bytes), increasing length to %d" % (len(data) - length, size))
|
||||
|
||||
fw_data += struct.pack("<BBxx16sIII", partype, subtype, label.encode(), 0, size, len(data))
|
||||
fw_data += data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user