Verified Commit f87de543 authored by Rahix's avatar Rahix
Browse files

feat(epicardium): Port to FreeRTOS


Signed-off-by: Rahix's avatarRahix <rahix@rahix.de>
parent 341b7660
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "max32665.h"
/* CMSIS keeps a global updated with current system clock in Hz */
#define configCPU_CLOCK_HZ ((unsigned long)120000000)
/* TODO: Adjust this for tickless idle */
#define configTICK_RATE_HZ ((portTickType)1000)
/* Memory */
#define configTOTAL_HEAP_SIZE ((size_t)(26 * 1024))
#define configMINIMAL_STACK_SIZE ((unsigned short)128)
#define configMAX_PRIORITIES 5
/* # of priority bits (configured in hardware) is provided by CMSIS */
#define configPRIO_BITS __NVIC_PRIO_BITS
/* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY ( ( unsigned char ) 7 << ( 8 - configPRIO_BITS) )
/* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( ( unsigned char ) 5 << ( 8 - configPRIO_BITS) )
/* We want to use preemption to easier integrate components */
#define configUSE_PREEMPTION 1
/* TODO: Adjust */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_CO_ROUTINES 0
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelay 1
/* Allow static allocation of data structures */
#define configSUPPORT_STATIC_ALLOCATION 1
/* Alias the default handler names to match CMSIS weak symbols */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif /* FREERTOS_CONFIG_H */
......@@ -344,7 +344,10 @@ void USB_IRQHandler(void)
}
/******************************************************************************/
/* TODO: We probably need to fix something related to this */
#if 0
void SysTick_Handler(void)
{
mxc_delay_handler();
}
#endif /* 0 */
#include <stdio.h>
#include "card10.h"
#include <stdlib.h>
#include "uart.h"
#include "cdcacm.h"
#include "card10.h"
#include "leds.h"
#include "api/dispatcher.h"
#include "serial.h"
extern mxc_uart_regs_t * ConsoleUart;
#include "FreeRTOS.h"
#include "task.h"
void epic_uart_write_str(char*str, intptr_t length)
void epic_leds_set(int led, uint8_t r, uint8_t g, uint8_t b)
{
UART_Write(ConsoleUart, (uint8_t*)str, length);
cdcacm_write((uint8_t*)str, length);
leds_set(led, r, g, b);
leds_update();
}
char epic_uart_read_chr(void)
void vApiDispatcher(void*pvParameters)
{
while(1) {
if(UART_NumReadAvail(ConsoleUart) > 0) {
return UART_ReadByte(ConsoleUart);
}
if(cdcacm_num_read_avail() > 0) {
return cdcacm_read();
}
while (1) {
api_dispatcher_poll();
vTaskDelay(portTICK_PERIOD_MS * 10);
}
}
void epic_leds_set(int led, uint8_t r, uint8_t g, uint8_t b)
void vApplicationGetIdleTaskMemory(
StaticTask_t**ppxIdleTaskTCBBuffer,
StackType_t**ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
leds_set(led, r, g, b);
leds_update();
/*
* If the buffers to be provided to the Idle task are declared inside this
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits.
*/
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/*
* Pass out a pointer to the StaticTask_t structure in which the Idle task's
* ktate will be stored.
*/
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/*
* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes.
*/
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
int main(void)
......@@ -39,14 +63,46 @@ int main(void)
cdcacm_init();
printf("Initializing tasks ...\n");
/* Serial */
if (xTaskCreate(
vSerialTask,
(const char*)"Serial",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL
) != pdPASS) {
printf("Failed to create serial-comms task!\n");
abort();
}
if (xTaskCreate(
vApiDispatcher,
(const char*)"API Dispatcher",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 2,
NULL
) != pdPASS) {
printf("Failed to create api dispatcher task!\n");
abort();
}
printf("Initializing dispatcher ...\n");
api_dispatcher_init();
printf("Staring core1 payload ...\n");
core1_start();
vTaskStartScheduler();
printf("ERROR: FreeRTOS did not start due to above error!\n");
#if 0
while(1) {
__WFE();
api_dispatcher_poll();
}
#endif
}
......@@ -39,6 +39,22 @@ api_dispatcher_lib = static_library(
dependencies: periphdriver,
)
##########################################################################
#
# FreeRTOS
#
##########################################################################
freertos = static_library(
'freertos',
freertos_sources,
dependencies: periphdriver,
include_directories: [
freertos_includes,
include_directories('./'),
],
)
##########################################################################
#
# Epicardium executable
......@@ -49,9 +65,11 @@ elf = executable(
name + '.elf',
'main.c',
'cdcacm.c',
'serial.c',
dependencies: [libcard10, max32665_startup_core0, maxusb],
link_with: api_dispatcher_lib,
link_with: [api_dispatcher_lib, freertos],
link_whole: [max32665_startup_core0_lib, board_card10_lib],
include_directories: [freertos_includes],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
......
#include <stdint.h>
#include <stdio.h>
#include "serial.h"
#include "cdcacm.h"
#include "uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
extern mxc_uart_regs_t * ConsoleUart;
static QueueHandle_t read_queue;
void epic_uart_write_str(char*str, intptr_t length)
{
UART_Write(ConsoleUart, (uint8_t*)str, length);
cdcacm_write((uint8_t*)str, length);
}
char epic_uart_read_chr(void)
{
char chr;
xQueueReceive(read_queue, &chr, portMAX_DELAY);
return chr;
}
void vSerialTask(void*pvParameters)
{
static uint8_t buffer[sizeof(char) * SERIAL_READ_BUFFER_SIZE];
static StaticQueue_t read_queue_data;
/* Setup read queue */
read_queue = xQueueCreateStatic(
SERIAL_READ_BUFFER_SIZE,
sizeof(char),
buffer,
&read_queue_data
);
/* Setup UART interrupt */
NVIC_ClearPendingIRQ(UART0_IRQn);
NVIC_DisableIRQ(UART0_IRQn);
NVIC_SetPriority(UART0_IRQn, 1);
NVIC_EnableIRQ(UART0_IRQn);
while (1) {
char chr;
/* TODO: Wait for interrupt on either device */
vTaskDelay(portTICK_PERIOD_MS * 10);
if(UART_NumReadAvail(ConsoleUart) > 0) {
chr = UART_ReadByte(ConsoleUart);
} else if(cdcacm_num_read_avail() > 0) {
chr = cdcacm_read();
} else {
continue;
}
if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) {
/* Queue overran, wait a bit */
vTaskDelay(portTICK_PERIOD_MS * 50);
}
}
}
#ifndef EPIC_SERIAL_H
#define EPIC_SERIAL_H
#define SERIAL_READ_BUFFER_SIZE 128
void vSerialTask(void*pvParameters);
#endif /* EPIC_SERIAL_H */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment