hz
This commit is contained in:
Executable
+7
@@ -0,0 +1,7 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.c)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${app_sources}
|
||||
INCLUDE_DIRS "." "${CMAKE_SOURCE_DIR}"
|
||||
REQUIRES esp_littlefs espressif__tinyusb
|
||||
)
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#include "answer_code.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* get_error(uint32_t code) {
|
||||
switch (code) {
|
||||
case OS_OK: return "Successfully";
|
||||
|
||||
case OS_ERR_NO_MEMORY: return "Error: Out of memory";
|
||||
case OS_ERR_NOT_INIT: return "Error: The object or table is not initialized";
|
||||
case OS_ERR_NOT_FOUND: return "Error: Not found";
|
||||
case OS_ERR_INVALID_ARG: return "Error: Invalid argument";
|
||||
case OS_ERR_FULL: return "Error: Object is full";
|
||||
case OS_ERR_MAGIC: return "Error: Unknown file type";
|
||||
case OS_WRN_ALREADY_INIT: return "Warning: Attempting to reinitialize an object";
|
||||
case OS_WRN_NOT_NEED_INIT: return "Warning: Attempt to initialize an uninitializable object";
|
||||
|
||||
case VRAM_ERR_RANGE: return "Error: Attempt to write/read outside the video memory block";
|
||||
case VRAM_ERR_HANDLE: return "Error: Invalid or non-existent Handle";
|
||||
case VRAM_WRN_DEFRAG_REQ: return "Warning: Defragmentation required to allocate memory";
|
||||
case VRAM_ERR_WR_or_RD: return "Error: Error reading record";
|
||||
case VRAM_ERR_POOL_MEMORY: return "Error: Memory allocation error";
|
||||
|
||||
case PROC_ERR_STACK: return "Error: There was not enough memory for the task stack.";
|
||||
case PROC_ERR_PRIORITY: return "Error: Invalid FreeRTOS priority";
|
||||
case PROC_ERR_ALIVE: return "Error: Attempting to operate on an already dead process";
|
||||
|
||||
case DISP_ERR_UNSUPPORTED: return "Error: Screen mode or pixel format not supported";
|
||||
|
||||
case APIOS_ERR_DUPLICATE_NAME: return "Error: Attempting to register a driver with a name that is already taken.";
|
||||
case APIOS_ERR_EMPTY_API: return "Error: The driver has an empty function table.";
|
||||
case APIOS_ERR_DRIVER_CRASH: return "Error: Error calling function: The function returned a critical failure that requires unloading.";
|
||||
case APIOS_WRN_PARTIAL_API: return "Warning: The driver is loaded, but some of its functions are not implemented.";
|
||||
case APIOS_ERR_NOT_INITIALIZED: return "Error: Attempting to call an API when the apios table is not initialized";
|
||||
case APIOS_ERR_DRIVER_NOT_FOUND: return "Error: Attempt to call API of non-existent driver";
|
||||
|
||||
default: return "Unknown system error";
|
||||
}
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#ifndef ANSWER_CODE_H
|
||||
#define ANSWER_CODE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define OS_OK 0x00000000
|
||||
|
||||
// Общие системные ошибки (Generic)
|
||||
#define OS_ERR_NO_MEMORY 0x00000001 // Ошибка malloc (не хватило ОЗУ)
|
||||
#define OS_ERR_NOT_INIT 0x00000002 // Объект или таблица не инициализированы (NULL)
|
||||
#define OS_ERR_NOT_FOUND 0x00000003 // Драйвер, функция или файл не найдены
|
||||
#define OS_ERR_INVALID_ARG 0x00000004 // Переданы неверные аргументы (argc/argv)
|
||||
#define OS_ERR_FULL 0x00000005 // Нет места в таблице или массиве
|
||||
#define OS_ERR_MAGIC 0x00000006 // Ошибка проверки магического числа (структура битая)
|
||||
#define OS_WRN_ALREADY_INIT 0x00000007 // Объект уже был инициализирован ранее
|
||||
#define OS_WRN_NOT_NEED_INIT 0x00000008 // Попытка инициалезировать когда она этого не требует
|
||||
|
||||
// Специфические ошибки VRAM (0x10+)
|
||||
#define VRAM_ERR_RANGE 0x00000010 // Попытка записи/чтения за пределами блока
|
||||
#define VRAM_ERR_HANDLE 0x00000011 // Неверный или несуществующий Handle
|
||||
#define VRAM_WRN_DEFRAG_REQ 0x00000012 // Требуется дефрагментация для выделения памяти
|
||||
#define VRAM_ERR_WR_or_RD 0x00000013 // Ошибка чтения записи
|
||||
#define VRAM_ERR_POOL_MEMORY 0x00000014 // Ошибка выделения памяти
|
||||
|
||||
// Ошибки процессов и планировщика (0x20+)
|
||||
#define PROC_ERR_STACK 0x00000020 // Не хватило памяти под стек задачи
|
||||
#define PROC_ERR_PRIORITY 0x00000021 // Недопустимый приоритет FreeRTOS
|
||||
#define PROC_ERR_ALIVE 0x00000022 // Попытка действия над уже мертвым процессом
|
||||
|
||||
// Ошибки графической подсистемы (0x30+)
|
||||
#define DISP_ERR_UNSUPPORTED 0x00000030 // Режим экрана или формат пикселя не поддерживается
|
||||
|
||||
// Ошибки APIOS (0x40+)
|
||||
#define APIOS_ERR_DUPLICATE_NAME 0x00000040 // Попытка зарегистрировать драйвер с именем, которое уже занято
|
||||
#define APIOS_ERR_EMPTY_API 0x00000041 // У драйвера пустая таблица функций (fn_count == 0)
|
||||
#define APIOS_ERR_DRIVER_CRASH 0x00000042 // Ошибка при вызове функции: функция вернула критический сбой, требующий выгрузки
|
||||
#define APIOS_WRN_PARTIAL_API 0x00000043 // Драйвер загружен, но некоторые его функции не реолизованны
|
||||
#define APIOS_ERR_NOT_INITIALIZED 0x00000044 // Попытка вызова API при неинициализированной таблице APIOS
|
||||
#define APIOS_ERR_DRIVER_NOT_FOUND 0x00000045 // Попытка вызвать API несущевствууещего драйвера
|
||||
|
||||
const char* get_error(uint32_t code);
|
||||
|
||||
#endif
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boot/apios.h"
|
||||
#include "boot/typedef.h"
|
||||
#include "boot/answer_code.h"
|
||||
#include "boot/entry.h"
|
||||
|
||||
apios_main_table_t *apios_table = NULL;
|
||||
|
||||
int apios_dump() {
|
||||
if (apios_table == NULL) {
|
||||
printf("\033[31mError: APIOS table is NULL (not initialized)\033[0m\n");
|
||||
return APIOS_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
printf("\n--- \033[34mAPIOS System Dump\033[0m ---\n");
|
||||
printf("Main Table Address: %p\n", (void*)apios_table);
|
||||
printf("Magic: 0x%04X\n", apios_table->magic);
|
||||
printf("Total Drivers: %d\n", apios_table->drivers_count);
|
||||
printf("---------------------------\n");
|
||||
|
||||
for (int i = 0; i < apios_table->drivers_count; i++) {
|
||||
driver_header_t *header = apios_table->drivers[i];
|
||||
|
||||
if (header == NULL) {
|
||||
printf(" [%d] Header is NULL!\n", i);
|
||||
continue;
|
||||
}
|
||||
printf(" [%d] Driver Name: \033[32m%s\033[0m\n", i, header->driver_name);
|
||||
printf(" Header Addr: %p\n", (void*)header);
|
||||
driver_api_t *api = header->api;
|
||||
if (api == NULL) {
|
||||
printf(" \033[31m! API Table is NULL\033[0m\n");
|
||||
continue;
|
||||
}
|
||||
printf(" API Addr: %p (v%d)\n", (void*)api, api->driver_version);
|
||||
printf(" Functions Count: %d\n", api->fn_count);
|
||||
if (api->functions != NULL) {
|
||||
printf(" Functions List:\n");
|
||||
for (int f = 0; f < api->fn_count; f++) {
|
||||
printf(" - [%d] %-15s -> Addr: %p\n",
|
||||
f,
|
||||
api->functions[f].name,
|
||||
(void*)api->functions[f].driver_fn);
|
||||
}
|
||||
} else {
|
||||
printf(" \033[31m! No functions array found\033[0m\n");
|
||||
}
|
||||
printf("---------------------------\n");
|
||||
}
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
int hendle_func(int_fn_t *func, char driver_name[16], char func_name[16]) {
|
||||
if (apios_table == NULL) return APIOS_ERR_NOT_INITIALIZED;
|
||||
bool drv_found = false;
|
||||
for (int i = 0; i < apios_table->drivers_count; i++) {
|
||||
if (strcmp(apios_table->drivers[i]->driver_name, driver_name) == 0) {
|
||||
drv_found = true;
|
||||
driver_api_t *api = apios_table->drivers[i]->api;
|
||||
bool fn_found = false;
|
||||
for (int f = 0; f < api->fn_count; f++) {
|
||||
if (strcmp(api->functions[f].name, func_name) == 0) {
|
||||
*func = api->functions[f].driver_fn;
|
||||
fn_found = true;
|
||||
return OS_OK;
|
||||
}
|
||||
}
|
||||
if (!fn_found) return APIOS_ERR_DRIVER_CRASH;
|
||||
}
|
||||
}
|
||||
if (!drv_found) return APIOS_ERR_DRIVER_NOT_FOUND;
|
||||
return OS_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int init_apios(apios_main_table_t *apios_table_) {
|
||||
if (apios_table == NULL) {
|
||||
if (load_log) printf("APIOS initings...\n");
|
||||
apios_table = (apios_main_table_t *)malloc(sizeof(apios_main_table_t));
|
||||
if (apios_table == NULL){
|
||||
if (load_log) printf("Failed to initialize table\n");
|
||||
return OS_ERR_NO_MEMORY;
|
||||
}
|
||||
static driver_fn_t fs_function[] = {
|
||||
{
|
||||
.name = "dump",
|
||||
.driver_fn = apios_dump,
|
||||
}
|
||||
};
|
||||
driver_api_t *fs_api = (driver_api_t *)malloc(sizeof(driver_api_t));
|
||||
fs_api->driver_version = 1;
|
||||
fs_api->fn_count = (int)(sizeof(fs_function)/sizeof(fs_function[0]));
|
||||
fs_api->functions = fs_function;
|
||||
driver_header_t *driver_header = (driver_header_t *)malloc(sizeof(driver_header_t));
|
||||
strcpy(driver_header->driver_name, "apios");
|
||||
driver_header->api = fs_api;
|
||||
apios_table->magic = 0xfa0c;
|
||||
apios_table->drivers = (driver_header_t **)malloc(sizeof(driver_header_t *) * 100);
|
||||
apios_table->drivers_count = 0;
|
||||
apios_table->drivers[apios_table->drivers_count] = driver_header;
|
||||
apios_table->drivers_count++;
|
||||
}
|
||||
else {
|
||||
if (load_log) printf("The table does not require initialization\n");
|
||||
return OS_WRN_NOT_NEED_INIT;
|
||||
}
|
||||
return OS_OK;
|
||||
}
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef APIOS_H
|
||||
#define APIOS_H
|
||||
|
||||
#include "boot/typedef.h"
|
||||
|
||||
int init_apios(apios_main_table_t *apios_table_);
|
||||
|
||||
extern apios_main_table_t *apios_table;
|
||||
|
||||
#endif
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "boot/apios.h"
|
||||
#include "drivers/fs/fs.h"
|
||||
#include "drivers/monitor/driver.h"
|
||||
#include "lib/video/vram.h"
|
||||
#include "boot/answer_code.h"
|
||||
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
|
||||
void log_result(int res, char *service_name){
|
||||
if (res == OS_OK) {
|
||||
printf("[ \033[0;32mOK\033[0m ] APIOS initialization\n");
|
||||
} else {
|
||||
char *err_text = "Error";
|
||||
const char *msg = get_error(res);
|
||||
if (strncmp(msg, err_text, 5) == 0) {
|
||||
printf("[ \033[0;31mEROR\033[0m ] %s initialization: %s (%d)\n", service_name, msg, res);
|
||||
} else {
|
||||
printf("[ \033[0;33mWARN\033[0m ] %s initialization: %s (%d)\n", service_name, msg, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OS_entry(void *pvParameters)
|
||||
{
|
||||
printf("Initializing subsystems\n");
|
||||
|
||||
log_result(init_apios(apios_table), "APIOS");
|
||||
|
||||
}
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
void OS_entry(void *pvParameters);
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "boot/recovery/boot.h"
|
||||
#include "boot/boot.h"
|
||||
#include "boot/entry.h"
|
||||
|
||||
bool load_log = true;
|
||||
|
||||
int main_entry()
|
||||
{
|
||||
printf("\033[2J\033[H");
|
||||
printf("OS started\n");
|
||||
|
||||
load_log = false;
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
OS_entry,
|
||||
"Os main task",
|
||||
4096,
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int recovery_entry()
|
||||
{
|
||||
printf("\033[2J\033[H");
|
||||
printf("Recovery started\n");
|
||||
|
||||
load_log = true;
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
recovery_shell,
|
||||
"Recovery Shell",
|
||||
4096,
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#ifndef ENTRY_H
|
||||
#define ENTRY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern bool load_log;
|
||||
|
||||
int main_entry();
|
||||
int recovery_entry();
|
||||
|
||||
#endif
|
||||
Executable
+175
@@ -0,0 +1,175 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "boot/recovery/boot.h"
|
||||
#include "boot/recovery/typedef.h"
|
||||
#include "boot/recovery/table.h"
|
||||
#include "boot/apios.h"
|
||||
|
||||
|
||||
|
||||
void recovery_shell(void *pvParameters) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
char buffer[64];
|
||||
char prm[8][16];
|
||||
int current_pos = 0;
|
||||
printf("\033[2J\033[H");
|
||||
printf("\033[32mrecovery:\033[33m> \033[0m");
|
||||
fflush(stdout);
|
||||
memset(buffer, 0, 64);
|
||||
while (1) {
|
||||
int in = getchar();
|
||||
|
||||
if (in == EOF) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
continue;
|
||||
}
|
||||
if (in == 0x08 || in == 0x7F) {
|
||||
if (current_pos > 0) {
|
||||
current_pos--;
|
||||
buffer[current_pos] = '\0';
|
||||
printf("\b \b");
|
||||
fflush(stdout);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (in == '\r' || in == '\n') {
|
||||
printf("\n");
|
||||
|
||||
if (current_pos > 0) {
|
||||
memset(prm, 0, sizeof(prm));
|
||||
int count = 0;
|
||||
char *token = strtok(buffer, " ");
|
||||
while (token != NULL && count < 8) {
|
||||
strncpy(prm[count], token, 15);
|
||||
prm[count][15] = '\0';
|
||||
count++;
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
if (count > 0) {
|
||||
if (strcmp(prm[0], "load") == 0) {
|
||||
char source[16] = "none";
|
||||
char name_load[16] = "none";
|
||||
for (int q = 1; q < count; q++) {
|
||||
char *key = strtok(prm[q], "=");
|
||||
char *val = strtok(NULL, "=");
|
||||
|
||||
if (key && val) {
|
||||
if (strcmp(key, "source") == 0) strncpy(source, val, 15);
|
||||
else if (strcmp(key, "name") == 0) strncpy(name_load, val, 15);
|
||||
}
|
||||
}
|
||||
printf("Action: Loading module [%s] from [%s]\n", name_load, source);
|
||||
bool found = false;
|
||||
int table_size = sizeof(moduls_table) / sizeof(moduls_table[0]);
|
||||
for (int i = 0; i < table_size; i++) {
|
||||
if (strcmp(moduls_table[i].module.name, name_load) == 0) {
|
||||
printf("\033[32mFound!\033[0m Starting driver...\n");
|
||||
int res = moduls_table[i].module.init_fn(apios_table);
|
||||
printf("Driver exited with code: %d\n", res);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && strcmp(name_load, "none") != 0) {
|
||||
printf("\033[31mError:\033[0m Module '%s' not found\n", name_load);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(prm[0], "init") == 0) {
|
||||
char name_load[16] = "none";
|
||||
for (int q = 1; q < count; q++) {
|
||||
char *key = strtok(prm[q], "=");
|
||||
char *val = strtok(NULL, "=");
|
||||
|
||||
if (key && val) {
|
||||
if (strcmp(key, "name") == 0) strncpy(name_load, val, 15);
|
||||
}
|
||||
}
|
||||
int table_size = sizeof(service_init) / sizeof(service_init[0]);
|
||||
bool found = false;
|
||||
for (int i = 0; i < table_size; i++) {
|
||||
if (strcmp(service_init[i].name, name_load) == 0) {
|
||||
printf("\033[32mFound!\033[0m Starting service ...\n");
|
||||
int res = service_init[i].init_fn(apios_table);
|
||||
printf("Service exited with code: %d\n", res);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printf("\033[31mError:\033[0m Service '%s' not found \n", name_load);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(prm[0], "apios") == 0) {
|
||||
char drv_name[16] = "none";
|
||||
char fn_name[16] = "none";
|
||||
|
||||
for (int q = 1; q < count; q++) {
|
||||
char *key = strtok(prm[q], "=");
|
||||
char *val = strtok(NULL, "=");
|
||||
if (key && val) {
|
||||
if (strcmp(key, "driver") == 0) strncpy(drv_name, val, 15);
|
||||
else if (strcmp(key, "func") == 0) strncpy(fn_name, val, 15);
|
||||
}
|
||||
}
|
||||
|
||||
if (apios_table == NULL) {
|
||||
printf("\033[31mError:\033[0m APIOS table not initialized\n");
|
||||
} else {
|
||||
bool drv_found = false;
|
||||
for (int i = 0; i < apios_table->drivers_count; i++) {
|
||||
if (strcmp(apios_table->drivers[i]->driver_name, drv_name) == 0) {
|
||||
drv_found = true;
|
||||
driver_api_t *api = apios_table->drivers[i]->api;
|
||||
bool fn_found = false;
|
||||
for (int f = 0; f < api->fn_count; f++) {
|
||||
if (strcmp(api->functions[f].name, fn_name) == 0) {
|
||||
printf("\033[32mExecuting:\033[0m %s->%s()...\n", drv_name, fn_name);
|
||||
int res = api->functions[f].driver_fn(NULL);
|
||||
|
||||
printf("\n\033[32mDone.\033[0m Return code: %d\n", res);
|
||||
fn_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fn_found) printf("\033[31mError:\033[0m Function '%s' not found in driver '%s'\n", fn_name, drv_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!drv_found) printf("\033[31mError:\033[0m Driver '%s' not found\n", drv_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if (strcmp(prm[0], "help") == 0) {
|
||||
printf("Commands: load source=X name=Y\n");
|
||||
printf("Commands: init name=Y, help\n");
|
||||
printf("Commands: apios driver=Y, func\n");
|
||||
}
|
||||
else {
|
||||
printf("Unknown command: %s\n", prm[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
current_pos = 0;
|
||||
memset(buffer, 0, 64);
|
||||
printf("\033[32mrecovery:\033[33m> \033[0m");
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
if (current_pos < 63) {
|
||||
buffer[current_pos] = (char)in;
|
||||
current_pos++;
|
||||
buffer[current_pos] = '\0';
|
||||
putchar(in);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
void recovery_shell(void *pvParameters);
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#ifndef TABLE_RECOVERY
|
||||
#define TABLE_RECOVERY
|
||||
|
||||
#include "boot/recovery/typedef.h"
|
||||
#include "drivers/fs/fs.h"
|
||||
#include "boot/apios.h"
|
||||
|
||||
load_source_t moduls_table[] = {
|
||||
{
|
||||
.name = "drivers",
|
||||
.module = {
|
||||
.name = "fs",
|
||||
.init_fn = init_fs,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module_t service_init[] = {
|
||||
{
|
||||
.name = "apios",
|
||||
.init_fn = init_apios
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#ifndef TYPEDEF_RECOVERY_H
|
||||
#define TYPEDEF_RECOVERY_H
|
||||
|
||||
struct apios_main_table_t;
|
||||
typedef struct apios_main_table_t apios_main_table_t;
|
||||
|
||||
typedef int (*init_fn_t)(apios_main_table_t *apios_table);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[16];
|
||||
init_fn_t init_fn;
|
||||
} module_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[16];
|
||||
module_t module;
|
||||
} load_source_t;
|
||||
|
||||
#endif
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef TYPEDEF
|
||||
#define TYPEDEF
|
||||
|
||||
struct apios_main_table_t;
|
||||
typedef struct apios_main_table_t apios_main_table_t;
|
||||
|
||||
typedef int (*entry_fn_t)(void *args);
|
||||
|
||||
typedef int (*int_fn_t)();
|
||||
|
||||
typedef struct {
|
||||
char name[128];
|
||||
char type[128];
|
||||
char path[256];
|
||||
entry_fn_t entry_function;
|
||||
} boot_entry_t;
|
||||
|
||||
typedef struct {
|
||||
char name[16];
|
||||
entry_fn_t driver_fn;
|
||||
} driver_fn_t;
|
||||
|
||||
typedef struct {
|
||||
int driver_version;
|
||||
int fn_count;
|
||||
driver_fn_t *functions;
|
||||
} driver_api_t;
|
||||
|
||||
typedef struct {
|
||||
char driver_name[16];
|
||||
driver_api_t *api;
|
||||
} driver_header_t;
|
||||
|
||||
struct apios_main_table_t {
|
||||
int magic;
|
||||
int drivers_count;
|
||||
driver_header_t **drivers;
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#include "boot/entry.h"
|
||||
#include "boot/typedef.h"
|
||||
#include "drivers/eft/eft.h"
|
||||
|
||||
boot_entry_t entry_data[] = {
|
||||
{
|
||||
.name = "ESP32S3-Linux",
|
||||
.type = "operating system",
|
||||
.path = "/boot/boot.bin",
|
||||
.entry_function = main_entry
|
||||
},
|
||||
{
|
||||
.name = "ESP32S3-Recovery",
|
||||
.type = "recovery OS",
|
||||
.path = "/boot/recovery.bin",
|
||||
.entry_function = recovery_entry
|
||||
},
|
||||
{
|
||||
.name = "EFT Server",
|
||||
.type = "server shell",
|
||||
.path = "/drivers/eft/eft_server.bin",
|
||||
.entry_function = eft_server_shell
|
||||
}
|
||||
};
|
||||
|
||||
const int autostart_index = 0;
|
||||
|
||||
const int entry_table_count = 3;
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
int eft_server_shell() {
|
||||
printf("\033[2J\033[H");
|
||||
printf("EFT server shell running\n");
|
||||
|
||||
size_t internal = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t total = esp_get_free_heap_size();
|
||||
size_t max_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
|
||||
printf("\n--- Memory Check ---\n");
|
||||
printf(" Internal RAM free: %u KB\n", internal / 1024);
|
||||
printf(" Total Heap free: %u KB\n", total / 1024);
|
||||
printf(" Max Alloc Block: %u KB\n", max_block / 1024);
|
||||
printf("---------------------------\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int eft_server_shell();
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "drivers/fs/fs.h"
|
||||
#include "boot/typedef.h"
|
||||
#include "boot/answer_code.h"
|
||||
#include "boot/entry.h"
|
||||
|
||||
int mount() {
|
||||
printf("fs: mount");
|
||||
return 0;
|
||||
}
|
||||
int unmount() {
|
||||
printf("fs: unmount");
|
||||
return 0;
|
||||
}
|
||||
int format() {
|
||||
printf("fs: format");
|
||||
return 0;
|
||||
}
|
||||
int get_info() {
|
||||
printf("fs: get_info");
|
||||
return 0;
|
||||
}
|
||||
int is_present() {
|
||||
printf("fs: is_present");
|
||||
return 0;
|
||||
}
|
||||
int get_vfs_config() {
|
||||
printf("fs: get_vfs_config");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_fs(apios_main_table_t *apios_table) {
|
||||
|
||||
(void)apios_table;
|
||||
|
||||
if (apios_table == NULL) {
|
||||
if (load_log) printf("The driver table is not initialized\n");
|
||||
return APIOS_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
static driver_fn_t fs_function[] = {
|
||||
{
|
||||
.name = "mount",
|
||||
.driver_fn = mount,
|
||||
},
|
||||
{
|
||||
.name = "unmount",
|
||||
.driver_fn = unmount,
|
||||
},
|
||||
{
|
||||
.name = "format",
|
||||
.driver_fn = format,
|
||||
},
|
||||
{
|
||||
.name = "get_info",
|
||||
.driver_fn = get_info,
|
||||
},
|
||||
{
|
||||
.name = "is_present",
|
||||
.driver_fn = is_present,
|
||||
},
|
||||
{
|
||||
.name = "get_vfs_config",
|
||||
.driver_fn = get_vfs_config,
|
||||
}
|
||||
};
|
||||
|
||||
driver_api_t *fs_api = (driver_api_t *)malloc(sizeof(driver_api_t));
|
||||
fs_api->driver_version = 1;
|
||||
fs_api->fn_count = (int)(sizeof(fs_function)/sizeof(fs_function[0]));
|
||||
fs_api->functions = fs_function;
|
||||
|
||||
driver_header_t *driver_header = (driver_header_t *)malloc(sizeof(driver_header_t));
|
||||
strcpy(driver_header->driver_name, "FileSystem");
|
||||
driver_header->api = fs_api;
|
||||
|
||||
apios_table->drivers[apios_table->drivers_count] = driver_header;
|
||||
apios_table->drivers_count++;
|
||||
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#include "boot/typedef.h"
|
||||
|
||||
int init_fs(apios_main_table_t *apios_table);
|
||||
|
||||
int mount();
|
||||
int unmount();
|
||||
int format();
|
||||
int get_info();
|
||||
int is_present();
|
||||
int get_vfs_config();
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp_tinyusb: "^1.4.2"
|
||||
espressif/esp-dsp: "^1.4.11"
|
||||
Executable
Executable
Executable
Executable
Executable
Executable
Executable
Executable
+214
@@ -0,0 +1,214 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
|
||||
#include "lib/video/vram.h"
|
||||
#include "boot/answer_code.h"
|
||||
#include "boot/entry.h"
|
||||
|
||||
vram_manager_t *vram_sys = NULL;
|
||||
|
||||
int init_vram(apios_main_table_t *apios_table)
|
||||
{
|
||||
(void)apios_table;
|
||||
|
||||
if (vram_sys != NULL) return OS_WRN_NOT_NEED_INIT;
|
||||
|
||||
int vram_kb[3] = {128, 512, 1024};
|
||||
int8_t val = 1;
|
||||
|
||||
nvs_handle_t h;
|
||||
if (nvs_open("config", NVS_READONLY, &h) == ESP_OK) {
|
||||
if (nvs_get_i8(h, "vram", &val) != ESP_OK || val < 0 || val > 2) {
|
||||
val = 1;
|
||||
}
|
||||
nvs_close(h);
|
||||
} else {
|
||||
if (load_log) printf("VRAM: No saved config, using default 512kb\n");
|
||||
val = 1;
|
||||
}
|
||||
|
||||
vram_sys = (vram_manager_t*)malloc(sizeof(vram_manager_t));
|
||||
if (!vram_sys) return OS_ERR_NO_MEMORY;
|
||||
|
||||
memset(vram_sys, 0, sizeof(vram_manager_t));
|
||||
|
||||
vram_sys->capacity = (uint32_t)(vram_kb[val] * 1024);
|
||||
vram_sys->next_id = 1;
|
||||
vram_sys->max_blocks = 256;
|
||||
vram_sys->blocks_count = 1;
|
||||
|
||||
vram_sys->base_ptr = (uint8_t*)malloc(vram_sys->capacity);
|
||||
vram_sys->blocks = (vram_block_t*)malloc(sizeof(vram_block_t) * vram_sys->max_blocks);
|
||||
|
||||
if (!vram_sys->base_ptr || !vram_sys->blocks) {
|
||||
if (vram_sys->base_ptr) free(vram_sys->base_ptr);
|
||||
if (vram_sys->blocks) free(vram_sys->blocks);
|
||||
free(vram_sys);
|
||||
vram_sys = NULL;
|
||||
return OS_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
vram_sys->blocks[0].offset = 0;
|
||||
vram_sys->blocks[0].size = vram_sys->capacity;
|
||||
vram_sys->blocks[0].is_free = true;
|
||||
vram_sys->blocks[0].id = -1;
|
||||
|
||||
if (load_log) {
|
||||
printf("VRAM: Initialized %d kb at %p\n",
|
||||
vram_kb[val],
|
||||
(void*)vram_sys->base_ptr);
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
vram_handle_t vram_alloc(uint32_t size)
|
||||
{
|
||||
if (!vram_sys) return -1;
|
||||
|
||||
size = (size + 3) & ~3;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (vram_sys->blocks[i].is_free && vram_sys->blocks[i].size >= size) {
|
||||
uint32_t remaining = vram_sys->blocks[i].size - size;
|
||||
|
||||
vram_sys->blocks[i].size = size;
|
||||
vram_sys->blocks[i].is_free = false;
|
||||
vram_sys->blocks[i].id = vram_sys->next_id++;
|
||||
|
||||
if (remaining > 0 && vram_sys->blocks_count < vram_sys->max_blocks) {
|
||||
for (int j = vram_sys->blocks_count; j > i + 1; j--) {
|
||||
vram_sys->blocks[j] = vram_sys->blocks[j - 1];
|
||||
}
|
||||
vram_sys->blocks[i + 1].offset = vram_sys->blocks[i].offset + size;
|
||||
vram_sys->blocks[i + 1].size = remaining;
|
||||
vram_sys->blocks[i + 1].is_free = true;
|
||||
vram_sys->blocks[i + 1].id = -1;
|
||||
vram_sys->blocks_count++;
|
||||
}
|
||||
|
||||
return vram_sys->blocks[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_log) printf("VRAM: No space for %lu bytes! Need defrag.\n", (unsigned long)size);
|
||||
return VRAM_WRN_DEFRAG_REQ;
|
||||
}
|
||||
|
||||
void* vram_get_ptr(vram_handle_t handle)
|
||||
{
|
||||
if (!vram_sys || handle <= 0) return NULL;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (vram_sys->blocks[i].id == handle) {
|
||||
return (void*)(vram_sys->base_ptr + vram_sys->blocks[i].offset);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vram_free(vram_handle_t handle)
|
||||
{
|
||||
if (!vram_sys) return;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (vram_sys->blocks[i].id == handle) {
|
||||
vram_sys->blocks[i].is_free = true;
|
||||
vram_sys->blocks[i].id = -1;
|
||||
|
||||
if (i + 1 < vram_sys->blocks_count && vram_sys->blocks[i + 1].is_free) {
|
||||
vram_sys->blocks[i].size += vram_sys->blocks[i + 1].size;
|
||||
for (int j = i + 1; j < vram_sys->blocks_count - 1; j++) {
|
||||
vram_sys->blocks[j] = vram_sys->blocks[j + 1];
|
||||
}
|
||||
vram_sys->blocks_count--;
|
||||
}
|
||||
|
||||
if (i > 0 && vram_sys->blocks[i - 1].is_free) {
|
||||
vram_sys->blocks[i - 1].size += vram_sys->blocks[i].size;
|
||||
for (int j = i; j < vram_sys->blocks_count - 1; j++) {
|
||||
vram_sys->blocks[j] = vram_sys->blocks[j + 1];
|
||||
}
|
||||
vram_sys->blocks_count--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vram_defrag(void)
|
||||
{
|
||||
if (!vram_sys) return;
|
||||
|
||||
uint32_t current_offset = 0;
|
||||
int write_idx = 0;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (!vram_sys->blocks[i].is_free) {
|
||||
if (vram_sys->blocks[i].offset != current_offset) {
|
||||
memmove(vram_sys->base_ptr + current_offset,
|
||||
vram_sys->base_ptr + vram_sys->blocks[i].offset,
|
||||
vram_sys->blocks[i].size);
|
||||
vram_sys->blocks[i].offset = current_offset;
|
||||
}
|
||||
|
||||
vram_sys->blocks[write_idx] = vram_sys->blocks[i];
|
||||
current_offset += vram_sys->blocks[write_idx].size;
|
||||
write_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
vram_sys->blocks_count = write_idx;
|
||||
|
||||
if (current_offset < vram_sys->capacity) {
|
||||
vram_sys->blocks[write_idx].offset = current_offset;
|
||||
vram_sys->blocks[write_idx].size = vram_sys->capacity - current_offset;
|
||||
vram_sys->blocks[write_idx].is_free = true;
|
||||
vram_sys->blocks[write_idx].id = -1;
|
||||
vram_sys->blocks_count++;
|
||||
}
|
||||
|
||||
if (load_log) {
|
||||
printf("VRAM: Defrag complete. Free: %lu bytes\n",
|
||||
(unsigned long)(vram_sys->capacity - current_offset));
|
||||
}
|
||||
}
|
||||
|
||||
int vram_write(vram_handle_t handle, const void *src, uint32_t size)
|
||||
{
|
||||
if (!vram_sys || handle <= 0 || !src) return -1;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (vram_sys->blocks[i].id == handle) {
|
||||
uint32_t write_size = (size < vram_sys->blocks[i].size)
|
||||
? size
|
||||
: vram_sys->blocks[i].size;
|
||||
memcpy(vram_sys->base_ptr + vram_sys->blocks[i].offset, src, write_size);
|
||||
return OS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return VRAM_ERR_WR_or_RD;
|
||||
}
|
||||
|
||||
int vram_read(vram_handle_t handle, void *dst, uint32_t size)
|
||||
{
|
||||
if (!vram_sys || handle <= 0 || !dst) return -1;
|
||||
|
||||
for (int i = 0; i < vram_sys->blocks_count; i++) {
|
||||
if (vram_sys->blocks[i].id == handle) {
|
||||
uint32_t read_size = (size < vram_sys->blocks[i].size)
|
||||
? size
|
||||
: vram_sys->blocks[i].size;
|
||||
memcpy(dst, vram_sys->base_ptr + vram_sys->blocks[i].offset, read_size);
|
||||
return OS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return VRAM_ERR_WR_or_RD;
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#ifndef VRAM_H
|
||||
#define VRAM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "boot/typedef.h"
|
||||
|
||||
typedef int32_t vram_handle_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
bool is_free;
|
||||
vram_handle_t id;
|
||||
} vram_block_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* base_ptr;
|
||||
uint32_t capacity;
|
||||
vram_block_t* blocks;
|
||||
int blocks_count;
|
||||
int max_blocks;
|
||||
vram_handle_t next_id;
|
||||
} vram_manager_t;
|
||||
|
||||
|
||||
extern vram_manager_t *vram_sys;
|
||||
|
||||
int init_vram(apios_main_table_t *apios_table_);
|
||||
vram_handle_t vram_alloc(uint32_t size);
|
||||
void vram_free(vram_handle_t handle);
|
||||
void* vram_get_ptr(vram_handle_t handle);
|
||||
int vram_write(vram_handle_t handle, const void* src, uint32_t size);
|
||||
int vram_read(vram_handle_t handle, void* dst, uint32_t size);
|
||||
void vram_defrag();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Executable
+1351
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user