mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Add VM task and source files to build system, wip: qor API
This commit is contained in:
parent
802f818735
commit
5104f9a6c0
5 changed files with 176 additions and 68 deletions
|
|
@ -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
|
||||
)
|
||||
|
||||
# ==================================================================================================
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue