/* * 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 #ifdef CODRV_USE_FREERTOS #include #include #include #include #include #include /* 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 */