foxBMS 2 is an embedded system and some parts of the code are near to the
hardware level.
The code relies on a Hardware Abstraction Layer (HAL), which is a set of
functions and definitions acting as an interface between the application and
the underlying hardware.
The HAL must be configured to fit the application and the hardware the software
is running on (e.g., configure IO pins for communication with the outside
world).
This configuration is done through a software called HALCoGen.
This is described in HALCoGen.
Another point is that foxBMS 2 is a development platform.
As such, many parts of the code must be configured to fit the target
application (e.g., which monitoring IC is used to monitor the battery cells).
This is explained in BMS Application.
HALCoGen is a graphic user interface used to configure the HAL sources.
It generates sources in form of .h and .c and .asm files.
These HAL sources are generated based on the HALCoGen configuration files
(*.hcg and *.dil).
foxBMS 2 uses the Waf tool HALCoGen to automatically run
HALCoGen and create the required sources.
Additional information on the tool can be found in
HALCoGen tool documentation.
Note
In some cases it might be beneficial to not generate the HAL during the
build step and instead use a generated version of the HAL.
For this use case see How to Use Generated Sources from HALCoGen.
HALCoGen ships with its own version of FreeRTOS and generates the
corresponding sources when running the code generator.
As foxBMS 2 uses its different own copy of FreeRTOS, the generated FreeRTOS
files from HALCoGen are removed after the code generator has run.
HALCoGen creates the source file HL_sys_startup.c which implements
(a weak implementation of) the function _c_int00 (the system’s startup
routine). foxBMS 2 provides its own non-weak implementation of _c_int00
in fstartup.c.
The foxBMS 2 implementation of _c_int00 must be coupled to the the current
HALCoGen configuration.
Most changes in the HALCoGen project do not alter the startup behavior and
no further action needs to be taken into account.
However there are settings that alter the startup behavior.
Such settings need to be ported to fstartup.c as this non-weak
implementation of _c_int00 outweighs the generated, new version of
_c_int00 in HL_sys_startup.c.
Otherwise the startup function used by foxBMS 2 would not reflect the
HALCoGen configuration.
The HALCoGen provides a mechanism to detected such changes.
The hash of the current HL_sys_startup.c implementation is stored in
src/app/hal/app-startup.hash and compared to the actual hash of the generated
HL_sys_startup.c file.
If these are not the same, the build aborts with the following message:
Listing 1.1 Example error message on hash mismatch of HL_sys_startup.c
C:\Users\vulpes\Documents\foxbms>waf build_app_embedded Waf: Entering directory C:\Users\vulpes\Documents\foxbms\build\app_embedded' [ 2/824] Compiling hcg_compiler: conf\hcg\app.hcg conf\hcg\app.dil -> build\app_embedded\src\hal\app.hcg build\app_embedded\src\hal\app.dil build\app_embedded\src\hal\app.log build\app_embedded\src\hal\include\config_cpu_clock_hz.h build\app_embedded\src\hal\include\HL_hal_stdtypes.h build\app_embedded\src\hal\include\HL_sys_common.h build\app_embedded\src\hal\include\HL_reg_system.h build\app_embedded\src\hal\include\HL_reg_flash.h build\app_embedded\src\hal\include\HL_reg_l2ramw.h build\app_embedded\src\hal\include\HL_reg_vim.h build\app_embedded\src\hal\include\HL_reg_pbist.h build\app_embedded\src\hal\include\HL_reg_stc.h build\app_embedded\src\hal\include\HL_reg_efc.h build\app_embedded\src\hal\include\HL_reg_pcr.h build\app_embedded\src\hal\include\HL_reg_pmm.h build\app_embedded\src\hal\include\HL_reg_dma.h build\app_embedded\src\hal\include\HL_reg_ccmr5.h build\app_embedded\src\hal\include\HL_sys_core.h build\app_embedded\src\hal\include\HL_system.h build\app_embedded\src\hal\include\HL_sys_mpu.h build\app_embedded\src\hal\include\HL_sys_pmu.h build\app_embedded\src\hal\include\HL_sys_pcr.h build\app_embedded\src\hal\include\HL_sys_pmm.h build\app_embedded\src\hal\include\HL_sys_dma.h build\app_embedded\src\hal\include\HL_reg_epc.h build\app_embedded\src\hal\include\HL_reg_nmpu.h build\app_embedded\src\hal\include\HL_reg_scm.h build\app_embedded\src\hal\include\HL_reg_sdcmmr.h build\app_embedded\src\hal\include\HL_epc.h build\app_embedded\src\hal\include\HL_nmpu.h build\app_embedded\src\hal\include\HL_errata.h build\app_embedded\src\hal\include\HL_errata_SSWF021_45.h build\app_embedded\src\hal\include\HL_errata_SSWF021_45_defs.h build\app_embedded\src\hal\include\HL_sys_vim.h build\app_embedded\src\hal\include\HL_reg_pinmux.h build\app_embedded\src\hal\include\HL_pinmux.h build\app_embedded\src\hal\include\HL_reg_gio.h build\app_embedded\src\hal\include\HL_gio.h build\app_embedded\src\hal\include\HL_reg_esm.h build\app_embedded\src\hal\include\HL_esm.h build\app_embedded\src\hal\include\HL_reg_sci.h build\app_embedded\src\hal\include\HL_sci.h build\app_embedded\src\hal\include\HL_reg_lin.h build\app_embedded\src\hal\include\HL_lin.h build\app_embedded\src\hal\include\HL_reg_mibspi.h build\app_embedded\src\hal\include\HL_mibspi.h build\app_embedded\src\hal\include\HL_reg_spi.h build\app_embedded\src\hal\include\HL_spi.h build\app_embedded\src\hal\include\HL_reg_can.h build\app_embedded\src\hal\include\HL_can.h build\app_embedded\src\hal\include\HL_reg_adc.h build\app_embedded\src\hal\include\HL_adc.h build\app_embedded\src\hal\include\std_nhet.h build\app_embedded\src\hal\include\HL_reg_het.h build\app_embedded\src\hal\include\HL_het.h build\app_embedded\src\hal\include\HL_reg_htu.h build\app_embedded\src\hal\include\HL_htu.h build\app_embedded\src\hal\include\HL_reg_i2c.h build\app_embedded\src\hal\include\HL_i2c.h build\app_embedded\src\hal\include\HL_emac.h build\app_embedded\src\hal\include\HL_hw_emac.h build\app_embedded\src\hal\include\HL_hw_emac_ctrl.h build\app_embedded\src\hal\include\HL_hw_mdio.h build\app_embedded\src\hal\include\HL_hw_reg_access.h build\app_embedded\src\hal\include\HL_mdio.h build\app_embedded\src\hal\include\HL_phy_dp83640.h build\app_embedded\src\hal\include\HL_phy_tlk111.h build\app_embedded\src\hal\include\HL_emac_phyConfig.h build\app_embedded\src\hal\include\HL_reg_dcc.h build\app_embedded\src\hal\include\HL_dcc.h build\app_embedded\src\hal\include\HL_reg_rtp.h build\app_embedded\src\hal\include\HL_rtp.h build\app_embedded\src\hal\include\HL_reg_dmm.h build\app_embedded\src\hal\include\HL_dmm.h build\app_embedded\src\hal\include\HL_reg_emif.h build\app_embedded\src\hal\include\HL_emif.h build\app_embedded\src\hal\include\HL_reg_pom.h build\app_embedded\src\hal\include\HL_pom.h build\app_embedded\src\hal\include\HL_reg_crc.h build\app_embedded\src\hal\include\HL_crc.h build\app_embedded\src\hal\include\HL_reg_etpwm.h build\app_embedded\src\hal\include\HL_etpwm.h build\app_embedded\src\hal\include\HL_reg_ecap.h build\app_embedded\src\hal\include\HL_ecap.h build\app_embedded\src\hal\include\HL_reg_eqep.h build\app_embedded\src\hal\include\HL_eqep.h build\app_embedded\src\hal\include\Device_TMS570LC43.h build\app_embedded\src\hal\include\Device_header.h build\app_embedded\src\hal\include\Device_types.h build\app_embedded\src\hal\include\ti_fee_cfg.h build\app_embedded\src\hal\include\MemMap.h build\app_embedded\src\hal\include\ti_fee_types.h build\app_embedded\src\hal\include\ti_fee.h build\app_embedded\src\hal\include\fee_interface.h build\app_embedded\src\hal\source\HL_sys_pcr.c build\app_embedded\src\hal\source\HL_sys_pmm.c build\app_embedded\src\hal\source\HL_sys_dma.c build\app_embedded\src\hal\source\HL_system.c build\app_embedded\src\hal\source\HL_sys_phantom.c build\app_embedded\src\hal\source\HL_sys_startup.c build\app_embedded\src\hal\source\HL_sys_vim.c build\app_embedded\src\hal\source\HL_notification.c build\app_embedded\src\hal\source\HL_epc.c build\app_embedded\src\hal\source\HL_nmpu.c build\app_embedded\src\hal\source\HL_errata.c build\app_embedded\src\hal\source\HL_errata_SSWF021_45.c build\app_embedded\src\hal\source\HL_sys_core.asm build\app_embedded\src\hal\source\HL_sys_intvecs.asm build\app_embedded\src\hal\source\HL_sys_mpu.asm build\app_embedded\src\hal\source\HL_sys_pmu.asm build\app_embedded\src\hal\source\HL_pinmux.c build\app_embedded\src\hal\source\HL_gio.c build\app_embedded\src\hal\source\HL_esm.c build\app_embedded\src\hal\source\HL_sci.c build\app_embedded\src\hal\source\HL_lin.c build\app_embedded\src\hal\source\HL_spi.c build\app_embedded\src\hal\source\HL_can.c build\app_embedded\src\hal\source\HL_adc.c build\app_embedded\src\hal\source\HL_het.c build\app_embedded\src\hal\source\HL_i2c.c build\app_embedded\src\hal\source\HL_emac.c build\app_embedded\src\hal\source\HL_mdio.c build\app_embedded\src\hal\source\HL_phy_dp83640.c build\app_embedded\src\hal\source\HL_phy_tlk111.c build\app_embedded\src\hal\source\HL_dcc.c build\app_embedded\src\hal\source\HL_emif.c build\app_embedded\src\hal\source\HL_pom.c build\app_embedded\src\hal\source\HL_crc.c build\app_embedded\src\hal\source\HL_etpwm.c build\app_embedded\src\hal\source\HL_ecap.c build\app_embedded\src\hal\source\HL_eqep.c build\app_embedded\src\hal\source\Device_TMS570LC43.c build\app_embedded\src\hal\source\ti_fee_cfg.c build\app_embedded\src\hal\source\ti_fee_Info.c build\app_embedded\src\hal\source\ti_fee_ini.c build\app_embedded\src\hal\source\ti_fee_main.c build\app_embedded\src\hal\source\ti_fee_read.c build\app_embedded\src\hal\source\ti_fee_writeSync.c build\app_embedded\src\hal\source\ti_fee_writeAsync.c build\app_embedded\src\hal\source\ti_fee_util.c build\app_embedded\src\hal\source\ti_fee_cancel.c build\app_embedded\src\hal\source\ti_fee_format.c build\app_embedded\src\hal\source\ti_fee_eraseimmediateblock.c build\app_embedded\src\hal\source\ti_fee_invalidateblock.c build\app_embedded\src\hal\source\ti_fee_shutdown.c build\app_embedded\src\hal\source\Fapi_UserDefinedFunctions.c build\app_embedded\src\hal\source\ti_fee_readSync.c build\app_embedded\src\hal\source\HL_ajsm.asm Waf: Leaving directory C:\Users\vulpes\Documents\foxbms\build\app_embedded' Build failed Traceback (most recent call last): File "C:\Users\vulpes\Documents\foxbms\tools\waf3-2.0.22-1241519b19b496207abef1f72bbf61c2\waflib\Task.py", line 180, in process ret=self.run() File "C:\Users\vulpes\Documents\foxbms\tools\waf-tools\f_hcg.py", line 260, in run "The auto-generated file 'HL_sys_startup.c' has changed due to " File "C:\Users\vulpes\Documents\foxbms\tools\waf3-2.0.22-1241519b19b496207abef1f72bbf61c2\waflib\Context.py", line 261, in fatal raise self.errors.ConfigurationError(msg,ex=ex) waflib.Errors.ConfigurationError: The auto-generated file 'HL_sys_startup.c' has changed due to a configuration change in the HALCoGen project. The expected hash is b'e2e61496edd65f44d7cc811b504ad1f2' but the generated hash is b'1something-other'. Compare 'C:\Users\vulpes\Documents\foxbms\build\app_embedded\src\hal\source\HL_sys_startup.c' with 'fstartup.c' and see if changes need to be applied to to 'fstartup.c'. If everything is changed as needed, updated the hash in 'C:\Users\vulpes\Documents\foxbms\src\hal\app-startup.hash' and build again. For more information see the documentation.
The build aborts as the expected hash is
b'e2e61496edd65f44d7cc811b504ad1f2' while the actual hash is
b'1something-other234'.
Next, the function _c_int00 in the two files (fstartup.c) and
HL_sys_startup.c needs to be compared by the developer and the developer
needs to update the _c_int00 implementation in the file fstartup.c to
reflect the HALCoGen startup routine.
The concluding step is to update the hash value in
src/app/hal/app-startup.hash with 1something-other.
Now the build toolchain knows, that the changes applied in the HALCoGen are
reflected in the dependencies and the build will not abort after the HAL
sources are generated.
The TI TMS570LC4357 can use cache to improve performance.
Since foxBMS 2 v1.3.0, cache is enabled by setting the define
OS_ENABLE_CACHE in src/app/task/os/os.h to true.
Therefore, the configuration setting in HALCoGen is ignored.
However, as the startup code generated in HL_sys_startup.c by HALCoGen
does still change (the line to activate cache is added), consequently the
hash in src/app/hal/app-startup.hash still needs to be updated, but no
further changes need to be applied.
The process to enable cache is then as follows:
Enable cache by setting OS_ENABLE_CACHE to true in
src/app/task/os/os.h.
Update the file hash in src/app/hal/app-startup.hash
Before foxBMS 2 v1.3.0, enabling cache relied on the HALCoGen configuration
and that this setting altered the startup code in HL_sys_startup.c.
The cache enable setting is found at setting TMS570LC4357ZWT_FREERTOS,
sub-setting R5-MPU-PMU and then the configuration Cortex-R5,
sub-configuration GeneralConfiguration : Enable Cache.
The process to enable cache is then as follows:
Enable cache in HALCoGen
Update the startup code in fstartup.c with the changes from
HL_sys_startup.c.
Update the file hash in src/app/hal/app-startup.hash
The project provides two very basic configuration options:
general options in conf/bms/bms.json
compiler options in conf/cc/cc-options.yaml (path is an option, see
f_ti_arm_cgt.options()) and compiler
remarks and remark severity level in conf/cc/remarks.txt
Furthermore, the used battery cells and the general configuration of the
battery system that is built up need to be defined:
for the used battery cell:
src/app/application/config/battery_cell_cfg.c
src/app/application/config/battery_cell_cfg.h
for the top level view on the battery system:
src/app/application/config/battery_system_cfg.c
src/app/application/config/battery_system_cfg.h
However, the actual behavior of the battery system in the target application is
highly dependent on the target application and can therefore not simply be
configured through some switches.
This needs to be implemented in e.g., the BMS_Trigger() function.
It is up to the developer to familiarize with the hardware, code and
documentation and adapt the source code to the application specific
requirements.
Some BMS configurations require compiling different sources.
That applies to the operating system and the Analog Front-End.
Note
Only very basic configurations can be changed via these options described
here.
Again, everything not mentioned here must still be configured by
programming the application behavior in the source code.
The operating system is configured in conf/bms/bms.json.
The value for os must be the name of the source directory in src/os/
that includes the operating system sources.
Currently only FreeRTOS is supported (option: "os":"freertos").
The AFE is configured in conf/bms/bms.json.
The joint path from the values of manufacturer and ic must be the
name of the source directory in src/app/driver/afe/<manufacturer>/<ic>
that includes the driver implementation.
A list of supported ICs is found in Section 4.30.
All options from conf/cc/cc-options.yaml are passed verbatim into the
build process. Compiler options are set during configuration time, that means
changing values in conf/cc/cc-options.yaml needs to be followed by
wafconfigure.
See the TI compiler manual before changing the flags in
conf/cc/cc-options.yaml.
The details of the project compiler configuration are described in
Compiler Configuration.
1.2.3. Basic Battery Cell And System Configuration
The basic parameters of the used battery cell of the battery system are defined
in:
src/app/application/config/battery_cell_cfg.c
src/app/application/config/battery_cell_cfg.h
The following parameters need to be defined (the links lead to the doxygen
documentation for the explanation of the specific parameter) in
src/app/application/config/battery_cell_cfg.h:
Setting
Details (define name)
Maximum discharge temperature MSL
BC_TEMPERATURE_MAX_DISCHARGE_MSL_ddegC
Maximum discharge temperature RSL
BC_TEMPERATURE_MAX_DISCHARGE_RSL_ddegC
Maximum discharge temperature MOL
BC_TEMPERATURE_MAX_DISCHARGE_MOL_ddegC
Minimum discharge temperature MSL
BC_TEMPERATURE_MIN_DISCHARGE_MSL_ddegC
Minimum discharge temperature RSL
BC_TEMPERATURE_MIN_DISCHARGE_RSL_ddegC
Minimum discharge temperature MOL
BC_TEMPERATURE_MIN_DISCHARGE_MOL_ddegC
Maximum temperature limit during charge MSL
BC_TEMPERATURE_MAX_CHARGE_MSL_ddegC
Maximum temperature limit during charge RSL
BC_TEMPERATURE_MAX_CHARGE_RSL_ddegC
Maximum temperature limit during charge MOL
BC_TEMPERATURE_MAX_CHARGE_MOL_ddegC
Minimum temperature limit during discharge MSL
BC_TEMPERATURE_MIN_CHARGE_MSL_ddegC
Minimum temperature limit during discharge RSL
BC_TEMPERATURE_MIN_CHARGE_RSL_ddegC
Minimum temperature limit during discharge MOL
BC_TEMPERATURE_MIN_CHARGE_MOL_ddegC
Maximum cell voltage limit MSL
BC_VOLTAGE_MAX_MSL_mV
Maximum cell voltage limit RSL
BC_VOLTAGE_MAX_RSL_mV
Maximum cell voltage limit MOL
BC_VOLTAGE_MAX_MOL_mV
Nominal cell voltage
BC_VOLTAGE_NOMINAL_mV
Minimum cell voltage limit MSL
BC_VOLTAGE_MIN_MSL_mV
Minimum cell voltage limit RSL
BC_VOLTAGE_MIN_RSL_mV
Minimum cell voltage limit MOL
BC_VOLTAGE_MIN_MOL_mV
Deep-discharge cell voltage limit
BC_VOLTAGE_DEEP_DISCHARGE_mV
Maximum discharge current limit MSL
BC_CURRENT_MAX_DISCHARGE_MSL_mA
Maximum discharge current limit RSL
BC_CURRENT_MAX_DISCHARGE_RSL_mA
Maximum discharge current limit MOL
BC_CURRENT_MAX_DISCHARGE_MOL_mA
Maximum charge current limit MSL
BC_CURRENT_MAX_CHARGE_MSL_mA
Maximum charge current limit RSL
BC_CURRENT_MAX_CHARGE_RSL_mA
Maximum charge current limit MOL
BC_CURRENT_MAX_CHARGE_MOL_mA
Cell capacity used for SOC calculation
BC_CAPACITY_mAh
Cell energy
BC_ENERGY_Wh
The lookup tables for the state of charge bc_stateOfChargeLookupTable
and for the state of energy bc_stateOfEnergyLookupTable need to be defined
in src/app/application/config/battery_cell_cfg.c.
The basic, top level view on the battery system configuration is defined at:
src/app/application/config/battery_system_cfg.c
src/app/application/config/battery_system_cfg.h
Setting
Details (define name)
Defines whether discharge current is seen as positive or negative
BS_POSITIVE_DISCHARGE_CURRENT
Number of parallel strings in the battery pack
BS_NR_OF_STRINGS
Number of modules in a string
BS_NR_OF_MODULES_PER_STRING
Number of cells per module
BS_NR_OF_CELL_BLOCKS_PER_MODULE
Number of battery cells in a parallel cell connection per battery module
BS_NR_OF_PARALLEL_CELLS_PER_CELL_BLOCK
Value of the balancing resistors on the slave-board
BS_BALANCING_RESISTANCE_ohm
Number of used GPIOs on the slave-board
BS_NR_OF_GPIOS_PER_MODULE
Number of temperature sensors per battery module
BS_NR_OF_TEMP_SENSORS_PER_MODULE
Defines whether CAN based current sensor is present or not
BS_CURRENT_SENSOR_PRESENT
Maximum break current of main contactors
BS_MAIN_CONTACTORS_MAXIMUM_BREAK_CURRENT_mA
Maximum fuse trigger duration
BS_MAIN_FUSE_MAXIMUM_TRIGGER_DURATION_ms
Maximum string current limit in mA that is used in the SOA module
BS_MAXIMUM_STRING_CURRENT_mA
Define if interlock feedback should be discarded or not
BS_IGNORE_INTERLOCK_FEEDBACK
Defines whether CAN timing shall be evaluated or not
BS_CHECK_CAN_TIMING
Defines whether balancing shall be available or not
BS_BALANCING_DEFAULT_INACTIVE
Number of contactors in addition to string contactors (e.g., precharge)
BS_NR_OF_CONTACTORS_OUTSIDE_STRINGS
Current threshold for determining rest state of battery
BS_REST_CURRENT_mA
Wait time in 10ms before battery system is at rest
BS_RELAXATION_PERIOD_10ms
Current sensor threshold for 0 current in mA as the sensor has a
BS_CS_THRESHOLD_NO_CURRENT_mA
Maximum voltage drop over fuse
BS_MAX_VOLTAGE_DROP_OVER_FUSE_mV
This section of the documentation is not yet complete.
BS_CHECK_FUSE_PLACED_IN_NORMAL_PATH
This section of the documentation is not yet complete.
BS_CHECK_FUSE_PLACED_IN_CHARGE_PATH
Enable open-wire checks during standby
BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK
Periodic open-wire check time in STANDBY state in ms
BS_STANDBY_OPEN_WIRE_PERIOD_ms
Open-wire check in normal mode (set to true or false)
BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK
Periodic open-wire check time in NORMAL state in ms
BS_NORMAL_OPEN_WIRE_PERIOD_ms
Open-wire check in charge mode (set to true or false)
BS_CHARGE_PERIODIC_OPEN_WIRE_CHECK
Periodic open-wire check time in CHARGE state in ms
BS_CHARGE_OPEN_WIRE_PERIOD_ms
Periodic open-wire check time in ERROR state in ms
BS_ERROR_OPEN_WIRE_PERIOD_ms
The symbolic names of the individual strings needs to be adapted in
BS_STRING_ID_e to the actual number of strings in the battery system.
The configuration array bs_stringsWithPrecharge need to define whether a
string can used for precharging or not.
This configuration array uses of the entries in BS_STRING_ID_e for the
assignment.