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 */
 |