Sys Module Sources¶
sys.c (primary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys.c
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE
* @prefix SYS
*
* @brief Sys driver implementation
*/
/*================== Includes =============================================*/
#include "sys.h"
#include "bal.h"
#include "bms.h"
#include "cansignal.h"
#include "contactor.h"
#include "diag.h"
#include "interlock.h"
#include "isoguard.h"
#include "meas.h"
#include "rtc.h"
#include "sox.h"
#include "FreeRTOS.h"
#include "task.h"
/*================== Macros and Definitions ===============================*/
/**
* Saves the last state and the last substate
*/
#define SYS_SAVELASTSTATES() sys_state.laststate = sys_state.state; \
sys_state.lastsubstate = sys_state.substate
/*================== Constant and Variable Definitions ====================*/
/**
* contains the state of the contactor state machine
*
*/
static SYS_STATE_s sys_state = {
.timer = 0,
.statereq = SYS_STATE_NO_REQUEST,
.state = SYS_STATEMACH_UNINITIALIZED,
.substate = SYS_ENTRY,
.laststate = SYS_STATEMACH_UNINITIALIZED,
.lastsubstate = 0,
.triggerentry = 0,
.ErrRequestCounter = 0,
};
/*================== Function Prototypes ==================================*/
static SYS_RETURN_TYPE_e SYS_CheckStateRequest(SYS_STATE_REQUEST_e statereq);
static SYS_STATE_REQUEST_e SYS_GetStateRequest(void);
static SYS_STATE_REQUEST_e SYS_TransferStateRequest(void);
static uint8_t SYS_CheckReEntrance(void);
/*================== Function Implementations =============================*/
/**
* @brief re-entrance check of SYS state machine trigger function
*
* This function is not re-entrant and should only be called time- or event-triggered.
* It increments the triggerentry counter from the state variable ltc_state.
* It should never be called by two different processes, so if it is the case, triggerentry
* should never be higher than 0 when this function is called.
*
*
* @return retval 0 if no further instance of the function is active, 0xff else
*
*/
static uint8_t SYS_CheckReEntrance(void) {
uint8_t retval = 0;
taskENTER_CRITICAL();
if (!sys_state.triggerentry) {
sys_state.triggerentry++;
} else {
retval = 0xFF; /* multiple calls of function */
}
taskEXIT_CRITICAL();
return retval;
}
/**
* @brief gets the current state request.
*
* This function is used in the functioning of the SYS state machine.
*
* @return retval current state request, taken from SYS_STATE_REQUEST_e
*/
static SYS_STATE_REQUEST_e SYS_GetStateRequest(void) {
SYS_STATE_REQUEST_e retval = SYS_STATE_NO_REQUEST;
taskENTER_CRITICAL();
retval = sys_state.statereq;
taskEXIT_CRITICAL();
return (retval);
}
SYS_STATEMACH_e SYS_GetState(void) {
return (sys_state.state);
}
/**
* @brief transfers the current state request to the state machine.
*
* This function takes the current state request from #sys_state and transfers it to the state machine.
* It resets the value from #sys_state to #SYS_STATE_NO_REQUEST
*
* @return retVal current state request, taken from #SYS_STATE_REQUEST_e
*
*/
static SYS_STATE_REQUEST_e SYS_TransferStateRequest(void) {
SYS_STATE_REQUEST_e retval = SYS_STATE_NO_REQUEST;
taskENTER_CRITICAL();
retval = sys_state.statereq;
sys_state.statereq = SYS_STATE_NO_REQUEST;
taskEXIT_CRITICAL();
return (retval);
}
SYS_RETURN_TYPE_e SYS_SetStateRequest(SYS_STATE_REQUEST_e statereq) {
SYS_RETURN_TYPE_e retVal = SYS_ILLEGAL_REQUEST;
taskENTER_CRITICAL();
retVal = SYS_CheckStateRequest(statereq);
if (retVal == SYS_OK) {
sys_state.statereq = statereq;
}
taskEXIT_CRITICAL();
return (retVal);
}
/**
* @brief checks the state requests that are made.
*
* This function checks the validity of the state requests.
* The results of the checked is returned immediately.
*
* @param statereq state request to be checked
*
* @return result of the state request that was made, taken from SYS_RETURN_TYPE_e
*/
static SYS_RETURN_TYPE_e SYS_CheckStateRequest(SYS_STATE_REQUEST_e statereq) {
SYS_RETURN_TYPE_e retval = SYS_ILLEGAL_REQUEST;
if (statereq == SYS_STATE_ERROR_REQUEST) {
retval = SYS_OK;
} else {
if (sys_state.statereq == SYS_STATE_NO_REQUEST) {
/* init only allowed from the uninitialized state */
if (statereq == SYS_STATE_INIT_REQUEST) {
if (sys_state.state == SYS_STATEMACH_UNINITIALIZED) {
retval = SYS_OK;
} else {
retval = SYS_ALREADY_INITIALIZED;
}
} else {
retval = SYS_ILLEGAL_REQUEST;
}
} else {
retval = SYS_REQUEST_PENDING;
}
}
return retval;
}
void SYS_Trigger(void) {
/* STD_RETURN_TYPE_e retVal=E_OK; */
SYS_STATE_REQUEST_e statereq = SYS_STATE_NO_REQUEST;
ILCK_STATEMACH_e ilckstate = ILCK_STATEMACH_UNDEFINED;
STD_RETURN_TYPE_e contstate = E_NOT_OK;
STD_RETURN_TYPE_e balInitState = E_NOT_OK;
STD_RETURN_TYPE_e bmsstate = E_NOT_OK;
DIAG_SysMonNotify(DIAG_SYSMON_SYS_ID, 0); /* task is running, state = ok */
/* Check re-entrance of function */
if (SYS_CheckReEntrance()) {
return;
}
if (sys_state.timer) {
if (--sys_state.timer) {
sys_state.triggerentry--;
return; /* handle state machine only if timer has elapsed */
}
}
/****Happens every time the state machine is triggered**************/
switch (sys_state.state) {
/****************************UNINITIALIZED***********************************/
case SYS_STATEMACH_UNINITIALIZED:
/* waiting for Initialization Request */
statereq = SYS_TransferStateRequest();
if (statereq == SYS_STATE_INIT_REQUEST) {
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZATION;
sys_state.substate = SYS_ENTRY;
} else if (statereq == SYS_STATE_NO_REQUEST) {
/* no actual request pending */
} else {
sys_state.ErrRequestCounter++; /* illegal request pending */
}
break;
/****************************INITIALIZATION**********************************/
case SYS_STATEMACH_INITIALIZATION:
SYS_SAVELASTSTATES();
/* Initializations done here */
/* Send CAN boot message directly on CAN */
SYS_SendBootMessage(1);
/* Check if undervoltage MSL violation was detected before reset */
if (RTC_DEEP_DISCHARGE_DETECTED == 1) {
/* Error detected */
DIAG_Handler(DIAG_CH_DEEP_DISCHARGE_DETECTED, DIAG_EVENT_NOK, 0);
} else {
DIAG_Handler(DIAG_CH_DEEP_DISCHARGE_DETECTED, DIAG_EVENT_OK, 0);
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZED;
sys_state.substate = SYS_ENTRY;
break;
/****************************INITIALIZED*************************************/
case SYS_STATEMACH_INITIALIZED:
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
#if BUILD_MODULE_ENABLE_ILCK == 1
sys_state.state = SYS_STATEMACH_INITIALIZE_INTERLOCK;
#elif BUILD_MODULE_ENABLE_CONTACTOR == 1
sys_state.state = SYS_STATEMACH_INITIALIZE_CONTACTORS;
#else
sys_state.state = SYS_STATEMACH_INITIALIZE_BALANCING;
#endif
sys_state.substate = SYS_ENTRY;
break;
#if BUILD_MODULE_ENABLE_ILCK == 1
/****************************INITIALIZE INTERLOCK*************************************/
case SYS_STATEMACH_INITIALIZE_INTERLOCK:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
ILCK_SetStateRequest(ILCK_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_INTERLOCK;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_INTERLOCK) {
ilckstate = ILCK_GetState();
if (ilckstate == ILCK_STATEMACH_WAIT_FIRST_REQUEST) {
ILCK_SetStateRequest(ILCK_STATE_OPEN_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
#if BUILD_MODULE_ENABLE_CONTACTOR == 1
sys_state.state = SYS_STATEMACH_INITIALIZE_CONTACTORS;
#else
sys_state.state = SYS_STATEMACH_INITIALIZE_BALANCING;
#endif
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_ILCK_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
#endif
#if BUILD_MODULE_ENABLE_CONTACTOR == 1
/****************************INITIALIZE CONTACTORS*************************************/
case SYS_STATEMACH_INITIALIZE_CONTACTORS:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
CONT_SetStateRequest(CONT_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_CONT;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_CONT) {
contstate = CONT_GetInitializationState();
if (contstate == E_OK) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_BALANCING;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_CONT_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
#endif
/****************************INITIALIZE BALANCING*************************************/
case SYS_STATEMACH_INITIALIZE_BALANCING:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
BAL_SetStateRequest(BAL_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_BAL;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_BAL) {
balInitState = BAL_GetInitializationState();
if (BALANCING_DEFAULT_INACTIVE == TRUE) {
BAL_SetStateRequest(BAL_STATE_GLOBAL_DISABLE_REQUEST);
} else {
BAL_SetStateRequest(BAL_STATE_GLOBAL_ENABLE_REQUEST);
}
if (balInitState == E_OK) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_ISOGUARD;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_BAL_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
/**************************** Initialize Isoguard **************************/
case SYS_STATEMACH_INITIALIZE_ISOGUARD:
#if BUILD_MODULE_ENABLE_ISOGUARD == 1
ISO_Init();
#endif
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_FIRST_MEASUREMENT_CYCLE;
sys_state.substate = SYS_ENTRY;
break;
/****************************START FIRST MEAS CYCLE**************************/
case SYS_STATEMACH_FIRST_MEASUREMENT_CYCLE:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
MEAS_StartMeasurement();
sys_state.InitCounter = 0;
sys_state.substate = SYS_WAIT_FIRST_MEASUREMENT_CYCLE;
} else if (sys_state.substate == SYS_WAIT_FIRST_MEASUREMENT_CYCLE) {
if (MEAS_IsFirstMeasurementCycleFinished() == TRUE) {
MEAS_Request_OpenWireCheck();
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
if (CURRENT_SENSOR_PRESENT == TRUE)
sys_state.state = SYS_STATEMACH_CHECK_CURRENT_SENSOR_PRESENCE;
else
sys_state.state = SYS_STATEMACH_INITIALIZE_MISC;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_MEAS_INIT_ERROR;
break;
} else {
sys_state.timer = SYS_STATEMACH_MEDIUMTIME_MS;
sys_state.InitCounter++;
break;
}
}
}
break;
/****************************CHECK CURRENT SENSOR PRESENCE*************************************/
case SYS_STATEMACH_CHECK_CURRENT_SENSOR_PRESENCE:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
sys_state.InitCounter = 0;
sys_state.substate = SYS_WAIT_CURRENT_SENSOR_PRESENCE;
} else if (sys_state.substate == SYS_WAIT_CURRENT_SENSOR_PRESENCE) {
if (CANS_IsCurrentSensorPresent() == TRUE) {
SOF_Init();
if (CANS_IsCurrentSensorCCPresent() == TRUE) {
SOC_Init(TRUE);
} else {
SOC_Init(FALSE);
}
CANS_Enable_Periodic(TRUE);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_MISC;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_CURRENT_SENSOR_PRESENCE_ERROR;
break;
} else {
sys_state.timer = SYS_STATEMACH_MEDIUMTIME_MS;
sys_state.InitCounter++;
break;
}
}
}
break;
/****************************INITIALIZED_MISC*************************************/
case SYS_STATEMACH_INITIALIZE_MISC:
SYS_SAVELASTSTATES();
if (CURRENT_SENSOR_PRESENT == FALSE) {
CANS_Enable_Periodic(TRUE);
SOC_Init(FALSE);
}
sys_state.timer = SYS_STATEMACH_MEDIUMTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_BMS;
sys_state.substate = SYS_ENTRY;
break;
/****************************INITIALIZE BMS*************************************/
case SYS_STATEMACH_INITIALIZE_BMS:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
BMS_SetStateRequest(BMS_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_BMS;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_BMS) {
bmsstate = BMS_GetInitializationState();
if (bmsstate == E_OK) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_RUNNING;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > (100/SYS_TASK_CYCLE_CONTEXT_MS)) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_BMS_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
/****************************RUNNNIG*************************************/
case SYS_STATEMACH_RUNNING:
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_LONGTIME_MS;
break;
/****************************ERROR*************************************/
case SYS_STATEMACH_ERROR:
SYS_SAVELASTSTATES();
CANS_Enable_Periodic(TRUE);
sys_state.timer = SYS_STATEMACH_LONGTIME_MS;
break;
/***************************DEFAULT CASE*************************************/
default:
/* This default case should never be entered.
* If we actually enter this case, it means that an
* unrecoverable error has occurred. Therefore the program
* will trap.
*/
configASSERT(0);
break;
} /* end switch (sys_state.state) */
sys_state.triggerentry--;
}
sys.h (primary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys.h
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE
* @prefix SYS
*
* @brief Sys driver header
*
*
*/
#ifndef SYS_H_
#define SYS_H_
/*================== Includes =============================================*/
#include "sys_cfg.h"
/*================== Macros and Definitions ===============================*/
/**
* Symbolic names for busyness of the system
*/
typedef enum {
SYS_CHECK_OK = 0, /*!< system ok */
SYS_CHECK_BUSY = 1, /*!< system busy */
SYS_CHECK_NOT_OK = 2, /*!< system not ok */
} SYS_CHECK_e;
typedef enum {
SYS_MODE_STARTUP_EVENT = 0, /*!< system startup */
/* SYS_MODE_EVENT_INIT = 1, !< todo */
SYS_MODE_CYCLIC_EVENT = 2, /*!< for cyclic events */
SYS_MODE_TRIGGERED_EVENT = 3, /*!< for triggered events */
SYS_MODE_ABNORMAL_EVENT = 4, /*!< for abnormal (error etc.) events */
SYS_MODE_EVENT_RESERVED = 0xFF, /*!< do not use */
} SYS_TRIG_EVENT_e;
/*================== Constant and Variable Definitions ====================*/
/**
* States of the SYS state machine
*/
typedef enum {
/* Init-Sequence */
SYS_STATEMACH_UNINITIALIZED = 0, /*!< */
SYS_STATEMACH_INITIALIZATION = 1, /*!< */
SYS_STATEMACH_INITIALIZED = 2, /*!< */
SYS_STATEMACH_INITIALIZE_INTERLOCK = 4, /*!< */
SYS_STATEMACH_INITIALIZE_CONTACTORS = 5, /*!< */
SYS_STATEMACH_INITIALIZE_BALANCING = 6, /*!< */
SYS_STATEMACH_INITIALIZE_BMS = 7, /*!< */
SYS_STATEMACH_RUNNING = 8, /*!< */
SYS_STATEMACH_FIRST_MEASUREMENT_CYCLE = 9, /*!< */
SYS_STATEMACH_INITIALIZE_MISC = 10, /*!< */
SYS_STATEMACH_CHECK_CURRENT_SENSOR_PRESENCE = 11, /*!< */
SYS_STATEMACH_INITIALIZE_ISOGUARD = 12, /*!< */
SYS_STATEMACH_ERROR = 0xF0, /*!< Error-State: */
} SYS_STATEMACH_e;
/**
* Substates of the SYS state machine
*/
typedef enum {
SYS_ENTRY = 0, /*!< Substate entry state */
SYS_CHECK_ERROR_FLAGS = 1, /*!< Substate check if any error flag set */
SYS_CHECK_STATE_REQUESTS = 2, /*!< Substate check if there is a state request */
SYS_WAIT_INITIALIZATION_INTERLOCK = 3, /*!< Substate to wait for initialization of the interlock state machine */
SYS_WAIT_INITIALIZATION_CONT = 4, /*!< Substate to wait for initialization of the contactor state machine */
SYS_WAIT_INITIALIZATION_BAL = 5, /*!< Substate to wait for initialization of the balancing state machine */
SYS_WAIT_INITIALIZATION_BMS = 6, /*!< Substate to wait for initialization of the bms state machine */
SYS_WAIT_FIRST_MEASUREMENT_CYCLE = 7, /*!< Substate to wait for first measurement cycle to complete */
SYS_WAIT_CURRENT_SENSOR_PRESENCE = 8, /*!< Substate to wait for first measurement cycle to complete */
SYS_CONT_INIT_ERROR = 9, /*!< Substate error of contactor state machine initialization */
SYS_BAL_INIT_ERROR = 10, /*!< Substate error of balancing state machine initialization */
SYS_ILCK_INIT_ERROR = 11, /*!< Substate error of contactor state machine initialization */
SYS_BMS_INIT_ERROR = 12, /*!< Substate error of bms state machine initialization */
SYS_MEAS_INIT_ERROR = 13, /*!< Substate error if first measurement cycle does not complete */
SYS_CURRENT_SENSOR_PRESENCE_ERROR = 14, /*!< Substate error if first measurement cycle does not complete */
} SYS_STATEMACH_SUB_e;
/**
* State requests for the SYS statemachine
*/
typedef enum {
SYS_STATE_INIT_REQUEST = SYS_STATEMACH_INITIALIZATION, /*!< */
SYS_STATE_ERROR_REQUEST = SYS_STATEMACH_ERROR, /*!< */
SYS_STATE_NO_REQUEST, /*!< */
} SYS_STATE_REQUEST_e;
/**
* Possible return values when state requests are made to the SYS statemachine
*/
typedef enum {
SYS_OK = 0, /*!< CONT --> ok */
SYS_BUSY_OK = 1, /*!< CONT under load --> ok */
SYS_REQUEST_PENDING = 2, /*!< requested to be executed */
SYS_ILLEGAL_REQUEST = 3, /*!< Request can not be executed */
SYS_ALREADY_INITIALIZED = 30, /*!< Initialization of LTC already finished */
SYS_ILLEGAL_TASK_TYPE = 99, /*!< Illegal */
} SYS_RETURN_TYPE_e;
/**
* This structure contains all the variables relevant for the CONT state machine.
* The user can get the current state of the CONT state machine with this variable
*/
typedef struct {
uint16_t timer; /*!< time in ms before the state machine processes the next state, e.g. in counts of 1ms */
SYS_STATE_REQUEST_e statereq; /*!< current state request made to the state machine */
SYS_STATEMACH_e state; /*!< state of Driver State Machine */
SYS_STATEMACH_SUB_e substate; /*!< current substate of the state machine */
SYS_STATEMACH_e laststate; /*!< previous state of the state machine */
SYS_STATEMACH_SUB_e lastsubstate; /*!< previous substate of the state machine */
uint32_t ErrRequestCounter; /*!< counts the number of illegal requests to the SYS state machine */
uint16_t InitCounter; /*!< Timeout to wait for initialization of state machine state machine */
uint8_t triggerentry; /*!< counter for re-entrance protection (function running flag) */
} SYS_STATE_s;
/*================== Function Prototypes ==================================*/
/**
* @brief sets the current state request of the state variable sys_state.
*
* @details This function is used to make a state request to the state machine, e.g., start
* voltage measurement, read result of voltage measurement, re-initialization.
* It calls SYS_CheckStateRequest() to check if the request is valid. The state request
* is rejected if is not valid. The result of the check is returned immediately, so that
* the requester can act in case it made a non-valid state request.
*
* @param statereq state requested to set
*
* @return If the request was successfully set, it returns the SYS_OK, else the current state of
* requests (type SYS_STATE_REQUEST_e)
*/
extern SYS_RETURN_TYPE_e SYS_SetStateRequest(SYS_STATE_REQUEST_e statereq);
/**
* @brief gets the current state.
*
* @details This function is used in the functioning of the SYS state machine.
*
* @return current state, taken from SYS_STATEMACH_e
*/
extern SYS_STATEMACH_e SYS_GetState(void);
/**
* @brief trigger function for the SYS driver state machine.
*
* @details This function contains the sequence of events in the SYS state machine. It must be
* called time-triggered, every 1ms.
*/
extern void SYS_Trigger(void);
#endif /* SYS_H_ */
sys.c (secondary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys.c
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE
* @prefix SYS
*
* @brief Sys driver implementation
*/
/*================== Includes =============================================*/
#include "sys.h"
#include "bms.h"
#include "diag.h"
#include "meas.h"
#include "interlock.h"
#include "FreeRTOS.h"
#include "task.h"
/*================== Macros and Definitions ===============================*/
/**
* Saves the last state and the last substate
*/
#define SYS_SAVELASTSTATES() sys_state.laststate = sys_state.state; \
sys_state.lastsubstate = sys_state.substate
/*================== Constant and Variable Definitions ====================*/
/**
* contains the state of the contactor state machine
*
*/
static SYS_STATE_s sys_state = {
.timer = 0,
.statereq = SYS_STATE_NO_REQUEST,
.state = SYS_STATEMACH_UNINITIALIZED,
.substate = SYS_ENTRY,
.laststate = SYS_STATEMACH_UNINITIALIZED,
.lastsubstate = 0,
.triggerentry = 0,
.ErrRequestCounter = 0,
};
/*================== Function Prototypes ==================================*/
static SYS_RETURN_TYPE_e SYS_CheckStateRequest(SYS_STATE_REQUEST_e statereq);
static SYS_STATE_REQUEST_e SYS_GetStateRequest(void);
static SYS_STATE_REQUEST_e SYS_TransferStateRequest(void);
static uint8_t SYS_CheckReEntrance(void);
/*================== Function Implementations =============================*/
/**
* @brief re-entrance check of SYS state machine trigger function
*
* This function is not re-entrant and should only be called time- or event-triggered.
* It increments the triggerentry counter from the state variable ltc_state.
* It should never be called by two different processes, so if it is the case, triggerentry
* should never be higher than 0 when this function is called.
*
*
* @return retval 0 if no further instance of the function is active, 0xff else
*
*/
static uint8_t SYS_CheckReEntrance(void) {
uint8_t retval = 0;
taskENTER_CRITICAL();
if (!sys_state.triggerentry) {
sys_state.triggerentry++;
} else {
retval = 0xFF; /* multiple calls of function */
}
taskEXIT_CRITICAL();
return retval;
}
/**
* @brief gets the current state request.
*
* This function is used in the functioning of the SYS state machine.
*
* @return retval current state request, taken from SYS_STATE_REQUEST_e
*/
static SYS_STATE_REQUEST_e SYS_GetStateRequest(void) {
SYS_STATE_REQUEST_e retval = SYS_STATE_NO_REQUEST;
taskENTER_CRITICAL();
retval = sys_state.statereq;
taskEXIT_CRITICAL();
return (retval);
}
SYS_STATEMACH_e SYS_GetState(void) {
return (sys_state.state);
}
/**
* @brief transfers the current state request to the state machine.
*
* This function takes the current state request from #sys_state and transfers it to the state machine.
* It resets the value from #sys_state to #SYS_STATE_NO_REQUEST
*
* @return retVal current state request, taken from #SYS_STATE_REQUEST_e
*
*/
static SYS_STATE_REQUEST_e SYS_TransferStateRequest(void) {
SYS_STATE_REQUEST_e retval = SYS_STATE_NO_REQUEST;
taskENTER_CRITICAL();
retval = sys_state.statereq;
sys_state.statereq = SYS_STATE_NO_REQUEST;
taskEXIT_CRITICAL();
return (retval);
}
SYS_RETURN_TYPE_e SYS_SetStateRequest(SYS_STATE_REQUEST_e statereq) {
SYS_RETURN_TYPE_e retVal = SYS_ILLEGAL_REQUEST;
taskENTER_CRITICAL();
retVal = SYS_CheckStateRequest(statereq);
if (retVal == SYS_OK) {
sys_state.statereq = statereq;
}
taskEXIT_CRITICAL();
return (retVal);
}
/**
* @brief checks the state requests that are made.
*
* This function checks the validity of the state requests.
* The results of the checked is returned immediately.
*
* @param statereq state request to be checked
*
* @return result of the state request that was made, taken from SYS_RETURN_TYPE_e
*/
static SYS_RETURN_TYPE_e SYS_CheckStateRequest(SYS_STATE_REQUEST_e statereq) {
SYS_RETURN_TYPE_e retval = SYS_ILLEGAL_REQUEST;
if (statereq == SYS_STATE_ERROR_REQUEST) {
retval = SYS_OK;
} else {
if (sys_state.statereq == SYS_STATE_NO_REQUEST) {
/* init only allowed from the uninitialized state */
if (statereq == SYS_STATE_INIT_REQUEST) {
if (sys_state.state == SYS_STATEMACH_UNINITIALIZED) {
retval = SYS_OK;
} else {
retval = SYS_ALREADY_INITIALIZED;
}
} else {
retval = SYS_ILLEGAL_REQUEST;
}
} else {
retval = SYS_REQUEST_PENDING;
}
}
return retval;
}
void SYS_Trigger(void) {
/* STD_RETURN_TYPE_e retVal=E_OK; */
SYS_STATE_REQUEST_e statereq = SYS_STATE_NO_REQUEST;
ILCK_STATEMACH_e ilckstate = ILCK_STATEMACH_UNDEFINED;
STD_RETURN_TYPE_e bmsstate = E_NOT_OK;
DIAG_SysMonNotify(DIAG_SYSMON_SYS_ID, 0); /* task is running, state = ok */
/* Check re-entrance of function */
if (SYS_CheckReEntrance()) {
return;
}
if (sys_state.timer) {
if (--sys_state.timer) {
sys_state.triggerentry--;
return; /* handle state machine only if timer has elapsed */
}
}
/****Happens every time the state machine is triggered**************/
switch (sys_state.state) {
/****************************UNINITIALIZED***********************************/
case SYS_STATEMACH_UNINITIALIZED:
/* waiting for Initialization Request */
statereq = SYS_TransferStateRequest();
if (statereq == SYS_STATE_INIT_REQUEST) {
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZATION;
sys_state.substate = SYS_ENTRY;
} else if (statereq == SYS_STATE_NO_REQUEST) {
/* no actual request pending */
} else {
sys_state.ErrRequestCounter++; /* illegal request pending */
}
break;
/****************************INITIALIZATION**********************************/
case SYS_STATEMACH_INITIALIZATION:
SYS_SAVELASTSTATES();
/* Initializations done here */
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZED;
sys_state.substate = SYS_ENTRY;
break;
/****************************INITIALIZED*************************************/
case SYS_STATEMACH_INITIALIZED:
SYS_SAVELASTSTATES();
MEAS_StartMeasurement();
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_INTERLOCK;
sys_state.substate = SYS_ENTRY;
break;
/****************************INITIALIZE INTERLOCK*************************************/
case SYS_STATEMACH_INITIALIZE_INTERLOCK:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
ILCK_SetStateRequest(ILCK_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_INTERLOCK;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_INTERLOCK) {
ilckstate = ILCK_GetState();
if (ilckstate == ILCK_STATEMACH_WAIT_FIRST_REQUEST) {
ILCK_SetStateRequest(ILCK_STATE_CLOSE_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_MISC;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > 1000) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_ILCK_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
/****************************INITIALIZED_MISC*************************************/
case SYS_STATEMACH_INITIALIZE_MISC:
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_MEDIUMTIME_MS;
sys_state.state = SYS_STATEMACH_INITIALIZE_BMS;
sys_state.substate = SYS_ENTRY;
break;
/****************************INITIALIZE BMS*************************************/
case SYS_STATEMACH_INITIALIZE_BMS:
SYS_SAVELASTSTATES();
if (sys_state.substate == SYS_ENTRY) {
BMS_SetStateRequest(BMS_STATE_INIT_REQUEST);
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.substate = SYS_WAIT_INITIALIZATION_BMS;
sys_state.InitCounter = 0;
break;
} else if (sys_state.substate == SYS_WAIT_INITIALIZATION_BMS) {
bmsstate = BMS_GetInitializationState();
if (bmsstate == E_OK) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_RUNNING;
sys_state.substate = SYS_ENTRY;
break;
} else {
if (sys_state.InitCounter > 1000) {
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.state = SYS_STATEMACH_ERROR;
sys_state.substate = SYS_BMS_INIT_ERROR;
break;
}
sys_state.timer = SYS_STATEMACH_SHORTTIME_MS;
sys_state.InitCounter++;
break;
}
}
break;
/****************************RUNNNIG*************************************/
case SYS_STATEMACH_RUNNING:
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_LONGTIME_MS;
break;
/****************************ERROR*************************************/
case SYS_STATEMACH_ERROR:
SYS_SAVELASTSTATES();
sys_state.timer = SYS_STATEMACH_LONGTIME_MS;
break;
/***************************DEFAULT CASE*************************************/
default:
/* This default case should never be entered.
* If we actually enter this case, it means that an
* unrecoverable error has occurred. Therefore the program
* will trap.
*/
configASSERT(0);
break;
} /* end switch (sys_state.state) */
sys_state.triggerentry--;
}
sys.h (secondary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys.h
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE
* @prefix SYS
*
* @brief Sys driver header
*
*
*/
#ifndef SYS_H_
#define SYS_H_
/*================== Includes =============================================*/
#include "sys_cfg.h"
/*================== Macros and Definitions ===============================*/
/**
* Symbolic names for busyness of the system
*/
typedef enum {
SYS_CHECK_OK = 0, /*!< system ok */
SYS_CHECK_BUSY = 1, /*!< system busy */
SYS_CHECK_NOT_OK = 2, /*!< system not ok */
} SYS_CHECK_e;
typedef enum {
SYS_MODE_STARTUP_EVENT = 0, /*!< system startup */
/* SYS_MODE_EVENT_INIT = 1, !< todo */
SYS_MODE_CYCLIC_EVENT = 2, /*!< for cyclic events */
SYS_MODE_TRIGGERED_EVENT = 3, /*!< for triggered events */
SYS_MODE_ABNORMAL_EVENT = 4, /*!< for abnormal (error etc.) events */
SYS_MODE_EVENT_RESERVED = 0xFF, /*!< do not use */
} SYS_TRIG_EVENT_e;
/*================== Constant and Variable Definitions ====================*/
/**
* States of the SYS state machine
*/
typedef enum {
/* Init-Sequence */
SYS_STATEMACH_UNINITIALIZED = 0, /*!< */
SYS_STATEMACH_INITIALIZATION = 1, /*!< */
SYS_STATEMACH_INITIALIZED = 2, /*!< */
SYS_STATEMACH_INITIALIZE_INTERLOCK = 4, /*!< */
SYS_STATEMACH_INITIALIZE_CONTACTORS = 5, /*!< */
SYS_STATEMACH_INITIALIZE_BALANCING = 6, /*!< */
SYS_STATEMACH_INITIALIZE_BMS = 7, /*!< */
SYS_STATEMACH_RUNNING = 8, /*!< */
SYS_STATEMACH_FIRST_MEASUREMENT_CYCLE = 9, /*!< */
SYS_STATEMACH_INITIALIZE_MISC = 10, /*!< */
SYS_STATEMACH_CHECK_CURRENT_SENSOR_PRESENCE = 11, /*!< */
SYS_STATEMACH_INITIALIZE_ISOGUARD = 12, /*!< */
SYS_STATEMACH_ERROR = 0xF0, /*!< Error-State: */
} SYS_STATEMACH_e;
/**
* Substates of the SYS state machine
*/
typedef enum {
SYS_ENTRY = 0, /*!< Substate entry state */
SYS_CHECK_ERROR_FLAGS = 1, /*!< Substate check if any error flag set */
SYS_CHECK_STATE_REQUESTS = 2, /*!< Substate check if there is a state request */
SYS_WAIT_INITIALIZATION_INTERLOCK = 3, /*!< Substate to wait for initialization of the interlock state machine */
SYS_WAIT_INITIALIZATION_CONT = 4, /*!< Substate to wait for initialization of the contactor state machine */
SYS_WAIT_INITIALIZATION_BAL = 5, /*!< Substate to wait for initialization of the balancing state machine */
SYS_WAIT_INITIALIZATION_BMS = 6, /*!< Substate to wait for initialization of the bms state machine */
SYS_WAIT_FIRST_MEASUREMENT_CYCLE = 7, /*!< Substate to wait for first measurement cycle to complete */
SYS_WAIT_CURRENT_SENSOR_PRESENCE = 8, /*!< Substate to wait for first measurement cycle to complete */
SYS_CONT_INIT_ERROR = 9, /*!< Substate error of contactor state machine initialization */
SYS_ILCK_INIT_ERROR = 10, /*!< Substate error of contactor state machine initialization */
SYS_BMS_INIT_ERROR = 11, /*!< Substate error of bms state machine initialization */
SYS_MEAS_INIT_ERROR = 12, /*!< Substate error if first measurement cycle does not complete */
SYS_CURRENT_SENSOR_PRESENCE_ERROR = 13, /*!< Substate error if first measurement cycle does not complete */
} SYS_STATEMACH_SUB_e;
/**
* State requests for the SYS statemachine
*/
typedef enum {
SYS_STATE_INIT_REQUEST = SYS_STATEMACH_INITIALIZATION, /*!< */
SYS_STATE_ERROR_REQUEST = SYS_STATEMACH_ERROR, /*!< */
SYS_STATE_NO_REQUEST, /*!< */
} SYS_STATE_REQUEST_e;
/**
* Possible return values when state requests are made to the SYS statemachine
*/
typedef enum {
SYS_OK = 0, /*!< CONT --> ok */
SYS_BUSY_OK = 1, /*!< CONT under load --> ok */
SYS_REQUEST_PENDING = 2, /*!< requested to be executed */
SYS_ILLEGAL_REQUEST = 3, /*!< Request can not be executed */
SYS_ALREADY_INITIALIZED = 30, /*!< Initialization of LTC already finished */
SYS_ILLEGAL_TASK_TYPE = 99, /*!< Illegal */
} SYS_RETURN_TYPE_e;
/**
* This structure contains all the variables relevant for the CONT state machine.
* The user can get the current state of the CONT state machine with this variable
*/
typedef struct {
uint16_t timer; /*!< time in ms before the state machine processes the next state, e.g. in counts of 1ms */
SYS_STATE_REQUEST_e statereq; /*!< current state request made to the state machine */
SYS_STATEMACH_e state; /*!< state of Driver State Machine */
SYS_STATEMACH_SUB_e substate; /*!< current substate of the state machine */
SYS_STATEMACH_e laststate; /*!< previous state of the state machine */
SYS_STATEMACH_SUB_e lastsubstate; /*!< previous substate of the state machine */
uint32_t ErrRequestCounter; /*!< counts the number of illegal requests to the SYS state machine */
uint16_t InitCounter; /*!< Timeout to wait for initialization of state machine state machine */
uint8_t triggerentry; /*!< counter for re-entrance protection (function running flag) */
} SYS_STATE_s;
/*================== Function Prototypes ==================================*/
/**
* @brief sets the current state request of the state variable sys_state.
*
* @details This function is used to make a state request to the state machine, e.g., start
* voltage measurement, read result of voltage measurement, re-initialization.
* It calls SYS_CheckStateRequest() to check if the request is valid. The state request
* is rejected if is not valid. The result of the check is returned immediately, so that
* the requester can act in case it made a non-valid state request.
*
* @param statereq state requested to set
*
* @return If the request was successfully set, it returns the SYS_OK, else the current state of
* requests (type SYS_STATE_REQUEST_e)
*/
extern SYS_RETURN_TYPE_e SYS_SetStateRequest(SYS_STATE_REQUEST_e statereq);
/**
* @brief gets the current state.
*
* @details This function is used in the functioning of the SYS state machine.
*
* @return current state, taken from SYS_STATEMACH_e
*/
extern SYS_STATEMACH_e SYS_GetState(void);
/**
* @brief trigger function for the SYS driver state machine.
*
* @details This function contains the sequence of events in the SYS state machine. It must be
* called time-triggered, every 1ms.
*/
extern void SYS_Trigger(void);
#endif /* SYS_H_ */
sys_cfg.c (primary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys_cfg.c
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix SYS
*
* @brief Sys driver configuration
*/
/*================== Includes =============================================*/
#include "sys_cfg.h"
#include "can.h"
#include "version.h"
#include "stdlib.h"
/*================== Macros and Definitions ===============================*/
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
void SYS_SendBootMessage(uint8_t directTransmission) {
/* Send CAN boot successful message */
uint8_t data[8];
data[0] = (uint8_t)atoi((char*)&ver_sw_validation.Version[0]); /* SW-Version number: major */
data[1] = (uint8_t)atoi((char*)&ver_sw_validation.Version[2]); /* SW-Version number: minor */
data[2] = (uint8_t)atoi((char*)&ver_sw_validation.Version[4]); /* SW-Version number: bugfix */
data[3] = 0;
data[4] = 0xFF & ver_sw_validation.Checksum_u32;
data[5] = 0xFF & (ver_sw_validation.Checksum_u32 >> 8);
data[6] = 0xFF & (ver_sw_validation.Checksum_u32 >> 16);
data[7] = 0xFF & (ver_sw_validation.Checksum_u32 >> 24);
if (directTransmission == 0) {
CAN_Send(CAN_NODE0, 0x101, &data[0], 8, 0);
} else {
CAN_TxMsg(CAN_NODE0, 0x101, &data[0], 8, 0);
}
}
sys_cfg.h (primary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys_cfg.h
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix SYS
*
* @brief Sys driver configuration header
*/
#ifndef SYS_CFG_H_
#define SYS_CFG_H_
/*================== Includes =============================================*/
#include "general.h"
/*================== Macros and Definitions ===============================*/
/**
* This define MUST represent the cycle time of the task in which context the
* functions run, e.g., if the SYS_Trigger() is running in the 10 ms task
* then the define must be set to 10.
*
* This define also sets the minimum time.
*/
#define SYS_TASK_CYCLE_CONTEXT_MS (10)
/**
* SYS statemachine short time definition in ms
*/
#define SYS_STATEMACH_SHORTTIME_MS (SYS_TASK_CYCLE_CONTEXT_MS)
/**
* SYS statemachine short time definition in ms
*/
#define SYS_STATEMACH_MEDIUMTIME_MS (SYS_TASK_CYCLE_CONTEXT_MS)
/**
* SYS statemachine long time definition in ms
*/
#define SYS_STATEMACH_LONGTIME_MS ((10) * (SYS_TASK_CYCLE_CONTEXT_MS))
/*================== Function Prototypes ==================================*/
/**
* Function to send out boot message with SW version
*/
extern void SYS_SendBootMessage(uint8_t directTransmission);
/*================== Function Implementations =============================*/
#endif /* SYS_CFG_H_ */
sys_cfg.c (secondary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys_cfg.c
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix SYS
*
* @brief Sys driver configuration
*/
/*================== Includes =============================================*/
#include "sys_cfg.h"
/*================== Macros and Definitions ===============================*/
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
sys_cfg.h (secondary)¶
/**
*
* @copyright © 2010 - 2019, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file sys_cfg.h
* @author foxBMS Team
* @date 21.09.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix SYS
*
* @brief Sys driver configuration header
*/
#ifndef SYS_CFG_H_
#define SYS_CFG_H_
/*================== Includes =============================================*/
#include "general.h"
/*================== Macros and Definitions ===============================*/
/**
* SYS statemachine short time definition in ms
*/
#define SYS_STATEMACH_SHORTTIME_MS 1
/**
* SYS statemachine short time definition in ms
*/
#define SYS_STATEMACH_MEDIUMTIME_MS 10
/**
* SYS statemachine long time definition in ms
*/
#define SYS_STATEMACH_LONGTIME_MS 100
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
#endif /* SYS_CFG_H_ */