Add VM task and source files to build system, wip: qor API

This commit is contained in:
Anthony Rabine 2023-07-26 21:41:56 +02:00
parent 802f818735
commit 5104f9a6c0
5 changed files with 176 additions and 68 deletions

View file

@ -42,12 +42,14 @@ set(OST_SRCS
system/ff/ff.c
system/ff/ffsystem.c
system/ff/ff_stubs.c
chip32/chip32_vm.c
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/library
${CMAKE_CURRENT_SOURCE_DIR}/system
${CMAKE_CURRENT_SOURCE_DIR}/system/ff
${CMAKE_CURRENT_SOURCE_DIR}/chip32
)
# ==================================================================================================

View file

@ -30,8 +30,8 @@
// ===========================================================================================================
// CONSTANTS / DEFINES
// ===========================================================================================================
const uint8_t LED_PIN = 14; // GP 14
const uint8_t DEBUG_PIN = 1;
const uint8_t LED_PIN = 14;
const uint8_t LCD_DC = 8;
const uint8_t LCD_CS = 9;
@ -99,6 +99,10 @@ void ost_system_initialize()
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
//------------------- Init DEBUG PIN
gpio_init(DEBUG_PIN);
gpio_set_dir(DEBUG_PIN, GPIO_OUT);
//------------------- Init UART
// Set up our UART with the required speed.
@ -180,6 +184,25 @@ void system_putc(char ch)
uart_putc_raw(UART_ID, ch);
}
#include <time.h>
clock_t clock()
{
return (clock_t)time_us_64() / 1000;
}
static uint64_t stopwatch_start_time;
static uint64_t stopwatch_end_time;
void ost_system_stopwatch_start()
{
stopwatch_start_time = clock();
}
uint32_t ost_system_stopwatch_stop()
{
stopwatch_end_time = clock();
return (stopwatch_end_time - stopwatch_start_time);
}
int ost_hal_gpio_get(ost_hal_gpio_t gpio)
{
int value = 0;
@ -205,6 +228,9 @@ void ost_hal_gpio_set(ost_hal_gpio_t gpio, int value)
case OST_GPIO_DEBUG_LED:
gpio_put(LED_PIN, value);
break;
case OST_GPIO_DEBUG_PIN:
gpio_put(DEBUG_PIN, value);
break;
// Nothing to do for these inputes
case OST_GPIO_ROTARY_A:

View file

@ -6,47 +6,6 @@
#include "qor.h"
#include "rotary-button.h"
#define RUN_TESTS 1
#ifndef RUN_TESTS
int main(void)
{
// Low level initialization, mainly platform stuff
// After this call, debug_printf *MUST* be available
ost_system_initialize();
debug_printf("\r\n [OST] Starting OpenStoryTeller tests: V%d.%d\r\n", 1, 0);
// File system access
filesystem_mount();
// Display
ost_display_initialize();
decompress();
// Audio
// Tasker
ost_tasker_init();
for (;;)
{
}
return 0;
}
#else
// Raspberry Pico SDK
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/spi.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "pico.h"
#include "pico/stdlib.h"
#include "sdcard.h"
#include <stdint.h>
@ -54,13 +13,76 @@ int main(void)
#include <stdlib.h>
#include "audio_player.h"
#include "chip32_vm.h"
void ost_hal_panic()
{
}
// ===========================================================================================================
// SD CARD TASK
// VIRTUAL MACHINE TASK
// ===========================================================================================================
static qor_tcb_t VmTcb;
static uint32_t VmStack[4096];
static qor_mbox_t VmMailBox;
typedef struct
{
uint8_t ev;
} ost_vm_event_t;
ost_vm_event_t VmQueue[10];
static ost_vm_event_t VmEvent;
static uint8_t m_rom_data[16 * 1024];
static uint8_t m_ram_data[16 * 1024];
static chip32_ctx_t m_chip32_ctx;
uint8_t vm_syscall(chip32_ctx_t *ctx, uint8_t signum)
{
}
void VmTask(void *args)
{
// VM Initialize
m_chip32_ctx.stack_size = 512;
m_chip32_ctx.rom.mem = m_rom_data;
m_chip32_ctx.rom.addr = 0;
m_chip32_ctx.rom.size = sizeof(m_rom_data);
m_chip32_ctx.ram.mem = m_ram_data;
m_chip32_ctx.ram.addr = sizeof(m_rom_data);
m_chip32_ctx.ram.size = sizeof(m_ram_data);
m_chip32_ctx.syscall = vm_syscall;
chip32_initialize(&m_chip32_ctx);
chip32_result_t run_result;
ost_vm_event_t *e = NULL;
while (1)
{
uint32_t res = qor_mbox_wait(&VmMailBox, (void **)&e, 300); // On devrait recevoir un message toutes les 3ms (durée d'envoi d'un buffer I2S)
if (res == QOR_MBOX_OK)
{
if (VmEvent.ev == 1)
{
do
{
run_result = chip32_step(&m_chip32_ctx);
} while (run_result != VM_OK);
}
}
}
}
// ===========================================================================================================
// FILE SYSTEM TASK
// ===========================================================================================================
static qor_tcb_t AudioTcb;
static uint32_t AudioStack[4096];
@ -82,14 +104,8 @@ static int dbg_state = 0;
static void audio_callback(void)
{
dbg_state = 1 - dbg_state;
gpio_put(1, dbg_state);
qor_mbox_notify(&AudioMailBox, (void **)&wake_up, QOR_MBOX_OPTION_SEND_BACK);
}
#include <time.h>
clock_t clock()
{
return (clock_t)time_us_64() / 1000;
}
void show_duration(uint32_t millisecondes)
{
@ -116,16 +132,12 @@ void AudioTask(void *args)
ost_audio_register_callback(audio_callback);
gpio_init(1);
gpio_set_dir(1, GPIO_OUT);
static bool onetime = true;
gpio_put(1, 0);
while (1)
{
debug_printf("\r\n-------------------------------------------------------\r\nPlaying: out2.wav\r\n");
clock_t startTime = clock();
ost_system_stopwatch_start();
ost_audio_play("out2.wav");
ost_audio_event_t *e = NULL;
@ -145,9 +157,8 @@ void AudioTask(void *args)
} while (isPlaying);
uint32_t executionTime = ost_system_stopwatch_stop();
ost_audio_stop();
clock_t endTime = clock();
uint32_t executionTime = endTime - startTime;
debug_printf("\r\nPackets: %d\r\n", count);
show_duration(executionTime);
@ -190,14 +201,15 @@ int main()
// 3. Filesystem / SDCard initialization
filesystem_mount();
// 4. Initialize OS and threads
// 4. Initialize OS before all other OS calls
qor_init(125000000UL);
// qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_1");
// qor_create_thread(&tcb2, UserTask_2, 1, "UserTask_2");
// 5. Initialize the tasks
qor_create_thread(&VmTcb, VmTask, VmStack, sizeof(VmStack) / sizeof(VmStack[0]), 2, "VmTask");
qor_create_thread(&AudioTcb, AudioTask, AudioStack, sizeof(AudioStack) / sizeof(AudioStack[0]), 3, "AudioTask"); ///< High priority for audio
// 6. Start the operating system!
qor_start(&IdleTcb, IdleTask, IdleStack, 1024);
return 0;
}
#endif

View file

@ -38,6 +38,7 @@ extern "C"
OST_GPIO_ROTARY_A,
OST_GPIO_ROTARY_B,
OST_GPIO_DEBUG_LED,
OST_GPIO_DEBUG_PIN,
} ost_hal_gpio_t;
// ----------------------------------------------------------------------------
@ -47,6 +48,9 @@ extern "C"
void system_putc(char ch);
void ost_system_delay_ms(uint32_t delay);
void ost_system_stopwatch_start();
uint32_t ost_system_stopwatch_stop();
void ost_audio_play(const char *filename);
void ost_audio_stop();
int ost_audio_process();

View file

@ -1,6 +1,8 @@
#ifndef QOR_H
#define QOR_H
#define QOR_VERSION "0.1"
#include <stdint.h>
#include <stdbool.h>
@ -23,24 +25,24 @@ typedef void (*thread_func_t)(void *args);
*/
typedef enum
{
qor_tcb_state_active,
qor_tcb_state_sleep
qor_tcb_state_active, //!< Thread is active (and can be scheduled or is currently running)
qor_tcb_state_sleep //!< Thread is wating for mailbox or sleep
} qor_tcb_state_t;
typedef struct qor_mbox_t qor_mbox_t; //!< Foreward declaration
/**
* @brief Thread Control Block
*
* IMPORTANT! keep the stack pointer on top, it is required by the task switch assembly
*
*/
typedef struct qor_mbox_t qor_mbox_t;
typedef struct TCB
{
uint32_t *sp; //!< Stack pointer, valid for threads not running
uint32_t *sp; //!< Stack pointer, valid for threads not running, keep it on top
struct TCB *next; //!< Pointer to circular-linked-list of TCBs
struct TCB *wait_next; //!< Next TCB in waiting list
uint32_t stack_size;
uint32_t stack_size; //!< Stack size, in number of uint32_t
qor_tcb_state_t state; //!< TCB active or free
uint32_t wait_time; //!< Timeout for mbox maiting or sleep
qor_mbox_t *mbox; //!< Pointer to mailbox on which the thread is blocked, NULL if not blocked
@ -51,21 +53,55 @@ typedef struct TCB
// Debug/traces
uint32_t stack_usage;
uint32_t *stack_bottom;
bool so; // stack overflow detected
bool so; //!< stack overflow detected
} qor_tcb_t;
/**
* @brief QoRTOS initialization, call it before anything else
*
* @param scheduler_frequency_hz: CPU frequency in Hz
*/
void qor_init(uint32_t scheduler_frequency_hz);
/**
* @brief
*
* @param tcb
* @param task
* @param stack
* @param stack_size
* @param priority
* @param name
*/
void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint32_t *stack, uint32_t stack_size, uint8_t priority, const char *name);
/**
* @brief
*
* @param idle_tcb
* @param idle_task
* @param idle_stack
* @param idle_stack_size
* @return true
* @return false
*/
bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task, uint32_t *idle_stack, uint32_t idle_stack_size);
/**
* @brief
*
* @param sleep_duration_ms
*/
void qor_sleep(uint32_t sleep_duration_ms);
// ===========================================================================================================
// MAILBOX API
// ===========================================================================================================
/**
* @brief
*
*/
struct qor_mbox_t
{
qor_tcb_t *head;
@ -76,6 +112,10 @@ struct qor_mbox_t
void **msgBuffer;
};
/**
* @brief
*
*/
typedef struct
{
uint32_t count;
@ -88,12 +128,36 @@ typedef struct
#define QOR_MBOX_ERROR 3
#define QOR_MBOX_FULL 4
/**
* @brief
*
* @param mbox
* @param msgBuffer
* @param maxCount
*/
void qor_mbox_init(qor_mbox_t *mbox, void **msgBuffer, uint32_t maxCount);
/**
* @brief
*
* @param mbox
* @param msg
* @param wait_ms
* @return uint32_t
*/
uint32_t qor_mbox_wait(qor_mbox_t *mbox, void **msg, uint32_t wait_ms);
#define QOR_MBOX_OPTION_SEND_FRONT 1
#define QOR_MBOX_OPTION_SEND_BACK 2
/**
* @brief
*
* @param mbox
* @param msg
* @param notifyOption
* @return uint32_t
*/
uint32_t qor_mbox_notify(qor_mbox_t *mbox, void *msg, uint32_t notifyOption);
#endif // QOR_H