added support for FreeRTOS

This commit is contained in:
suiauthon
2016-02-15 11:15:42 +01:00
parent 702f6f0560
commit b4f6e1e553
6 changed files with 154 additions and 19 deletions
@@ -19,6 +19,10 @@
# define UAVCAN_STM32_BAREMETAL 0
#endif
#ifndef UAVCAN_STM32_FREERTOS
# define UAVCAN_STM32_FREERTOS 0
#endif
/**
* Number of interfaces must be enabled explicitly
*/
@@ -17,6 +17,12 @@
# include <ctime>
# include <cstring>
#elif UAVCAN_STM32_BAREMETAL
#elif UAVCAN_STM32_FREERTOS
# include <stm32f4xx.h>
# include <cmsis_os.h>
#ifndef MAX_SEMAPHORE_COUNT
#define MAX_SEMAPHORE_COUNT 50
#endif
#else
# error "Unknown OS"
#endif
@@ -136,7 +142,7 @@ public:
(void)can_driver;
}
bool wait(uavcan::MonotonicDuration)
bool wait(uavcan::MonotonicDuration duration)
{
(void)duration;
bool lready = ready;
@@ -161,6 +167,40 @@ public:
void unlock() { }
};
#elif UAVCAN_STM32_FREERTOS
class BusEvent
{
SemaphoreHandle_t sem_;
BaseType_t xHigherPriorityTaskWoken;
public:
BusEvent(CanDriver& can_driver)
{
(void)can_driver;
sem_ = xSemaphoreCreateCounting( MAX_SEMAPHORE_COUNT, 0 );
}
bool wait(uavcan::MonotonicDuration duration);
void signal();
void signalFromInterrupt();
};
class Mutex
{
SemaphoreHandle_t mtx_;
BaseType_t xHigherPriorityTaskWoken;
public:
Mutex(void)
{
mtx_ = xSemaphoreCreateMutex();
}
void lock();
void unlock();
};
#endif
@@ -14,7 +14,10 @@
# include <chip/stm32_tim.h>
# include <syslog.h>
#elif UAVCAN_STM32_BAREMETAL
# include <chip.h>
# include <stm32f4xx.h>
#elif UAVCAN_STM32_FREERTOS
# include <stm32f4xx.h>
# include <cmsis_os.h>
#else
# error "Unknown OS"
#endif
@@ -71,6 +74,15 @@
# endif
#endif
#if UAVCAN_STM32_FREERTOS
/**
* Priority mask for timer and CAN interrupts.
*/
# ifndef UAVCAN_STM32_IRQ_PRIORITY_MASK
# define UAVCAN_STM32_IRQ_PRIORITY_MASK configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
# endif
#endif
/**
* Glue macros
*/
@@ -122,6 +134,22 @@ struct CriticalSectionLocker
}
};
#elif UAVCAN_STM32_FREERTOS
struct CriticalSectionLocker
{
//TODO napisati funkcije
CriticalSectionLocker()
{
taskENTER_CRITICAL();
}
~CriticalSectionLocker()
{
taskEXIT_CRITICAL();
}
};
#endif
namespace clock
@@ -15,7 +15,10 @@
# include <nuttx/irq.h>
# include <arch/board/board.h>
#elif UAVCAN_STM32_BAREMETAL
#include <chip.h>
#include <stm32f4xx.h>
#elif UAVCAN_STM32_FREERTOS
#include <stm32f4xx.h>
#include <cmsis_os.h>
#else
# error "Unknown OS"
#endif
@@ -200,11 +203,13 @@ int CanIface::computeTimings(const uavcan::uint32_t target_bitrate, Timings& out
* Hardware configuration
*/
#if UAVCAN_STM32_BAREMETAL
const uavcan::uint32_t pclk = STM32_PCLK1_FREQUENCY;
const uavcan::uint32_t pclk = STM32_PCLK1;
#elif UAVCAN_STM32_CHIBIOS
const uavcan::uint32_t pclk = STM32_PCLK1;
#elif UAVCAN_STM32_NUTTX
const uavcan::uint32_t pclk = STM32_PCLK1_FREQUENCY;
#elif UAVCAN_STM32_FREERTOS
const uavcan::uint32_t pclk = HAL_RCC_GetPCLK1Freq();
#else
# error "Unknown OS"
#endif
@@ -454,7 +459,7 @@ uavcan::int16_t CanIface::configureFilters(const uavcan::CanFilterConfig* filter
bool CanIface::waitMsrINakBitStateChange(bool target_state)
{
#if UAVCAN_STM32_NUTTX || UAVCAN_STM32_CHIBIOS
#if UAVCAN_STM32_NUTTX || UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_FREERTOS
const unsigned Timeout = 1000;
#else
const unsigned Timeout = 2000000;
@@ -471,6 +476,9 @@ bool CanIface::waitMsrINakBitStateChange(bool target_state)
#endif
#if UAVCAN_STM32_CHIBIOS
::chThdSleep(MS2ST(1));
#endif
#if UAVCAN_STM32_FREERTOS
//::osDelay(1);
#endif
}
return false;
@@ -861,16 +869,18 @@ uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks,
}
#if UAVCAN_STM32_BAREMETAL
#if UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
static void nvicEnableVector(int irq, uint8_t prio)
static void nvicEnableVector(IRQn_Type irq, uint8_t prio)
{
NVIC_InitTypeDef NVIC_InitStructure;
/*NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_Init(&NVIC_InitStructure);*/
HAL_NVIC_SetPriority(irq, prio, 0);
HAL_NVIC_EnableIRQ(irq);
}
#endif
@@ -923,7 +933,7 @@ void CanDriver::initOnce()
IRQ_ATTACH(STM32_IRQ_CAN2RX1, can2_irq);
# endif
# undef IRQ_ATTACH
#elif UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
#elif UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
{
CriticalSectionLocker lock;
nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
@@ -14,7 +14,7 @@
/*
* Timer instance
*/
# if (UAVCAN_STM32_CHIBIOS && CH_KERNEL_MAJOR == 2) || UAVCAN_STM32_BAREMETAL
# if (UAVCAN_STM32_CHIBIOS && CH_KERNEL_MAJOR == 2) || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
# define TIMX UAVCAN_STM32_GLUE2(TIM, UAVCAN_STM32_TIMER_NUMBER)
# define TIMX_IRQn UAVCAN_STM32_GLUE3(TIM, UAVCAN_STM32_TIMER_NUMBER, _IRQn)
# define TIMX_INPUT_CLOCK STM32_TIMCLK1
@@ -81,16 +81,18 @@ uavcan::uint64_t time_utc = 0;
}
#if UAVCAN_STM32_BAREMETAL
#if UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
static void nvicEnableVector(int irq, uint8_t prio)
static void nvicEnableVector(IRQn_Type irq, uint8_t prio)
{
NVIC_InitTypeDef NVIC_InitStructure;
/*NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_Init(&NVIC_InitStructure);*/
HAL_NVIC_SetPriority(irq, prio, 0);
HAL_NVIC_EnableIRQ(irq);
}
@@ -106,7 +108,7 @@ void init()
initialized = true;
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
// Power-on and reset
TIMX_RCC_ENR |= TIMX_RCC_ENR_MASK;
TIMX_RCC_RSTR |= TIMX_RCC_RSTR_MASK;
@@ -178,7 +180,7 @@ void setUtc(uavcan::UtcTime time)
static uavcan::uint64_t sampleUtcFromCriticalSection()
{
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
UAVCAN_ASSERT(initialized);
UAVCAN_ASSERT(TIMX->DIER & TIM_DIER_UIE);
@@ -228,7 +230,7 @@ uavcan::MonotonicTime getMonotonic()
volatile uavcan::uint64_t time = time_mono;
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
volatile uavcan::uint32_t cnt = TIMX->CNT;
if (TIMX->SR & TIM_SR_UIF)
@@ -435,7 +437,7 @@ UAVCAN_STM32_IRQ_HANDLER(TIMX_IRQHandler)
{
UAVCAN_STM32_IRQ_PROLOGUE();
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
TIMX->SR = 0;
# endif
# if UAVCAN_STM32_NUTTX
@@ -7,6 +7,7 @@
#include <uavcan_stm32/can.hpp>
#include "internal.hpp"
namespace uavcan_stm32
{
@@ -79,6 +80,56 @@ void Mutex::unlock()
# endif
}
#elif UAVCAN_STM32_FREERTOS
bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
static const uavcan::int64_t MaxDelayMSec = 0x000FFFFF;
const uavcan::int64_t msec = duration.toMSec();
BaseType_t ret;
if (msec <= 0)
{
ret = xSemaphoreTake( sem_, ( TickType_t ) 0 );
}
else
{
ret = xSemaphoreTake( sem_, (msec > MaxDelayMSec) ? (MaxDelayMSec/portTICK_RATE_MS) : (msec/portTICK_RATE_MS));
}
return ret == pdTRUE;
}
void BusEvent::signal()
{
xSemaphoreGive( sem_ );
}
void BusEvent::signalFromInterrupt()
{
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( sem_, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
/*
* Mutex
*/
void Mutex::lock()
{
xSemaphoreTake( mtx_, portMAX_DELAY );
}
void Mutex::unlock()
{
xSemaphoreGive( mtx_ );
}
#elif UAVCAN_STM32_NUTTX
const unsigned BusEvent::MaxPollWaiters;