Jtag-Optimisation For Canoe: Anton Karlsson
Jtag-Optimisation For Canoe: Anton Karlsson
Anton Karlsson
This master thesis investigates the possibilities to perform software validation tests
on ECUs with customer-identical software. Instead of using a ”test specific” soft-
ware which sends ”test specific” information on the CAN-bus this data is to be
extracted from the target CPU by a JTAG debugger and integrated in the testing
software CANoe. The benefit of this method is that it eliminates the problems that
may be encountered during building of the ”test specific” software and that may
affect other parts of the software.
The work has been done at BorgWarner in Landskrona at the TTT-SW (software
test) department.
3
Acknowledgements
Individuals whom I would like to thank include - but are not limited to - my su-
pervisor at BorgWarner TTT, Mattias Wozniak whom have been to a lot of help in
CANoe and test specific issues and Henrik Björk at BorgWarner TTE for a lot of
help and input in Lauterbach and target software related issues.
5
Contents
List of Figures 9
1. Introduction 12
1.1 BorgWarner and the product . . . . . . . . . . . . . . . . . . . . 12
1.2 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Software testing . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3 Problem formulation . . . . . . . . . . . . . . . . . . . . . . . . 14
1.4 Related work . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5 Outline of the report . . . . . . . . . . . . . . . . . . . . . . . . 15
2. Background 16
2.1 CAN-bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
CAN-message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2 Software Test Rig . . . . . . . . . . . . . . . . . . . . . . . . . 18
VT-system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
VN 8970 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3 CANoe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
CANoe API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4 JTAG and Trace32 . . . . . . . . . . . . . . . . . . . . . . . . . 21
Trace32 API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.5 The ECU and ECU software . . . . . . . . . . . . . . . . . . . . 23
3. Equipment 26
4. Performance 27
4.1 Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2 Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5. Solution approach 30
5.1 RS232 approach . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2 Integrated approach . . . . . . . . . . . . . . . . . . . . . . . . 31
6. Implementation 33
6.1 Test rig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7
Contents
8
List of Figures
1.1 The clutch visualised in a car that is front wheel drive during normal
circumstances. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.1 The standard identifier CAN frame with one byte of data. . . . . . . . 17
2.2 The VT-system with its modules mounted in a 19” rack cabinet. Real-
time module to the far left. Power supply below the VT-system. . . . . 19
2.3 The VN8970 device. . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4 Simulation Setup in CANoe. . . . . . . . . . . . . . . . . . . . . . . 21
2.5 Several TAPs connected through daisy-chain, TRST not shown. This
might illustrate separate devices/chips or different modules on one de-
vice/chip. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.6 A standard and a JTAG-modified ECU. . . . . . . . . . . . . . . . . . 23
2.7 Example debug cases (241, 244 and 250) showing what case could con-
tain what variable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1 Equipment and set up overview. The different software run be the dif-
ferent devices are shown in red. . . . . . . . . . . . . . . . . . . . . . 26
4.1 The ECU during the test, regular traffic on the CAN bus specifying
driving scenario, status of the car, status of the ECU/AWD clutch, etc,
and the JTAG connection reading a part of the CPU’s memory. . . . . 27
4.2 Accumulated time by the operating schedule for different software and
JTAG data extraction loads. The blue bars represent how much time is
added to the thread by reading the memory. . . . . . . . . . . . . . . 29
4.3 Accumulated time by the suspended schedule for different software and
JTAG data extraction loads. The blue bars represent how much time is
added to the thread by reading the memory. . . . . . . . . . . . . . . 29
9
List of Figures
7.1 A part of the Control Software Test shown where some of the Quality
Signal Test Cases have failed. . . . . . . . . . . . . . . . . . . . . . . 56
10
Abbreviations
11
1
Introduction
Figure 1.1 The clutch visualised in a car that is front wheel drive during normal
circumstances.
12
1.2 Testing
with a lot of information about the status of the car such as steering angle, throttle
position, wheel speed, acceleration, etc. via CAN-bus (see Chapter 2.1). The torque
is provided to the undriven axis by applying hydraulic pressure to the clutch plates
by running an electric pump motor. There is, in most cases, no feedback in terms
of hydraulic pressure on the clutch, the calculations are based on the voltage and
current supplied to the motor and the aforementioned signals provided to the ECU
via CAN, see Figure 1.1.
The demand of all-wheel drive vehicles is predicted to increase over the coming
years [2] and several of the world’s car manufacturers use the BorgWarner AWD-
clutch, for example Volkswagen, Volvo and Jaguar Land Rover.
The thesis work has been done at the department TTT-SW which mainly per-
forms software testing of the ECU.
1.2 Testing
In order to make sure that the finished product meets the initial requirements both
the mechanical, electrical and software related aspects are extensively tested during
development - it is a part of the development process rather than being performed at
the end of each project. Since the thesis work has been done at the Software Testing
department the focus of it will be on this part.
Software testing
The testing of the software is governed by a test strategy which describes how the
testing should be performed so that there is a unified way of working within all the
projects [10]. This also leads to that a part of the test scripts can be used across
several projects.
During most of the tests the ECU is connected to a tool which simulates the car,
which is controlled by the tester’s PC (see Chapter 2.2) and also some further equip-
ment such as a pump, different sensors and so on in order to simulate the reality the
ECU will experience in a car. Several so called functional tests are performed on
different areas of the software, such as:
• Bootloader
• Hardware Error Handling
• CAN interface
• Automatic Calibration of the pump
In a more explicit sense some of the tests might see to that the ECU responds in
a certain amount of time, and in the correct way, when the anti-lock brakes are
activated or that correct actions are taken by the ECU when some kind of problem
or error is encountered.
13
Chapter 1. Introduction
• By how much will the JTAG-debugger degrade the performance of the CPU?
• What are possible ways of integrating the data from the JTAG-debugger in
CANoe?
14
1.4 Related work
15
2
Background
2.1 CAN-bus
The CAN protocol is an ISO standard for serial data communication which was de-
veloped by Roberth Bosch GmbH [3] during the ’80s for automotive applications.
Now, however, CAN is not exclusively used in automotive context but also in in-
dustrial automation and mobile machinery. CAN differs from several other buses
in the way that it does not require a host computer or processor; every node on the
bus has its own processor which allows them to communicate with each other. This
makes the technique well suited for automotive purposes since a modern car may
have 50-100 ECUs for various subsystems.
Since all nodes on the bus are able to communicate, all nodes ”hear” all trans-
missions - all nodes pick up all traffic. This might lead to undesirable interaction
between different nodes or systems on the bus. There are, however, methods like
filtering in the hardware to make sure that certain messages only reach a certain
node.
Hardware
The physical connections between the nodes on the CAN bus most commonly com-
prise a two-wire (plus ground) scheme, each line called CAN-HI and CAN-LO
respectively. The signal is differential and also usually connected in a twisted-pair
fashion making it less prone to interfere with a noisy environment. Each end of the
bus has to be terminated with a 120 Ω resistor.
According to the CAN standard - ISO-11898-1 - the maximum transmission
speed is 1 Mb/s when the cable length is less than ∼40 meters. If the network gets
larger the bit rate has to be reduced.
CAN-message
There are basically three different message types, called ”Frames”, on a CAN-bus:
16
2.1 CAN-bus
Figure 2.1 The standard identifier CAN frame with one byte of data.
The Data frame carries, as the name implies, the data on the bus. Since a spe-
cific frame can not be directed to a specific node each frame comprises an identifier
which is unique on the bus. Apart from the identifier (which is a part of the arbi-
tration field) the frame also consists of, see Figure 2.1, a control field containing
information regarding type of identifier and number of bytes of data; a data field
which contains zero to eight bytes of data; a CRC field which contains a 15-bit
checksum used for error detection and an acknowledgement slot which tells the re-
ceiver that the frame has been received by a node, not necessarily the node the data
was intended to.
The identifier can be either 11-bit or 29-bit long, called standard (also CAN
2.0A) and extended (CAN 2.0B) identifier respectively. To differentiate between
the two a reserved bit in the control field is used. It is possible to mix 2.0A and 2.0B
nodes on a bus as long as a B node does not send frames with an extended identifier
(it is capable of sending standard identifiers as well). The extra ”space” in the B
message can then be used as an extension of the data field.
The Remote frame is different from the Data frame in two ways, it is marked
as a remote frame with a dedicated bit in the arbitration field and there is no data
field. The Remote frame is used by a node when it is requesting data with a specific
identifier.
The Error frame is used when a node detects an error on the bus and does not
look like the regular Data or Remote frames. When the frame is sent the other nodes
detecting this frame will also start sending error frames, hopefully making sure that
it is detected by the last transmitting node which then tries to retransmit the message.
Error counters make sure that the bus traffic does not become destroyed by the error
frames.
There is also a fourth type of frame, the Overload frame, which is sent when
a node becomes too busy. This frame is, however, rarely used nowadays since the
only CAN controller capable of sending it is the outdated Intel AN82526 [4].
On the CAN bus a transmitted ”0” is dominant and a ”1” is recessive which
means that if two nodes are trying to transmit a message simultaneously the one
17
Chapter 2. Background
with the lower ID will succeed. The node trying to transmit the message with the
higher ID will wait and try again.
VT-system
The VT-system, developed by the company Vector Informatik GmbH [8], is the
”heart” of the test rig and the main part of it is its real-time module which basically
is a computer that simulates the car to which the ECU is connected. The real-time
module is used to enhance the performance by running the real-time parts of the
CANoe tests on a dedicated platform rather than the user PC, which often has a lot of
different processes running at all times. It is accessed from the user PC by Ethernet
which does not affect the behaviour or performance of the real-time system.
The system is modular in itself and consists of, apart from the real-time module;
a CAN network module, general purpose relay and analog-/digital I/O modules and
a couple of power modules, see Figure 2.2.
VN 8970
The VN8970, also from Vector [14], is similar to the VT-system in that sense that it
is also running a real-time computer and CANoe in order to simulate the imaginary
car. It differs in that it is not a modular system with the capability to expand with
modules such as I/O and relay modules. It does, however, comprise several CAN-
bus channels and a general I/O port, see Figure 2.3. For the scope of the thesis work
18
2.2 Software Test Rig
Figure 2.2 The VT-system with its modules mounted in a 19” rack cabinet. Real-
time module to the far left. Power supply below the VT-system.
19
Chapter 2. Background
either of the mentioned Vector hardware devices fulfil the requirements. The major
difference is that it is possible to expand the VT-system and suit it to the specific
task by means of I/Os and so on, the VN8970 has a fixed number of I/Os from the
beginning.
2.3 CANoe
All the tests, called measurements, performed on the ECU are implemented in CA-
Noe, also developed by, just as the VT-system and the VN8970, Vector [6]. CANoe
is highly integrated with the VT/VN hardware and comprises functions such as sim-
ulation of bus systems, analysis of bus communication, testing of entire networks
and/or individual ECUs etc.
A CANoe test set up, called configuration, consists partly of a Simulation Setup
where the CAN network, with its nodes, is graphically presented, see Figure 2.4.
The node presented to the far right is the CAN interface towards the hardware used;
the ECU. Each other node is configured by CANoe and might be of different type.
For example, as seen in Figure 2.4, an ’I-Generator’ (Interactive Generator) block
which can be set to send one or several specific frames once or on a cyclic basis or
more configurable nodes, such as the ’ECU’ blocks. These blocks are configured by
a C-like programming language called CAPL [9] which makes the nodes convenient
to suit the specific application. The actual test scripts are also implemented in this
language, see example code below.
20
2.4 JTAG and Trace32
CANoe API
Vector provides an API written in C with CANoe that, when used, has to be built
as a dll-file which in turn has to be linked in the specific CANoe configuration. The
API consist of a number of functions like reading and writing system variables but
also comprises some functions that have to be implemented so that CANoe is able to
”run” the dll. These are functions that are called, for example, when the dll is loaded,
when the measurement (test) starts, and when the measurement stops. The names
of the functions in the CANoe API are preceded by ccl, for example cclPrintf
which is a standard printf-function but writes specifically to the ’write’-window
in CANoe.
21
Chapter 2. Background
Figure 2.5 Several TAPs connected through daisy-chain, TRST not shown. This
might illustrate separate devices/chips or different modules on one device/chip.
The TMS signal controls the behaviour of the JTAG interface by controlling
in which state the TAP controller is. The clock signal synchronizes the TAP con-
troller’s operations and the Data In and Data Out signals represents the data shifted
in/out of the controller’s test or programming logic at rising and falling edge of
TCK, respectively. The reset signal, which is optional can reset the TAP controller’s
state machine [7].
Trace32 is a debug and development tool supplied by Lauterbach GmbH [12]
which uses said JTAG interface to communicate with the CPU in the ECU. All the
variables that are interesting for the scope of the thesis work are accessible by the
software.
Trace32 API
The API provided by Trace32 is written as a C library with a number of predefined
functions making it possible to remotely, for example from a Visual Studio-written
application, control the software and the debugger [1]. When configured the appli-
cation communicates with Trace32 via a socket interface making it possible to run
the application and Trace32 on different hosts. Every function name of the Trace32
API is preceded by T32_. Important functions for the scope of the thesis work pro-
vided by the API are among others:
// Configures the communication driver of the API.
// Example T32_Config("NODE", "LOCALHOST")
int T32_Config(char* string1, char* string2)
22
2.5 The ECU and ECU software
In order to get Trace32 to work with the specific project on the target CPU one
has to load an .elf file which is created during compilation of the project. The file
contains information about memory, symbols, debug information, etc, and is loaded
through the command line in Trace32 via DATA.LOAD.ELF [path_to_file].
23
Chapter 2. Background
The software on the ECU consists of basically two parts, base software
and control software. The control part is relatively similar between the differ-
ent project/customers comprising management of the pump, mathematical mod-
els for temperature calculations and so on, while the base software is more
project/customer specific, handling the CAN frames sent on the CAN-bus to and
from the car, car-specific behaviour and so on.
There are two major builds of software used for different purposes at the com-
pany, one called Application and one called Monitor. The Application software is
the software which the customer is going to get on the ECUs mounted on the cars,
the Monitor software is used in-house for testing and development purposes. The
two builds differ mainly by a part of code called ioDebug which does not exist in
the Application build. ioDebug handles the frames sent on the CAN-bus specifically
for software testing and evaluation purposes i.e. the part of code, which by the the-
sis work, we aim to get rid of and instead extract the data via JTAG. Not all debug
variables are sent all the time, the tester can select (manually or in the test script for
the change to be done automatically) which group of variables to receive from the
ECU by sending a frame to the ECU on the CAN-bus specifying a so called ”debug
case”. This is to reduce the load on the bus and each case is created so that a specific
group of tests can be performed without changing it. This means that some variables
exist in several cases, see example cases in Figure 2.7, but since only one case is
active at any given time, the overall bus load is reduced compared to if all variables
where to be transmitted. In the project from which the thesis work is based on there
are a total of five different debug cases ranging from 26 to 9 variables in each.
24
2.5 The ECU and ECU software
241----------------------------------------------------
FLVel
FRVel
RLVel
RRVel
EngineOmega
ActionTorque
EngineTorque
ReqEngineTorque
244----------------------------------------------------
PumpCurrent
PumpVoltage
Curvature
VehicleVel
VehicleMaxAcc
VehActualAcc
TorqueDistBrake
VehicleMode
ErrorCtrlMode
250----------------------------------------------------
PumpCurrent
PumpVoltage
AutoCalibState
AutoCalibStatus
VehicleVel
VehicleMode
ErrorCtrlMode
Figure 2.7 Example debug cases (241, 244 and 250) showing what case could
contain what variable.
25
3
Equipment
The equipment used was a PC, an ECU - connected to the JTAG debugger, a JTAG
debugger - connected to the PC via USB and a Vector real-time system - VT or VN
8970 - also connected to the ECU via CAN and the personal computer via Ethernet,
see Figure 3.1 where which software is run on which device is shown in red. The
PC runs CANoe and Trace32 whilst the Vector real-time system runs the real-time
part of the CANoe tests. The ECU is also connected to a pump block so that it
can perform all the test as if it was installed in a car. Between the real-time system
and the ECU the hardware layer is connected which is controlled by the real-time
system via a couple of I/O-signals which in turn controls the power supply to the
ECU, see Chapter 6.1 for more details.
For development and using the APIs provided by CANoe and Trace32, Visual
Studio C++ 2010 [13] was used.
Figure 3.1 Equipment and set up overview. The different software run be the dif-
ferent devices are shown in red.
26
4
Performance
BorgWarner has implemented tests to measure the performance of the ECU in terms
of cycle time, CPU-load, execution time of certain threads etc, which are performed
on the ECU when changes in the software have been made. It was possible to use
these tests to measure the performance when at the same time extracting data on the
JTAG interface to see if the performance was degraded.
ECU
CAN CAN
JTAG
Figure 4.1 The ECU during the test, regular traffic on the CAN bus specifying
driving scenario, status of the car, status of the ECU/AWD clutch, etc, and the JTAG
connection reading a part of the CPU’s memory.
4.1 Procedure
The set up in order to test the performance is the same as in Figure 3.1. During
the test CANoe runs a general measurement running the ECU through a number
of different driving scenarios whilst the CPU is being ”stressed” by the reading of
memory and the data being extracted on the JTAG interface every 20 ms, see Figure
4.1. At the end of the test Trace32 runs a script which extracts information from the
CPU regarding the performance by means of execution times, loads, etc.
Several tests were run with different software (Application and Monitor) and
different amount of data extracted. Tests on the application software without any
27
Chapter 4. Performance
data extraction were run in order to have a reference and also to evaluate what dif-
ference the ioDebug part - the part of the software that sends the debug/test specific
frames over CAN, see Chapter 2.5 - of the software makes to the overall perfor-
mance. In order to decide how large amount of data to extract during the tests the
ioDebug code was studied to actually see what variables are sent on the bus. In the
case of the project used during testing ioDebug sent variables adding up to approx-
imately 1 kB of data. Normally during a test not all variables are necessary which
is why separate tests with different amount of data extracted were performed - one
with all the data, one with approximately half and one with approximately a tenth
of the data. Furthermore, in order to stress the system to its max, one test where the
whole RAM was extracted was performed. All of the tests with simultaneous data
extraction were done on an ECU with the Application software flashed.
The performance script presents the result from the tests by means of execution
time and CPU-load for all the different so called schedules in the CPU - initiali-
sation schedule, operating schedule, suspended schedule, shut down schedule and
so on, which basically are different modes in which the CPU can be operating. It
is implemented so that it presents the worst case times and loads recorded for the
different schedules and threads. That is, the result presented below shows the max-
imum execution time of that thread recorded during the test. The most important
schedule to investigate is the operating schedule since it is in this schedule the CPU
is operating when everything is normal.
Execution times and loads might change slightly due to different noise factors
which is why each test case was run three times to get statistical validity. The result
is then presented as a mean value of the three measurements.
4.2 Result
Figures 4.2 and 4.3 show the accumulated time for all the threads in the different
schedules for the different software and amount of data extracted. Even though the
differences are small in absolute time (Monitor is roughly 2% slower than Applica-
tion in operating mode) it is clear that the Application build is the fastest and that
when the whole RAM is extracted is the slowest. When extracting the amount of
data corresponding to 10% of the ioDebug variables no noticeable difference can be
seen.
More importantly, the more realistic cases when data corresponding to all, or a
part, of the variables in ioDebug are extracted are not worse than the Monitor build.
All of the schedules (not presented here) show a similar behaviour which is why it
is possible to conclude that, for these purposes, the JTAG data extraction method
satisfies the current needs of not degrading the CPU’s performance.
28
4.2 Result
Figure 4.2 Accumulated time by the operating schedule for different software and
JTAG data extraction loads. The blue bars represent how much time is added to the
thread by reading the memory.
Figure 4.3 Accumulated time by the suspended schedule for different software and
JTAG data extraction loads. The blue bars represent how much time is added to the
thread by reading the memory.
29
5
Solution approach
In order to analyse data extracted from the ECU via the JTAG debugger in the regu-
lar testing environment, CANoe, the data has to be shifted from the JTAG debugger
software, Trace32, to CANoe. Two main approaches where considered trying to
achieve this, see Sections 5.1 and 5.2.
Common for the two approaches are that the JTAG debugger is connected to the
user PC via USB.
30
5.2 Integrated approach
31
Chapter 5. Solution approach
CANoe API
Trace32
Trace32 API Ethernet CANoe
32
6
Implementation
The following chapter will describe how the suggested solution to the challenges
described in Chapter 1.3 was implemented. Firstly the hardware of the test rig will
be described followed by the two parts of software implemented; the graphical user
application which function is that the user can create a file containing the informa-
tion needed by the second part - the software governing the actual transmission of
data between the ECU and CANoe.
33
Chapter 6. Implementation
the VN8970 unit are used since the standard outputs cannot supply enough current
for the relays. The outputs are not really relay outputs but rather solid state outputs
controlled by MOSFETs. In practice this means that the supply to the relays has to
be connected to, and through, the VN8970 but since the large power supply feed-
ing the ECU might drop well below 12V during testing another 12VDC source is
needed. For this purpose a standard, wall-socket mounted 230VAC-12VDC trans-
former is used, capable of delivering ~650mA, enough for the relays consuming
roughly 150mA a piece.
Further two LEDs are implemented so that it is easy to see if any or both relays
are set and also a protection circuit for the acting contact in the relay, see Figure 6.1.
34
6.2 User application
PumpCurrent
m_ulGradientFixPoint
m_uiPumpCurrentRAWValue
m_lOffsetFixPoint
ClutchPedalPressed m_boClutchPedalPressed
BrakePedalActive m_boBrakesActive
HandBrake m_boHandBrakeActive
CONSTANTS
m_uiTEMP_IN_TABLE
m_uiPCB_RESISTANCE_IN_TABLE
to Trace32 which specifies the code and variables available on the CPU.
Usage
As a first step a .txt-file has to be manually created which specifies what variables
ioDebug.c actually puts in the different debug frames sent on the CAN-bus. This is
achieved by looking through the source code in ioDebug.c. Most variables are global
and are just copied into the frame, but there are also variables calculated locally in
ioDebug.c which means that in some cases several variables have to be extracted
in order to calculate this value. Therefore the file is to be written according to the
syntax shown in Figure 6.2, depending on whether it is a ”dynamic” or ”indirect”
variable. In the eaxmple PumpCurrent is ”indirect” and calculated from the three,
indented, following variables and e.g. BrakePedalPressed is ”dynamic” and di-
rectly revealed in the variable on the same line. The names in the second column
or with indentation are the exact names which are used in the code on the CPU. By
loading this file via the ”Load File” button, see Figure 6.3, the file is read and all
the available variables are shown in the box in the centre of the GUI. Here only the
names in the first column of the file are shown, this is also the exact name of the
system variables specified in the CANoe configuration.
Further, another file has to be loaded via the ”Load Map” button. This file is
created when the code for the CPU is compiled and contains, among others, name,
address and size of all variables in the code. It usually has the extension .map when
created but has the appearance of a standard text file and it is possible to just save it
as a .txt file, which is the format the application needs. When the file is loaded each
line of it is added as an element in a container. Since the map file might be very
large, several thousands of lines in some cases, this might take a few seconds and
during this time any interaction with the application is unavailable or ”grayed out”.
It is through this file the mapping between the name that is shown in the GUI and
the address and size is done, which is vital information when reading the memory
of the CPU via the JTAG debugger.
35
Chapter 6. Implementation
Figure 6.3 The user interface of the application with variable-file loaded and all
available variables shown.
As seen in Figure 6.3 there is a field where the user should state the IP-address
of the host running Trace32. The address is needed by the Trace32 API when con-
necting to the actual Trace32 application since the API is not running on the same
host as Trace32 but rather on the Vector real-time device. There is also a field where
the user should input the path to the .elf-file containing information about the code
and project on the CPU such as symbols, hardware, etc, needed by Trace32 in order
to use the API functions see Section 2.4.
When clicking the ”Create and Save” button the container holding the informa-
tion from the Map-file is searched for the variables specified in the first loaded file.
When the container is searched and the variables are found (or not found) the final
file is created and the user is prompted to specify name and place where to save the
file. The user must not change the name from that the application suggests for the
file - ”CANoeUserFileDebugVars.txt” - since this name is used when reading it in a
later stage, see Section 6.3. If not all variables were found the user will be prompted
with this information and suggestions for what the reason might be, spelling error
or wrong map file loaded. The file is still created and the variables not found will be
pointed out. If all was found the file is created with the syntax shown in Figure 6.4.
36
6.2 User application
IPADRESS: 169.254.233.80
The second and third columns are the address and size of the variable respec-
tively. The names of the dynamic variables are also the names of the system vari-
ables specified in CANoe, this is also the case for the names under ”CANoe System
Variables” which are the names of the variables that must be calculated from the
”Indirect variables”. The "Constant variables" are variables that are read just once,
at the beginning of each measurement and later used during the calculations.
37
Chapter 6. Implementation
below.
In order to activate a function when i.e. a button is pressed one have to link it in a
macro function ON_COMMAND(object_ID, function), see below.
ON_COMMAND(But_Save, save)
The above piece links the event of the ”Save” button pressed and the function save
which is declared as a public function in the sub class to ’CDialog’. The functions
in this class have to be declared with afx_msg before the return type, see example
below.
/**************************************************************
* FUNCTION NAME save
* DESCRIPTION Called when button "Save" is pressed. Creates and
* lets the user specify name and location of file
* containing chosen variable name, address and size.
* PARAMETERS None
* RETURN VALUE None
**************************************************************/
afx_msg void save()
{
if(varMap.empty())
{
MessageBox(defCstrMapNotLoaded,
defCstrError, MB_ICONERROR);
return;
}
...
}
Program Structure
There are mainly three events that have to be handled when using the application;
when either file (variable- and map-file) is loaded and when the new file is created
and saved. To get a better overview, the following are the important global variables
used for storing the different names, addresses and sizes:
38
6.3 Data extraction/integration dll
When loading the first file, the one revealing name and dependencies of the
different variables, the std::map<...> vars is filled with the name of the system
variable (first column of the file, see Figure 6.2) as key and the dependencies or
the dynamic variable name in a std::vector<std:string> as value. If it is a
”dynamic” variable the string dynamic is added as first element in the vector. All
key values are then added to the ListBox in the center of the GUI, see Figure 6.3,
showing all available variables.
When the map-file is loaded every line of it is added to the std::map<...>
varMap with the first word of the line as key and the rest of it as value. The file is
created in such a way that each key is a name of a variable and the value contains
the address and size. The file might be large, several thousands of lines in some
cases, which is the reason it is added to a std::map which is sorted and has a time
complexity when searching it of O(log(n)). A linear search inside the file for each
variable would take far too long time.
The mapping is done when the ”Create and save” button is pressed; vars is iter-
ated over the elements and each variable in the vector associated to each element
is searched for in the varMap. Depending on type; dynamic, indirect, constant or
system variable name, a string containing name, address and size (just name in the
case of system variable) is added to the corresponding std::set<std::string>.
A stream to a file is then created and each std::set is iterated over creating the
structure seen in Figure 6.4 with the ip-address and path to the elf-file defined in the
corresponding field in the GUI copied to the beginning of the file.
39
Chapter 6. Implementation
Besides the above mentioned functions there are also timers available through
the API as well as functions to trigger when certain events have occurred in the
measurement, such as a reset of a system variable etc.
In order to extract the data the Trace32 API, see Section 2.4, is used within the
framework specified by CANoe.
Usage
One of the main goals was to create a solution that is as transparent for the tester
as possible, i.e. he or she should not have to change the work flow by a substantial
amount. However, a few actions have to be taken in order to get the data transmis-
sion running within an existing CANoe configuration.
First the dll has to be added in the ’Options-Programming-C libraries’ field of
the configuration of CANoe. This specifies the path to the dll which is loaded and
run by the Vector real-time unit at every measurement start. Furthermore, by the
way the dll is implemented it reads information from two files, one specified by
the graphical user application described in Section 6.2 and another on specifying
what variables exists in each debug case, see example in Figure 2.7, named ”CA-
NoeUserFileDebugCase.txt”. For the dll to be able to access these files, since it is
executed on the real time device, they have to be loaded onto the real time device as
well. This is possible through ’Options-Extensions-User Files’ where the files then
are loaded to a pre-defined location on the real time device’s storage area at every
measurement start, making it possible to access them from the dll.
40
6.3 Data extraction/integration dll
INIT
Read/Write
STOP
Figure 6.5 The flow of the data extraction/integration application. The dashed lines
represents interrupt-like events.
version since that adds debug information to the build and makes it impossible to
use for CANoe.
Program Structure
First a brief overview of the program will be described followed by a more detailed
description of each part.
Overview A concise chart over the flow during a measurement is shown in Figure
6.5. At the start of each measurement - the ”INIT”-block - a number of initialisa-
tions are done; the files loaded via ’User-Files’ in CANoe are read and processed,
a connection with Trace32 over Ethernet is established and the ID number of each
system variable to write to CANoe is retrieved.
One measurement may comprise several sub-tests which are started manually
- or automatically - a while after the main measurement is started, it is therefore
unnecessary to start the reading/writing of data before the actual test starts. This
is taken care of in the ”KL15/30”-block by listening on two system variables in
CANoe telling if KL15 and/or KL30 is high or low (see Section 2.5 for an exlanation
of the functionality of KL15 and KL30), that is, if either is low the reading/writing
is halted and then started again when both are high.
The ”Read/Write”-block may start to loop with just KL15 and KL30 high but
nothing of essence will actually be performed until a debug case has been specified
by CANoe. Just as in the ”KL15/30”-block the dll observes a certain system variable
41
Chapter 6. Implementation
Figure 6.6 Overview similar to Figure 6.5 where functions called in each block is
shown in red.
in CANoe which specifies the debug case that is needed by the test running. When
a change is detected the corresponding variables are read from the target CPU and
sent to CANoe.
The ”Read/Write”-block takes care of the reading of data from the target CPU
- via Trace32 and its API -, processing the data and performing calculations of the
indirect variables and writing to CANoe. It is repeated after a certain amount of
milliseconds according to which debug case is active. The loop is stopped if the
power supply to the ECU is disconnected and it is paused during the short period of
time the program adjusts to a new debug case.
When the measurement is stopped - the ”STOP”-block - the connection to
Trace32 is terminated and all memory that has been allocated by the dll during
the measurement is deleted.
An overview similar to Figure 6.5 - where some of the functions called in each
block are shown - is seen in Figure 6.6.
Initialisation At the very start of every measurement the function cclOnDllLoad
is called, below the implementation is shown.
/**************************************************************
* FUNCTION NAME cclOnDllLoad
42
6.3 Data extraction/integration dll
/**************************************************************
* FUNCTION NAME OnMeasurementPreStart
* DESCRIPTION Called right before a measurement starts.
* Initialises event routines for timers and
* system variable reset.
* PARAMETERS None.
* RETURN VALUE None.
**************************************************************/
void OnMeasurementPreStart()
{
iTimerID1 = cclTimerCreate(&OnTimer1);
iTimerID2 = cclTimerCreate(&OnTimer2);
initOK = onMPreStart();
if(findFeedBackVarsID(&iKL15ID, &iKL30ID,
&debugCaseID) >= 0)
{
cclSysVarSetHandler(iKL15ID, &onKL15Update);
cclSysVarSetHandler(iKL30ID, &onKL30Update);
cclSysVarSetHandler(debugCaseID, &onDebugCaseUpdate);
}
}
As the description of the function tells, the function initialises event routines for
timers and system variable reset. This means that when the timer is started and later
expires, the function referenced as an argument to the create function is run. In a
similar way the function referenced to in cclSysVarSetHandler is run when the
system variable with the corresponding ID is reset in CANoe, hence the interrupt-
like behaviour. The ID of the ’feedback’ variables (called so for the reason that
43
Chapter 6. Implementation
these three tell the dll that something has happened in CANoe during the mea-
surement) are fetched in findFeedBackVarsID through the use of the function
cclSysVarGetID(char* variableName) where the name of the variable has to
match the exact name specified in ’System variables’ in CANoe, see Section 6.4. If
the variable is not found an error value will be returned.
The function onMPreStart reads and processes the files loaded through ’User
Files’ and adds all the variables to the following global containers,
struct varInfo {
uint32_t adress;
int size;
uint8_t* data;
};
struct CANoeVarInfo{
int ID;
int32_t data;
};
The address and size of the variables are found directly in the file created by the
graphical user application, see Section 6.2. The ID’s, however, must be fetched in
the way described above. Apart from the variables found in the file another one is
added by default called ”Update”. This one is needed by CANoe in order to update
all of the other variables, see Section Process and Calculate below.
Help to the user is provided in the way that if either file is inaccessible a help
text will be shown in the write window in CANoe as well as if the user created the
file in the graphical user application with error, i.e. not all variables found, the user
will be informed.
Besides the processing of the files onMPreStart also establishes a connection
with Trace32 with information received from the file specifying the IP-address of
the user’s PC and the path to the .elf-file. The initialisation is basically shown below,
all error handling and return statements are omitted.
/**************************************************************
* FUNCTION NAME Init_Trace32
44
6.3 Data extraction/integration dll
/**************************************************************
* FUNCTION NAME onDebugCaseUpdate
* DESCRIPTION Called when the system variable containing debug
* case changes.
* PARAMETERS time - current time of the measurement.
* sysVarID - System Variable ID.
* RETURN VALUE None.
**************************************************************/
void onDebugCaseUpdate(long long time, int sysVarID)
{
static int preCase;
cclSysVarGetInteger(sysVarID, &debugCase);
if(debugCase != preCase)
{
cclTimerCancel(iTimerID1);
cclPrintf("Current debug case: %i", debugCase);
delay = debugCaseChanged(debugCase);
cclTimerSet(iTimerID1, cclTimeMilliseconds(20));
preCase = debugCase;
45
Chapter 6. Implementation
}
}
When it is detected that an update in debug case has occurred the timer governing
the read/write functions is halted and the new debug case is passed to the function
debugCaseChanged. This function clears all variables from the debug case active
before from, and adds the correct variables corresponding to the current debug case
to, the following global containers.
These containers are the ones that are iterated over during the read/write phase. The
ones mentioned above, ending with ...All are always containing all the variables
and are constant during a measurement.
Since the test in CANoe may be implemented in such a way that the de-
bug case is updated on a cyclic basis, even though the actual case is the same, a
static int preCase is defined to make sure that the update in the dll is run only
when there has been an actual change.
KL15 KL30 Just as in the case of an update of debug case two special functions
are called when an update of either KL15 or KL30 occurs. These functions call a
common function shown below.
/**************************************************************
* FUNCTION NAME startStopDataReading
* DESCRIPTION Called when either system variable KL15 or KL30
* is changed.
* PARAMETERS sysVarID - ID of either KL15 or KL30 system
* variable.
* RETURN VALUE None.
**************************************************************/
void startStopDataReading(int sysVarID)
{
static long pre15Val, pre30Val;
long val;
cclSysVarGetInteger(sysVarID, &val);
pre15Val = (sysVarID == iKL15ID && val != pre15Val) ?
val : pre15Val;
pre30Val = (sysVarID == iKL30ID && val != pre30Val) ?
val : pre30Val;
if(pre15Val == 1 && pre30Val == 1)
{
systemUp = 1;
46
6.3 Data extraction/integration dll
cclTimerSet(iTimerID2, cclTimeMilliseconds(10));
cclPrintf("LauterBach reading started");
}
else
{
systemUp = 0;
cclPrintf("LauterBach reading paused");
}
}
The essential feature of the function above is the flag systemUp which is a global
variable passed to the function responsible for the read/write loop telling if the sys-
tem is up and running. After detecting that the ECU is fully powered up a second
timer is set in order to start the actual execution by a couple of Trace32 commands,
see below, error handling omitted.
/**************************************************************
* FUNCTION NAME onTimer2
* DESCRIPTION Called when Timer2 expires; just after it is
* detected that the ECU is powered up.
* PARAMETERS iInitOK - parameter telling if initialisation is
* done successfully.
* RETURN VALUE None.
**************************************************************/
void onTimer2( int iInitOK )
{
if( !iInitOK )
{
return;
}
T32_Cmd("System.up");
T32_Cmd("Go");
readConstantVars();
}
The calling of the function reading the constant variables is done here since it is not
necessary to read these at every Read/Write-loop, see below.
Read/write loop The timer called on a cyclic basis, calling the function responsi-
ble for reading, calculating and writing - onTimer1 - is shown below.
/**************************************************************
* FUNCTION NAME OnTimer1
47
Chapter 6. Implementation
If the initialisation was done successfully onTimer1 is called and the timer re-
sets itself with the time determined by what debug case is active. The details of
onTimer1 are described in the following topics.
Read The reading of the target CPU memory is done by calling a function in the
Trace32 API; T32_ReadMemory. By calling the following function with each of the
containers indirectVars and dynamicVars as parameters once per cycle, all the
current variables are read and stored.
/**************************************************************
* FUNCTION NAME readVars
* DESCRIPTION Reads memory of target from Trace32.
* PARAMETERS *map - pointer to container with stored variables.
* RETURN VALUE EXIT_SUCCESS if all variables successfully read.
* EXIT_FAILURE if one variable unsuccessfully
* read.
**************************************************************/
int readVars( std::map<std::string, varInfo*> *map )
{
varInfo* vI;
for( auto it = map->begin(); it != map->end(); ++it )
{
vI = it->second;
if( T32_ReadMemory(vI->adress, 0x40,
vI->data, vI->size) != 0 )
{
cclPrintf("Failed to read memory at: %x",
vI->adress);
48
6.3 Data extraction/integration dll
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
Process and Calculate After all the data has been read from the target CPU some
processing and calculation has to be done. Firstly, the data gathered from the CPU
is stored in a 8-bit array, see the varInfo struct further above, the value that is to
be written to CANoe is a long which is why all the dynamic variables can directly
be assembled to a long, see below.
/**************************************************************
* FUNCTION NAME assembleInt
* DESCRIPTION Assembles 8-bit data to 16, 24 or 32 bit data.
* PARAMETERS vI - struct containing 8-bit data.
* RETURN VALUE Assembled value.
**************************************************************/
long assembleInt( varInfo* vI )
{
int sz;
sz = vI->size;
long tmp = 0;
for(int i = 0; i < sz; ++i)
{
tmp |= vI->data[sz-i-1] << (i*8);
}
return tmp;
}
The assembled values are then stored in the container CANoeSysVars which is iter-
ated over when writing to CANoe. The variable ”Update” is assigned each loop as
Update++ in order to trig a function in CANoe, see Section 6.4.
Furthermore, a number of calculations have to be done to calculate the vari-
ables that are not directly accessible in the memory of the target CPU. All of the
variables needed in order to perform the calculations are stored in the container
indirectVars and the actual functions performing the calculations are more or
less copied from the source code on the target CPU. A streamlined ”calculations”
header file (not all functions shown) can be seen in Appendix B. Several of the func-
tions take a reference to the whole indirectVars container as a parameter and sort
out which values in it that are necessary for that specific calculation. When all the
calculations are done, the final values are stored in CANoeSysVars together with
the dynamic variables.
49
Chapter 6. Implementation
Write After the processing and calculation CANoeSysVars contains all the values
that are to be sent to CANoe. This is done as the final part of onTimer1 and in a
similar way to when the memory is read from the target CPU, see below.
Stop When the measurement is stopped the following function is called which
stops the execution of the CPU, deletes allocated memory, and terminates the con-
nection to Trace32:
/**************************************************************
* FUNCTION NAME onMStop
* DESCRIPTION Called on measurement stops. Terminates
* connection with Trace32, deletes allocated
* memory.
* PARAMETERS None.
* RETURN VALUE None.
**************************************************************/
void onMStop(){
T32_Cmd("Break");
T32_Cmd("System.down");
deleteAllocMem(&constVars);
deleteAllocMem(&indirectVarsAll);
deleteAllocMem(&dynamicVarsAll);
for(auto it = CANoeSysVarsAll.begin();
it != CANoeSysVarsAll.end(); ++it)
{
delete it->second;
}
T32_Exit();
cclWrite("Connection with Trace32 terminated.");
}
50
6.4 CANoe configuration modifications
/**************************************************************
* FUNCTION NAME deleteAllocMem
* DESCRIPTION Deletes allocated memory.
* PARAMETERS *map - pointer to std::map containing memory area
* to be deleted.
* RETURN VALUE None.
**************************************************************/
void deleteAllocMem( std::map<std::string, varInfo*> *map )
{
for( auto it = map->begin(); it != map->end(); ++it )
{
delete[] it->second->data;
delete it->second;
}
}
on message CAN1.INFO_CTRL_3
{
float fHighByte,fLowByte;
switch (bDevFrameCase)
{
case 241:
@sysvar::CSWTest::fFLWheelVel=(float) ((word)
((this.byte(1)<<8)+this.byte(0)))/512;
@sysvar::CSWTest::fFRWheelVel =(float) ((word)
((this.byte(3)<<8)+this.byte(2)))/512;
@sysvar::CSWTest::fRLWheelVel=(float) ((word)
((this.byte(5)<<8)+this.byte(4)))/512;
51
Chapter 6. Implementation
@sysvar::CSWTest::fRRWheelVel=(float) ((word)
((this.byte(7)<<8)+this.byte(6)))/512;
break;
case 242:
...
}
}
There are four different INFO_CTRL frames and the above function is called when
the specific frame is received. To replace the above mentioned code the following
is used, the scaling and type casting is kept in the same way.
on sysvarUpdate T32::Update
{
switch(bDevFrameCase)
{
case 241:
@sysvar::CSWTest::fFLWheelVel = (float) ((word)
@sysvar::T32::FLVelRaw)/512;
@sysvar::CSWTest::fFRWheelVel = (float) ((word)
@sysvar::T32::FRVelRaw)/512;
@sysvar::CSWTest::fRLWheelVel = (float) ((word)
@sysvar::T32::RLVelRaw)/512;
@sysvar::CSWTest::fRRWheelVel = (float) ((word)
@sysvar::T32::RRVelRaw)/512;
...
}
}
Just as the onDebugCaseUpdate and onKL15Update functions in the dll this func-
tion is automatically called when the system variable ”Update” is reset which occurs
every read/write cycle by the data extraction/integration dll.
52
7
Result and discussion
This chapter will present and discuss the result of the thesis. First a section ex-
plaining how the concept of integrating data read from the target CPU by JTAG in
CANoe works in practice, followed by a section explaining how the software test of
the ECU works with this solution.
7.1 Concept
The data extracted from the target CPU via its JTAG interface is provided to CANoe
by a dll - created in Visual Studio 2010, written in C++ - using the CANoe and
Trace32 API:s loaded as a ’C-library’ in CANoe. To incorporate this solution in an
existing CANoe configuration the user has to follow the work flow below.
• Create a file defining what variables exist in which debug case, see Figure
2.7, named ”CANoeUserFileDebugCase.txt”.
• Use the graphical user application, see Section 6.2, in order to create the file
with the variables with associated address and size. Use default file name -
”CANoeUserFileDebugVars.txt”.
• Load the newly created file together with the debug case file in ’User Files’
in CANoe configuration options.
• Add the system variables defined in the first file in the CANoe configuration
under the namespace T32 and the feedback system variables, see Section 6.4,
in a sub namespace to T32 called Feedback.
53
Chapter 7. Result and discussion
The variables are updated in CANoe cyclically with a period depending on de-
bug case, see Section 6.3. It was proven that the update frequency had to be adjusted
according to how many variables there are in each debug case, trying to run the same
frequency in a debug case with 26 variables as one with 7 generated an error during
the measurement. The error given tells the information that ”Real time event pro-
cessing was interrupted at simulation time <t>. Events may be lost!” and that the
cause basically is that the work load of real time system is too high and that the
remedy is to reduce it. The repetition period of each debug case is shown in Table
7.1 and by using these periods the error is suppressed.
The time it takes to read a single, 1-byte, variable was evaluated in order to see
in which region the bandwidth of the transmitted data was. The measurement was
done using a MSDN function called QueryPerformanceCounter in the readVars
function, see Section 6.3 - Read, as follows.
QueryPerformanceCounter(&start);
retVal = T32_ReadMemory(vI->adress, 0x40, vI->data, vI->size);
QueryPerformanceCounter(&finish);
By evaluating start and finish it was shown that reading a single variable took
roughly around 1 ms. This together with the fact that the update periods for the
different debug cases need a certain amount of time in order to avoid an error, means
that there is an obvious limitation in speed. Attempts to try to decrease this time has
been taken without any major improvement such as increasing the JTAG interface
clock and also halting the execution of the ECU when reading the memory. The
former made no noticeable difference telling us that the bottleneck most likely is
not the actual JTAG interface, the latter made a small difference - approximately
54
7.2 The test
0.1 ms - for the better. However, halting the ECU during a measurement is not a
feasible option since this will have a too great effect on the real time properties.
An option could be to read a larger amount of data each loop, since the JTAG
does not seem to be the bottleneck, and sort out the different variables locally in
the dll. There is, however, a problem with this approach as well, since the data of
interest is spread out over an area of roughly 1.5 kB in the memory.
In order to try and locate where the time is consumed an attempt was done
by installing the Trace32 application on to the Vector real time device; the VT-
system more specifically since the VN8970 does not support remote desktop. It was
possible to install the application and drivers for the Lauterbach hardware on to the
real time system and it is therefore possible to run the solution entirely stand alone
since the debugger then is connected to the VT-system; the user PC does not do any
of the real time tasks. However, the time of reading the memory of the target CPU
was not shortened by a noticeable amount.
55
Chapter 7. Result and discussion
Figure 7.1 A part of the Control Software Test shown where some of the Quality
Signal Test Cases have failed.
56
7.2 The test
As long as there is no fault the variable is read as true at all times; no issues. The
problem presents itself when there is a fault and boAllWheelSpeedsOK is set to
false; as long as there is a fault present the read value of the quality flag will fluctuate
between true and false since this solution reads the memory asynchronously with
the execution of the CPU. (The monitor software uses the same variable but only
when it is valid.) This is a serious problem that presented itself in the final stages
of the thesis work period due to the lack of depth in the study of the software when
studying current system and solutions.
Attempts to implement a kind of filter looking for a trend in the signal have been
tried with some success, without it almost every Quality Signal Test Case in Figure
7.1 would have failed. It is implemented in such a way that when the signal has
gone low for one sample a further 5 consecutive samples of the high state have to be
recorded in order to actually set the variable high in the dll. This of course reduces
the bandwidth of those signals and it is still very possible to sample more than 5
high states even though the signal after fault control is low. Therefore this approach
is considered not to be a viable option.
Further possible ways of solving this problem - that not have been tried - are
discussed in Chapter 8.
57
8
Conclusion and Further
Work
The future work should focus on investigating possible solutions to the problem
discussed in Section 7.1. To solve this problem some synchronisation between the
reading of memory and execution of the CPU has to be established. One way could
be to declare one or several variables in the software telling ”It is now okay to read
variables XX and YY”. This comes with some further challenges; first, to declare
new variables in the software is not preferable - the aim was to be able to run the
tests on pure application builds. Second, since the CPU runs most of its cycles with
58
Chapter 8. Conclusion and Further Work
59
Bibliography
[1] API for Remote Control and JTAG Access. URL: http : / / www2 .
lauterbach.com/pdf/api_remote.pdf (visited on 05/19/2014).
[2] J. Barlage, D. Bruder, V. Jones, E. Nielsen, T. Perttola, and L. Pritchard. All-
Wheel Drive. BorgWarner Inc., 2009.
[3] CAN history. URL: http://www.can-cia.de/index.php?id=161#c137
(visited on 02/04/2014).
[4] CAN message. URL: http://www.kvaser.com/en/about- can/the-
can-protocol/17.html (visited on 02/04/2014).
[5] CANoe.XCP Read and Write Access on Memory Addresses in the ECU. URL:
https://vector.com/vi_canoe_xcp_en.html (visited on 05/19/2014).
[6] ECU Development and Test with CANoe. URL: http://vector.com/vi_
canoe_en.html (visited on 05/16/2014).
[7] Jtag technical guide. URL: http : / / www . xjtag . com / support - jtag /
jtag-technical-guide.php (visited on 03/25/2014).
[8] Modular Test Hardware: VT System. URL: http://vector.com/vi_vt-
system_en.html (visited on 05/16/2014).
[9] Programming with CAPL. URL: http : / / vector . com / portal /
medien / vector _ cantech / faq / ProgrammingWithCAPL . pdf (visited
on 05/16/2014).
[10] M. Åkesson. Software Test Strategy. BorgWarner Internal Documentation,
2014.
[11] Standard Test Access Port and Boundary Scan Architecture. IEEE 1149.1-
2001, 2008.
[12] Trace32 In-Circuit debugger. URL: http : / / www . lauterbach . com /
tutorial.pdf (visited on 05/16/2014).
[13] Visual Studio 2010. URL: http : / / msdn . microsoft . com / en - us /
library/dd831853(v=vs.100).aspx (visited on 05/16/2014).
60
Bibliography
61
A
Essentials of Visual Studio
MFC project
#include <afxwin.h>
#include "resource.h"
62
Appendix A. Essentials of Visual Studio MFC project
CDialog::OnInitDialog();
/* --- Pointers to all objects in the
interface are initialized here on the form
(type cast to correct type) GetDlgItem(ID_of_object),
see example below --- */
pVarFilePath = (CEdit*) GetDlgItem(varFilePath);
}
public:
/* --- User defined functions on the form
''afx_msg void functionName()'', see example below --- */
afx_msg void loadVars()
{
pListBoxIn->ResetContent();
CFileDialog dlgFile(TRUE);
dlgFile.DoModal();
CString path = dlgFile.GetPathName();
pVarFilePath->SetWindowTextW(path);
addVarsToListBoxInAndMap(path);
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(GUI_FORM, CDialog)
/* --- Links an event in the interface with a public
function declared in GUI_FORM on the form
''ON_COMMAND(ID_of_object, function)'',
see example below --- */
ON_COMMAND(But_LoadVars, loadVars)
63
Appendix A. Essentials of Visual Studio MFC project
END_MESSAGE_MAP()
64
B
Selection from
calculations.h
/**************************************************************
* FUNCTION NAME iMathMul
* DESCRIPTION Multiplies iMul1 and iMul2.
* PARAMETERS iMul1, iMul2 - factors.
* RETURN VALUE iMul1 * iMul2
**************************************************************/
long lMathMul(int iMul1, int iMul2);
/**************************************************************
* FUNCTION NAME iMathDiv
* DESCRIPTION Divides iNum by iDem.
* PARAMETERS iNum, iDem - Numerator, Denominator.
* RETURN VALUE iNum / iDem.
**************************************************************/
long lMathDiv(int iNum, int iDem);
/**************************************************************
* FUNCTION NAME iGetKL30Value
* DESCRIPTION Calculates KL30 voltage.
* PARAMETERS iKL30RawValue - raw value.
* RETURN VALUE KL30 voltage.
**************************************************************/
int iGetKL30Value(int iKL30RawValue);
/**************************************************************
* FUNCTION NAME iGetPumpCurrent
* DESCRIPTION Calculates pumpcurrent when raw value NOT
* already defined.
65
Appendix B. Selection from calculations.h
/**************************************************************
* FUNCTION NAME iGetPmpVoltage
* DESCRIPTION Calculates Pump voltage.
* PARAMETERS *vars - pointer to std::map containing variables.
* RETURN VALUE Pump voltage in mV.
**************************************************************/
int iGetPmpVoltage(std::map<std::string, varInfo*> *vars);
66
Document name
Lund University
MASTER´S THESIS
Department of Automatic Control Date of issue
Box 118 June 2014
SE-221 00 Lund Sweden Document Number
ISRN LUTFD2/TFRT--5945--SE
Author(s) Supervisor
Anton Karlsson Mattias Wozniak, BorgWarner AB
Anders Nilsson, Dept. of Automatic Control, Lund
University, Sweden
Karl-Erik Årzén, Dept. of Automatic Control, Lund
University, Sweden (examiner)
Sponsoring organization
Abstract
This master thesis investigates the possibilities to perform software validation tests on ECUs with
customer-identical software. Instead of using a ”test specific” software which sends ”test specific”
information on the CAN-bus this data is to be extracted from the target CPU by a JTAG debugger and
integrated in the testing software CANoe. The benefit of this method is that it eliminates the problems
that may be encountered during building of the ”test specific” software and that may affect other parts
of the software.
The work has been done at BorgWarner in Landskrona at the TTT-SW (software test) department.
Keywords
http://www.control.lth.se/publications/