1. Configuration
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.
1.1. HALCoGen
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
like e.g., enabling the cache (Setting: TMS570LC4357ZWT_FREERTOS
,
sub-setting R5-MPU-PMU
and then the configuration Cortex-R5
,
sub-configuration General Configuration
: Enable Cache). 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/hal/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:
C:\Users\vulpes\Documents\foxbms>waf build_bin
Waf: Entering directory C:\Users\vulpes\Documents\foxbms\build\bin'
[ 2/824] Compiling hcg_compiler: conf\hcg\hcg.hcg conf\hcg\hcg.dil -> build\bin\src\hal\hcg.hcg build\bin\src\hal\hcg.dil build\bin\src\hal\hcg.log build\bin\src\hal\include\config_cpu_clock_hz.h build\bin\src\hal\include\HL_hal_stdtypes.h build\bin\src\hal\include\HL_sys_common.h build\bin\src\hal\include\HL_reg_system.h build\bin\src\hal\include\HL_reg_flash.h build\bin\src\hal\include\HL_reg_l2ramw.h build\bin\src\hal\include\HL_reg_vim.h build\bin\src\hal\include\HL_reg_pbist.h build\bin\src\hal\include\HL_reg_stc.h build\bin\src\hal\include\HL_reg_efc.h build\bin\src\hal\include\HL_reg_pcr.h build\bin\src\hal\include\HL_reg_pmm.h build\bin\src\hal\include\HL_reg_dma.h build\bin\src\hal\include\HL_reg_ccmr5.h build\bin\src\hal\include\HL_sys_core.h build\bin\src\hal\include\HL_system.h build\bin\src\hal\include\HL_sys_mpu.h build\bin\src\hal\include\HL_sys_pmu.h build\bin\src\hal\include\HL_sys_pcr.h build\bin\src\hal\include\HL_sys_pmm.h build\bin\src\hal\include\HL_sys_dma.h build\bin\src\hal\include\HL_reg_epc.h build\bin\src\hal\include\HL_reg_nmpu.h build\bin\src\hal\include\HL_reg_scm.h build\bin\src\hal\include\HL_reg_sdcmmr.h build\bin\src\hal\include\HL_epc.h build\bin\src\hal\include\HL_nmpu.h build\bin\src\hal\include\HL_errata.h build\bin\src\hal\include\HL_errata_SSWF021_45.h build\bin\src\hal\include\HL_errata_SSWF021_45_defs.h build\bin\src\hal\include\HL_sys_vim.h build\bin\src\hal\include\HL_reg_pinmux.h build\bin\src\hal\include\HL_pinmux.h build\bin\src\hal\include\HL_reg_gio.h build\bin\src\hal\include\HL_gio.h build\bin\src\hal\include\HL_reg_esm.h build\bin\src\hal\include\HL_esm.h build\bin\src\hal\include\HL_reg_sci.h build\bin\src\hal\include\HL_sci.h build\bin\src\hal\include\HL_reg_lin.h build\bin\src\hal\include\HL_lin.h build\bin\src\hal\include\HL_reg_mibspi.h build\bin\src\hal\include\HL_mibspi.h build\bin\src\hal\include\HL_reg_spi.h build\bin\src\hal\include\HL_spi.h build\bin\src\hal\include\HL_reg_can.h build\bin\src\hal\include\HL_can.h build\bin\src\hal\include\HL_reg_adc.h build\bin\src\hal\include\HL_adc.h build\bin\src\hal\include\std_nhet.h build\bin\src\hal\include\HL_reg_het.h build\bin\src\hal\include\HL_het.h build\bin\src\hal\include\HL_reg_htu.h build\bin\src\hal\include\HL_htu.h build\bin\src\hal\include\HL_reg_i2c.h build\bin\src\hal\include\HL_i2c.h build\bin\src\hal\include\HL_emac.h build\bin\src\hal\include\HL_hw_emac.h build\bin\src\hal\include\HL_hw_emac_ctrl.h build\bin\src\hal\include\HL_hw_mdio.h build\bin\src\hal\include\HL_hw_reg_access.h build\bin\src\hal\include\HL_mdio.h build\bin\src\hal\include\HL_phy_dp83640.h build\bin\src\hal\include\HL_phy_tlk111.h build\bin\src\hal\include\HL_emac_phyConfig.h build\bin\src\hal\include\HL_reg_dcc.h build\bin\src\hal\include\HL_dcc.h build\bin\src\hal\include\HL_reg_rtp.h build\bin\src\hal\include\HL_rtp.h build\bin\src\hal\include\HL_reg_dmm.h build\bin\src\hal\include\HL_dmm.h build\bin\src\hal\include\HL_reg_emif.h build\bin\src\hal\include\HL_emif.h build\bin\src\hal\include\HL_reg_pom.h build\bin\src\hal\include\HL_pom.h build\bin\src\hal\include\HL_reg_crc.h build\bin\src\hal\include\HL_crc.h build\bin\src\hal\include\HL_reg_etpwm.h build\bin\src\hal\include\HL_etpwm.h build\bin\src\hal\include\HL_reg_ecap.h build\bin\src\hal\include\HL_ecap.h build\bin\src\hal\include\HL_reg_eqep.h build\bin\src\hal\include\HL_eqep.h build\bin\src\hal\include\Device_TMS570LC43.h build\bin\src\hal\include\Device_header.h build\bin\src\hal\include\Device_types.h build\bin\src\hal\include\ti_fee_cfg.h build\bin\src\hal\include\MemMap.h build\bin\src\hal\include\ti_fee_types.h build\bin\src\hal\include\ti_fee.h build\bin\src\hal\include\fee_interface.h build\bin\src\hal\source\HL_sys_pcr.c build\bin\src\hal\source\HL_sys_pmm.c build\bin\src\hal\source\HL_sys_dma.c build\bin\src\hal\source\HL_system.c build\bin\src\hal\source\HL_sys_phantom.c build\bin\src\hal\source\HL_sys_startup.c build\bin\src\hal\source\HL_sys_vim.c build\bin\src\hal\source\HL_notification.c build\bin\src\hal\source\HL_epc.c build\bin\src\hal\source\HL_nmpu.c build\bin\src\hal\source\HL_errata.c build\bin\src\hal\source\HL_errata_SSWF021_45.c build\bin\src\hal\source\HL_sys_core.asm build\bin\src\hal\source\HL_sys_intvecs.asm build\bin\src\hal\source\HL_sys_mpu.asm build\bin\src\hal\source\HL_sys_pmu.asm build\bin\src\hal\source\HL_pinmux.c build\bin\src\hal\source\HL_gio.c build\bin\src\hal\source\HL_esm.c build\bin\src\hal\source\HL_sci.c build\bin\src\hal\source\HL_lin.c build\bin\src\hal\source\HL_spi.c build\bin\src\hal\source\HL_can.c build\bin\src\hal\source\HL_adc.c build\bin\src\hal\source\HL_het.c build\bin\src\hal\source\HL_i2c.c build\bin\src\hal\source\HL_emac.c build\bin\src\hal\source\HL_mdio.c build\bin\src\hal\source\HL_phy_dp83640.c build\bin\src\hal\source\HL_phy_tlk111.c build\bin\src\hal\source\HL_dcc.c build\bin\src\hal\source\HL_emif.c build\bin\src\hal\source\HL_pom.c build\bin\src\hal\source\HL_crc.c build\bin\src\hal\source\HL_etpwm.c build\bin\src\hal\source\HL_ecap.c build\bin\src\hal\source\HL_eqep.c build\bin\src\hal\source\Device_TMS570LC43.c build\bin\src\hal\source\ti_fee_cfg.c build\bin\src\hal\source\ti_fee_Info.c build\bin\src\hal\source\ti_fee_ini.c build\bin\src\hal\source\ti_fee_main.c build\bin\src\hal\source\ti_fee_read.c build\bin\src\hal\source\ti_fee_writeSync.c build\bin\src\hal\source\ti_fee_writeAsync.c build\bin\src\hal\source\ti_fee_util.c build\bin\src\hal\source\ti_fee_cancel.c build\bin\src\hal\source\ti_fee_format.c build\bin\src\hal\source\ti_fee_eraseimmediateblock.c build\bin\src\hal\source\ti_fee_invalidateblock.c build\bin\src\hal\source\ti_fee_shutdown.c build\bin\src\hal\source\Fapi_UserDefinedFunctions.c build\bin\src\hal\source\ti_fee_readSync.c build\bin\src\hal\source\HL_ajsm.asm
Waf: Leaving directory C:\Users\vulpes\Documents\foxbms\build\bin'
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\bin\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\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-other'
. 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/hal/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 process is illustrated in figure Fig. 1.1.
1.2. BMS application
The project provides two basic configuration options:
source options in
conf/bms/bms.json
compiler options in
conf/cc/cc-options.yaml
(path is an option, seef_ti_arm_cgt.options()
) and compiler remarks and remark severity level inconf/cc/remarks.txt
1.2.1. Source Options
Some BMS configurations require compiling different sources. That applies to the Operating System and the measurement IC.
Note
Only very basic configurations can be changed via these options described here. Everything not mentioned here must still be configured by programming the application behavior in the sources.
1.2.1.1. Operating System
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"
).
1.2.1.2. Analog Front-End
The AFE is configured in conf/bms/bms.json
. The joint path
from the values of manufacturer
and chip
must be the name of the
source directory in src/app/driver/afe/<manufacturer>/<chip>
that includes
the driver implementation. A list of supported ICs is found in
Section 4.29.
The build process behind this configuration is documented at Building the Analog Front-End Library.
1.2.1.3. Balancing Strategy
foxBMS 2 supports three different balancing strategies:
Voltage-based balancing: Cell balancing based on voltage differences (key-value:
voltage
). Details are found in Voltage-based BalancingHistory-based balancing: Cell balancing based on voltage history (key-value:
history
). Details are found in History-based BalancingNo balancing: No balancing of any cell (key-value:
none
). Details are found in No Balancing
1.2.2. Compiler and Linker Options and Remarks
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
waf configure
.
See the TI compiler manual before changing the flags in
conf/cc/cc-options.yaml
.
The following subsections describe the options in conf/cc/cc-options.yaml
.
1.2.2.1. INCLUDE_PATHS
Additional INCLUDE_PATHS
that are not standard compiler includes.
Standard compiler includes are derived in the configure step of the compiler.
1.2.2.2. LIBRARY_PATHS
Additional LIBRARY_PATHS
that are not standard compiler library search
paths. Standard compiler library search paths are derived in the configure
step of the compiler.
1.2.2.3. LIBRARIES
Libraries that are used when linking.
1.2.2.4. CFLAGS
CFLAGS
are configured differently or the BMS application, the Operating
System and the Hardware Abstraction Layer.
common
: options are applied to all sources (BMS, OS, HAL).common_compile_only
: options are applied to all sources (BMS, OS, HAL), but only for the compile step, not for the preprocessor build steps. The build tool automatically adds that the options--gen_cross_reference_listing
,--gen_func_info_listing
,--gen_preprocessor_listing
. These options control the generation of the*.aux
,*.crl
and*.rl
files.foxbms
:CFLAGS
that should only be applied to the BMS application sources (src/app/*
).hal
:CFLAGS
that should only be applied to the generated hardware abstraction layer sources (src/hal/*
).operating_system
:CFLAGS
that should only be applied to the operating system sources (src/os/*
).
1.2.2.5. LINKFLAGS
Flags that are passed to the compiler when linking (Note: The compiler is
used as linker when run with the argument
--run_linker
). Flags here do typically not needed to be changed except
for --heap_size=0x800
,
--stack_size=0x800
or the optimization flag -oN
where N
is the
level of optimization.
1.2.2.6. HEXGENFLAGS
Flags passed to hex file generation tool armhex
(Note: hex files are only
generated when passing a node by keyword linker_script_hex
in
bld.tiprogram(..., linker_script_hex=some_node, ...)
).
1.2.2.7. NMFLAGS
Flags passed to hex file generation tool armnm
. Flags here do
typically not needed to be changed.
1.2.2.8. Remarks
Compiler remarks help to find potential problems at an early stage of
development. The file conf/cc/remarks.txt
allows to list remarks and how
they should be handled. Global remarks are set in conf/cc/remarks.txt
.
Remarks are re-loaded before compiling. Remarks can be added to a single build
step as shown in Listing 1.2
1def build(bld):
2 bld.stlib(
3 source=source,
4 includes=includes,
5 cflags=cflags,
6 target=target,
7 cmd_files=
8 [bld.path.find_node("path/to/some/remark/file.txt").abspath()],
9 )
Warning
If remarks should be disabled, the option --issue_remarks
needs to be
removed in conf/cc/cc-options.yaml
. Furthermore all command files that
specify remarks need to be checked and all diagnosis related commands need
to be removed or the severity level needs to be set to --diag_remark=...
to avoid compile errors.
The default remark settings are relatively strict to avoid common mistakes. Changing them is generally not recommended.
Note
It is possible to add all kinds of compiler flags in command files, this is not only related to remarks.
1.2.2.9. Linker Output Processing
Note
Linker output validation only works if --scan_libraries
is specified.
The linker output is processed in order to validate that the correct symbols are linked into the binary.
If a symbol is defined in multiple places the linker decided which symbol to use. This is described in TI ARM assembly tools manual in section Exhaustively Read and Search Libraries.
Consider the following linker output in Listing 1.3.
1 Linking build\bin\src\app\main\foxbms.elf
2 remark #10252-D: Symbol "_c_int00" (pulled from "src\app\main\fstartup.c.1.obj") defined in 3 places:
3 src\app\main\fstartup.c.1.obj
4 src\hal\libfoxbms-hal.a<HL_sys_startup.c.1.obj>
5 C:\ti\ccs1030\ccs\tools\compiler\ti-cgt-arm_20.2.0.LTS\lib\rtsv7R4_A_be_v3D16_eabi.lib<boot_non_cortex_m.asm.obj>
If the symbol _c_int00
should be pulled from
src/app/main/fstartup.c.1.obj
, the linking step should be treated as
successful. If the symbol is pulled from somewhere else an error must be
generated. To tell this to the linker output parser a json
file that
indicates which symbol should be pulled from where needs to be defined (see
Listing 1.4). In this file use Unix-separator and specify the
linked source as seen from the build directory.
1{
2 "_c_int00": "src/app/main/fstartup.c.1.obj"
3}
This file needs to be specified when a program is built (see
Listing 1.5). If the symbol _c_int00
would not be
pulled from src/app/main/fstartup.c.1.obj
an error would be generated.
1
2def build(bld):
3 """Build the binary"""
4 source = [
5 # list sources here
6 ]
7 includes = [
8 # list include directories here
9 ]
10 linker_script = bld.path.find_node("linker_script.cmd")
11 linker_pulls = bld.path.find_node("linker_pulls.json")
12 bld.tiprogram(
13 source=source,
14 linker_script=linker_script,
15 linker_pulls=linker_pulls,
16 includes=includes,
17 target="my-app",
18 )
For implementation details see f_ti_arm_cgt.cprogram.parse_output()
.