273 lines
6.9 KiB
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 */
|