NorthStar-Endurance-TestBench/NorthStar-Emotas-Stack/codrv_sl/stm32_mcan/codrv_FreeRTOS.c

273 lines
6.9 KiB
C

/*
* codrv_FreeRTOS.c - contains OS specific function definitions
*
* Copyright (c) 2012-2020 emotas embedded communication GmbH
*-------------------------------------------------------------------
* $Id: codrv_FreeRTOS.c 54858 2024-07-31 14:37:47Z hil $
*
*
*-------------------------------------------------------------------
*
*
*/
/********************************************************************/
/**
* \file
* \brief OS specific function definitions
*
*/
/* header of standard C - libraries
---------------------------------------------------------------------------*/
/* header of project specific types
---------------------------------------------------------------------------*/
#include <gen_define.h>
#ifdef CODRV_USE_FREERTOS
#include <co_canopen.h>
#include <FreeRTOS.h>
#include <event_groups.h>
#include <task.h>
#include <semphr.h>
#include <codrv_FreeRTOS.h>
/* constant definitions
---------------------------------------------------------------------------*/
//#define YIELD_IN_ISR 1
/* local defined data types
---------------------------------------------------------------------------*/
/* list of external used functions, if not in headers
--------------------------------------------------------------------------*/
extern void codrvTimerISR(void); /* Timer interrupt routine */
/* list of global defined functions
---------------------------------------------------------------------------*/
/* list of local defined functions
---------------------------------------------------------------------------*/
static void timerCallback(TimerHandle_t xTimer);
static RET_T codrvCreateLockObjects(void);
/* external variables
---------------------------------------------------------------------------*/
/* global variables
---------------------------------------------------------------------------*/
SemaphoreHandle_t semphCANopen; /* CANopen task lock */
SemaphoreHandle_t semphObjDir; /* object dictionary lock */
/* local defined variables
---------------------------------------------------------------------------*/
static TimerHandle_t timerHandle = NULL; /* CANopen timer object */
/***************************************************************************/
/**
* \brief codrvOSConfig - OS specific setup
*
* creates and starts the CANopen timer and
* creates objects to lock object directory and CANopen thread
*
* \return RET_T
*/
RET_T codrvOSConfig(void)
{
RET_T retVal = RET_DRV_ERROR;
/* create objects to lock object directory and CANopen thread */
retVal = codrvCreateLockObjects();
if (retVal != RET_OK) {
return(retVal);
}
/* create and setup CANopen timer */
retVal = codrvTimerSetup(CO_TIMER_INTERVAL);
if (retVal != RET_OK) {
return(retVal);
}
return(RET_OK);
}
/***************************************************************************/
/**
* \brief codrvTimerSetup - initialize timer
*
* Start a cyclic hardware timer to provide timing interval.
* alternatively it can be derived from an other system timer
* with the interval given from the DeviceDesigner.
*
* \returns RET_T
*/
RET_T codrvTimerSetup(
UNSIGNED32 timerInterval
)
{
BaseType_t ret = pdPASS;
/* define CANopenTimer */
timerHandle = xTimerCreate("CANopenTimer", pdMS_TO_TICKS(timerInterval/1000), pdTRUE,
(void*)0, timerCallback);
if (timerHandle == NULL) {
return(RET_DRV_ERROR);
}
/* start CANopenTimer */
ret = xTimerStart(timerHandle, 0ul);
if (ret == pdFAIL) {
return(RET_DRV_ERROR);
}
return(RET_OK);
}
/***************************************************************************/
/**
* \brief timerCallback - call timer interrupt service routine
*
* \returns void
*/
static void timerCallback(TimerHandle_t xTimer)
{
(void)xTimer;
/* call timer interrupt service routine */
codrvTimerISR();
}
/***************************************************************************/
/**
* \brief codrvCreateLockObjects - create lock objects
*
* Create objects to lock CANopen thread and CANopen object dictionary
*
* \returns RET_T
*/
static RET_T codrvCreateLockObjects(
void
)
{
/* create a mutex to lock the CANopen object dictionary */
semphObjDir = xSemaphoreCreateMutex();
if(semphObjDir == NULL) {
return(RET_DRV_ERROR);
}
/* create a semaphore to lock the CANopen Thread */
semphCANopen = xSemaphoreCreateBinary();
if (semphCANopen == NULL) {
return(RET_DRV_ERROR);
}
return(RET_OK);
}
/***************************************************************************/
/**
* \brief codrvWaitForEvent - wait for timer or CAN event
*
* \returns void
*/
void codrvWaitForEvent(UNSIGNED32 msecTimeout)
{
/* wait until semaphore is unlocked */
(void)xSemaphoreTake(semphCANopen, msecTimeout);
}
/***************************************************************************/
void codrvOsSignal_CAN_TRANSMIT(void)
{
(void)xSemaphoreGive(semphCANopen);
}
/***************************************************************************/
void codrvOsSignal_CAN_TRANSMIT_ISR(void)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
(void)xSemaphoreGiveFromISR(semphCANopen, &xHigherPriorityTaskWoken);
#ifdef YIELD_IN_ISR
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
#endif
}
/***************************************************************************/
void codrvOsSignal_CAN_RECEIVE(void)
{
(void)xSemaphoreGive(semphCANopen);
}
/***************************************************************************/
void codrvOsSignal_CAN_RECEIVE_ISR(void)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
(void)xSemaphoreGiveFromISR(semphCANopen, &xHigherPriorityTaskWoken);
#ifdef YIELD_IN_ISR
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
#endif
}
/***************************************************************************/
void codrvOsSignal_TIMER(void)
{
(void)xSemaphoreGive(semphCANopen);
}
/***************************************************************************/
void codrvOsSignal_TIMER_ISR(void)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
(void)xSemaphoreGiveFromISR(semphCANopen, &xHigherPriorityTaskWoken);
#ifdef YIELD_IN_ISR
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
#endif
}
/***************************************************************************/
void codrvOsSignal_CAN_STATE(void)
{
(void)xSemaphoreGive(semphCANopen);
}
/***************************************************************************/
void codrvOsSignal_CAN_STATE_ISR(void)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
(void)xSemaphoreGiveFromISR(semphCANopen, &xHigherPriorityTaskWoken);
#ifdef YIELD_IN_ISR
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
#endif
}
/***************************************************************************/
void codrvOs_LOCK_OD(void)
{
(void)xSemaphoreTake(semphObjDir, portMAX_DELAY);
}
/***************************************************************************/
void codrvOs_UNLOCK_OD(void)
{
(void)xSemaphoreGive(semphObjDir);
}
#endif /* CODRV_USE_FREERTOS */