User Guide
OpenECU Developer Platform
C-API

Release 2.9.0 (r2020-1)

13-Apr-2020


Table of Contents

Foreword
1. Disclaimer
2. Health and Safety information
1. Introduction
1.1. Included in your OpenECU kit
1.1.1. Hardware
1.1.2. Software
1.2. Licensed Features
1.3. OpenECU requirements
1.3.1. Hardware requirements
1.3.2. Software requirements
1.3.3. Assumed knowledge
1.4. Co-operational development with Pi
1.5. Warnings and safety guidelines
1.5.1. Verification of OpenECU by Pi Innovo
1.6. Warning
1.6.1. Personal safety
1.6.2. Disclaimer
2. Installation
2.1. Introduction
2.1.1. Third party tool requirements
2.1.2. Third party tool requirements — C-API
2.1.3. Third party tool requirements — Simulink-API
2.1.4. Third party tool requirements — installation
2.1.5. Third party tool requirements — compatibility
2.2. Installing OpenECU
2.3. License setup
2.3.1. Floating license
2.3.2. Node-locked license
2.4. Removing OpenECU
2.5. Integration notes for third party tools
2.5.1. Microsoft Windows 10
2.5.2. Microsoft Windows 7
2.5.3. Microsoft Windows XP
2.5.4. PiSnoop
2.5.5. ATI Vision
2.5.6. ETAS INCA calibration tool
2.5.7. Vector CANape
2.5.8. Wind River (Diab) C Compiler v5.5.1.0
2.5.9. Wind River (Diab) C Compiler v5.8.0.0
2.5.10. Wind River (Diab) C Compiler v5.9.0.0
2.5.11. GCC Compiler v4.7.3
2.5.12. Python
3. Quick start
3.1. Introduction
3.2. Installed examples
3.3. Exercise — Step 1
3.3.1. Designing the application
3.3.2. Create the application
3.3.3. Review the application
3.3.4. Implement the sensor reading
3.3.5. Implement the sensor conversion to temperature
3.3.6. Implement the threshold comparison
3.3.7. Implement the lamp driver
3.3.8. Summary so far
3.3.9. Create data dictionary and interface specification files
3.3.10. Building the application
3.3.11. Program the ECU
3.3.12. Play with the application
4. Software overview
4.1. Introduction
4.2. System components
4.3. System modes
4.4. Boot mode
4.5. Reprogramming mode
4.6. Application mode
4.6.1. Building an application
4.6.2. Interface specification
4.6.3. Data dictionary and engineering unit files
4.6.4. Application and library tasks
4.6.5. Library status and error handling
4.6.6. Compiler library support
4.6.7. Deprecated library features
4.6.8. Examples
5. Library interface
5.1. Introduction
5.1.1. Name-spaces, naming conventions and library composition
5.1.2. File locations
5.1.3. Layout of each feature section
5.1.4. Notations
5.2. System feature (PSY)
5.2.1. Overview
5.2.2. System types
5.2.3. Error log
5.2.4. Interface index
5.2.5. Interface detail
5.3. System start-up and background processing (PSC)
5.3.1. Overview
5.3.2. Interface index
5.3.3. Interface detail
5.4. ECU registry information (PREG)
5.4.1. Overview
5.4.2. Interface index
5.4.3. Interface detail
5.5. System timing feature (PTM)
5.5.1. Overview
5.5.2. Interface index
5.5.3. Interface detail
5.6. Task scheduling (PKN)
5.6.1. Tasking model
5.6.2. Interface index
5.6.3. Interface detail
5.7. Library input and output configuration (PIO)
5.7.1. Overview
5.8. Feature for specific target configuration (PCFG)
5.8.1. Overview
5.8.2. M110, M220 and M461 targets
5.8.3. M250 target
5.8.4. M460 target
5.8.5. M670 target
5.8.6. Interface index
5.8.7. Interface detail
5.9. Analogue input/output feature (PAX)
5.9.1. Overview
5.9.2. Interface index
5.9.3. Interface detail
5.10. Digital input/output feature (PDX)
5.10.1. Overview
5.10.2. Interface index
5.10.3. Interface detail
5.11. Digital data feature (PDD)
5.11.1. Overview
5.11.2. Interface index
5.11.3. Interface detail
5.12. Output driver control feature (PSS)
5.12.1. Overview
5.12.2. M220 target
5.12.3. M250 target
5.12.4. M460 target
5.12.5. M461 target
5.12.6. M670 target
5.12.7. Interface index
5.12.8. Interface detail
5.13. Serial peripheral feature (PSP)
5.13.1. Overview
5.13.2. Input and output processing
5.13.3. Interface index
5.13.4. Interface detail
5.14. CJ125 device driver for UEGO measurement feature (PCJ125)
5.14.1. Overview
5.14.2. Initialisation
5.14.3. Diagnostics
5.14.4. Interface index
5.14.5. Interface detail
5.15. CAN messaging feature (PCX)
5.15.1. Overview
5.15.2. Initialisation
5.15.3. Receiving messages
5.15.4. Transmitting messages
5.15.5. CAN status
5.15.6. CAN buses
5.15.7. Build time buffer sizing
5.15.8. Library tasks
5.15.9. Interface index
5.15.10. Interface detail
5.16. CAN Calibration Protocol (CCP) messaging feature (PCP)
5.16.1. Overview
5.16.2. Interface index
5.16.3. Interface detail
5.17. J1939 (SAE) messaging feature (PJ1939)
5.17.1. Overview
5.17.2. Node addressing
5.17.3. Messaging
5.17.4. Message bit and byte numbering
5.17.5. PGNs
5.17.6. Receive messages
5.17.7. Transmit messages
5.17.8. Core Diagnostic messages
5.17.9. Build time buffer sizing
5.17.10. Library tasks
5.17.11. Interface index
5.17.12. Interface detail
5.18. Diagnostic Trouble Code (DTC) feature (PDTC)
5.18.1. Overview
5.18.2. Diagnostic trouble codes — generic
5.18.3. Diagnostic trouble codes — J1939
5.18.4. Storage of data across power cycles
5.18.5. Build time buffer sizing
5.18.6. Interface index
5.18.7. Interface detail
5.19. Adaptive non-volatile memory feature (PNV)
5.19.1. Overview
5.19.2. Storage of data across power cycles
5.19.3. Interface index
5.19.4. Interface detail
5.20. Non-volatile Filesystem feature (PFS)
5.20.1. Overview
5.20.2. Interface index
5.20.3. Interface detail
5.21. On-board external flash (PEF)
5.21.1. Overview
5.21.2. Interface index
5.21.3. Interface detail
5.22. General utilities feature (PUT)
5.22.1. Overview
5.22.2. Interface index
5.22.3. Interface detail
6. Library interface — Engine
6.1. Engine position sensor processing
6.1.1. Crankshaft position sensor processing
6.1.2. Crankshaft position detection
6.1.3. Crankshaft zero degrees
6.1.4. Angle clock
6.1.5. Crank tooth identification
6.1.6. Crankshaft speed
6.1.7. Multiple crankshaft sensor inputs
6.1.8. Camshaft position sensor processing
6.1.9. Engine synchronisation modes
6.2. Engine TDC-firing events
6.2.1. Relative angles to TDC-firing
6.2.2. Cylinder TDC-firing angles
6.2.3. Cylinder TDC-calculation application events
6.2.4. Engine angle offset
6.2.5. Engine tooth identification
6.2.6. Engine speed
6.3. Analogue input processing
6.4. Knock sensor processing
6.5. Scheduling injector outputs
6.5.1. Port injection
6.5.2. Direct injection
6.5.3. Injection waveform configuration
6.6. Scheduling coil outputs
6.7. Scheduling digital outputs
6.8. Angular function feature (PAN)
6.8.1. Interface index
6.8.2. Interface detail
6.9. Waveform properties feature (PROP)
6.9.1. Interface index
6.9.2. Interface detail
7. Extended Diagnostics Functions
7.1. Introduction to Diagnostics
7.2. Diagnostic Legislation
7.3. Approach
7.4. Diagnostic Trouble Codes and Freeze-Frames
7.5. Diagnostic Monitors, Tests and Performance Ratios
7.6. Worked Example - building a diagnostic system
7.6.1. Step 1 — Test Conditions at the Monitor level
7.6.2. Step 2 — Individual Flow Tests
7.6.3. J1979/ISO 15031 Scan tool request/response
7.7. Extended Diagnostic Functions
7.7.1. J1939 Extended Diagnostics feature (PJ1939)
7.7.2. Diagnostics (ISO-15765 and KWP2000) feature (PDG)
7.7.3. Diagnostic Trouble Code Extended (DTC) feature (PDTC)
7.7.4. Freeze Frame feature (PFF)
7.7.5. Parameter Identifier feature (PPID)
7.7.6. In-Use Performance Ratio feature (PPR)
8. Support tools
8.1. Interface and DDE tool
8.1.1. Simple interface file example
8.1.2. Running the interface tool
8.1.3. Warning and error messages
8.1.4. Interface file contents
8.1.5. DDE specification
8.1.6. Units file
8.1.7. Automatic ASAP2 entries
8.1.8. OpenECU software versioning
8.2. Supporting build scripts
8.2.1. Creating a binary image with a supported compiler
A. Reference documentation
A.1. ECU hardware reference documentation
B. OpenECU error and warning codes
B.1. Interface tool messages
B.1.1. Command line option messages
B.1.2. File handling messages
B.1.3. Interface file messages
B.1.4. DDE processing messages
B.1.5. Automatic DDE generation messages
B.1.6. Code generation messages
B.1.7. ASAP2 generation messages
B.1.8. ELF to DDE generation messages
B.1.9. Data type checks between ELF and DDE messages
C. Supporting tools
C.1. Introduction
C.2. PiSnoop
C.2.1. Example Screenshots
C.3. ATI Vision
C.3.1. Creating a new project and strategy in ATI Vision
C.3.2. Downloading an application with an ATI Vision strategy
C.3.3. Configuring two OpenECUs on the same CAN bus with ATI Vision
C.3.4. Configuring CCP seed/key security with ATI Vision
C.4. ETAS INCA
C.5. Vector CANape
C.5.1. Configuring CCP seed/key security with Vector CANape
C.6. FreeCCP
C.6.1. Programming an OpenECU
C.6.2. Choosing the CAN card device (Kvaser)
C.6.3. Choosing the CAN card device (Vector)
C.6.4. Choosing the CCP settings
C.6.5. Checking that the OpenECU device is active
D. Memory configurations
E. ASAP2 compliance
F. CCP compliance
F.1. EXCHANGE_ID message handling
G. CCP troubleshooting guide
G.1. Anatomy of an ATI Hub
G.2. No communication between PC and ATI Hub
G.2.1. Symptoms
G.2.2. Possible causes
G.3. No communication between PC and OpenECU
G.3.1. Symptoms
G.3.2. Possible causes
H. Change log
H.1.
I. Glossary of terms
J. Contact information

List of Figures

3.1. Quick start loom
3.2. Transfer function for temperature sensor
4.1. System components
4.2. System modes
4.3. System modes for M220, M250, M460 and M461
4.4. System modes for M110, M221 and M670
4.5. System initialisation
4.6. Building an application (in outline)
5.1. Tasking model states
5.2. Task pre-emption
5.3. Task pre-emption with resource locking
5.4. TLE8242-2 Dither
5.5. TLE8242-2 constant current control diagram
5.6. TLE8242-2 KP and KI equations
5.7. Direct and indirect analogue outputs
5.8. Quadrature encoder and generated signals
5.9. Direction of encoder and generated signals
5.10. Pulse count example
5.11. SENT frame
5.12. Peak-hold injector output
5.13. Output of H-Bridge during mode transition
5.14. Signal update rates
5.15. CAN bit sample point
5.16. ASAM MCD-MC1 interaction
5.17. CCP messaging
5.18. J1939 activation state machine
5.19. Map look-up
5.20. Map look-up with interpolation
6.1. Output pulse - Angle-Time Duration (turn-on/turn-off)
6.2. Output pulse - Angle-Time Duration (turn-on/no-action)
6.3. Output pulse - Angle-Angle Duration (turn-off/toggle)
6.4. Output pulse - Angle-Angle Duration (turn-on/turn-off)
6.5. Output data updated during an event, end modification allowed
6.6. Output data updated during an event, end modification not allowed
6.7. Output event with overlap between two events
6.8. Output event starting within minimum off time
7.1. Functional Levels within a Diagnostics System
7.2. Scan tool link via Platform
7.3. Routine control usage flowchart
7.4. Platform OBD state machine — no transitions between Previously Active and Pending
7.5. Platform OBD state machine — transitions between Previously Active and Pending
7.6. ISO DTC state machine — no transitions from Inactive to Pending
7.7. ISO DTC state machine — transitions from Inactive to Pending
8.1. Building the interface code
8.2. Finishing a build
8.3. Building the binary images

List of Tables

2.1. Third party tool compatibility
2.2. Install components
3.1. FEPS voltages
4.1. FEPS voltages
4.2. CCP defaults
4.3. Library and application tasks
5.1. Library composition
5.2. Interval notation
5.3. Registry entries
5.4. DTC initialisation values
6.1. Function availability based on engine synchronisation mode
6.2. Angular digital output pin actions
7.1. Diagnostic Service Comparisons
7.2. PDG supported services
7.3. PDG supported services
7.4. DTC initialisation values
8.1. CCP privilege levels
8.2. Value ranges for J1939 name statements
8.3. Value ranges for J1939 PDUs
8.4. Value ranges for J1939 PDUs
8.5. Bit information for the lamps to be set per DTC
8.6. Bit information per lamp type
8.7. Data dictionary columns (prefix-style)
8.8. Variable naming convention (prefix-style)
8.9. 1-d map lookup naming convention (prefix-style)
8.10. 2-d map lookup naming convention (prefix-style)
8.11. Data dictionary columns (C-style)
8.12. Classes of DDE
8.13. Examples of C-style DDE names
8.14. Automatic ASAP2 entries for boot build information
8.15. Automatic ASAP2 entries for reprogramming build information (M220, M221, M250, M460, M461, M670)
8.16. Automatic ASAP2 entries for platform build information
8.17. Automatic ASAP2 entries for application build information
8.18. Automatic ASAP2 entries for application rate task timing information
8.19. Automatic ASAP2 entries for auxiliary task timing information
8.20. Automatic ASAP2 entries for CPU loading information
8.21. Automatic ASAP2 entries for eTPU loading information
8.22. Automatic ASAP2 entries for maximum application rate task timing information
8.23. Automatic ASAP2 entries for run-time information
8.24. Automatic ASAP2 entries for reset information (M110, M220, M250, M460, M461)
8.25. Automatic ASAP2 entries for number of instances of period overruns of periodic tasks
8.26. Automatic ASAP2 entries for memory use information
8.27. Automatic ASAP2 entries for memory error correction events
8.28. Automatic ASAP2 entries for floating point conditions
8.29. Automatic ASAP2 entries for J1939 related information
8.30. Software component versions (for M110-000)
8.31. Software component versions (for M220-000)
8.32. Software component versions (for M220-0AU)
8.33. Software component versions (for M221-000)
8.34. Software component versions (for M250-000)
8.35. Software component versions (for M460-000)
8.36. Software component versions (for M461-000)
8.37. Software component versions (for M670-000)
D.1. Memory configurations supported
D.2. Memory configurations supported
D.3. Memory configurations supported
F.1. Supported CCP commands
F.2. Supported CCP commands (in older versions of ECUs)
F.3. Original EXCHANGE_ID message
F.4. Modified EXCHANGE_ID message
F.5. EXCHANGE_ID selection values
F.6. EXCHANGE_ID manufacturing data key values and binary format
H.1. Release summary for v2.9.0-r2020-1

Foreword

Before using OpenECU, it is very important to read and understand the warning and safety information given in Section 1.5, “Warnings and safety guidelines” and in Section 1.6, “Warning”.

Pi, the Pi logo and OpenECU are trademarks of Pi Innovo Ltd. Microsoft, Windows, Excel, Word, Vision, CANape and INCA are all registered trademarks of their respective owners.

1. Disclaimer

Pi Innovo makes no representation or warranties of any kind whatsoever with respect to the contents hereof, and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Pi Innovo shall not be liable for any errors contained herein, or for incidental or consequential damages in connection with the furnishing, performance or use of the software, associated hardware, or this written material.

Pi Innovo reserves the right to revise this publication from time to time, and to make changes in the content hereof without obligation to notify any person of such revision or changes.

A copy of the Pi Innovo Terms and Conditions of Sale is available on request, and includes a declaration of the warranty and limitation of liability which apply to all Pi Innovo products and services.

2. Health and Safety information

Under the terms of European and UK Health and Safety Legislation, Pi Innovo is required to classify any hazardous materials in the products it supplies and to provide relevant safety information to users.

Any hazardous materials in Pi products are clearly marked with appropriate symbols. Product Safety Data Sheets relating to these materials are available on request.

Chapter 1. Introduction

Thank you for choosing Pi Innovo's OpenECU platform.

Pi Innovo's OpenECU platform offers a new solution to engine and vehicle control system development. Based on Pi's extensive experience of ECU development, and backed by Pi's unrivalled capabilities in project and customer support, OpenECU helps you get quickly to what you need: working, robust control systems.

By using production ECU hardware as an auto-code platform, you gain all the advantages of auto-coding and rapid prototyping, but with hardware that meets full production environmental and packaging requirements (see Section A.1, “ECU hardware reference documentation” for environmental and packaging details).

The OpenECU system consists of:

  • a range of production ECU hardware modules — some have support for engines with up to 8 cylinders (or more with multiple modules);

  • an optional range of tested engine and vehicle control strategies, from individual functional blocks to complete strategy suites;

  • a comprehensive range of support and consultancy services, ranging from sensor selection and system design advice through to complete bespoke system development.

Applications of the OpenECU platform include:

  • engine control system development;

  • chassis control system development;

  • after treatment control system development;

  • transmission control system development;

  • hybrid powertrain control system development;

  • vehicle fleet trials.

For support contact information, please see the last page of this manual.

1.1. Included in your OpenECU kit

There are several OpenECU packages available from Pi, which can include the following items.

1.1.1. Hardware

The following items of hardware are available as part of OpenECU:

Electronic Control Unit (ECU)

This is the computer that monitors and controls all aspects of the electronic system's behaviour. The built file from your application is programmed into the ECU. There are four different models of ECU currently available — 4 in-line cylinder and V8 cylinder, in both development and fleet models (see Section A.1, “ECU hardware reference documentation” for further details).

Connectors

All the connectors and terminals required to connect the ECU, the calibration tool and your PC together.

Tools

You will require an appropriate crimping tool for the ECU connectors. Pi Innovo will give you details on request.

1.1.2. Software

The following items of software are available as part of OpenECU:

OpenECU C Application Programming Interface (API)

A documented C-API to the OpenECU library which allows control of the ECU from an application. The C-API broadly provides the same functionality as the OpenECU Simulink blockset.

And the following items of software are required but not provided as part of OpenECU.

Calibration Tool

This electronic tool is used to program the auto-generated code into the ECU, and to monitor (and, in some cases, alter) the values of certain parameters while the ECU is running. Pi's own PiSnoop product is one option, along with several industry-standard alternatives, and we will be able to recommend a suitable product on request.

Compiler

A tool which takes application code and turns it into an executable image that can be run on OpenECU hardware.

1.2. Licensed Features

OpenECU allows for several different options enabling different features. The licensing system retains control of the ability to use these features depending on what the customer has purchased.

The current set of available features is:

  • OPENECU

    The main feature. Enabled when you purchase any version of OpenECU

  • CAPI_BUILD

    Allows for building OpenECU applications with the C-API.

  • EXT_DIAG

    Extended diagnostics features.

    • Allows use of the Extended diagnostics blockset in Simulink models.
    • Allows use of the Extended diagnostics library functions at run time in OpenECU applications

    See Chapter 7, Extended Diagnostics Functions.

1.3. OpenECU requirements

To make the best use of OpenECU, certain hardware, software and knowledge requirements need to be fulfilled, as described below.

1.3.1. Hardware requirements

To run the Pi OpenECU software, you will need an IBM-compatible PC with the specifications listed below.

  • CPU: a modern Intel or AMD x86 32-bit or 64-bit processor.

  • RAM: 2 GiB minimum, but more recommended (larger applications will require more RAM).

  • Free hard disk space: 2 GiB.

  • Peripheral hardware: keyboard, mouse, DVD/CD-ROM drive (for installation from CD media), at least 8-bit graphics adapter and display (for at least 256 colours).

Either the physical system or a system simulator is ultimately required to test and calibrate your ECU and the system model you have created to run on it. A suitable Calibration/reprogramming communications tool is also required conforming to the ASAP2 standard.

1.3.2. Software requirements

You will need the following software pre-installed on your PC:

  • Operating system: Microsoft Windows 10 or Microsoft Windows7 SP1 32-bit or 64-bit.

  • Compiler: Wind River Diab version 5.5.1.0 (M220, M221, M250, M460 and M461); or version 5.8.0.0 (M220, M221, M250, M460 and M461); or version 5.9.0.0 (M220, M221, M250, M460, M461 and M670) or GCC version 4.7.3 (M220, M221, M250, M460, M461 and M670). Only the C language version is required (note, C++ is not yet supported).

  • Calibration tool: PiSnoop, ATI Vision™ (version 2.5 through 5.1.2), ETAS INCA (version 7.2.7) or Vector CANape (version 8.0 through 16.0).

Note

OpenECU developer software does not support earlier versions of Windows than XP (SP3), Windows Vista, or Windows 8.

See the Chapter 2, Installation for full details of the software required.

1.3.3. Assumed knowledge

This manual describes how to use the C-API to create your own designs, but does not include a tutorial about C or embedded systems.

A working knowledge of design modelling and system dynamics principles in an engineering environment is required to make the best use of OpenECU. Ultimately, it is the quality of your own system designs that will be reflected in the quality of your system control strategy.

Note also that there are serious hardware and personal safety considerations involved in developing automotive control systems. Please make sure that you read and understand the notes given in Section 1.5, “Warnings and safety guidelines” to reduce the chance of any such hazards.

1.4. Co-operational development with Pi

Pi Innovo has over 14 years of experience designing powertrain controllers, working closely with customers to get to the best possible control system solution. Millions of cars and trucks on the road use Pi-designed engine control.

OpenECU comes with a wide range of options for customer and project support, allowing you to draw on over 500 man-years of control system design experience. Whichever option you choose, you can count on real commitment from Pi to provide what you need, and to go the extra mile.

For contact information, refer to Appendix J, Contact information.

1.5. Warnings and safety guidelines

It is very important to read and understand the following warnings and safety guidelines. Inappropriate use of the OpenECU system can lead to loss of data, damage to software and hardware, and possible personal injury if safe vehicle operation is compromised.

The safe operation of OpenECU is the responsibility of the those using it. The level of risk associated with the user's application must be ascertained and appropriate mitigation devices used to reduce the potential risks to an acceptable level. These mitigation devices may include a system 'kill switch', driver training, backup systems and use of the vehicle in safe environments.

A structured approach to testing is recommended, particularly before the product is used in environments where it may be in contact with members of the public (e.g. the public highway). This testing may include HIL, static vehicle system test and/or vehicle test in a test track environment.

Pi Innovo supplies OpenECU on the basis that:

  • The responsibility for ensuring that the use of OpenECU is safe lies with the customer.

  • The customer will include appropriate mitigation devices as identified by the hazard analysis they perform (such as engine kill switch, back up devices).

  • The user will read all OpenECU documentation (including this document) to ensure its safe use.

  • OpenECU is not to be used in safety critical applications, e.g. aerospace.

  • OpenECU is to be used in a system development environment only.

  • OpenECU is not to be sold to the public.

  • All users must be competent to make appropriate safety judgements.

Pi Innovo also strongly recommends that:

  • Applications be developed using a process suitable for the application.

  • HIL testing be used prior vehicle testing.

  • "Off public highway" vehicle testing be performed prior to road testing.

1.5.1. Verification of OpenECU by Pi Innovo

Pi Innovo considers the safety and quality of its products to be of paramount importance. The integrity of the product can be considered by assessing the three 'components' which comprise the system.

Systems, rather than software, have a Safety Integrity Level (SIL). The SIL of the customer's resultant system will have to be assessed and defined by their knowledge of the processes used to develop all the components (including those supplied by Pi) comprising the complete system.

1.5.1.1. Hardware

The hardware is a production unit (see Section A.1, “ECU hardware reference documentation” for module environmental specifications). However different applications will have different requirements for output monitoring. Those outputs that are selected (by the customer) to drive safety related outputs should include output monitor circuits. The use of outputs for critical devices which do not contain a monitor feedback is strongly discouraged.

1.5.1.2. Platform

The platform comprises functionality which allows the high level strategy to operate in the specific hardware target (electronic box). It includes:

  • The operating system (RTOS) to schedule tasks, process interrupts and manage the internal stack etc..

  • The hardware drivers enabling the inputs to be read, and the outputs driven.

  • The calibration tool support, CAN support and module reprogramming.

OpenECU has been developed using a lean SIL 0 process enabling its rapid introduction to the market place. This process included internal review, module testing and considerable vehicle testing. It is considered to be a reliable and robust platform on which to build vehicle control applications.

The configuration of the platform is the customer's responsibility. It is entirely possible, through careless configuration, to 'cross wire' inputs or outputs for example. This could, for example, lead to injector 1 firing when you intended injector 2 to fire. The mis-calibration of analogue inputs could lead to undesired behaviour such as steering angle or accelerator pedal position to be mis-calculated.

Documented vehicle prove out tests should mitigate against this leading to severe outcomes.

1.5.1.3. Strategy

The strategy may be developed entirely by the customer, or be a development by the customer of generic libraries supplied by Pi Innovo. In either case the integrity of the resultant strategy model must be the responsibility of the customer.

Pi's generic libraries have been extensively validated via module testing, HIL system testing and vehicle testing but have not undergone unit testing.

1.6. Warning

The supplied libraries have been validated for a specific application and a specific hardware set. The user MUST validate the correct function of the strategies in their application.

1.6.1. Personal safety

The process of testing automotive systems can involve many personal safety hazards — high-speed machinery, extremely flammable and potentially explosive fuels, and the possibility of loss of vehicle control is a combination that can be fatal if sensible precautions are not followed.

As the system designer and tester, it is your responsibility to ensure that your working practices are specifically designed to minimise or eliminate the possibility of personal injury, and to incorporate into your designs such fail-safe functionality as is necessary. This includes the avoidance of certain dynamical situations such as open throttles and other 'positive feedback' scenarios where control of the system may be lost.

1.6.2. Disclaimer

Pi Innovo makes no representation or warranties of any kind whatsoever with respect to the contents hereof, and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Pi Innovo shall not be liable for any errors contained herein, or for incidental or consequential damages in connection with the furnishing, performance or use of the software, associated hardware, or this written material.

Pi Innovo reserves the right to revise this publication from time to time, and to make changes in the content hereof without obligation to notify any person of such revision or changes.

A copy of the Pi Innovo Terms and Conditions of Sale is available on request, and includes a declaration of the warranty and limitation of liability which apply to all Pi Innovo products and services.

Chapter 2. Installation

2.1. Introduction

This chapter describes the installation process for the OpenECU C-API package and its dependencies.

2.1.1. Third party tool requirements

OpenECU developer software has been tested to work with Windows 10. OpenECU is compatible with Windows 7 SP1 (32-bit and 64-bit) and Windows XP SP3, but support for these operating systems is deprecated. OpenECU is not compatible with Windows Vista or Windows 8.

2.1.2. Third party tool requirements — C-API

For C based development, OpenECU requires (at a minimum) one of the following compiler tools:

  • Wind River Diab compiler

  • GCC Compiler

Note

GCC is an optional component in the OpenECU installation (installed by default). Additionally, GCC support is currently in a beta stage. As such, there a number of known limitations for compiling an OpenECU application with GCC. Please see the “Integration notes for third party tools” of the “Release notes” for a list of known issues building with GCC for further details.

To program and calibrate an OpenECU with an application, OpenECU integrates with the following calibration tools. Only one calibration tool is required:

  • PiSnoop

  • ATI VISION

  • ETAS INCA

  • Vector CANape

2.1.3. Third party tool requirements — Simulink-API

For Simulink model based development, OpenECU requires (at a minimum) the following MathWorks tools:

  • MATLAB (base product)

  • Simulink (to develop the models)

  • Simulink Coder (to generate C code from the models)

  • MATLAB Coder (Simulink Coder depends on this)

In addition, if you need to add state diagrams to the model, then you will also need:

  • Stateflow (to develop state flow diagrams inside your model) Simulink Coder generates C code from the state flow diagrams inside your model.

Simulink Coder generates C code which does not lend itself to efficient repeatable testing. When creating a production version of your product, you may need better control of the structure of the C code generated from the model to reduce the cost of testing the C code against any industry standards. Under these circumstances you will also need:

  • Embedded Coder (to generate C code from the models)

To compile the generated C code (from either Simulink Coder or Embedded Coder), you will need one of the following compilers:

  • Wind River Diab compiler

  • GCC compiler (free compiler but with known issues)

To program and calibrate an OpenECU with an application, OpenECU integrates with the following calibration tools. Only one calibration tool is required:

  • PiSnoop

  • ATI VISION

  • ETAS INCA

  • Vector CANape

2.1.4. Third party tool requirements — installation

OpenECU works with a number of applications (both required and optional) supplied by other companies. If you intend to use OpenECU with one of the following tools, it is best to install them before OpenECU. The installer will then integrate the OpenECU developer software with these applications.

OpenECU works with a number of other applications, but these need not be installed prior to the OpenECU developer software.

  • Simulink Coder, formerly Real-Time Workshop, (optional): (see OpenECU Compatibility with Third Party Tools for a list of supported versions)

  • Embedded Coder, formerly Real-Time Workshop Embedded Coder, (optional): (see OpenECU Compatibility with Third Party Tools for a list of supported versions)

  • Stateflow: (see OpenECU Compatibility with Third Party Tools for a list of supported versions)

  • Wind River (Diab) C compiler (versions 5.5.1.0, 5.8.0.0 and 5.9.0.0) for M110, M220, M221, M250, M460 and M461 targets

  • Wind River (Diab) C compiler (version 5.9.0.0) for M670 target

  • GCC Compiler (version 4.7.3 free compiler option) for M110, M220, M250, M460, M461 and M670 targets

    Note

    GCC is an optional component in the OpenECU installation (installed by default)

  • PiSnoop (any version)

  • ATI Vision calibration tool (version 2.5 through 4.0)

  • Vector CANape calibration tool (version 8.0 through 13.0)

The applications above have been listed with a version or release number. These are the versions or releases that OpenECU has been tested against. It may be that OpenECU will work with other versions of these applications, but it is recommended against and Pi may not provide technical support if these versions or releases are not used.

2.1.5. Third party tool requirements — compatibility

In summary, the following third party tools are compatible with this version of OpenECU:

Table 2.1. Third party tool compatibility

Third party toolCompatible versions
Operating systems
Microsoft Windows [a] Win10 (64-bit)
Win7 SP1 (32-bit) (deprecated)
Win7 SP1 (64-bit) (deprecated)
XP SP3 (32-bit) (deprecated)
Modelling and code generation tools
MathWorks MATLAB

R2015a, R2015b (32-bit)
R2015a, R2015b, R2016a, R2016b, R2017a, R2017b, R2018a, R2018b, R2019a, R2019b, R2020a (64-bit)

MathWorks Simulink
MathWorks MATLAB Coder
MathWorks Simulink Coder [b]
MathWorks Embedded Coder
Compiler tools [c]
Wind River Diab C compiler v5.5.1.0, v5.8.0.0, v5.9.0.0 for M110, M220, M221, M250, M460 and M461 targets
v5.9.0.0 for M670 target
GCC Compiler [d] v4.7.3 for M110, M220, M250, M460, M461 and M670 targets
Reprogramming, data logging and calibration tools [e]
PiSnoopAny version
ATI Vision [f] [g] v2.5 through v5.1.2
ETAS INCAv7.2.7
Vector CANapev8.0 through v16.0

[a] OpenECU developer software has been tested to work with Windows 10. OpenECU is compatible with Windows 7 SP1 (32-bit and 64-bit) and Windows XP SP3, but support for these operating systems is deprecated. OpenECU is not compatible with Windows Vista or Windows 8.

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives.

[b] Mathworks Simulink Coder includes functionality of RTW and Stateflow Coder.

[c] All OpenECU targets use Freescale PowerPC microcontrollers. The M110, M220, M221, M250, M460 and M461 use an MPC5534 microcontroller, the M670 uses an MPC5674F microcontroller. The M560 and M580 use an MPC5746C for the primary microcontroller and SPC560P34 for the secondary microcontroller.

See the Technicical Specification for your target for more information.

[d] OpenECU has only been tested using GCC Compiler version 4.7.3 and is in the beta stage. As such, there are a number of known issues to keep in mind when compiling an OpenECU application using GCC. For further details, please see "Integration notes for third party tools" for a list of known issues.

[e] These tools have been tested for reprogramming, data logging, and calibration. Some of them have many other features which have not been tested with OpenECU.

[f] The OpenECU method of configuring ATI Vision uses standardised ASAP2 files. As a result, all future versions of Vision are expected to be backwardly compatible (e.g., version 3.7 and version 4.0 are known to be compatible).

[g] The following Vision toolkits are typically used when working with OpenECU: Data Acquisition Toolkit, Calibration Toolkit, Universal ECU Interface Standard Toolkit, APOLLO Data Analysis Toolkit, CAN Interface Toolkit and HORIZON Scripting/Remote API Toolkit. In particular, the HORIZON Scripting/Remote API Toolkit is required if OpenECU builds are to generate Vision strategy files (.vst).


Some third party tools have been marked deprecated and support for these tools will be removed in a future release of OpenECU.

Third party toolReplacement
MathWorks MATLAB R2015a MATLAB latest version (see Pi Innovo's website for a complete list of supported versions of MATLAB).
MathWorks MATLAB R2015b
MathWorks MATLAB R2016a
MathWorks MATLAB R2016b
MathWorks MATLAB R2017a
MathWorks MATLAB R2017b
WindRiver Diab 5.5.1.0WindRiver Diab 5.8.0 and 5.9.0

2.2. Installing OpenECU

The installer program, openecu_platform_2_9_0_r2020-1.exe, installs all the necessary files for the OpenECU platform. This file can be obtained from the Pi Document and Download Center web page.

The installation process for the OpenECU developer software is performed by a wizard. To run the wizard, execute the appropriate installer program. The installation can be stopped at any point by selecting the Cancel button.

The installer requires that the user has administrative rights to make changes on the computer. If a user without rights is trying to execute the installer a dialog box will be displayed and the installation stops. Login with an administrator account or contact your network administrator and try again.

If a version of an OpenECU installer is already running, a dialog box will appear saying so. Select OK (which stops the current installer) and change to the other OpenECU installer to continue.

The installation process starts with an introduction. Select Next to continue.

The next windows to appear present the license agreement for using OpenECU developer software and related software. Read the license agreements and if acceptable, select I accept the terms of the License Agreement and then Next. If not acceptable, do not install the software.

The next window to appear provides a number of components that can be installed or patched.

The following table breaks out each of the components:

Table 2.2. Install components

ComponentRequiredInstalled by defaultDescription
PlatformYesYesA selection of packages to install, including the C-API and Sim-API components.
OpenECU Sim-APIYesYesInstall the Simulink interface to OpenECU, documentation and support packages.
BlocksetYesYesInstall the OpenECU blockset.
Sim-API Manuals (HTML)(optional)YesInstall the OpenECU blockset, ECU Technical Specifications and other documentation in HTML format.
Sim-API Manuals (PDF)(optional)YesInstall the OpenECU blockset, ECU Technical Specifications and other documentation in PDF format.
Sim-API Examples(optional)YesInstall some examples of how to use the OpenECU blockset.
OpenECU C-APIYesYesInstall the OpenECU C-API files and libraries.
C-APIYesYesInstall the C interface to OpenECU, documentation and support packages.
C-API Manuals (HTML)(optional)YesInstall the OpenECU C-API User Guide, ECU Technical Specifications and other documentation in HTML format.
C-API Manuals (PDF)(optional)YesInstall the OpenECU C-API User Guide, ECU Technical Specifications and other documentation in PDF format.
C-API Examples(optional)YesInstall some examples of how to use the OpenECU C interface.
Extended Diagnostics Features(optional)NoInstall the On-Board Diagnostic (OBD) library. This library is available at extra cost.
PythonYesYesInstall the Python application. This application is used to provide build support when generating and compiling the model source code.
Tools(optional)NoInstalls additional OpenECU tools.
GCC(optional)YesInstalls the GNU Compiler Collection (v4.7.3) and related tools for OpenECU targets.
lmadmin installer(optional)NoInstalls the installers for the lmadmin license server from flexera.
FreeCCP(optional)NoInstalls the FreeCCP programming tool (note that this tool is provided without support or warranty).
Integration(optional)YesOptions to have the OpenECU installer integrate OpenECU with third party tools, like MATLAB and INCA.
MATLAB Integration(optional)YesDuring installation, the OpenECU blockset is integrated into MATLAB's PATH.
INCA-ProF Integration(optional)NoDuring installation, INCA-ProF is update to understand how to program an OpenECU.
Start Menu Shortcuts(optional)YesDuring installation, the Window's Start menu is updated to include shortcuts to installed components.

Adjust the component selection as required (especially if you require the installer to update an installed copy of ETAS INCA) and select the Next button.

The next window asks for a destination path to be specified. By default, the installer presents a path to your local drive.

Warning

If the default path is changed, ensure that only digits, upper and lower case letters and the _ character are used to specify directory names. An installation path that includes any space characters will cause problems later on.

If the INCA-ProF integration component was selected, the next window presented provides a list of installed versions of INCA.

Select which versions of INCA will be used with OpenECU and select the Next button. If no version should be updated select None.

Note

If any version of INCA is selected, then the installer will add OpenECU integration to all versions of INCA. This is simply a consequence of the way INCA works.

If no versions of INCA were found, the next window presents details on how to achieve this by hand (more details given in Section 2.5.6, “ETAS INCA calibration tool”). The instructions should be carried out when INCA-ProF runs.

If the Start Menu Shortcuts component was selected, then the next window presented asks the user to select where in the Start menu the OpenECU items will be added. During install, the installer adds short cuts to the documentation components selected and to the OpenECU uninstall application.

Once installation has completed, the user is provided an option to read the getting started guide, the release notes and to visit the OpenECU web site.

Getting started guide

If you are a first time user of OpenECU, it is strongly recommend following the getting started guide, which covers what tools can be used with OpenECU and how to configure OpenECU and those tools to work together.

Release notes

If you are installing a new version of OpenECU, it is strongly recommended that you read the release notes. Some releases of OpenECU change the functionality of features which may have an impact on existing applications.

2.3. License setup

Machine identification generated by the license tools is required to activate an OpenECU platform license.

This section is a quick setup guide to get OpenECU working with your license. Consult the license administration guide for more information on license management and administration. This document is provided with the installation at "[install path]\doc_user\License-Administration-Guide.pdf".

2.3.1. Floating license

To setup a floating license, the vender daemon will have to be run on the designated license server as well as have a license file on that machine. This section describes setting up the vendor daemon for a floating license.

2.3.1.1. Server

  • After installing the platform, copy the files in "[install path]\tools\flexera\i86_n3\" to your designated license server. On that machine, run lmtools.exe.

  • Select the "System Settings tab", check "Include Domain", and press the button that says "Save HOSTID Info to a File".

  • Email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send you a valid license file. (Or if you have already completed the purchase, reply to the welcome email with this information)

  • It is recommended that lmadmin license server manager be used to serve licenses. Run the lmadmin installer to install the software. Once the installation is complete, copy the vender daemon, openecu.exe, into the install directory, "C:\Program Files (x86)\FlexNet Publisher License Server Manager\".

  • Start the license server manager. You can then use the web interface to upload the license file and start serving your license.

    Note

    If a license has not yet been purchased, email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send a valid license file. If the purchace has already been completed, reply to the welcome email with this information.

  • It is recommended that lmadmin license server manager be used to serve licenses. Run the lmadmin installer and start the license server manager. The web interface can then be used to upload the license file and start serving your license.

    Note

    Details on installing and using the lmadmin tool are in Chapter 9 of the License Administration Guide, "[install path]\doc_user\License-Administration-Guide.pdf".

    Note

    lmgrd is also provided with the platform as an alternative to lmadmin; consult Chapter 10 of the License Administration guide for details on its use.

2.3.1.2. Client

  • On the user development machine, set the environment variable OPENECU_LICENSE_FILE to <port>@<hostname>to tell the OpenECU platform to look for a floating license from the license server.

2.3.2. Node-locked license

To setup a node-locked license, a license file must be placed on the development machine.

  • After installing the platform, run the file: '[install path]\tools\flexera\i86_n3\lmtools.exe'

  • Select the "System Settings tab", check "Include Domain", and Press the button that says "Save HOSTID Info to a File" (see screen shot above)

  • Email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send you a valid license file. (Or if you have already completed the purchase, reply to the welcome email with this information) If a license has not yet been purchased, email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send a valid license file. If the purchace has already been completed, reply to the welcome email with this information.

  • Copy the file to the directory "C:\openecu" or update the OPENECU_LICENSE_FILE environment variable with the location of your file.

2.4. Removing OpenECU

Navigate through the Windows All Programs Start Menu shortcuts and find the OpenECU Developer Software directory. Select the version of OpenECU to remove and run the uninstaller.

The uninstaller requires that the user has administrative rights to make changes on the computer. If a user without rights is trying to execute the uninstaller a dialog box will be displayed and the uninstaller stops. Login with an administrator account or contact your network administrator and try again.

If a version of an OpenECU uninstaller is already running, a dialog box will appear saying so. Select OK and change to the other OpenECU uninstaller to continue.

The uninstaller presents the location of the previous install to remove. Select the Uninstall button to continue (this will remove that version of OpenECU) or select the Cancel button to stop the uninstall.

Note

The OpenECU uninstaller does not remove the INCA-ProF configuration files for CCP.

2.5. Integration notes for third party tools

2.5.1. Microsoft Windows 10

2.5.1.1. Integration

The installer integrates the OpenECU package with Windows 10 by modifying the Start menu, by modifying some registry items and by copying files to a local drive.

2.5.1.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives.

2.5.2. Microsoft Windows 7

2.5.2.1. Integration

The installer integrates the OpenECU package with Windows 7 SP1 by modifying the Start menu, by modifying some registry items and by copying files to a local drive.

2.5.2.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives.

2.5.3. Microsoft Windows XP

2.5.3.1. Integration

The installer integrates the OpenECU package with Windows XP SP3 by modifying the Start menu, by modifying some registry items and by copying files to a local drive.

2.5.3.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives.

2.5.4. PiSnoop

2.5.4.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating PiSnoop and OpenECU.

2.5.4.2. Known defects/issues

None.

2.5.5. ATI Vision

2.5.5.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating Vision and OpenECU.

2.5.5.2. Known defects/issues

  • Open: integration issues with OpenECU while creating a Vision VST (strategy) file.

    There have been integration issues between Vision and OpenECU, when the user requests a build create a Vision VST (strategy) file. If OpenECU cannot create a strategy file, then it may be necessary to register the COM interface for Vision by running the RegisterCOMInterface.bat file included in the install of ATI Vision.

  • Open: does not operate correctly with encrypted hard drives.

    There have been reports of Vision interacting poorly with encrypted hard drives. At the moment, it is not clear what the problem might be. On one occasion, Pi worked with ATI and a customer and determined a work around that is not understood. The work around was to rename the executable file for Vision to something longer than 11 characters.

  • Open: some earlier versions do not support CCP seed/key correctly.

    ATI Vision 2006 (v3.2) is the earliest version for which CCP seed/key security has been validated by Pi Innovo. Earlier versions may support CCP seed/key security (see the relevant Vision documentation) but bugs in the CCP implementation on various targets are known to exist. ATI have recommended that earlier versions should not be used, or should be used with caution.

2.5.6. ETAS INCA calibration tool

2.5.6.1. Integration

The installer integrates the OpenECU package with the ETAS INCA tool. However, if for any reason the installer could not find an installed version of INCA, the user can manually integrate the necessary ProF component.

The INCA-ProF tool programs OpenECU over CCP using a set of configuration files. In order to manually integrate these configuration files, the user must run INCA, open an experiment, select manage memory then flash programming.

The user is then presented with a dialog box to browse ProF configurations, or a ProF settings dialog box (in which case the user must select Configure...).

With the browse ProF configurations dialog box, select the "Install..." button and browse to the install location of OpenECU:

[install path]\tools_integration\inca_prof

and select OK. This will have manually installed the INCA-ProF configuration file for OpenECU.

Note

If manually integrating and the ProF files cannot be found in the location above, then re-run the OpenECU installer and select the Integration -> INCA-ProF Integration option and try again.

2.5.6.2. Known defects/issues

None.

2.5.7. Vector CANape

2.5.7.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating CANape and OpenECU.

2.5.7.2. Known defects/issues

None.

2.5.8. Wind River (Diab) C Compiler v5.5.1.0

2.5.8.1. Installation

The Wind River (Diab) compiler 5.5.1.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

  • On Choose your Activation Type window, select one of the following options:

    • Permanent activation if you have been assigned with a license file from Wind River, usually named WRSLicence.lic. The full path should point to the license file.

    • Temporary activation if you wish to use the Wind River (Diab) compiler on an evaluation basis, or temporary basis until a permanent license is provided.

  • A reboot may be required to complete installation of the Wind River (Diab) compiler.

  • If using one version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_5_1_0 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory.

  • If using more than one version of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_5_1_0 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

    E.g., D:\Progra~1\diab\5_5_1_0\win32\bin\

2.5.8.2. Known defects

  • Closed: incorrect generation of object code for “float <= float” comparisons.

    The compiler incorrectly generates object code for “float <= float” comparisons, turning the comparison into “float > float”. This issue has been resolved by removing the -Xieee754-pedantic command line option to the compiler command line option to the build configuration files.

  • Open: incorrect generation of object code for long C functions.

    The compiler incorrectly generates jump instructions in the object code if the jump destination address differs from the address of the jump instruction by more than 15 bits (signed). No warning or error is generated by the compiler. The result is a model which does not behave as expected when run on target (usually the ECU appears as if it is continually resetting).

    Workaround (C-API): Break up large functions into small sub-functions.

  • Open: generation of non-existent labels.

    The compiler can generate non-existent labels such as ".L1013" when compiling code involving large structures, such as those generated by TargetLink. The code then fails to link because the labels are not defined. This has not yet been seen with Simulink builds but it may possibly be seen in future.

    Workaround: if this problem is encountered, a patched version of the compiler is available from Wind River for customers who have compiler support (quote service request 1054126).

  • Open: incorrect rounding on conversion from float to integer types.

    The compiler rounds values when converting from floating point to integer, e.g. from "float" to "signed long" (in terms of native types, otherwise known as F32 and S32 in the OpenECU environment). For example, 3.6 as a float is rounded to 4 as an integer, but the C standard requires that the fractional part is truncated, so a converted value of 3 would be correct. Similarly -3.6 is rounded to -4 instead of being truncated to -3. This defect is fixed in version 5.8.0.0 of the compiler.

    Workaround: if this problem is encountered, a patched version of the compiler is available from Wind River for customers who have compiler support (quote service request 864470).

2.5.8.3. Known issues

  • Closed: Can't use Simulink look up blocks

    There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

    '[model-name].c', line [line-num]: warning (dcc:1792):
                                       trying to assign 'ptr to volatile' to 'ptr'

    This has now been fixed, see F-CR 13325 in the release notes.

  • Closed: compiling the main model file can take a long time.

    Small models compile in a short period of time, but once the code presented to the compiler exceeds a limit, the compiler takes a long time to compile the main model file (model-name.c).

    Workaround: the compiler sets aside an amount of memory for the compilation phase and if the size of the model code exceeds the limit, the compilation slows down. This can be avoided by increasing the size of the compiler's buffer using a command line option. Add the pcomp_CompileOptions block to the model, set the mode parameter to Add to options and set the compiler options parameter to -Xparse-size=100000. If the compilation is still slow, increase the option value further.

2.5.9. Wind River (Diab) C Compiler v5.8.0.0

2.5.9.1. Installation

The Wind River (Diab) compiler 5.8.0.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

  • Follow the guidance given in Section 2.5.8, “Wind River (Diab) C Compiler v5.5.1.0”.

  • If using a single version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_8 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory.

  • If using multiple versions of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_8 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

    E.g., D:\Progra~1\diab\5_8_0_0\win32\bin\

2.5.9.2. Known defects

None identified.

2.5.9.3. Known issues

  • Closed: Can't use Simulink look up blocks

    There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

    '[model-name].c', line [line-num]: warning (dcc:1792):
                                       trying to assign 'ptr to volatile' to 'ptr'

    This has now been fixed, see F-CR 13325 in the release notes.

2.5.10. Wind River (Diab) C Compiler v5.9.0.0

2.5.10.1. Installation

The Wind River (Diab) compiler 5.9.0.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

  • Follow the guidance given in Section 2.5.8, “Wind River (Diab) C Compiler v5.5.1.0”.

  • If using a single version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_9 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory.

  • If using multiple versions of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_9 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

    E.g., D:\Progra~1\diab\5_9_0_0\win32\bin\

2.5.10.2. Known defects

None identified.

2.5.10.3. Known issues

  • Closed: Can't use Simulink look up blocks

    There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

    '[model-name].c', line [line-num]: warning (dcc:1792):
                                       trying to assign 'ptr to volatile' to 'ptr'

    This has now been fixed, see F-CR 13325 in the release notes.

  • Open: Error message 0169

    The Diab 5.9.0.0 compiler generates object files that cause the Diab ddump command to generate the following error message during an application build.

    Error 0169 at offset NNNNNNNN: Unexpected EOF.

    The error appears to be benign and can be ignored. Currently, there is no known workaround.

2.5.11. GCC Compiler v4.7.3

GCC, also known as the GNU Compiler Collection, is a free compiler system produced by the GNU Project supporting various programming languages. The Free Software Foundation (FSF) distributes GCC under the GNU Public License (GNU GPL). GCC has been adopted as the standard compiler by most modern Unix-like computer operating system and has also been ported to a wide variety of processor architectures and is available for most embedded platforms.

GCC is used with permission under the GPL Version 3. If GCC is installed with OpenECU, the license file can be found in the [install path]\tools\gcc\ppc\docs directory of the OpenECU install. If desired, a copy of the GCC source code can be found and downloaded from the Pi Innovo website.

Support for GCC is currently in beta and as such, the user may run into issues which can cause an application to fail to build or run correctly on target. Listed below are a set of known issues when building an application using GCC. See Appendix J, Contact information for details on how to get in contact with OpenECU support if support is needed for using GCC.

GCC is not recommended for production programs at this time.

2.5.11.1. Installation

GCC is an optional component in the OpenECU installation and is installed by default.

2.5.11.2. Known defects

None identified.

2.5.11.3. Known issues

  • Open: Applications built with the GCC compiler do not support the diagnostics feature at this time. Applications using the diagnostics feature will not compile.

  • Information: compiler warnings when using Simulink look up blocks.

    When building a model that uses Simulink look up blocks, the compiler will emit diagnostic messages similar to the following. These can be ignored.

    [file-line]: warning: passing argument 2 of '[lookup function]'
                          discards 'volatile' qualifier from pointer target type
                          [enabled by default]
    [file-line]: note: expected 'const real_T *' but argument is of type
                       'const volatile real_T *'
  • Information: GCC only supports non-VLE code. Therefore, the compiled code will be larger. In general, GCC applications will be about 50% bigger than code generated by Diab.

  • Information: The GNU linker locates data slightly differently than the Diab linker in the final images. RAM and Flash memory utilization may be different for the same application compiled by different compilers.

  • Open: Applications built with GCC in general exhibit higher CPU loading than applications build with Diab.

2.5.12. Python

Python is general purpose, high level interpreted programming language, distributed under the PSF license which allows use in non open-source commercial applications. The license can be found in the [install path]\tools\python\license.txt file.

2.5.12.1. Installation

Python is a required component of the OpenECU installation.

2.5.12.2. Known defects

None identified.

2.5.12.3. Known issues

  • Open: When using OpenECU, Python may raise an error about an incorrect DLL. For example, The procedure entry point for X could not be located in the dynamic link library py[name].dll. This can occur if another application installed on the same machine as OpenECU has also installed Python (for instance, dSpace ControlDesk).

    Workaround: Browse to the Windows system directory. Depending on the version of Windows, this will be one of:

    c:\windows\system32; or
    c:\windows\syswow64

    Locate the DLL referred to in the error message. The file will start with the characters “py” and end with “.dll”. Group all Python DLLs and move them to a temporary location, then restart OpenECU.

    Temporarily moving DLLs will cause the other application to run incorrectly (and if DLLs unrelated to Python are inadvertantly moved, then the applications that rely on those DLLs may not run correctly). You can resolve this by returning the moved DLLs to their original location, or possibly moving the DLLs to the location of the installed applications.

    Note

    The OpenECU installation of Python does not write files to the Windows directories, or modify global registry entries relating to Python. As such, the OpenECU installation of Python is entirely local to OpenECU and will not affect other packages.

Chapter 3. Quick start

3.1. Introduction

This chapter gives you a quick introduction to creating an OpenECU application written in C, and an introduction to programming an OpenECU device.

The step1 exercise in Section 3.3, “Exercise — Step 1” describes how to incorporate the OpenECU C-API library into your own application designs, and how to test and calibrate your models on the ECU. The exercise requires the following resources:

3.2. Installed examples

The installation of OpenECU comes with a number of explanatory examples of how to use OpenECU, including a completed step1 example (see Section 3.3, “Exercise — Step 1”) configured for various ECUs. See Section 4.6.8, “Examples” and Section 4.6.8.1, “Building the examples” for further details.

3.3. Exercise — Step 1

Create a temperature limit warning

This exercise describes how to build, program, and test an application that monitors a temperature sensor and activates a warning lamp if a temperature threshold is breached. The application uses a single analogue input to measure the temperature, and a single PWM output to activate a warning lamp connected to the power supply.

The exercise requires the OpenECU to be connected to various devices and components as pictured in Figure 3.1, “Quick start loom”.

Figure 3.1. Quick start loom

Quick start loom

By following the instructions below, you will complete the application design, create C code, build the application and test the application running on the ECU.

3.3.1. Designing the application

Before any engineering project reaches the design stage, several detailed planning stages should be carried out to define suitable functional requirements and specifications. Once you have a detailed target for your design, you can then start to create an implementation of the application.

For this example, we'll skip the functional specification stage for brevity. The application will read an analogue input every 100 milliseconds, transform the input into a temperature reading, check for sensor faults, and turn on a lamp if the temperature exceeds a limit. We have designed and partially implemented the application for you — you need only finish the implementation as described below.

3.3.2. Create the application

To create the application, copy the [installation directory]\examples\c_api\step1_quick_start directory to somewhere local on your machine. Avoid placing the copy in a directory which contains a space in the path name. The copy has the following directories:

build

The build directory contains a batch file which will compile and link the completed step1 implementation.

We'll see how to build the application in Section 3.3.10, “Building the application”.

interface_specification

The interface_specification directory the initial implementation of two files: step1_[target-ecu].capi which describes supporting functionality the OpenECU library will provide to the application (for instance, what CCP settings are required to communicate with the calibration tool); and step1.dde which contains a description of the C variables in the step1 implementation which will be exposed to the calibration tool.

We'll see how to write these files in Section 3.3.9, “Create data dictionary and interface specification files”.

loom_specification

The loom_specification directory contains a copy of the diagram given in Figure 3.1, “Quick start loom”.

src

The src directory contains the initial implementation of the step1 application. We'll see how to implement the functionality of the temperature limit warning in Section 3.3.3, “Review the application”.

3.3.3. Review the application

Open the src\step1_[target-name].c file in a text editor. The file contains a few variables and functions. The M460 version is shown in summary here (and indeed all subsequent examples reflect the M460, there will be some differences to files targeting other ECUs):

#include "openecu.h" 1

/*...*/

#include "step1_m460_api.h" 2

static S16 stp_adc_raw; 3
static F32 stp_adc_eng; 4

static OE_CAL F32 stpc_adc_limit = 90.0; 5

void psc_initialise_app(void) 6
{
    (void) pcx_config(PIO_CAN_A37_A36, PIO_CBAUD_500_KBPS); 7
    (void) pcx_config(PIO_CAN_C37_C36, PIO_CBAUD_500_KBPS);

    /* Delete this comment and conditionals below when filling out this
     * example from the User Guide.
     */
#if (1)
#error "There is more to do here, see the User Guide." 8
#endif
}

void stp_task_100ms(void) 9
{
    /* Delete this comment and conditionals below when filling out this
     * example from the User Guide.
     */
#if (1)
#error "There is more to do here, see the User Guide."
#endif
}

void psc_background_app(void) 10
{
}

1

The source file starts by including openecu.h, which itself includes numerous other OpenECU header files. These header files provide declarations for the OpenECU library, including macros, variables and functions which give the application access the functionality of the ECU.

The OpenECU library isolates the application from the target hardware and provides the framework for allowing the application to perform work on a periodic (and sometimes on an event) basis. You can read more about the library in Chapter 4, Software overview.

2

The last include file is generated by the interface tool. The interface tool reads an interface specification (which is described in more detail for this exercise in Section 3.3.9, “Create data dictionary and interface specification files”) and generates source code which is compiled and linked with the application and OpenECU library. The source code provides the source definitions to glue the application and library together.

3

The C variable stp_adc_raw is used to hold the A/D conversion of the temperature sensor. The use of adc is a reference to the pin on the ECU connector (see the loom specification in Figure 3.1, “Quick start loom” to review how the ECU will be connected to power, to communications, to the temperature sensor and to the warning lamp).

4

The C variable stp_adc_eng is used to hold the result of converting stp_adc_raw into a temperature. It has units °C.

5

The C variable stpc_adc_limit is a calibration. A calibration is a C variable which can be modified by a calibration tool, without having to recompile the application. Calibrations are typically editable with a calibration tool (there is an introduction to the more common calibration tools in Appendix C, Supporting tools), and some ECUs support editing calibrations while the application is running (useful for tuning your application).

Calibrations used in OpenECU should have the OE_CAL macro for variables that are meant to be declared as volatile const. This is to ensure that calibrations are put into calibration flash in memory. If this macro is not used for calibrations, you may not be able to access calibrations in your calibration tool.

Calibration parameters which are used as the defaults for adaptive parameters must use the OE_ADAP macro instead of OE_CAL for proper operation. Failure to use OE_ADAP in a parameter used with one of the PNV function may result in unexpected module resets or other undefined behaviour. See the C-API nvm_demo source code in the examples folder of the OpenECU installation directory for more information.

This variable is the calibratable temperature limit, above which the application will turn on the warning lamp. The variable has units of °C.

Note

Notice how the name of this variable and the others make use of a prefix, either stpc or stp. All variables in an OpenECU application which will be read or written by a calibration tool need to adhere to this naming policy (which is covered in detail outside of this exercise in Section 8.1.5.2, “DDE naming rules (prefix_style)”). Other variables, private to the application, do not need to follow the naming policy.

6

The C function psc_initialise_app() is called by the OpenECU library during initialisation. The function currently calls the library to initialise the CAN buses and we'll later add more code to perform additional initialisation.

You can read about the initialisation sequence in Section 4.6, “Application mode”.

7

The C function psc_initialise_app() initialises the CAN buses by calling the OpenECU library pcx_config() function. The function takes two parameters: the first specifies the CAN bus to configure; and the second specifies the baud rate for the CAN bus. In both cases, the parameters use macros from the pio.h header file. We'll see how similar macros are used in other situations as the exercise progresses.

The function returns a code indicating success or failure of the operation. For this exercise, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

8

These blocks will throw a compiler error at build time. They are to prevent the compiler from building the quick start without reading this user guide. They should be deleted in order to build the project

9

The C function stp_task_100ms() performs the main functionality of the application. The interface specification instructs the library to call this function every 100 milliseconds (we'll see more about the interface specification for this exercise in Section 3.3.9, “Create data dictionary and interface specification files”. At the moment, the function does nothing — we'll expand on it in just a moment.

10

The C function psc_background_app() is called by the library when the processor is not running anything else. For the purposes of this exercise, we won't need it to do anything but you read more about the background function in Section 5.3.1.2, “System background processing”.

We need to extend the basic functionality of the application to read an analogue input, process it into a temperature reading, and set the state of a PWM output based on the temperature calibration.

3.3.4. Implement the sensor reading

The input portion of the application means reading an analogue input and converting the result to a temperature. Add the following code to the stp_task_100ms() function.

    (void) 1 pax_adc_input 2 (PIO_AIN_A28 3, &stp_adc_raw 4, FALSE 5);

1

The function returns a code indicating success or failure of the operation. For this exercise, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

2

The OpenECU library provides a function called pax_adc_input() to convert the voltage in of a connector pin to the range [0, 4096], where 0 corresponds to ground, and 4096 corresponds to full scale voltage. The full scale voltage depends on the connector pin chosen — A28 in this case corresponds to 5V full scale. The full scale range for each pin is detailed in the ECU's technical specification (Section A.1, “ECU hardware reference documentation”).

3

The first parameter to the function specifies the channel to convert. As with the CAN bus configuration example, the referenced hardware element is given as a macro. In this case, the macro specifies that the function must provide the result of reading pin A28.

4

The second parameter to the function specifies the variable to write the result of reading pin A28. We covered variable stp_adc_raw earlier.

5

The third and final parameter to the function specifies whether the channel given by the first parameter should be initialised or not. In this case, we need to read pin A28, hence the FALSE value. We'll cover initialisation shortly.

We also need to initialise the library to read pin A28, add the following code to function psc_initialise_app().

    (void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, TRUE);

Initialisation uses the same function and parameters except for the last. The final parameter, set to TRUE this time, tells the function to initialise pin A28 to be processed as an analogue input.

With these changes in place, the application can now initialise the temperature sensor input pin and reads the temperature sensor every 100 milliseconds. We now need to convert the reading into a sensible engineering value.

3.3.5. Implement the sensor conversion to temperature

Temperature sensors, and other sensors in general, can often generate a non-linear response to the physical characteristic under measurement. For the purposes of this exercise, we'll assume the temperature sensor is non-linear, and has a response similar to the following:

Figure 3.2. Transfer function for temperature sensor

Transfer function for temperature sensor

The OpenECU library directly supports converting linear and non-linear analogue readings to engineering values with the put_process_analog_input() function. Add the following code immediately below the call to put_adc_in().

    put_process_analog_input(stp_adc_raw, 1
                             0.1, 2
                             &stp_adc_eng, 3
                             &stp_adc_confirmed_raw_min_flt, 4
                             &stp_adc_confirmed_raw_max_flt,
                             &stp_adc_confirmed_slew_rate_flt,
                             &stp_adc_confirmed_eng_min_flt,
                             &stp_adc_confirmed_eng_max_flt,
                             &stp_adc_transient_flt,
                             &stp_adc_process_analog_input_pai_cal, 5
                             &stp_adc_process_analog_input_pai_wrk 6);

1

The first parameter provides the function with the A/D conversion of the input. It is this value which is converted to engineering units.

2

The second parameter specifies how long it has been since the last call to put_process_analog_input() for pin A28. As the function is called from stp_task_100ms() which runs every 100 milliseconds, 100 milliseconds is specified.

3

The third parameter points to a variable which is written with the result of converting stp_adc_raw to engineering units.

4

The fourth through to the ninth parameters point to variables which are written with the results of fault checking the input and conversion process. For the purposes of this exercise, the code won't act on any of the fault flags, but you will probably want to address any detected faults in your own applications.

5

The tenth parameter points to a work space which the function uses to record information between calls to put_process_analog_input().

6

The eleventh parameter points to a group of calibrations which define how the

The function call references numerous variables which have not yet been declared. Add the following code after the declaration of stpc_adc_limit.

static BOOL stp_adc_confirmed_raw_min_flt;
static BOOL stp_adc_confirmed_raw_max_flt;
static BOOL stp_adc_confirmed_slew_rate_flt;
static BOOL stp_adc_confirmed_eng_min_flt;
static BOOL stp_adc_confirmed_eng_max_flt;
static BOOL stp_adc_transient_flt;

which declares the fault flags passed to put_process_analog_input(). We also need to declare the work space and calibration structures. Add the following code immediately after the fault variables:

static PUT_ANALOGUE_WORKSPACE_T stp_adc_process_analog_input_pai_wrk;
static const PUT_ANALOGUE_CAL_DATA_T stp_adc_process_analog_input_pai_cal 1 =
{
    &stpc_adc_min_raw_value, 2
    &stpc_adc_max_raw_value,
    &stp_adc_eng_lookup_axis_size, 3
    stpc_adc_eng_lookup_x_axis,
    stpc_adc_eng_lookup_z_data,
    &stpc_adc_min_eng_value, 4
    &stpc_adc_max_eng_value,
    &stpc_adc_leaky_bucket_rise_rate, 5
    &stpc_adc_leaky_bucket_fall_rate,
    &stpc_adc_leaky_bucket_flt_clear_level,
    &stpc_adc_default_output_value, 6
    &stpc_adc_max_slew_rate 7
};

1

The structure is essentially a set of pointers to calibrations. The calibrations can themselves be changed by a calibration tool while the application is running. The calibration detail the different transformations and checks applied to the A/D reading.

2

These specify the minimum and maximum allowable value for the A/D conversion, which in this exercise is stp_adc_raw. If stp_adc_raw is outside the range given by these calibrations, then put_process_analog_input() will record a fault.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_min_raw_value        = 90;
static OE_CAL F32 stpc_adc_max_raw_value        = 4000;

For this exercise, the raw A/D limits do not bound the full scale, and it will be possible to see the raw fault flags become set if the temperature sensor is shorted to ground or to 5V.

3

These specify how the A/D conversion is transformed into an engineering value. The x_axis and z_data match the transfer function for the temperature sensor given in Figure 3.2, “Transfer function for temperature sensor”.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static const  S32 stp_adc_eng_lookup_axis_size  = 6;
static OE_CAL F32 stpc_adc_eng_lookup_x_axis[]  = {163,  917,  1671,
                                                   2424, 3178, 3932 };
static OE_CAL F32 stpc_adc_eng_lookup_z_data[]  = {135,  96,   74,
                                                   55,   20,   -42  };

What these lines of code say, is that an A/D range of [163, 3932] will be mapped onto an engineering range of [-42, 135]°C, following the curve given in the transfer graph.

4

These specify the minimum and maximum allowable value for the engineering value. If the engineering value is outside the range given by these calibrations, then put_process_analog_input() will record a fault.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_min_eng_value        = -40;
static OE_CAL F32 stpc_adc_max_eng_value        = 130;

For this exercise, the engineering limits do not bound the full range of the transfer function declared above (range [-42, 135]°C), and it will be possible to see the engineering fault flags become set if the temperature sensor voltage is close to 0V or 5V.

5

These specify how a detected fault will be validated. For this exercise, it is not important to understand the fault mechanism (although you can read more about it in Section 5.22.1.6, “Leaky bucket fault detection”).

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_leaky_bucket_rise_rate       = 0.5;
static OE_CAL F32 stpc_adc_leaky_bucket_fall_rate       = 0.25;
static OE_CAL F32 stpc_adc_leaky_bucket_flt_clear_level = 0.5;

6

This specifies the engineering value to use if a fault is validated by the leaky bucket. Its a mechanism where by a default engineering value can be used if the temperature sensor is found to be at fault.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_default_output_value = 60;

For this exercise, it will be possible to see the engineering value default to 60°C if a raw or engineering fault is present for some time.

7

This specifies the maximum rate of change of the A/D reading. If the rate of change exceeds the limit, a fault is reported. For the purposes of this exercise, we'll set the maximum to a large value to prevent a slew rate fault being reported.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_max_slew_rate        = 10000000;

We also need to initialise the workspace used for processing the analogue input, add the following code to function psc_initialise_app().

    put_process_analog_input_init(&stp_adc_process_analog_input_pai_wrk);

3.3.6. Implement the threshold comparison

To be able to turn the warning lamp on or off, the application must decide whether the processed temperature input has exceeded a limit. We already have the processed temperature value (stp_adc_eng) and a calibratable temperature limit (stpc_adc_limit), comparing the two is simple. Add the following code to the end of function stp_task_100ms().

    stp_adc_state = (stp_adc_eng > stpc_adc_limit);

This code introduces a new variable, stp_adc_state. It holds the boolean result of the comparison, 0 if the temperature limit has not been exceeded, 1 if the temperature limit has been exceeded. Add the following code after the definition of stp_adc_eng.

static BOOL stp_adc_state;

3.3.7. Implement the lamp driver

Finally, the application must drive the lamp on or off based on the comparison. Add the following code to the end of function stp_task_100ms().

    (void) 1 pdx_pwm_output 2 (PIO_POT_A15, 3
                                1000, 4
                                stp_adc_state, 5
                                0, 6
                                FALSE); 7

1

The function returns a code indicating success or failure of the operation. For this exercise, just like the call to pax_adc_input() earlier, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

2

The OpenECU library provides a function called pdx_pwm_output() drive a pin at a given frequency and duty cycle, essentially generating pulses. The application only needs to turn the lamp on or off so the PWM function may seem like an odd function to choose. It has been chosen to show that some OpenECU library functions can be used for multiple purposes. In this case, the PWM function can generate a low signal without pulses if the duty cycle is set to 0, and a high signal without pulses if the duty cycle is set to 1. Duty cycles of 0 and 1 exactly match the comparison value calculated earlier.

Note that the actual state of the output (low versus high) depends on the particular pin used and if the pin is configured for a high-side or low-side control. In this example, M460 pin A15 is a low-side only output, so a duty cycle of 0 will have the output off (high voltage if connected to a load) and a duty cycle of 1 will have the output pulled to ground.

3

The first parameter to the function specifies the channel to drive. As with the pax_adc_input() function, the referenced hardware element is given as a macro. In this case, the macro specifies that the function must drive pin A15.

4

The second parameter to the function specifies the rate at which pulses should be generated. For this exercise, we don't need pulses to be generated but simply need a constant low or high signal, so any valid frequency which is at least as quick as the task itself will do.

5

The third parameter to the function specifies the proportion of the frequency which must be pulsed high. Again, for this exercise, we don't need pulses to be generated but simply need a constant low or high signal. In this case, the PWM function can generate a low signal without pulses if the duty cycle is set to 0, and a high signal without pulses if the duty cycle is set to 1. Duty cycles of 0 and 1 exactly match the comparison value stp_adc_state.

6

The fourth parameter to the function specifies a phase offset that can be set for a given channel relative to other channels with the same frequency. In this case, just set this to zero.

7

The fifth and final parameter to the function specifies whether the channel given by the first parameter should be initialised or not. In this case, we'll need to drive A15, hence the FALSE value. We'll cover initialisation shortly.

We also need to initialise the library to drive pin A15, add the following code to the end of function psc_initialise_app().

    (void) pdx_pwm_output(PIO_POT_A15, 1000, 0, 0, TRUE);

Most OpenECU hardware implements a switch to control whether an output driver can be turned on or not (although some do not, for instance, the M461). The switch can be used as a secondary system to prevent accidental changes to the output drivers. However, for the purposes of this exercise there is no need for this level of functionality, instead, we simply need to ensure that pin A15 can be driven. Add the following code to the end of function psc_initialise_app() if the ECU target supports the function (see pss_set_safety_switch()). for more).

    pss_set_safety_switch(TRUE);

3.3.8. Summary so far

Having followed the instructions you will have a simple application which reads an analogue temperature sensor and turns on a lamp if the temperature exceeds a calibratable limit. Your code should now look something like the following.

#include "openecu.h"

#include "step1_m460_api.h"

static S16  stp_adc_raw;
static F32  stp_adc_eng;
static BOOL stp_adc_state;

static OE_CAL F32 stpc_adc_limit = 90.0;

static BOOL stp_adc_confirmed_raw_min_flt;
static BOOL stp_adc_confirmed_raw_max_flt;
static BOOL stp_adc_confirmed_slew_rate_flt;
static BOOL stp_adc_confirmed_eng_min_flt;
static BOOL stp_adc_confirmed_eng_max_flt;
static BOOL stp_adc_transient_flt;

static OE_CAL F32 stpc_adc_min_raw_value                = 90;
static OE_CAL F32 stpc_adc_max_raw_value                = 4000;
static const  S32 stp_adc_eng_lookup_axis_size          = 6;
static OE_CAL F32 stpc_adc_eng_lookup_x_axis[]          = { 163,  917,  1671,
                                                            2424, 3178, 3932 };
static OE_CAL F32 stpc_adc_eng_lookup_z_data[]          = { 135,  96,   74,
                                                            55,   20,   -42  };
static OE_CAL F32 stpc_adc_min_eng_value                = -40;
static OE_CAL F32 stpc_adc_max_eng_value                = 130;
static OE_CAL F32 stpc_adc_leaky_bucket_rise_rate       = 0.5;
static OE_CAL F32 stpc_adc_leaky_bucket_fall_rate       = 0.25;
static OE_CAL F32 stpc_adc_leaky_bucket_flt_clear_level = 0.5;
static OE_CAL F32 stpc_adc_default_output_value         = 60;
static OE_CAL F32 stpc_adc_max_slew_rate                = 10000000;

static PUT_ANALOGUE_WORKSPACE_T stp_adc_process_analog_input_pai_wrk;
static const PUT_ANALOGUE_CAL_DATA_T stp_adc_process_analog_input_pai_cal =
{
    &stpc_adc_min_raw_value,
    &stpc_adc_max_raw_value,
    &stp_adc_eng_lookup_axis_size,
    stpc_adc_eng_lookup_x_axis,
    stpc_adc_eng_lookup_z_data,
    &stpc_adc_min_eng_value,
    &stpc_adc_max_eng_value,
    &stpc_adc_leaky_bucket_rise_rate,
    &stpc_adc_leaky_bucket_fall_rate,
    &stpc_adc_leaky_bucket_flt_clear_level,
    &stpc_adc_default_output_value,
    &stpc_adc_max_slew_rate
};

void psc_initialise_app(void)
{
    (void) pcx_config(PIO_CAN_A37_A36, PIO_CBAUD_500_KBPS);
    (void) pcx_config(PIO_CAN_C37_C36, PIO_CBAUD_500_KBPS);

    (void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, TRUE);

    put_process_analog_input_init(&stp_adc_process_analog_input_pai_wrk);

    (void) pdx_pwm_output(PIO_POT_A15, 1000, 0, 0, TRUE);

    pss_set_safety_switch(TRUE);
}

void stp_task_100ms(void)
{
    (void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, FALSE);

    put_process_analog_input(stp_adc_raw,
                             0.1,
                             &stp_adc_eng,
                             &stp_adc_confirmed_raw_min_flt,
                             &stp_adc_confirmed_raw_max_flt,
                             &stp_adc_confirmed_slew_rate_flt,
                             &stp_adc_confirmed_eng_min_flt,
                             &stp_adc_confirmed_eng_max_flt,
                             &stp_adc_transient_flt,
                             &stp_adc_process_analog_input_pai_cal,
                             &stp_adc_process_analog_input_pai_wrk);

    stp_adc_state = (stp_adc_eng > stpc_adc_limit);

    (void) pdx_pwm_output (PIO_POT_A15,
                           1000,
                           stp_adc_state,
                           0,
                           FALSE);
}

void psc_background_app(void)
{
}

Before we build the application and link it with the OpenECU library we need to specify how the library and application will work together. For instance, we need to tell the library that function stp_task_100ms must be called every 100 milliseconds. We do this by writing a data dictionary file and an interface specification file.

3.3.9. Create data dictionary and interface specification files

There are two aspects to linking an application with the OpenECU library:

Data dictionary file

Used to explain the C variables that will be accessible by a calibration tool while the application is running on an ECU. For this exercise, we'll define data dictionary elements (DDEs) for most of the global variables in the code, so that, for instance, the processed temperature (stp_adc_eng) can be viewed in real-time.

Interface specification file

Used to detail information about the application and how it will use the library. The interface specification file is converted into supporting C code to be built with the application and linked to the OpenECU library. For instance, one of the functions of the interface specification file is to declare the application tasks, which in this exercise, consists of stp_task_100ms called every 100 milliseconds.

Both the data dictionary file (or files) and the interface specification file are read by a tool which generates:

  • Additional code files which must be linked with the application and OpenECU library to create a binary image to program an ECU with; and

  • An ASAP2 file which can be read by a calibration tool to provide access to the application's C variables while the application runs on an ECU.

3.3.9.1. Review the data dictionary file

When the application was created during Section 3.3.2, “Create the application”, a complete data dictionary file was copied. Edit the file interface_specification\step1.dde in a text editor and you'll find it contains numerous lines including:

Name          Units         Class  Accuracy  Min  Max     Description 1

stp_adc_raw 2 A/D counts 3 d  4  1         0    4096 5  Temp. pin A28 as A/D...

Each line is either a comment line (starting with either “**” or “--”) or a line specifying data as a set of columns, each column separated by a single TAB character.

1

The column specification line consists of a set of named columns, each separated by a single TAB character. The columns can be re-arranged so long as Name remains the first.

2

The Name column gives the name of the C variable. In this case, stp_adc_raw refers to the C variable of the same name, the variable is used to store the A/D reading of pin A28.

3

The Units column gives the units to be applied to the value of stp_adc_raw. The units are displayed by calibration tools, but in general, are otherwise ignored by OpenECU and other tools.

4

The Class column gives the ASAP2 type used for the C variable. Here, the variable is a displayable, that is, something which is stored in RAM and writable by the application, so the class is set to d (for displayable).

5

The Min and Max columns give the minimum and maximum range the C variable should contain. The range is loosely used by a few tools, but does not in any way restrict what the code can do. For instance, if the range is [0, 4096] but the code assigns value 10000 to the variable, then the variable will be written with 10000 and if the calibration tool is viewing the variable at the time, it may flag the variable as being out of range.

The other lines in the data dictionary file make up comments and other data definitions for both displayables (readable variables) and calibrations (writable variables declared volatile const).

More detailed information about the structure of the data dictionary file can be found in Section 4.6.3, “Data dictionary and engineering unit files”.

3.3.9.2. Review the interface specification file

When the application was created during Section 3.3.2, “Create the application”, a complete data dictionary file was copied. Edit the file interface_specification\step1_[target-ecu].capi in a text editor. The interface file contains various statements, some of which we'll take a closer look at.

target-ecu
{
  hw-part-number  = "01T-068144"; 1
  hw-issue-number = 1;
  hw-option       = "000";
}

1

Specifies that the application will be run on an M460 Developer ECU Issue 1.

application
{
  major-version    = 1; 1
  minor-version    = 0;
  subminor-version = 0;

  description      = "Step-1 example for the C-API.";
  copyright        = "Copyright 2015, Pi Innovo";
  name             = "Step1 v%ver-major%.%ver-minor%.%ver-subminor%, %target%";

  os-native
  {
    stack-size = 8192; 2

    task
    {
      name     = stp_task; 3
      priority = 1;
      period   = 100;
      function = stp_task_100ms;
    }
  }
}

1

Specifies version, name, description and copyright information which is embedded into the source code and is programmed onto the target ECU with the application. The information can be read out of the target ECU later.

In particular, note that the name statement can take tokens, single words starting and ending with the “%” character. See Section 8.1.4.8, “Compound statement: application” for a complete list of tokens.

2

Specifies the overall stack size to be allocated to the application and OpenECU library. A simple application like the one presented in this exercise typically uses less than 1KB of stack, the 5KB specified here could be reduced if necessary.

3

Specifies that one function called stp_task_100ms must be called every 100 milliseconds. That is sufficient for this exercise, but other tasks can be specified. When more than one task is specified, the relative priority of each dictates the running order of the functions (see Section 5.6.1.2, “Preemptive scheduling” for more details).

ccp-messaging
{
  cro             = 1785; 1
  dto             = 1784;
  station-address = 0;
  can-bus         = 0;
  baud            = 500;

  enabled-during-application-mode = true;
}

1

Specifies the calibration communication protocol (CCP) parameters for communication between the calibration tool and application running on the target ECU. The values presented here are the default set that each target ECU is delivered with re-programmed. We'll see how to program an ECU in Section 3.3.11, “Program the ECU”.

ddes
{
  include-dde-tabbed "../interface_specification/step1.dde"; 1

  generate-library-ddes = true;
}

1

Specifies the data dictionary files which describe the application C variables of interest.

3.3.10. Building the application

The following sections detail how to build the application. Building the application can be done using either the Diab Compiler, or by using GCC. Please follow the steps relevant to your compiler.

3.3.10.1. Build the application using a Diab Compiler

The description that follows assumes the example is being built using the Wind River Diab compiler, v5.5.1.0. If you are using another supported compiler, you will need to select files or settings to match your target and compiler combination.

When the application was created during Section 3.3.2, “Create the application”, a simple batch file was copied. Edit the file build\build_[target-ecu]_diab_5_5_1_0.bat. Change the line:

SET OPENECU_DIAB=

to match the installed location of the compiler. The location must end in a trailing directory slash (the “\” character). For instance, if the compiler was installed at c:\diab\5.5.1.0\win32\bin, then the line should be set to:

SET OPENECU_DIAB=c:\diab\5.5.1.0\win32\bin\

Once edited, the build can be run by executing the batch file. The result of a successful build produces a number of files in the same directory as the build directory.

  • step1_[target-ecu]_vision.a2l — the ATI Vision specific ASAP2 file for the build application;

  • step1_[target-ecu]_image_small.s37 — the image bytes to program into the OpenECU in Motorola S-record format (small representing the minimum amount of code and data bytes to program the OpenECU device) — suitable for the ATI Vision calibration tool.

If the build fails for any reason, go back through the stages of the example and identify any corrections, or look at the installed and completed step1 application to identify any differences.

3.3.10.2. Build the application using the GCC Compiler

The description that follows assumes the example is being built using the GCC Compiler v4.7.3 that comes packaged in your OpenECU installation. Please see Section 2.1.5, “Third party tool requirements — compatibility” for a list of supported targets for GCC. If you are using another supported compiler, you will need to select files or settings to match your target and compiler combination.

When the application was created during Section 3.3.2, “Create the application”, a simple batch file was copied. Use the file build\build_[target-ecu]_gcc_4_7_3.bat.

The build can be run by executing the batch file. The result of a successful build produces a number of files in the same directory as the build directory.

  • step1_[target-ecu]_vision.a2l — the ATI Vision specific ASAP2 file for the build application;

  • step1_[target-ecu]_image_small.s37 — the image bytes to program into the OpenECU in Motorola S-record format (small representing the minimum amount of code and data bytes to program the OpenECU device) — suitable for the ATI Vision calibration tool.

If the build fails for any reason, go back through the stages of the example and identify any corrections, or look at the installed and completed step1 application to identify any differences.

3.3.11. Program the ECU

The OpenECU is programmed with any CCP compliant tool. Specific instructions for ATI Vision, Vector CANape and ETAS INCA calibration tools are provided in Appendix C, Supporting tools.

At a minimum, the OpenECU device will need to be powered and be connected to the CCP tool over CAN as shown in the following diagram.

The OpenECU device can be programmed by following these steps:

  1. Apply a positive FEPS voltage, as given in the following table and then power cycle the ECU (the FEPS signal may not be detected if applied simultaneously with the ECU power). Upon detecting the FEPS signal the ECU is placed into its reprogramming mode, where it does not run the application and responds only to reprogramming commands.

  2. Program the ECU following the instructions in Appendix C, Supporting tools.

  3. Once programmed, ground the FEPS pin and power cycle the ECU. This places the ECU in its application mode, where the ECU runs the programmed application.

Table 3.1. FEPS voltages

M110 M221 M250 M220
M460
M461
M670
Result
0V0V0V0V FEPS pin is grounded. On power up, the ECU attempts to run the last programmed application in application mode. If a application has not been programmed, the ECU enters reprogramming mode.
> +36V> +13V> +17V FEPS pin is positive. On power up, the ECU enters reprogramming mode. If a application has previously been programmed, the ECU uses the CCP settings of the application. Otherwise, the ECU uses the default CCP settings.
< -16V< -16V< -18V< -16V FEPS pin is negative. On power up, the ECU enters reprogramming mode. The ECU uses the default CCP settings and ignores any CCP settings stored in any programmed application.

3.3.12. Play with the application

Once programmed, ground the FEPS pin, power cycle the ECU, and the application will start. With your calibration tool, you will be able to view the stp_adc_raw and stp_adc_eng variables and see them vary as the voltage applied to pin A28 is varied.

Varying the voltage so stp_adc_eng exceeds the value for stpc_adc_limit (which defaults to 90°C) will cause the output driver for A15 to turn on and light the warning lamp.

Grounding the A28 pin will cause the application to determine there is a fault with the temperature sensor, and reported through the stp_adc_confirmed_raw_min_flt and/or stp_adc_confirmed_eng_min_flt variables.

There are some automatically added data definitions you can view which provides some information about the application (you can find a complete list in Section 8.1.7, “Automatic ASAP2 entries”).

mpl_run_time

A counter which the library increments every second the application is running. During reset, the counter is set to zero.

mpl_cpu_loaded

The percentage of the CPU used during the last 50 milliseconds. Provides an indication of how hard the application is working.

mpl_tt_stp_task

The time in microseconds the step1 task took to run every 100 milliseconds.

Chapter 4. Software overview

4.1. Introduction

4.2. System components

In Figure 4.1, “System components”, each of the different system components is shown in relation to the others. Components in yellow are supplied by Pi, components in white are supplied by the customer.

Figure 4.1. System components

System components

An ECU is composed of the bootloader, the reprogrammer, the library and the application code.

Bootloader

The bootloader handles the ECU start-up and determines which system mode (Section 4.3, “System modes”) to enter. The bootloader component is programmed into the ECU when the ECU is manufactured.

Reprogrammer

The reprogrammer handles requests to reprogram the application code using the CAN calibration protocol (see Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)”). The reprogrammer component is reprogrammed into the ECU before the ECU is manufactured.

Library

The library provides start-up, communication, I/O and non-volatile memory functionality usable by the application code. The library component is linked with the application code before being programmed into the ECU.

Application

The application uses the library to access the sensors and actuators, and to access other devices via communication buses.

The ECU comes in two types: fleet units and developer units. The main difference between the fleet unit and the developer unit, is that the developer has the capability to adjust calibrations while the application is running. Calibrations are essentially C variables and support is included for single calibrations through to 1d and 2d table calibrations.

Components external to the ECU include:

Sensors/actuators

The application can read sensors and drive actuators through the ECU hardware using the library. The sensors and actuators need to match the electrical specification of the ECU (see Section A.1, “ECU hardware reference documentation” for details on each supported ECU).

Physical communication buses

The application can receive and transmit messages on the communication buses using the library. Library support ranges from single messages to complete protocol handling (e.g., CCP or J1939).

Calibration tool

A (usually) PC based tool which interacts with the ECU to read and modify variables while the application is running (modification of variables only supported on developer units). Appendix C, Supporting tools provides an overview of the supported calibration tools.

The calibration tool also has the ability to reprogram the application when the ECU is running the reprogrammer.

Bus analysis tool

A (usually) PC based tool which can analyse the various messages and protocols on the bus, useful for diagnosis. Some tools also support transmission of messages to simulate other bus devices.

Other bus devices

Usually smart sensors or actuators, possible other ECUs, all of which need to communicate between each other to achieve the system behaviour required.

4.3. System modes

In Figure 4.2, “System modes”, each of the major system modes is shown. When the ECU is turned on (or is recovering from a powered reset), the bootloader decides which major mode to enter based on external inputs to the ECU.

Figure 4.2. System modes

System modes

Boot mode

Boot mode starts after reset, performs some tests and, if successful, determines what mode to enter (see Section 4.4, “Boot mode”).

Reprogramming mode

Reprogramming mode is entered if the FEPS pin is asserted before the ECU is powered up, if there is an invalid application image in memory, or for certain targets if the ECU is running the application and allowing reprogramming while a reprogramming request is received (FEPS-less) (see Section 4.5, “Reprogramming mode”).

Entering reprogramming mode causes the ECU to listen to the communication buses for reprogramming instructions. The ECU does not run the application.

Application mode

Application mode is entered if the FEPS pin is not asserted and if there is a valid application image in memory (see Section 4.6, “Application mode”).

Entering application mode causes the ECU to run the application. The ECU listens to the communications buses for reprogramming instructions, but the application can inhibit reprogramming from occurring if necessary.

4.4. Boot mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader performs various tests. These include:

  • Tests on memory devices, looking for hard faults such as shorts on address lines, or memory locations which cannot hold their contents;

  • Tests on the code to run, looking for hard faults in the contents of code and data;

  • Tests on the frequency of reset, looking for unexpected resets which occur back to back in a short period of time.

If the tests fail then the bootloader will either reset or attempt to enter reprogramming mode, flashing a code to indicate the cause (see the technical specification for each ECU for details about code flashing). If the tests pass, then the bootloader will determine what mode to enter next (see Section 4.5, “Reprogramming mode” and Section 4.6, “Application mode” for details on how each mode is chosen).

4.5. Reprogramming mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader will enter reprogramming mode if the FEPS pin is asserted, if there is an invalid application image in memory, or for certain targets if the ECU is running the application and allowing reprogramming while a reprogramming request is received (FEPS-less).

In reprogramming mode, the ECU listens to the communications buses for instructions to reprogram. Specifically, the ECU listens for CCP commands using either the application CCP settings (if a valid application image is in memory) or the default CCP settings otherwise.

The OpenECU is programmed with any CCP compliant tool. Specific instructions for ATI Vision, Vector CANape and ETAS INCA calibration tools are provided in Appendix C, Supporting tools. If you have another CCP compliant tool, please refer to the manufacturer's instructions for further details in programming and refer to Appendix F, CCP compliance which details how OpenECU complies with the CCP 2.1 standard.

At a minimum, the OpenECU device will need to be powered and be connected to the CCP tool over CAN 0 or CAN A (whichever the target ECU makes available). In some cases the OpenECU module will need to have the FEPS line connected to a power supply capable of up to 19 volts (depending on target), as shown in the following diagram.

Note

The FEPS voltage must be asserted before the ECU is powered up. Powering the FEPS input and ECU simultaneously (i.e. shorting the FEPS and VPWR inputs) may result in reprogramming mode not being detected.

OpenECU operates in three system modes:

Boot mode

This is the mode initiated when the ECU is turned on (or recovering from a powered reset). Boot mode choose whether to enter reprogramming mode or application mode.

Reprogramming mode

This is the mode required to reprogram the OpenECU with the CCP tool. This mode is entered differently depending on the ECU. All OpenECU modules can be made to enter this mode by asserting the FEPS pin with a positive voltage (above the required threshold) and power cycling the OpenECU device.

Application mode

This is the mode required to run the application on OpenECU. Start this mode by grounding the FEPS pin and power cycle the OpenECU device.

How reprogramming and application mode is entered differs slightly between groups of ECUs due to differences in the electronics. For the M220, M250, M460 and M461 targets, the next illustration shows how each mode is entered.

Figure 4.3. System modes for M220, M250, M460 and M461

System modes for M220, M250, M460 and M461

For the M221 and M670 targets, the next illustration shows how each mode is entered.

Figure 4.4. System modes for M110, M221 and M670

System modes for M110, M221 and M670

There are a number of ways in which an ECU can be reprogrammed:

Reprogramming — ECU not previously programmed

Reprogramming the ECU without an application can be done with or without FEPS on the M110, M220, M221, M250, M460, M461 and M670.

Without a programmed application, reprogramming mode will use the default CCP settings as defined in Table 4.2, “CCP defaults”. As explained in the table, these settings will vary depending on the version of firmware that is programmed into the ECU.

Reprogramming without FEPS — ECU previously programmed (M110, M220, M221, M250, M460, M461 and M670 only)

Once an M110, M220, M221, M250, M460, M461 or M670 ECU has been programmed with a valid application, that ECU can be reprogrammed without having to apply FEPS.

With a programmed application, reprogramming mode will use the CCP settings defined by the application already programmed. If an application with different CCP settings is programmed then the new CCP settings are used after the ECU is power cycled.

Reprogramming with FEPS — ECU previously programmed (M220, M221, M250, M460, M461 and M670 only)

All OpenECU targets can be programmed by first applying FEPS and then cycling power to the ECU to enter reprogramming mode.

Furthermore, if the application is running and the application is not inhibiting programming then, without cycling power, the ECU can be programmed by applying FEPS and starting programming.

With a programmed application, reprogramming mode will use the CCP settings defined by the application already programmed. If an application with different CCP settings is programmed then the new CCP settings are used after the ECU is power cycled.

Forced reprogramming with negative FEPS (M110, M220, M221, M250, M460, M461 and M670 only)

The M220, M221, M250, M460, M461 and M670 ECUs can be made to use the default CCP settings instead of the application settings by applying a negative voltage to FEPS and then cycling power to the ECU. Reprogramming mode will then use the default settings for CCP.

The defined CCP settings are defined in Table 4.2, “CCP defaults”. As explained in the table, these settings will vary depending on the version of firmware that is programmed into the ECU.

Once programmed, an ECU will remain in reprogramming mode until the power is cycled. After the power cycle, the ECU will determine which mode to enter based on the FEPS voltage. To start the application after programming, ensure FEPS is grounded and power cycle the ECU.

The FEPS pin is asserted by applying a voltage to the pin. The required voltage varies between ECUs.

Table 4.1. FEPS voltages

M110 M221 M250 M220
M460
M461
M670
Result
0V0V0V0V FEPS pin is grounded. On power up, the ECU attempts to run the last programmed application in application mode. If a application has not been programmed, the ECU enters reprogramming mode.
> +36V> +13V> +17V FEPS pin is positive. On power up, the ECU enters reprogramming mode. If a application has previously been programmed, the ECU uses the CCP settings of the application. Otherwise, the ECU uses the default CCP settings.
< -16V< -16V< -18V< -16V FEPS pin is negative. On power up, the ECU enters reprogramming mode. The ECU uses the default CCP settings and ignores any CCP settings stored in any programmed application.

As a shortcut, FEPS may be applied while the model is running and, without power cycling the device, be reprogrammed via a CCP compliant tool. When reprogramming starts, the OpenECU device switches from application mode to reprogramming mode. It may be undesirable to allow this method due to safety reasons, so the pcp_inhibit_reprogramming() function can switch this method off.

If the OpenECU device has never been programmed before, it uses the CCP settings given in Table 4.2, “CCP defaults”. The CCP compliant tool must use the same settings. Once the OpenECU device has been reprogrammed with an application that uses different CCP settings, the CCP compliant tool must be changed to use these settings.

Table 4.2. CCP defaults

CCP settingDefault value
CRO message identifier1785
DTO message identifier1784
Station identifier0
CAN bus identifierCAN 0
CAN bus baud-rate 250kBps or 500kBps [a]

[a] The default baud-rate for CCP will depend on which version of firmware was flashed into the ECU. All ECUs (such as M220-000 or M250-000) use 500 kBps default baud rate, except for the M461-000 which uses 250 kBps. Refer to Section 8.1.8, “OpenECU software versioning” for details.


4.6. Application mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader will enter application mode if the FEPS pin is not asserted and if there is a valid application image in memory.

When application mode is entered, the library co-ordinates the sequence of initialisation as shown in Figure 4.5, “System initialisation”.

Figure 4.5. System initialisation

System initialisation

Perhaps the best way to understand how the different components of the OpenECU library interact with the application, is to look at how an application is built into a binary image for reprogramming, and into a data description file for calibration tools.

  1. Bootloader — determine which major system mode to enter. When entering application mode, the bootloader changes program flow to the library pre-initialisation phase.

  2. Library pre-initialisation — occurs after the bootloader has decided to enter the application mode. During pre-initialisation, the library configures the ECU's hardware in a largely generic way and initialises the C run-time environment.

    Hardware configuration includes decoding the reason for reset (which can be inspected by the application by calling psc_decode_reset()).

    Initialising the C run-time environment includes clearing C objects with no initialiser to zero, setting C objects with initialisers, and setting up the system stack. The system stack is explained in more detail in Section 5.6.1.3, “Stack sharing”. The size of used stack can be retrieved during application run by calling psc_get_used_stack_size().

  3. Application initialisation — occurs after library pre-initialisation, this is the point in time when the application can initialise itself and declare information to the library for post initialisation.

    The library invokes the application defined function psc_initialise_app() during application initialisation. The application can initialise any data structures necessary for the application to perform, as well as configuring some aspects of the library. For instance, during application initialisation, the application must declare CAN messages it will receive and transmit (e.g., see pcx_declare_message()) or initialise ECU pins for use (e.g., see pdx_digital_output()).

  4. Library post-initialisation — occurs after application initialisation to complete any hardware setup (especially any dependent on information declared during application initialisation) then starts the task scheduler.

    Note

    Typically, library and application initialisation are complete within a few hundred milliseconds of powering up the ECU. A rough guide to the boot time of the ECU can be retrieved by calling psc_decode_reset().

    Once the scheduler has started, the application can perform its processing each time one of the application tasks runs.

  5. Application run — occurs after library post-initialisation is complete. During application run, both application and library tasks are scheduled in a fixed-priority scheme (see Section 5.6, “Task scheduling (PKN)” for details about task scheduling).

4.6.1. Building an application

With application source code, interface specification and data dictionary files in place, the application can be built and linked with the OpenECU and compiler libraries to generate a binary image which can be programmed and run on an OpenECU. Figure 4.6, “Building an application (in outline)” shows in outline how a build is achieved.

Figure 4.6. Building an application (in outline)

Building an application (in outline)

The build process has a number of inputs:

Data dictionary files

The data dictionary files describe the data variables of the application code. Data variables are all C global variables, either RAM or ROM based. For each data variable which must be accessible from the calibration tool, there is a corresponding data dictionary element (DDE) which details attributes of the data variable, like description, type, units, and so on. See Section 4.6.3, “Data dictionary and engineering unit files” and Section 8.1.5, “DDE specification” for more.

Interface description file

The OpenECU library has a number of function interfaces and data interfaces. The data interfaces are largely exposed so that the build application can closely control the amount of memory the library uses. Some of the data interfaces are hard to write and maintain by hand, so there is an interface tool which will read an interface description file and generate the data interface code. See Section 4.6.2, “Interface specification” and Section 8.1, “Interface and DDE tool” for more.

Application source code

Source code for the application.

OpenECU library file

A compiler specific library file for OpenECU. The library file is linked with the application object files to create a binary image for execution on the target.

There is a library file for each target and compiler supported by OpenECU. It is important to link the correct library to match the compiler and target, otherwise the ECU may not operate correctly (see Section 5.1.2, “File locations”).

Compiler library file

The compiler's own support libraries (e.g., implementation of the C standard library or compiler specific extensions). See Section 4.6.6, “Compiler library support” for more.

Linker script files

The scripts tell the compiler how to combine the application object files, interface object files and libraries to create the binary image to run on the target ECU. This includes details about the layout of memory and how object file sections are allocated to memory.

The inputs are processed in a number of steps to create intermediate objects:

  1. Runs the interface tool to generate information about the target and DDEs used in step 5, and to generate the data and task interface code between the application and library.

  2. Runs the compiler for the interface code and application code files. The compiler generates object files used in the link stage.

  3. Runs the linker to combine the object files from the application and interface tool, as well as the compiler's library and OpenECU libraries, to generate an ELF file.

  4. Runs support tools and scripts to extract a binary image of the application from the ELF file. At this stage, the binary image is modified with check-sums and auxiliary data to support robust operation on the ECU. See Section 8.2, “Supporting build scripts” for details.

  5. Runs a support tool to extract information from the ELF file (optional). Then runs the interface tool again to generate an ASAP2 file from the target and DDE information from the interface specification. The ASAP2 file is used during reprogramming and calibration of the ECU.

From those intermediate steps, the final set of objects are created:

Target ASAP2 file

An ASAP2 file details the memory areas used by the binary application image as well as how DDEs have been allocated to memory. The ASAP2 file is used by PC based tools to reprogram an ECU or to calibrate an ECU. See Appendix C, Supporting tools for more.

Target image file

The target image file contains the binary image of the application code and data. Once an ECU is programmed with the image file, the application can be executed. See Appendix C, Supporting tools for more.

The C-API examples supplied with OpenECU show how each of these stages can be implemented in a simple fashion using batch files (see Section 4.6.8.1, “Building the examples”). These are the minimum steps required to build and can be copied if required. But an application may have additional stages to implement and there is no reason why a more sophisticated system (like make or SCons for example) might not be used.

4.6.2. Interface specification

As described already, the library has both data and function parts to its API. Some of the data components are hard to write and maintain by hand and so there is an interface tool which takes a simple description of the interface between the application and library, and generates the data components as required. This helps simplify the coding required to link the application and library together.

The interface tool and format of the interface specification file is given in detail in Section 8.1, “Interface and DDE tool”.

The interface specification also specifies the data dictionaries used to describe application data variables.

4.6.3. Data dictionary and engineering unit files

The OpenECU library can interact with calibration tools to read and write application data while the application is executing on the target. To support the interface between the calibration tool and the application, a data description file is required so the calibration tool understands how the application memory is laid out.

To support the interaction between the calibration tool and application, the interface tool can read a description of the application data and generate the data description file for the calibration tool. The application data is described in a set of data dictionary files explained in more detail in Section 8.1.5, “DDE specification” and the resulting data description file used by the calibration tool can also be used for reprogramming the ECU.

4.6.4. Application and library tasks

The framework of OpenECU requires application processing to occur in one or more tasks. These tasks are declared in the interface specification file, each declaring an application function to call and a priority to schedule the task relative to others.

In order to support the services provided by the library (e.g., J1939 messaging), the library defines a number of auxiliary tasks. These tasks have a unique priority relative to each other and the application tasks, as shown in Table 4.3, “Library and application tasks”.

Table 4.3. Library and application tasks

PriorityTaskTriggerTargetsDescription
20+nModule protection task10ms periodicM220, M221, M250, M460, M461 and M670Handles protection mechanisms to avoid ECU damage.
19+nTPU taskSporadicM220, M221, M250 and M670Handles the event processing required of the TPU peripheral on some ECUs.
18+nPower management task100ms periodicM221, and M670Handles the power hold processing on some ECUs.
17+nFlash code task100ms periodicM220, M221, M250, M460, M461 and M670Handles the Flash code output pin on some ECUs.
16+nHigh-Side ASIC task100ms periodicM670Handles the high side output pin(s) on some ECUs.
15+nSPI messaging taskSporadicM220, M221, M250, M460, M461 and M670Handles SPI messaging between peripherals on-board the ECU.
14+nCAN messaging (event) task2ms periodic burstAllHandles CAN messaging.
13+nJ1939 messaging task5ms periodicAllHandles J1939 messaging.
12+nPFF task10ms periodicAllHandles freeze frame processing.
11+nPFS task10ms periodicAllHandles non-volatile filesystem.
10+nPISO messaging task5ms periodicAllHandles ISO-15765 messaging.
9+nPDG messaging task10ms periodicAllHandles ISO-15765 based diagnostics messaging.
8+nApplication crank sync-point trigger taskSporadicM220, M221, M250 and M670Handles crank synchronous sync-point processing.
7+nApplication TDC-calculation taskAngularM220, M221, M250 and M670Handles engine synchronous TDC-calculation processing.
6..6+nApplication tasksAngularAllHandles application processing.
5PDTC task100msAllHandles diagnostic trouble code processing.
4CAN messaging task2ms periodic burstAllHandles CAN messaging.
3SPI task1000ms periodicM220, M221, M250, M460, M461 and M670Handles SPI messaging utility functions.
2Watchdog task200ms periodicAllHandles the processor watchdog.
1CCP task5ms periodicAllHandles the CAN Calibration Protocol messaging to and from the calibration tool.

Tasks can have different triggers. Triggers make the task become ready to run. The highest priority task ready to run is given the CPU.

Sporadic

The task becomes ready to run based on an event. The event is generally not periodic, but may be periodic under some conditions.

Angular

The task becomes ready to run based on the crank or engine position. See Chapter 6, Library interface — Engine for more about supported engine functionality.

Periodic

The task becomes ready to run on a periodic basis.

Periodic (burst)

The task becomes ready to run based on an event. Once ready, the task becomes periodic for a number of iterations, before stopping and waiting for another event.

Note

The scheduler deals with both application and library tasks. It is possible for a high priority application task to use the processor for as long as it needs and there is no protection offered by the library to prevent tasks from using up more processor time than they should.

The application tasks are scheduled to relative to the library tasks such that a long running task may cause a lower priority library task to become unduly delayed.

An example of this would be the CCP task which runs every 5ms. It is conceivable that an application task may take longer than 5ms to complete and that is a desirable property of the application. However, when the application task takes longer than 5ms, the CCP task becomes delayed by the application task.

The design of the library tries to mitigate the consequences of delayed library tasks. Delaying the library CCP task may cause a burst of DAQ messages to the calibration tool to become delayed and the calibration tool may complain, but delaying the CCP task will not cause the I/O functionality to become delayed or mis-behave.

However, mitigation is all that the library can achieve if the application uses large amounts of the processor, and, for this reason the design of the application must take this into account by keeping the application tasks short. For instance, by splitting long running tasks up into discrete parts which are scheduled on successive task invocations.

See the API documentation for the scheduler feature for more (Section 5.6, “Task scheduling (PKN)”).

4.6.5. Library status and error handling

As the application performs work, it may call the library to access the hardware or perform a function. Depending on the current state of the ECU or the data passed to the library function, the library may or may not be able to perform as required. The library employs two mechanisms to report status and error information when interacting with the application.

Function return values

In this case, the function returns an value which indicates the success or not of the call. The application can read the return value and made decisions based on the status of the function.

System feature

In this case, the function calls the system feature (see Section 5.2, “System feature (PSY)”) to record that an error has occurred. The system feature records these errors and makes them available to the application via psy_get_error()).

The error handling mechanisms are not mutually exclusive — a function may return a status value and raise an error in the system log. For each library function, the documentation in the sub-sections of Chapter 5, Library interface detail how a function handles errors.

Note

Error checking within the library is not comprehensive, based largely on a design decision to keep the library small and efficient. It is possible to setup or pass invalid data to the library and the library will not raise an error. This is especially true of pointer based function arguments or of build time data structures.

It is the responsibility of the application to interact with the library API correctly.

4.6.6. Compiler library support

The compiler library implements the C standard library as well as any additional functions and data the compiler may require. The OpenECU library relies on some of the standard C library functions and therefore the C library must be included in a build.

OpenECU does the least necessary to make the compiler library work for the functions OpenECU requires. Any additional setup, for instance, to allow memory allocation to work via malloc() and free(), must be performed by the application.

Note

Most compilers supply their implementation of the C standard library as a set of object files. See the compiler documentation for a list of library names.

4.6.7. Deprecated library features

To allow for change in the library, some API features can become marked as deprecated. API features become deprecated when newer features replace older features, or because a change in API naming makes the API more consistent. For instance, when the library is updated to automatically perform a function that the application was required to perform then that function will become marked as deprecated.

As well as being marked deprecated in the documentation, the library header files mark deprecated functions by wrapping them in pre-processor conditional statements. For instance, the API function pss_set_switch() was deprecated (replaced by function pss_set_safety_switch()) and declared in the library header files as:

#if !defined(CFG_DONT_USE_DEPRECATED)
/* Deprecated, see pss_set_safety_switch(). */
extern void pss_set_switch
(
    BOOL pssf_enable
);
#else
#define pss_set_switch(pssf_enable) pss_set_switch_is_deprecated_see_user_guide()
#endif

By defining the CFG_DONT_USE_DEPRECATED macro in the compile command, the compiler pre-processor will replace deprecated API functions with functions which do not exist in the library resulting in a build which does not link. For instance, using the example above, calling pss_set_switch() results in the Diab linker generating the following error:

dld: warning: Undefined symbol 'pss_set_switch_is_deprecated_see_user_guide'
              in file '[file-name].o'
dld: error: Undefined symbols found - no output written

4.6.8. Examples

As part of the install process, a number of examples which use the library are installed, ready to be built.

[install location]\examples\c_api\angular_demo

Demonstrates how to use the angular feature for engine control described in Chapter 6, Library interface — Engine , including crank and cam trigger wheel configuration, angle based task triggering, and injection and coil pulse generation.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\can_demo

Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify CAN buses and baud rates when calling the library.

Demonstrates how to use the CAN feature described in Section 5.15, “CAN messaging feature (PCX)” to receive and transmit CAN messages, unpack and pack data into messages, and monitor the CAN bus status.

Demonstrates how to use the J1939 feature described in Section 5.17, “J1939 (SAE) messaging feature (PJ1939)” to receive and transmit J1939 messages, unpack and pack data into messages and manipulate diagnostic trouble codes (DTCs).

See the example's read-me.txt file for further details.

[install location]\examples\c_api\hbridge_demo

Demonstrates how to drive the hbridge outputs by using the digital input/output feature described in Section 5.10, “Digital input/output feature (PDX)”.

Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify input and output channels when calling the library.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\io_demo

Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify input and output channels when calling the library.

Demonstrates how to use the analogue input/output feature described in Section 5.9, “Analogue input/output feature (PAX)” to read and process analogue inputs.

Demonstrates how to use the digital input/output feature described in Section 5.10, “Digital input/output feature (PDX)” to read and drive various signal types.

Demonstrates how to use the safety switch feature described in Section 5.12, “Output driver control feature (PSS)” to control whether the output drivers are enabled or not.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\nvm_util_demo

Demonstrates how to use the non-volatile memory feature described in Section 5.19, “Adaptive non-volatile memory feature (PNV)” to store and recall information from non-volatile memory, such as array updates and adaptive table lookup and interpolations.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\step1_completed

Demonstrates a simple application which reads an analogue input and if it is above a calibratable threshold, turns on a digital output. This is the completed application from Chapter 3, Quick start.

[install location]\examples\c_api\step1_quick_start

A copy of the step1 completed example, used in Chapter 3, Quick start to familiarise new users with the C-API.

[install location]\examples\c_api\util_demo

Demonstrates how to use the utility feature described in Section 5.22, “General utilities feature (PUT)” perform auxiliary functions, such as table lookup with interpolation and digital input debounce.

See the example's read-me.txt file for further details.

Each example has the same directory layout. The directories store different types of files and includes a simple batch file to build the example.

build\*

Contains a simple batch file for each supported compiler on a given target. See Section 4.6.8.1, “Building the examples” for further details.

interface_specification\*

Contains the interface specification and DDEs for the application. The interface specification is processed by the build batch files as described in Section 4.6.1, “Building an application”.

loom_specification\*

Contains a bitmap diagram showing how a target ECU should be connected to power, the calibration tool and any other additional equipment for the example to work.

src\*

Contains the source files for the application. The source files processed by the build batch files as described in Section 4.6.1, “Building an application”.

4.6.8.1. Building the examples

Each of the examples comes with a batch file which builds the example for a given compiler and target ECU. The batch files are kept as simple as possible to help understand the sequence of commands which goes into building an application.

To build an example using the GCC compiler, no edits are required in the batch file in order to run.

To build an example using the Diab compiler, locate and edit the appropriate batch file (based on Diab compiler and target ECU required). Check the following environment variable at the start of the batch file points to your compiler version, change the path if necessary, then run the batch file from the command line.

OPENECU_DIAB

The path to the Diab compiler tool as stored on the build machine, e.g., [diab install location]\diab\5.5.1.0\win32\bin\. The environment variable must end with a directory slash.

The environment variable can be a path to the Diab compiler or a reference to another environment variable, e.g., %OPENECU_DIAB_5_8%. See section Section 2.5.9, “Wind River (Diab) C Compiler v5.8.0.0” for a description of the OPENECU_DIAB_5_8 environment variable.

For instance, to build the step1 completed example for an M220 ECU using Diab 5.5.1.0, at the command prompt, issue the following commands:

cd [install location]\examples\c_api

cd step1_completed\build

build_m220_diab_5_5_1_0.bat

Chapter 5. Library interface

5.1. Introduction
5.1.1. Name-spaces, naming conventions and library composition
5.1.2. File locations
5.1.3. Layout of each feature section
5.1.4. Notations
5.2. System feature (PSY)
5.2.1. Overview
5.2.2. System types
5.2.3. Error log
5.2.4. Interface index
5.2.5. Interface detail
5.3. System start-up and background processing (PSC)
5.3.1. Overview
5.3.2. Interface index
5.3.3. Interface detail
5.4. ECU registry information (PREG)
5.4.1. Overview
5.4.2. Interface index
5.4.3. Interface detail
5.5. System timing feature (PTM)
5.5.1. Overview
5.5.2. Interface index
5.5.3. Interface detail
5.6. Task scheduling (PKN)
5.6.1. Tasking model
5.6.2. Interface index
5.6.3. Interface detail
5.7. Library input and output configuration (PIO)
5.7.1. Overview
5.8. Feature for specific target configuration (PCFG)
5.8.1. Overview
5.8.2. M110, M220 and M461 targets
5.8.3. M250 target
5.8.4. M460 target
5.8.5. M670 target
5.8.6. Interface index
5.8.7. Interface detail
5.9. Analogue input/output feature (PAX)
5.9.1. Overview
5.9.2. Interface index
5.9.3. Interface detail
5.10. Digital input/output feature (PDX)
5.10.1. Overview
5.10.2. Interface index
5.10.3. Interface detail
5.11. Digital data feature (PDD)
5.11.1. Overview
5.11.2. Interface index
5.11.3. Interface detail
5.12. Output driver control feature (PSS)
5.12.1. Overview
5.12.2. M220 target
5.12.3. M250 target
5.12.4. M460 target
5.12.5. M461 target
5.12.6. M670 target
5.12.7. Interface index
5.12.8. Interface detail
5.13. Serial peripheral feature (PSP)
5.13.1. Overview
5.13.2. Input and output processing
5.13.3. Interface index
5.13.4. Interface detail
5.14. CJ125 device driver for UEGO measurement feature (PCJ125)
5.14.1. Overview
5.14.2. Initialisation
5.14.3. Diagnostics
5.14.4. Interface index
5.14.5. Interface detail
5.15. CAN messaging feature (PCX)
5.15.1. Overview
5.15.2. Initialisation
5.15.3. Receiving messages
5.15.4. Transmitting messages
5.15.5. CAN status
5.15.6. CAN buses
5.15.7. Build time buffer sizing
5.15.8. Library tasks
5.15.9. Interface index
5.15.10. Interface detail
5.16. CAN Calibration Protocol (CCP) messaging feature (PCP)
5.16.1. Overview
5.16.2. Interface index
5.16.3. Interface detail
5.17. J1939 (SAE) messaging feature (PJ1939)
5.17.1. Overview
5.17.2. Node addressing
5.17.3. Messaging
5.17.4. Message bit and byte numbering
5.17.5. PGNs
5.17.6. Receive messages
5.17.7. Transmit messages
5.17.8. Core Diagnostic messages
5.17.9. Build time buffer sizing
5.17.10. Library tasks
5.17.11. Interface index
5.17.12. Interface detail
5.18. Diagnostic Trouble Code (DTC) feature (PDTC)
5.18.1. Overview
5.18.2. Diagnostic trouble codes — generic
5.18.3. Diagnostic trouble codes — J1939
5.18.4. Storage of data across power cycles
5.18.5. Build time buffer sizing
5.18.6. Interface index
5.18.7. Interface detail
5.19. Adaptive non-volatile memory feature (PNV)
5.19.1. Overview
5.19.2. Storage of data across power cycles
5.19.3. Interface index
5.19.4. Interface detail
5.20. Non-volatile Filesystem feature (PFS)
5.20.1. Overview
5.20.2. Interface index
5.20.3. Interface detail
5.21. On-board external flash (PEF)
5.21.1. Overview
5.21.2. Interface index
5.21.3. Interface detail
5.22. General utilities feature (PUT)
5.22.1. Overview
5.22.2. Interface index
5.22.3. Interface detail

5.1. Introduction

5.1.1. Name-spaces, naming conventions and library composition

Based on the C language, there are a limited number of global name-spaces for identifiers. To avoid clashes with application identifiers which share the same global name-spaces, the library uses a standard naming convention (covered in detail in Section 8.1.5.2, “DDE naming rules (prefix_style)”).

In short, the library uses a 3, 4 or 5 character prefix for all function and data identifiers. Each prefix identifies an area of functionality that the library covers, e.g., PDX for digital I/O or PJ1939 for J1939 messaging. This prefix scheme is similar to the DDE naming scheme covered in Section 8.1.5.2, “DDE naming rules (prefix_style)”.

The current composition of functionality is broken down into a set of features, each with a unique prefix, as shown in Table 5.1, “Library composition”.

Table 5.1. Library composition

PrefixDescription
Public
PSY System feature — definition of integer types and system error logging.
PSC System start-up and background processing — handles hardware and library pre and post initialisation, starting application run and implementing the background processing function.
PREG ECU registry information — handles retrieval of data specific to the ECU, such as date of manufacturing or the serial number.
PTM System timing — provides access to second, millisecond and microsecond timers.
PKN Task scheduling — schedules library and application tasks in a fixed pre-emptive fashion.
PIO Library input and output configuration — provides macros for logical channels for each type of input and output, macros for supported CAN buses and baud rates, and so on.
PCFG ECU specific configuration — provides functions specific to some ECUs for utilising functionality not available on other ECUs.
PAX Analogue input and output — provides access to analogue based input and output signals (e.g., analogue inputs and constant current outputs).
PDX Digital input and output — provides access to digital based input and output signals (e.g., frequency inputs and stepper motor outputs).
PDD Digital data — provides access to digital data based signals
PAN Angular input and output — provides access to crank, cam, ignition and injector functionality.
PSS Output driver control and diagnostics — provides access to the overall output driver switch.
PCX CAN messaging — provides access to receive and transmit CAN messages on a periodic basis, and some utility functions to pack and unpack data in messages.
PCP CAN calibration protocol messaging — provides basic access to the underlying CCP implementation for interaction with reprogramming and calibration tools.
PJ1939 SAE J1939 messaging — provides access to receive and transmit J1939 messages on a periodic basis, handling the transport protocol and address claim negotiations.
PDTC Diagnostic trouble codes — handles a simplistic model of diagnostic trouble codes for J1939 messaging.
PPR In-Use Performance Ratio (IUPR) calculation — Tracks IUPR and other related information for Diagnostic Test Entities (DTEs)belonging to Diagnostic Monitor Entities (DMEs) and makes them available to report over ISO and J1939 protocols.
PNV Non-volatile and adaptive memory — handles storage of data parameters across power cycles and provides some utility functions for adaptive data and maps.
PFS Non-volatile filesystem — handles underlying storage of both library and application-specific data in flash memory on supported targets.
PEF External flash — handles access to serial flash fitted to some ECUs.
PCJ125 CJ125 lambda sensor ASIC — handles access to this device on some ECUs.
PNTK NTK lambda sensor ASIC — handles access to this device on some ECUs.
PUT General utilities — provides a set of functions for performing some typical functions on an ECU, e.g., table look-up and interpolation.
Private
Numerous other features are used by the library internally and are not exposed through the C-API.

5.1.2. File locations

The library is provided as a set of C include files and a library object file to be linked with the final application. There is a library object for each target and each compiler supported for that target. These files are located relative to the install location of OpenECU.

[install location]\targets\[ecu]\[ecu]_[option]\[processor]_lib\include\*.h

Location of library include files.

[install location]\targets\[ecu]\[ecu]_[option]\[processor]_lib\*.a

Location of library object files, one for each supported compiler.

where: [install location] refers to the install location of OpenECU; [ecu] refers to the target ECU for the application; [option] refers to the specific ECU option for the application; and [processor] refers to the ECU's target processor (some ECUs have more than one processor populated).

For instance, when building for a M250 target ECU using Diab v5.5.1.0, the library header files and library object file are located at:

[install location]\targets\m250\m250_000\mpc5534_lib\include\*.h
[install location]\targets\m250\m250_000\mpc5534_lib\platform_diab_5_5_1_0.a

When compiling with GCC specifically, the libary object files will not follow the same naming convention mentioned above. Since GCC does not support non-VLE code, the platform is rebuilt, using Diab v5.9 but using non-VLE compiler options. Therefore the library object files are not named using the GCC compiler, but rather with the Diab Compiler (with no_vle specified). The library header files and library object files are located at:

[install location]\targets\m250\m250_000\mpc5534_lib\include\*.h
[install location]\targets\m250\m250_000\mpc5534_lib\platform_no_vle_diab_5_5_1_0.a

5.1.3. Layout of each feature section

Each feature is detailed in a separate section from other features. Each feature section is broken down as follows:

Overview section

The overview section explains the feature functionality with enough detail to understand what the feature can achieve and how to interface with it at the function level.

Feature index section

The feature index section provides a table of macros, enums, structs, typedefs, variables and functions exposed by the feature, along with a summary of the object's description. Each object is linked to the object's detail given in the feature detail section.

Feature detail section

The feature detail section provides a series of sub-sections, one for each of macros, types, variables and functions. Each sub-section describes the object is detail, linking to related objects as necessary.

The C object names (for macros, typedefs, variables and so on) are fully linked, allowing for quick browsing.

5.1.4. Notations

5.1.4.1. Range notation

Some function parameters and variables have a valid numerical range or size of array. If so, the range and size information is given beside the object's description using internal notation.

Table 5.2. Interval notation

NotationRange
(x, y)x < value < y
[x, y)x <= value < y
(x, y]x < value <= y
[x, y]x <= value <= y

Some objects are not clipped to a range but folded into a range using modulo arithmetic and where this occurs, the description includes details.

5.1.4.2. Fixed point notation

Some function parameters and variables are represented using fixed point numbers rather than floating point numbers. A fixed point number has a fixed number of digits after the radix point (e.g., after the decimal point '.' in floating point decimal notation) in a given base.

Fixed point numbers are expressed as @ fraction units per LSB in the documentation. For instance, the notation @ 0.5 °C per LSB means the least significant bit of the fixed point number represents 0.5 °C. Hence, the value 1 represents 0.5 °C, value 2 represents 1 °C, value 3 represent 1.5 °C and so on.

5.2. System feature (PSY)

5.2.1. Overview

The system feature (PSY) provides the base set of types for the library and a simple logging mechanism for recording conditions that the library believes to be in error.

5.2.2. System types

The library types (BOOL, S8, U8, S16, U16, S32, U32, U64, F32, F64) are to be used when interfacing with the library. Whether that be parameter types, return types, or member types of structures. Each represents an integer or floating point type of a minimum bit width (but the actual underlying type may implement a larger bit width).

The library also defines the NULL, pointer, as well as the TRUE, and FALSE booleans as macros, if those macros have not already been defined.

5.2.3. Error log

As described in Section 4.6.5, “Library status and error handling”, the library records some errors in a log. The system feature gives access to the log for debugging purposes. The log consists of a fixed size array, where each element stores a reference to the feature which raised the error and a code for the error. Once the log is full, further errors raised by the library are discarded.

The feature reference matches one of the feature macros (e.g., PSY_PAX for the analogue input/output feature). The code for an error matches one of the corresponding feature's Pxxx_ERROR_CODE_T enumeration (e.g., PAX_ERROR_CODE_T).

The application can access elements of the log through the psy_get_error() function. The number of reported errors can be determined by calling psy_get_num_errors().

5.2.4. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and psy.h
Macros
 PSY_MAX_NUM_STORED_ERRORS

The maximum number of different errors that are simultaneously stored.

 PSY_PBT

This is the error log identifier for the PBT (boot) feature.

 PSY_PSY

This is the error log identifier for the PSY (system) feature.

 PSY_PTPU

This is the error log identifier for the PTPU (TPU or eTPU) feature.

 PSY_PSC

This is the error log identifier for the PSC (startup and idle) feature.

 PSY_PAX

This is the error log identifier for the PAX (analogue I/O) feature.

 PSY_PCX

This is the error log identifier for the PCX (CAN messaging) feature.

 PSY_PDX

This is the error log identifier for the PDX (digital I/O) feature.

 PSY_PUT

This is the error log identifier for the PUT (general utility) feature.

 PSY_PSP

This is the error log identifier for the PSP (SPI messaging) feature.

 PSY_PNV

This is the error log identifier for the PNV (adaptive non-volatile) feature.

 PSY_PRS

This is the error log identifier for the PRS (RS232) feature.

 PSY_PCP

This is the error log identifier for the PCP (CCP scheduling) feature.

 PSY_PKN

This is the error log identifier for the PKN (scheduler) feature.

 PSY_PMIOS

This is the error log identifier for the PMIOS (MIOS or eMIOS) feature.

 PSY_PFL

This is the error log identifier for the PFL (Flash memory) feature.

 PSY_PCCP

This is the error log identifier for the PCCP (CCP messaging) feature.

 PSY_PQADC

This is the error log identifier for the PQADC (QADC or eQADC) feature.

 PSY_PDTC

This is the error log identifier for the PDTC (diagnostic trouble code) feature.

 PSY_PJ1939

This is the error log identifier for the PJ1939 (SAE J1939 messaging) feature.

 PSY_PSPI

This is the error log identifier for the PSPI (SPI messaging) feature.

 PSY_PDG

This is the error log identifier for the PDG (ISO diagnostics) feature.

 PSY_PFF

This is the error log identifier for the PFF (freeze frame) feature.

 PSY_PEM

This is the error log identifier for the PEM (emulutor and memory) feature.

 PSY_PFS

This is the error log identifier for the PFS (filesystem) feature.

 PSY_PROP

This is the error log identifier for the waveform properties (PROP) feature.

 PSY_PDD

This is the error log identifier for the PDD (digital data) feature.

 PSY_PAN

This is the error log identifier for the PAN (angular) feature.

 PSY_PPP

This is the error log identifier for the PPP (Tunes) feature.

 PSY_PPM

This is the error log identifier for the PPM (power management) feature.

 PSY_PSS

This is the error log identifier for the PSS (system safety) feature.

 PSY_PFC

This is the error log identifier for the PFC (flash code) feature.

 PSY_PXS

This is the error log identifier for the PXS (extreme switch) feature.

 PSY_PDC

This is the error log identifier for the PDC (daughter card) feature.

 PSY_PISO

This is the error log identifier for the PISO (ISO 15765) feature.

 PSY_APP

This is the error log identifier for the application.

 NULL

Ensure the NULL pointer is defined (if it is not already)

 FALSE

Ensure FALSE is defined (if it is not already)

 TRUE

Ensure TRUE is defined (if it is not already)

Data types
 PSY_ERROR_LOG_T

The type for an error log.

 S8

This typedef declares a signed 8 bit integer.

 U8

This typedef declares an unsigned 8 bit integer.

 BOOL

This typedef declares a boolean integer.

 S16

This typedef declares a signed 16 bit integer.

 U16

This typedef declares an unsigned 16 bit integer.

 S32

This typedef declares a signed 32 bit integer.

 U32

This typedef declares an unsigned 32 bit integer.

 S64

This typedef declares a signed 64 bit integer.

 U64

This typedef declares an unsigned 64 bit integer.

 INT

This typedef declares a signed 32 bit integer.

 UINT

This typedef declares an unsigned 32 bit integer.

 F32

This typedef declares a 32 bit floating point.

 FREAL

This typedef declares a 32 bit floating point.

 F64

This typedef declares a 64 bit floating point.

Functions
U8psy_get_num_errors

Returns the number of errors detected by the platform software.

BOOLpsy_get_error

Gets the information related to an error.

5.2.5. Interface detail

5.2.5.1.  Macros

5.2.5.1.1. PSY_MAX_NUM_STORED_ERRORS
Definition:

#define PSY_MAX_NUM_STORED_ERRORS 16

Description:

The maximum number of different errors that are simultaneously stored.

The errors can be accessed by calling psy_get_error().

5.2.5.1.2. PSY_PBT
Definition:

#define PSY_PBT (U8)1

Description:

This is the error log identifier for the PBT (boot) feature.

5.2.5.1.3. PSY_PSY
Definition:

#define PSY_PSY (U8)2

Description:

This is the error log identifier for the PSY (system) feature.

5.2.5.1.4. PSY_PTPU
Definition:

#define PSY_PTPU (U8)3

Description:

This is the error log identifier for the PTPU (TPU or eTPU) feature.

5.2.5.1.5. PSY_PSC
Definition:

#define PSY_PSC (U8)4

Description:

This is the error log identifier for the PSC (startup and idle) feature.

5.2.5.1.6. PSY_PAX
Definition:

#define PSY_PAX (U8)5

Description:

This is the error log identifier for the PAX (analogue I/O) feature.

5.2.5.1.7. PSY_PCX
Definition:

#define PSY_PCX (U8)6

Description:

This is the error log identifier for the PCX (CAN messaging) feature.

5.2.5.1.8. PSY_PDX
Definition:

#define PSY_PDX (U8)8

Description:

This is the error log identifier for the PDX (digital I/O) feature.

5.2.5.1.9. PSY_PUT
Definition:

#define PSY_PUT (U8)9

Description:

This is the error log identifier for the PUT (general utility) feature.

5.2.5.1.10. PSY_PSP
Definition:

#define PSY_PSP (U8)10

Description:

This is the error log identifier for the PSP (SPI messaging) feature.

5.2.5.1.11. PSY_PNV
Definition:

#define PSY_PNV (U8)11

Description:

This is the error log identifier for the PNV (adaptive non-volatile) feature.

5.2.5.1.12. PSY_PRS
Definition:

#define PSY_PRS (U8)12

Description:

This is the error log identifier for the PRS (RS232) feature.

5.2.5.1.13. PSY_PCP
Definition:

#define PSY_PCP (U8)13

Description:

This is the error log identifier for the PCP (CCP scheduling) feature.

5.2.5.1.14. PSY_PKN
Definition:

#define PSY_PKN (U8)14

Description:

This is the error log identifier for the PKN (scheduler) feature.

5.2.5.1.15. PSY_PMIOS
Definition:

#define PSY_PMIOS (U8)15

Description:

This is the error log identifier for the PMIOS (MIOS or eMIOS) feature.

5.2.5.1.16. PSY_PFL
Definition:

#define PSY_PFL (U8)16

Description:

This is the error log identifier for the PFL (Flash memory) feature.

5.2.5.1.17. PSY_PCCP
Definition:

#define PSY_PCCP (U8)17

Description:

This is the error log identifier for the PCCP (CCP messaging) feature.

5.2.5.1.18. PSY_PQADC
Definition:

#define PSY_PQADC (U8)18

Description:

This is the error log identifier for the PQADC (QADC or eQADC) feature.

5.2.5.1.19. PSY_PDTC
Definition:

#define PSY_PDTC (U8)19

Description:

This is the error log identifier for the PDTC (diagnostic trouble code) feature.

5.2.5.1.20. PSY_PJ1939
Definition:

#define PSY_PJ1939 (U8)20

Description:

This is the error log identifier for the PJ1939 (SAE J1939 messaging) feature.

5.2.5.1.21. PSY_PSPI
Definition:

#define PSY_PSPI (U8)21

Description:

This is the error log identifier for the PSPI (SPI messaging) feature.

5.2.5.1.22. PSY_PDG
Definition:

#define PSY_PDG (U8)22

Description:

This is the error log identifier for the PDG (ISO diagnostics) feature.

5.2.5.1.23. PSY_PFF
Definition:

#define PSY_PFF (U8)23

Description:

This is the error log identifier for the PFF (freeze frame) feature.

5.2.5.1.24. PSY_PEM
Definition:

#define PSY_PEM (U8)24

Description:

This is the error log identifier for the PEM (emulutor and memory) feature.

5.2.5.1.25. PSY_PFS
Definition:

#define PSY_PFS (U8)25

Description:

This is the error log identifier for the PFS (filesystem) feature.

5.2.5.1.26. PSY_PROP
Definition:

#define PSY_PROP (U8)26

Description:

This is the error log identifier for the waveform properties (PROP) feature.

5.2.5.1.27. PSY_PDD
Definition:

#define PSY_PDD (U8)27

Description:

This is the error log identifier for the PDD (digital data) feature.

5.2.5.1.28. PSY_PAN
Definition:

#define PSY_PAN (U8)28

Description:

This is the error log identifier for the PAN (angular) feature.

5.2.5.1.29. PSY_PPP
Definition:

#define PSY_PPP (U8)29

Description:

This is the error log identifier for the PPP (Tunes) feature.

5.2.5.1.30. PSY_PPM
Definition:

#define PSY_PPM (U8)30

Description:

This is the error log identifier for the PPM (power management) feature.

5.2.5.1.31. PSY_PSS
Definition:

#define PSY_PSS (U8)31

Description:

This is the error log identifier for the PSS (system safety) feature.

5.2.5.1.32. PSY_PFC
Definition:

#define PSY_PFC (U8)32

Description:

This is the error log identifier for the PFC (flash code) feature.

5.2.5.1.33. PSY_PXS
Definition:

#define PSY_PXS (U8)33

Description:

This is the error log identifier for the PXS (extreme switch) feature.

5.2.5.1.34. PSY_PDC
Definition:

#define PSY_PDC (U8)34

Description:

This is the error log identifier for the PDC (daughter card) feature.

5.2.5.1.35. PSY_PISO
Definition:

#define PSY_PISO (U8)35

Description:

This is the error log identifier for the PISO (ISO 15765) feature.

5.2.5.1.36. PSY_APP
Definition:

#define PSY_APP (U8)36

Description:

This is the error log identifier for the application.

5.2.5.1.37. NULL
Definition:

#define NULL ((void *) 0)

Description:

Ensure the NULL pointer is defined (if it is not already)

5.2.5.1.38. FALSE
Definition:

#define FALSE ((BOOL)0)

Description:

Ensure FALSE is defined (if it is not already)

5.2.5.1.39. TRUE
Definition:

#define TRUE ((BOOL)1)

Description:

Ensure TRUE is defined (if it is not already)

5.2.5.2.  Data types

5.2.5.2.1. PSY_ERROR_LOG_T
Summary:

The type for an error log.

Members:
U8 PSY_ERROR_LOG_T::feature_id

This is the feature identifier for the declared error (e.g., PSY_PFL).


Range: [0, 255] unitless

U16 PSY_ERROR_LOG_T::error_id

This is the identifier for the declared error.


Range: [0, 65535]

Description:

The type for an error log.

This type declares a structure containing information relating to a system error (detected by the platform software).

5.2.5.2.2. S8
Definition:

typedef signed char S8

Description:

This typedef declares a signed 8 bit integer.

5.2.5.2.3. U8
Definition:

typedef unsigned char U8

Description:

This typedef declares an unsigned 8 bit integer.

5.2.5.2.4. BOOL
Definition:

typedef unsigned char BOOL

Description:

This typedef declares a boolean integer.

5.2.5.2.5. S16
Definition:

typedef signed short S16

Description:

This typedef declares a signed 16 bit integer.

5.2.5.2.6. U16
Definition:

typedef unsigned short U16

Description:

This typedef declares an unsigned 16 bit integer.

5.2.5.2.7. S32
Definition:

typedef signed long S32

Description:

This typedef declares a signed 32 bit integer.

5.2.5.2.8. U32
Definition:

typedef unsigned long U32

Description:

This typedef declares an unsigned 32 bit integer.

5.2.5.2.9. S64
Definition:

typedef signed long long S64

Description:

This typedef declares a signed 64 bit integer.

5.2.5.2.10. U64
Definition:

typedef unsigned long long U64

Description:

This typedef declares an unsigned 64 bit integer.

5.2.5.2.11. INT
Definition:

typedef int INT

Description:

This typedef declares a signed 32 bit integer.

5.2.5.2.12. UINT
Definition:

typedef unsigned long UINT

Description:

This typedef declares an unsigned 32 bit integer.

5.2.5.2.13. F32
Definition:

typedef float F32

Description:

This typedef declares a 32 bit floating point.

5.2.5.2.14. FREAL
Definition:

typedef float FREAL

Description:

This typedef declares a 32 bit floating point.

5.2.5.2.15. F64
Definition:

typedef double F64

Description:

This typedef declares a 64 bit floating point.

5.2.5.3.  Functions

5.2.5.3.1. psy_get_num_errors()
Definition:

U8 psy_get_num_errors(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Returns the number of errors detected by the platform software.

Note

System errors are stored in RAM and are recovered across a reset if possible.

Return:

Number of declared errors.
Range: [0, PSY_MAX_NUM_STORED_ERRORS] errors

5.2.5.3.2. psy_get_error()
Definition:

BOOL psy_get_error(
   U8                psyf_error_index,
   PSY_ERROR_LOG_T  *psyf_log);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Gets the information related to an error.

Note

System errors are stored in RAM and are recovered across a reset if possible.

Arg (data in): psyf_error_index

The index into the error log to retrieve error information from.
Range: [0, PSY_MAX_NUM_STORED_ERRORS - 1] unitless

Arg (data out): psyf_log

Pointer to store for error information.
Cannot be NULL.

Return:

True if the error information could be retrieved, false otherwise.

5.3. System start-up and background processing (PSC)

5.3.1. Overview

5.3.1.1. System initialisation

The feature handles the C run-time environment, library and application initialisation. See Section 4.6, “Application mode” for further details. The application must define the psc_initialise_app() function which is called between pre and post initialisation.

5.3.1.2. System background processing

Once initialisation is complete, application run starts. This involves starting the scheduler, which in turn causes library and application tasks to run; and involves calling the background processing functions. Background processing occurs when no other task is running or is ready to run (i.e., when the CPU would otherwise be idle).

The library will call the applications background processing function (psc_background_app()) when it can. The library makes no guarantees that the application background processing function is called, only that if there is CPU idle time when tasks are not running, then an attempt to call the application background processing will eventually be made.

The platform itself performs various operations in the background including checks on RAM hardware. If a RAM error is detected, an unrecoverable error is raised (resulting in ECU reset) because program execution is otherwise likely to fail in an unpredictable manner.

Similarly non-volatile data is revalidated in the background and treated as if it is no longer available if validation fails. Thus if run-time memory corruption occurs affecting non-volatile data, any subsequent attempt to read that data will be handled in the same way as if the data were not present (default used instead).

Background checking for code or calibration corruption works through the Calibration Verification Number computation on supported targets with the OBD library option. Ensure that the CVN is recomputed continually if run-time corruption checking is required. If it is detected, an unrecoverable error is raised (resulting in ECU reset). This is in addition to boot-time checksum validation.

5.3.1.3. System reset

A controlled system reset occurs when the ECU is turned on, or when the ECU software invokes a reset. A reset causes the bootloader to determine which major system mode to enter (see Section 4.3, “System modes” for more).

The reason for a reset can be determined during application run by calling psc_decode_reset(), which also provides a rough guide to the duration between reset and the start of application run.

5.3.1.4. System up-time (run-time)

The feature maintains a second timer, called the run-timer or up-timer. The current value of the run-timer is returned by calling psc_get_run_time(). It is cleared to zero during library pre-initialisation and incremented every second during application run. The run timer can be used as an indication of how long the system has been running in application mode without a reset.

5.3.1.5. System loading

The feature maintains an estimate of the CPU utilisation. The current CPU loading is returned by calling psc_get_cpu_loading(). The CPU load is calculated every 50 milliseconds during background processing (or longer if any set of tasks cause the background processing to be delayed). The CPU loading is essentially the time used by running tasks over the 50ms period, expressed as a percentage.

The feature also records the highest estimate of CPU utilisation. The highest recorded CPU loading is returned by calling psc_get_max_cpu_loading().

For some target ECUs, this feature maintains an estimate of the eTPU utilisation (the eTPU is used for simple and complex I/O operations, such as crank wheel decoding). As with the CPU, the eTPU loading is calculated every 50 milliseconds during background processing (or longer if any set of tasks cause the background processing to be delayed). Call psc_get_etpu_loading() or psc_get_max_etpu_loading() to retrieve the latest eTPU loading, and maximum eTPU loading seen since reset.

5.3.1.6. System stack

The system stack is configured during library pre-initialisation. The system stack is shared between background processing, library and application tasks (see Section 5.6.1.3, “Stack sharing” for more detail on how the stack is shared).

During pre-initialisation, the memory area allocated to the system stack is filled with a pre-determined set of bit patterns. As the stack becomes used, these bit patterns are over-written, and the library determines the amount of used stack by scanning through the memory area to find the point where the bit patterns have been overwritten. This scanning is performed as background processing, and the last calculated system stack use is returned from calling psc_get_used_stack_size().

Note

On supported ECUs, an overflow of the system stack is trapped by this feature. Rather than allow a stack overflow to overwrite valid system variables, resulting in possibly undefined or unexpected behaviour, this feature traps the error, records the issue and resets the ECU.

5.3.1.7. System watchdog handling

The library provides for a simple system which kicks the ECU watchdog periodically. If the watchdog task is starved of CPU time, the ECU watchdog will eventually trigger causing a reset.

Target ECUWatchdog durationMaximum kick period
M110, M220, M221,
M250, M460, M461
[~419, ~838] milliseconds [a] 200 milliseconds
M670 [~508, ~1016] milliseconds [a] 200 milliseconds

[a] The range reflects the configuration of the processor's watchdog, which uses two time out periods before resetting the processor.

The library automatically kicks the watchdog at the maximum period for the target ECU. But the application may take control of the watchdog by using the watchdog statement (see Section 8.1.4.9, “Compound statement: os-native”) and calling psc_kick_watchdog() as necessary whilst the application runs.

5.3.1.8. System identification

The feature provides a number of variables which can identify the application. The variables contain version numbers, build dates and part numbers. Part numbers are provided for the bootloader components and the library. These variables are added to the ASAP2 file (Target ASAP2 file) which provides for inspection of the application identification while the ECU is running in application mode using a calibration tool (see Section 8.1.7, “Automatic ASAP2 entries” for more).

The application can retreive the bootloader components and the library version numbers, build dates and part numbers by invoking the following functions: psc_get_boot_version(), psc_get_boot_build_date(), psc_get_boot_part_number(), psc_get_prg_version(), psc_get_prg_build_date(), psc_get_prg_part_number(), psc_get_platform_version(), psc_get_platform_build_date(), psc_get_platform_part_number(). There is also a set of functions that can be used to dynamically retrieve the application version and build date: psc_get_application_version() and psc_get_application_build_date().

5.3.1.9. Library header

The library contains a 1KB header. The header contains information about the processor initialisation, library entry point and various other data, but also contains a check-sum. The check-sum is tested by the bootloader when choosing the system mode to enter (see Section 4.3, “System modes”). The check-sum is set when the application is built — see the batch files for each example to see how this is achieved (see Section 4.6.8, “Examples”).

5.3.1.10. Memory tests

Each ECU implements an internal memory test during startup to check for hard memory faults. Hard memory faults are memory faults that have become permanent such as a shorted address line, or a memory cell that cannot change state. RAM is tested by performing a destructive walking one's test on the address and data lines and a memory recall test on the memory cells. ROM is tested by calculating a checksum of the contents. If a hard memory fault is detected, then the ECU will reset itself to force safety related outputs to a default state.

Some ECUs also implement a continuous internal memory test during runtime to check for soft memory faults. Soft memory faults are transient memory faults, such as might occur when a memory cell changes state due to stray electron releases. The error correction module hardware is capable of detecting and correcting errors that are limited to a single bit wrong in a 64-bit double word. If more than one bit is wrong in a 64-bit double word, then the hardware can detect the error, but it cannot be corrected. If an uncorrectable soft memory fault is detected, then the ECU will reset itself to force safety related outputs to a default state.

The application can retrieve the status of the continuous internal memory soft error test as well as the address of the last detected correctable error by invoking the following functions:

5.3.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and psc.h
Enumerations
 PSC_ERROR_CODE_T

Error values for debugging when an error is found by the system start and idle feature (PSC), the feature calls a system error log function with an enumeration from this type.

 PSC_RC_T

An enumerated type which contains success and failure codes returned by some system start and idle feature (PSC) functions.

Variables
const U8psc_watchdog_task_enabled

This determines whether the watchdog task is active or not.

const BOOLpsc_mem_runtime_checks_enabled

This determines whether run-time background memory checks are active or not.

const U16psc_app_major_ver_num

This is the major version number of the application.

const U16psc_app_minor_ver_num

This is the minor version number of the application.

const U16psc_app_sub_minor_ver_num

This is the subminor version number of the application.

const U8psc_app_name

This is the name of the application.

const U8psc_app_desc

This is a description of the application.

const U8psc_app_copyright

This is a copyright notice for the application.

const PHDR_HEADER_Tpsc_platform_header

The application data header which contains details of CPU initialisation, CCP settings, application version info, etc.

Functions
voidpsc_initialise_app

This function is invoked from the library between pre-initialisation and post-initialisation.

voidpsc_background_app

This function is invoked by the library when no tasks are running.

U8psc_get_cpu_loading

Return the last calculated CPU loading.

U8psc_get_max_cpu_loading

Return the maximum CPU loading recorded since reset.

PSC_RC_Tpsc_decode_reset

Determine the reason for the last reset and the duration from reset to the start of the application code.

voidpsc_store_suicide_note

Store data across a reset.

U32psc_get_suicide_note

Recover data stored across a reset.

U32psc_get_reset_count

Return the reset count.

U32psc_get_unstable_reset_count

Return the reset count.

PSC_RC_Tpsc_get_etpu_loading

Return the last calculated eTPU loading for an eTPU device.

PSC_RC_Tpsc_get_max_etpu_loading

Return the maximum eTPU loading recorded since reset for an eTPU device.

PSC_RC_Tpsc_get_hw_version

Return the hardware version information.

PSC_RC_Tpsc_get_boot_version

Return the boot code version information.

PSC_RC_Tpsc_get_boot_build_date

Return the boot code build date information.

PSC_RC_Tpsc_get_boot_part_number

Return the boot code part number information.

PSC_RC_Tpsc_get_prg_version

Return the reprogramming code version information.

PSC_RC_Tpsc_get_prg_build_date

Return the reprogramming code build date information.

PSC_RC_Tpsc_get_prg_part_number

Return the reprogramming code part number information.

PSC_RC_Tpsc_get_platform_version

Return the platform code version information.

PSC_RC_Tpsc_get_platform_build_date

Return the platform code build date information.

PSC_RC_Tpsc_get_platform_part_number

Return the platform code part number information.

PSC_RC_Tpsc_get_application_version

Return the application version information.

PSC_RC_Tpsc_get_application_build_date

Return the application build date information.

PSC_RC_Tpsc_int_ram_test_progress

Report the current progress of the internal RAM test.

PSC_RC_Tpsc_int_rom_test_progress

Report the current progress of the internal ROM test.

PSC_RC_Tpsc_int_ram_test_error_detected

Report the last recorded recoverable error detected during the internal RAM test.

PSC_RC_Tpsc_int_rom_test_error_detected

Report the last recorded recoverable error detected during the internal ROM test.

U32psc_get_run_time

Get the run time of the ECU (the time the ECU has been powered without reset or loss of power).

U32psc_get_used_stack_size

Report the amount of stack used by the application and library code.

voidpsc_watchdog_task

The watchdog handling task.

voidpsc_kick_watchdog

Kick the watchdog to prevent the watchdog causing a reset.

5.3.3. Interface detail

5.3.3.1.  Enumerations

5.3.3.1.1. PSC_ERROR_CODE_T
Summary:

Error values for debugging when an error is found by the system start and idle feature (PSC), the feature calls a system error log function with an enumeration from this type.

Enumerations:
PSC_DECODE_RESET_INVALID_ARG

Error raised if the decode reset function finds an invalid argument.

PSC_ERR_FORCED_RESET

Error raised if the platform library forces a reset of the ECU.

PSC_ERR_VERSION_INVALID_PARAM

Error raised if at least one of the version pointer arguments to a version function is invalid.

PSC_ERR_BUILD_DATE_INVALID_PARAM

Error raised if at least one of the build date pointer arguments to a version function is invalid.

PSC_ERR_PART_NUMBER_INVALID_PARAM

Error raised if at least one of the part number pointer arguments to a part-number function is invalid.

PSC_UNEXPECTED_CVN_CHANGE

Error raised if the Calibration Verification Number calculation found an unexpected change in flash memory contents.

PSC_ERR_CELL_RETENTION

Error raised if internal RAM failure detected.

PSC_ERR_ADDRESS_BUS

Error raised if overspill RAM failure detected.

PSC_ERR_DATA_BUS

Error raised if external RAM 1 failure detected.

PSC_ERR_HW_VERSION_UNKNOWN

Error raised if hardware version is unknown.

5.3.3.1.2. PSC_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some system start and idle feature (PSC) functions.

Enumerations:
PSC_RC_OK

Return code if everything progressed as expected.

PSC_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

5.3.3.2.  Variables

5.3.3.2.1. psc_watchdog_task_enabled
Definition:

const U8 psc_watchdog_task_enabled

Description:

This determines whether the watchdog task is active or not.

Set true to enable the watchdog task (which automatically kicks the watchdog on a periodic basis) or set false to disable the watchdog task (and handle watchdog functionality from within the application).

5.3.3.2.2. psc_mem_runtime_checks_enabled
Definition:

const BOOL psc_mem_runtime_checks_enabled

Description:

This determines whether run-time background memory checks are active or not.

Set true to enable the background tests of RAM, flash and non-volatile memory.

5.3.3.2.3. psc_app_major_ver_num
Definition:

const U16 psc_app_major_ver_num

Description:

This is the major version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image.
Range: [0, 65535] unitless

5.3.3.2.4. psc_app_minor_ver_num
Definition:

const U16 psc_app_minor_ver_num

Description:

This is the minor version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image.
Range: [0, 65535] unitless

5.3.3.2.5. psc_app_sub_minor_ver_num
Definition:

const U16 psc_app_sub_minor_ver_num

Description:

This is the subminor version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image.
Range: [0, 65535] unitless.

5.3.3.2.6. psc_app_name
Definition:

const U8 psc_app_name[]

Description:

This is the name of the application.

The name is a null-terminated string of ASCII characters. The name is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.7. psc_app_desc
Definition:

const U8 psc_app_desc[]

Description:

This is a description of the application.

The description is a null-terminated string of ASCII characters. The description is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.8. psc_app_copyright
Definition:

const U8 psc_app_copyright[]

Description:

This is a copyright notice for the application.

The copyright notice is a null-terminated string of ASCII characters. The copyright notice is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.9. psc_platform_header
Definition:

const PHDR_HEADER_T psc_platform_header

Description:

The application data header which contains details of CPU initialisation, CCP settings, application version info, etc.

5.3.3.3.  Functions

5.3.3.3.1. psc_initialise_app()
Definition:

void psc_initialise_app(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function is invoked from the library between pre-initialisation and post-initialisation.

The application must define this function. The application may use the function to initialise itself and configure the library (e.g., by calling pcx_declare_message()).

5.3.3.3.2. psc_background_app()
Definition:

void psc_background_app(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function is invoked by the library when no tasks are running.

The application must define this function. The application may use the function to perform any time or event independent processing.

5.3.3.3.3. psc_get_cpu_loading()
Definition:

U8 psc_get_cpu_loading(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the last calculated CPU loading.

Return:

The last calculated CPU loading.
Range: [0, 100] %

5.3.3.3.4. psc_get_max_cpu_loading()
Definition:

U8 psc_get_max_cpu_loading(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the maximum CPU loading recorded since reset.

Return:

The maximum value of any previously calculated CPU loading since reset.
Range: [0, 100] %

5.3.3.3.5. psc_decode_reset()
Definition:

PSC_RC_T psc_decode_reset(
   U8   *pscf_power_reset,
   U8   *pscf_watchdog_reset,
   U8   *pscf_access_reset,
   U8   *pscf_fp_reset,
   U8   *pscf_mem_reset,
   U8   *pscf_forced_reset,
   U8   *pscf_other_reset,
   F32  *pscf_boot_duration);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Determine the reason for the last reset and the duration from reset to the start of the application code.

Arg (data out): pscf_power_reset

Pointer to where the boolean result of whether the reset occurred due to a power cycle will be written. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_watchdog_reset

Pointer to where the boolean result of whether the reset occurred due to a watchdog timeout will be written. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_access_reset

Pointer to where the boolean result of whether the reset occurred due to an illegal memory access will be written. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_fp_reset

Pointer to where the boolean result of whether the reset occurred due to a floating point exception will be written. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_mem_reset

Pointer to where the Boolean result of whether the reset occurred due to an unrecoverable corruption of internal memory.
Cannot be NULL.

Arg (data out): pscf_forced_reset

Pointer to where the boolean result of whether the reset occurred due to a forced reset will be written. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_other_reset

Pointer to where the boolean result of whether an undetermined reset occurred. Set true if the reset could not be determined, false otherwise.
Cannot be NULL.

Arg (data out): pscf_boot_duration

A pointer to where the boot duration in seconds will be written. The boot duration is a rough estimate of time between the boot code starting to run and the scheduler starting all tasks (including the application tasks).
Cannot be NULL.

Return:

5.3.3.3.6. psc_store_suicide_note()
Definition:

void psc_store_suicide_note(
   U32   pscf_note);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Store data across a reset.

The function stores a value that will survive a reset. This can be read back when the ECU restarts using the psc_get_suicide_note function.

Note

Data saved this way will not survive a power-cycle.

This function should not be called. It is intended only for testing purposes, and may be removed in future releases.

Arg (data in): pscf_note

The data to save.

5.3.3.3.7. psc_get_suicide_note()
Definition:

U32 psc_get_suicide_note(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Recover data stored across a reset.

The function returns the last value stored using the psc_store_suicide_note function. The data is reset to 0 during a power-on reset.

Note

This function should not be called. It is intended only for testing purposes, and may be removed in future releases.

Return:

The data previously stored using the psc_store_suicide_note function.

5.3.3.3.8. psc_get_reset_count()
Definition:

U32 psc_get_reset_count(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the reset count.

The function returns the free running count of the number of powered resets.

Note

The count is reset to one upon power cycle.

5.3.3.3.9. psc_get_unstable_reset_count()
Definition:

U32 psc_get_unstable_reset_count(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the reset count.

The function returns the limited counter of powered resets that occur within 60 seconds of initialisation. It is cleared once the application been running for at least 60 seconds. If the unstable reset counter reaches 5, then the module will be forced in to reprogramming mode.

Note

The count is reset to one upon power cycle.

5.3.3.3.10. psc_get_etpu_loading()
Definition:

PSC_RC_T psc_get_etpu_loading(
   PIO_ETPU_DEVICE_T   pscf_etpu_device,
   U8                 *pscf_etpu_loading);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Return the last calculated eTPU loading for an eTPU device.

Arg (data in): pscf_etpu_device

Identifies the eTPU device to report on. Use the macros included by the pio.h file, of the form PIO_ETPU_DEVICE_[NAME].

Arg (data out): pscf_etpu_loading

The last calculated eTPU loading for the requested eTPU device.
Range: [0, 100] %

Return:

5.3.3.3.11. psc_get_max_etpu_loading()
Definition:

PSC_RC_T psc_get_max_etpu_loading(
   PIO_ETPU_DEVICE_T   pscf_etpu_device,
   U8                 *pscf_etpu_loading);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Return the maximum eTPU loading recorded since reset for an eTPU device.

Arg (data in): pscf_etpu_device

Identifies the eTPU device to report on. Use the macros included by the pio.h file, of the form PIO_ETPU_DEVICE_[NAME].

Arg (data out): pscf_etpu_loading

The maximum value of any previously calculated eTPU loading since reset for the requested eTPU device.
Range: [0, 100] %

Return:

5.3.3.3.12. psc_get_hw_version()
Definition:

PSC_RC_T psc_get_hw_version(
   S16  *pscf_hw_ver);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Return the hardware version information.

Return the detected version number for the hardware from the PCB.

Can raise the following errors:
PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_hw_ver

Pointer to a variable the function will write the hardware version to.
Cannot be NULL. Range: [-1, 100], -1 if hardware version is unknown

Return:

5.3.3.3.13. psc_get_boot_version()
Definition:

PSC_RC_T psc_get_boot_version(
   U16  *pscf_major_ver,
   U16  *pscf_minor_ver,
   U16  *pscf_sub_minor_ver);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the boot code version information.

Return the major, minor and sub-minor version numbers for boot code programmed into the ECU.

Can raise the following errors:
PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver

Pointer to a variable the function will write the major version to.
Cannot be NULL.

Arg (data out): pscf_minor_ver

Pointer to a variable the function will write the minor version to.
Cannot be NULL.

Arg (data out): pscf_sub_minor_ver

Pointer to a variable the function will write the sub-minor version to.
Cannot be NULL.

Return:

5.3.3.3.14. psc_get_boot_build_date()
Definition:

PSC_RC_T psc_get_boot_build_date(
   U16  *pscf_year,
   U16  *pscf_month,
   U16  *pscf_day);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the boot code build date information.

Return the year, month and day of the build date for boot code programmed into the ECU.

Can raise the following errors:
PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year

Pointer to a variable the function will write the build year to.
Cannot be NULL.
Range: 0, 65535

Arg (data out): pscf_month

Pointer to a variable the function will write the build month to.
Cannot be NULL.
Range: [1, 12] (representing January through December)

Arg (data out): pscf_day

Pointer to a variable the function will write the build day to.
Cannot be NULL.
Range: [1, 31]

Return:

5.3.3.3.15. psc_get_boot_part_number()
Definition:

PSC_RC_T psc_get_boot_part_number(
   U8   *pscf_group,
   U8   *pscf_letter,
   U32  *pscf_id,
   U16  *pscf_issue);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the boot code part number information.

Return the group ID number, group ID letter, part ID number and issue ID number of the boot code programmed into the ECU.

Can raise the following errors:
PSC_ERR_PART_NUMBER_INVALID_PARAM.

Arg (data out): pscf_group

Pointer to a variable the function will write the group id number to.
Cannot be NULL.
Range: 0, 99

Arg (data out): pscf_letter

Pointer to a variable the function will write the group letter to.
Cannot be NULL.
Range: 0, 255

Arg (data out): pscf_id

Pointer to a variable the function will write the part id number to.
Cannot be NULL.
Range: 0, 999999

Arg (data out): pscf_issue

Pointer to a variable the function will write the part issue number to.
Cannot be NULL.
Range: [0, 65535]

Return:

5.3.3.3.16. psc_get_prg_version()
Definition:

PSC_RC_T psc_get_prg_version(
   U16  *pscf_major_ver,
   U16  *pscf_minor_ver,
   U16  *pscf_sub_minor_ver);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the reprogramming code version information.

Return the major, minor and sub-minor version numbers for reprogramming code programmed into the ECU.

Can raise the following errors:
PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver

Pointer to a variable the function will write the major version to.
Cannot be NULL.

Arg (data out): pscf_minor_ver

Pointer to a variable the function will write the minor version to.
Cannot be NULL.

Arg (data out): pscf_sub_minor_ver

Pointer to a variable the function will write the sub-minor version to.
Cannot be NULL.

Return:

5.3.3.3.17. psc_get_prg_build_date()
Definition:

PSC_RC_T psc_get_prg_build_date(
   U16  *pscf_year,
   U16  *pscf_month,
   U16  *pscf_day);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the reprogramming code build date information.

Return the year, month and day of the build date for reprogramming code programmed into the ECU.

Can raise the following errors:
PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year

Pointer to a variable the function will write the build year to.
Cannot be NULL.
Range: 0, 65535

Arg (data out): pscf_month

Pointer to a variable the function will write the build month to.
Cannot be NULL.
Range: [1, 12] (representing January through December)

Arg (data out): pscf_day

Pointer to a variable the function will write the build day to.
Cannot be NULL.
Range: [1, 31]

Return:

5.3.3.3.18. psc_get_prg_part_number()
Definition:

PSC_RC_T psc_get_prg_part_number(
   U8   *pscf_group,
   U8   *pscf_letter,
   U32  *pscf_id,
   U16  *pscf_issue);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the reprogramming code part number information.

Return the group ID number, group ID letter, part ID number and issue ID number of the reprogramming code programmed into the ECU.

Can raise the following errors:
PSC_ERR_PART_NUMBER_INVALID_PARAM.

Arg (data out): pscf_group

Pointer to a variable the function will write the group id number to.
Cannot be NULL.
Range: 0, 99

Arg (data out): pscf_letter

Pointer to a variable the function will write the group letter to.
Cannot be NULL.
Range: 0, 255

Arg (data out): pscf_id

Pointer to a variable the function will write the part id number to.
Cannot be NULL.
Range: 0, 999999

Arg (data out): pscf_issue

Pointer to a variable the function will write the part issue number to.
Cannot be NULL.
Range: [0, 65535]

Return:

5.3.3.3.19. psc_get_platform_version()
Definition:

PSC_RC_T psc_get_platform_version(
   U16  *pscf_major_ver,
   U16  *pscf_minor_ver,
   U16  *pscf_sub_minor_ver);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the platform code version information.

Return the major, minor and sub-minor version numbers for platform code programmed into the ECU.

Can raise the following errors:
PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver

Pointer to a variable the function will write the major version to.
Cannot be NULL.

Arg (data out): pscf_minor_ver

Pointer to a variable the function will write the minor version to.
Cannot be NULL.

Arg (data out): pscf_sub_minor_ver

Pointer to a variable the function will write the sub-minor version to.
Cannot be NULL.

Return:

5.3.3.3.20. psc_get_platform_build_date()
Definition:

PSC_RC_T psc_get_platform_build_date(
   U16  *pscf_year,
   U16  *pscf_month,
   U16  *pscf_day);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the platform code build date information.

Return the year, month and day of the build date for platform code programmed into the ECU.

Can raise the following errors:
PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year

Pointer to a variable the function will write the build year to.
Cannot be NULL.
Range: 0, 65535

Arg (data out): pscf_month

Pointer to a variable the function will write the build month to.
Cannot be NULL.
Range: [1, 12] (representing January through December)

Arg (data out): pscf_day

Pointer to a variable the function will write the build day to.
Cannot be NULL.
Range: [1, 31]

Return:

5.3.3.3.21. psc_get_platform_part_number()
Definition:

PSC_RC_T psc_get_platform_part_number(
   U8   *pscf_group,
   U8   *pscf_letter,
   U32  *pscf_id,
   U16  *pscf_issue);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the platform code part number information.

Return the group ID number, group ID letter, part ID number and issue ID number of the platform code programmed into the ECU.

Can raise the following errors:
PSC_ERR_PART_NUMBER_INVALID_PARAM.

Arg (data out): pscf_group

Pointer to a variable the function will write the group id number to.
Cannot be NULL.
Range: 0, 99

Arg (data out): pscf_letter

Pointer to a variable the function will write the group letter to.
Cannot be NULL.
Range: 0, 255

Arg (data out): pscf_id

Pointer to a variable the function will write the part id number to.
Cannot be NULL.
Range: 0, 999999

Arg (data out): pscf_issue

Pointer to a variable the function will write the part issue number to.
Cannot be NULL.
Range: [0, 65535]

Return:

5.3.3.3.22. psc_get_application_version()
Definition:

PSC_RC_T psc_get_application_version(
   U16  *pscf_major_ver,
   U16  *pscf_minor_ver,
   U16  *pscf_sub_minor_ver);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the application version information.

Return the major, minor and sub-minor version numbers for application programmed into the ECU.

Can raise the following errors:
PSC_ERR_VERSION_INVALID_PARAM.

Arg (data in): pscf_major_ver

Pointer to a variable the function will write the major version to.
Cannot be NULL.

Arg (data in): pscf_minor_ver

Pointer to a variable the function will write the minor version to.
Cannot be NULL.

Arg (data in): pscf_sub_minor_ver

Pointer to a variable the function will write the sub-minor version to.
Cannot be NULL.

Return:

5.3.3.3.23. psc_get_application_build_date()
Definition:

PSC_RC_T psc_get_application_build_date(
   U16  *pscf_year,
   U16  *pscf_month,
   U16  *pscf_day);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the application build date information.

Return the year, month and day of the build date for the application programmed into the ECU.

Can raise the following errors:
PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data in): pscf_year

Pointer to a variable the function will write the build year to.
Cannot be NULL.
Range: 0, 65535

Arg (data in): pscf_month

Pointer to a variable the function will write the build month to.
Cannot be NULL.
Range: [1, 12] (representing January through December)

Arg (data in): pscf_day

Pointer to a variable the function will write the build day to.
Cannot be NULL.
Range: [1, 31]

Return:

5.3.3.3.24. psc_int_ram_test_progress()
Definition:

PSC_RC_T psc_int_ram_test_progress(
   U32  *pscf_start_address,
   U32  *pscf_end_address,
   U32  *pscf_current_address);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Report the current progress of the internal RAM test.

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64-bit accesses are automatically corrected and are reported through the associated error reporting function. Two bit or greater errors are not recoverable and will immediately trigger a reset. The application may determine the reason for the reset.

Arg (data out): pscf_start_address

Pointer to where to write the first address of the internal RAM test.
Cannot be NULL.

Arg (data out): pscf_end_address

Pointer to where to write the end address of the internal RAM test.
Cannot be NULL.

Arg (data out): pscf_current_address

Pointer to where to write the current address of the internal RAM test.
Cannot be NULL.

Return:

5.3.3.3.25. psc_int_rom_test_progress()
Definition:

PSC_RC_T psc_int_rom_test_progress(
   U32  *pscf_start_address,
   U32  *pscf_end_address,
   U32  *pscf_current_address);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Report the current progress of the internal ROM test.

The internal RAM test continuously cycles through the internal ROM and checks for errors. One bit errors that are detected in aligned 64-bit accesses are automatically corrected and are reported through the associated error reporting function. Two bit or greater errors are not recoverable and will immediately trigger a reset. The application may determine the reason for the reset.

Arg (data out): pscf_start_address

Pointer to where to write the first address of the internal ROM test.
Cannot be NULL.

Arg (data out): pscf_end_address

Pointer to where to write the end address of the internal ROM test.
Cannot be NULL.

Arg (data out): pscf_current_address

Pointer to where to write the current address of the internal ROM test.
Cannot be NULL.

Return:

5.3.3.3.26. psc_int_ram_test_error_detected()
Definition:

PSC_RC_T psc_int_ram_test_error_detected(
   BOOL  *pscf_error_detected,
   U32   *pscf_error_address);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Report the last recorded recoverable error detected during the internal RAM test.

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64-bit accesses are automatically corrected and are reported through this interface.

Arg (data out): pscf_error_detected

Pointer to where to write the boolean result of whether a recoverable internal RAM fault has been detected. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_error_address

Pointer to where to write the address of the last recoverable internal RAM fault.
Cannot be NULL.

Return:

5.3.3.3.27. psc_int_rom_test_error_detected()
Definition:

PSC_RC_T psc_int_rom_test_error_detected(
   BOOL  *pscf_error_detected,
   U32   *pscf_error_address);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Report the last recorded recoverable error detected during the internal ROM test.

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64-bit accesses are automatically corrected and are reported through this interface.

Arg (data out): pscf_error_detected

Pointer to where to write the boolean result of whether a recoverable internal ROM fault has been detected. Set true if so, false otherwise.
Cannot be NULL.

Arg (data out): pscf_error_address

Pointer to where to write the address of the last recoverable internal ROM fault.
Cannot be NULL.

Return:

5.3.3.3.28. psc_get_run_time()
Definition:

U32 psc_get_run_time(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Get the run time of the ECU (the time the ECU has been powered without reset or loss of power).

Return:

The run time.
Range: [0, 4294967295] seconds

5.3.3.3.29. psc_get_used_stack_size()
Definition:

U32 psc_get_used_stack_size(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Report the amount of stack used by the application and library code.

Return:

The size of stack used by the application and library code.
Range: [0, 4294967295] bytes

5.3.3.3.30. psc_watchdog_task()
Definition:

void psc_watchdog_task(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

The watchdog handling task.

This is the entry point for the watchdog handling task. The task ensures the watchdog does not timeout and cause a reset (which can be determined by calling psc_decode_reset()).

The watchdog handling task is assigned a low priority relative to other tasks. This includes the application tasks. It is important that application tasks do not run for longer than the watchdog timeout period, otherwise the ECU will reset.

The watchdog task is enabled when psc_watchdog_task_enabled is set true. If set false, the application may control when the watchdog is kicked by calling psc_kick_watchdog() (or not).

Note

The watchdog handling task must be scheduled every 200 milliseconds. The period of the watchdog is hard coded by the library and cannot be modified by the application.

5.3.3.3.31. psc_kick_watchdog()
Definition:

void psc_kick_watchdog(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Kick the watchdog to prevent the watchdog causing a reset.

Kick the main processor's watchdog to prevent a reset. This function should only be called when the watchdog task is disabled (by setting psc_watchdog_task_enabled false).

Note

The watchdog handling must be scheduled periodically greater than 200 milliseconds. The period of the watchdog is hard coded by the library and cannot be modified by the application.

5.4. ECU registry information (PREG)

5.4.1. Overview

The feature provides access to the ECU's registry. The registry represents data that is specific to the ECU, such as the ECU's date of manufacture or serial number. Read access to the registry is provided through either the preg_retrieve_value_from_key() or preg_retrieve_value_generic() functions. Write access is not permitted.

The registry contains various pieces of structured data, represented as a set of key-value pairs. To read the registry, an appropriate key is passed to preg_retrieve_value_from_key(). In turn the function searches the registry for a matching key and if found, extracts the value part of the pair into a buffer provided by the caller. To read the raw data of the registry field, a generic key can be passed to the preg_retrieve_value_generic() function, which searches for the matching key, and if found, extracts the raw data bytes of the value part of the key-value pair.

Table 5.3. Registry entries

KeyEnumeration
Serial numberPREG_KEY_SERIAL_NUM
Date of manufacturePREG_KEY_DATE_OF_MANUFACTURE
Engineering part numberPREG_KEY_ENG_PART_NUM
Hardware issue and modification levelPREG_KEY_HW_ISSUE_MOD_NUM
Factory part numberPREG_KEY_FACTORY_PART_NUM
Factory part number build typePREG_KEY_FACTORY_BUILD_TYPE

For a description of each key-value pair, see the enumeration and structures referred to in the previous table.

Note

Not all ECUs have registry information programmed. The preg_is_data_available() function will return whether registry information is available or not.

5.4.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and preg.h
Enumerations
 PREG_RC_T

An enumerated type which contains success and failure codes returned by some registry feature (PREG) functions.

 PREG_KEY_T

An enumerated type which represents each of the keys supported by this feature.

Data types
 PREG_VALUE_SERIAL_NUM_T

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM.

 PREG_VALUE_DATE_OF_MANUFACTURE_T

A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE.

 PREG_VALUE_ENG_PART_NUM_T

A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM.

 PREG_VALUE_HW_ISSUE_MOD_NUM_T

A structure which represents the structured data for the ECU's issue-mod key, see PREG_KEY_HW_ISSUE_MOD_NUM.

 PREG_VALUE_FACTORY_PART_NUM_T

A structure which represents the structured data for the ECU's factory part number key,.

 PREG_VALUE_FACTORY_BUILD_TYPE_T

A structure which represents the structured data for the ECU's factory part number build type key, see PREG_KEY_FACTORY_BUILD_TYPE.

 PREG_VALUE_DEV_HW_T

A structure which represents the structured data for the ECU's developer hardware configuration see PREG_KEY_DEV_HW.

Functions
BOOLpreg_is_data_available

Determine whether the registry is available or not.

PREG_RC_Tpreg_retrieve_value_from_key

Retrieve the value for a registry key.

PREG_RC_Tpreg_retrieve_value_generic

Retrieve the value for a generic registry key.

5.4.3. Interface detail

5.4.3.1.  Enumerations

5.4.3.1.1. PREG_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some registry feature (PREG) functions.

Enumerations:
PREG_RC_OK

Return code if everything progressed as expected.

PREG_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PREG_RC_INVALID_KEY

Return code if the key argument is not one recognised by the feature.

PREG_RC_NOT_FOUND

Return code if the key argument could not be found in the registry when retrieving the key's value.

5.4.3.1.2. PREG_KEY_T
Summary:

An enumerated type which represents each of the keys supported by this feature.

Enumerations:
PREG_KEY_SERIAL_NUM

The key for the ECU's serial number, see PREG_VALUE_SERIAL_NUM_T for the associated data.

PREG_KEY_DATE_OF_MANUFACTURE

The key for the ECU's date of manufacture, see PREG_VALUE_DATE_OF_MANUFACTURE_T for the associated data.

PREG_KEY_ENG_PART_NUM

The key for the ECU's engineering part number, see PREG_VALUE_ENG_PART_NUM_T for the associated data.

PREG_KEY_HW_ISSUE_MOD_NUM

The key for the ECU's mod and issue number, see PREG_VALUE_HW_ISSUE_MOD_NUM_T for the associated data.

PREG_KEY_FACTORY_PART_NUM

The key for the ECU's factory part number, see PREG_VALUE_FACTORY_PART_NUM_T for the associated data.

PREG_KEY_FACTORY_BUILD_TYPE

The key for the ECU's factory part number build type, see PREG_VALUE_FACTORY_BUILD_TYPE_T for the associated data.

PREG_KEY_RESERVED_1
PREG_KEY_RESERVED_2
PREG_KEY_RESERVED_3
PREG_KEY_RESERVED_4
PREG_KEY_DEV_HW

The key for the ECU's ECU's developer hardware configuration, see PREG_VALUE_DEV_HW_T for the associated data.

Description:

An enumerated type which represents each of the keys supported by this feature.

A key is a reference associated to some structured data. For instance, the PREG_KEY_SERIAL_NUM key is associated with the ECU's 32-bit serial number.

5.4.3.2.  Data types

5.4.3.2.1. PREG_VALUE_SERIAL_NUM_T
Summary:

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM.

Members:
U32 PREG_VALUE_SERIAL_NUM_T::serial_num

The serial number is a 32-bit positive integer.

Description:

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM.

The serial number is a 32-bit positive integer. Serial numbers across different families of ECUs do not overlap.

5.4.3.2.2. PREG_VALUE_DATE_OF_MANUFACTURE_T
Summary:

A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE.

Members:
U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::shift

The team shift at time of manufacture.


Range: [1, 3]

U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::day

The day of the month of manufacture.


Range: [1, 31]

U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::month

The month of manufacture.


Range: [1, 12]

U16 PREG_VALUE_DATE_OF_MANUFACTURE_T::year

The year of manufacture.


Range: [2010, ..]

Description:

A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE.

The date is composed as (shift) dd:mm:yyyy, where the shift identifies the team involved in the manufacturing process.

5.4.3.2.3. PREG_VALUE_ENG_PART_NUM_T
Summary:

A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM.

Members:
U8 PREG_VALUE_ENG_PART_NUM_T::prefix

The part number prefix.


Range: [0, 99]

U8 PREG_VALUE_ENG_PART_NUM_T::letter

The part number letter represented as an ASCII character.


Range: [A, Z]

U32 PREG_VALUE_ENG_PART_NUM_T::eng_part_num

The engineering part number.


Range: [0, 999999]

Description:

A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM.

The engineering part number matches the pattern: prefix letter engineering-part-number. For instance, the engineering part number assigned to the M250-000 is '01T068165', where '01' represents the prefix, 'T' represents the letter and '068165' represents the engineering part number.

5.4.3.2.4. PREG_VALUE_HW_ISSUE_MOD_NUM_T
Summary:

A structure which represents the structured data for the ECU's issue-mod key, see PREG_KEY_HW_ISSUE_MOD_NUM.

Members:
U8 PREG_VALUE_HW_ISSUE_MOD_NUM_T::issue

The PCB issue level.


Range: [0, 255]

U8 PREG_VALUE_HW_ISSUE_MOD_NUM_T::mod

The PCB modification level.


Range: [0, 255]

Description:

A structure which represents the structured data for the ECU's issue-mod key, see PREG_KEY_HW_ISSUE_MOD_NUM.

The issue level represents a specific design of PCB. Changes to the issue level may have an effect on the platform library.

The modification level represents what changes were performed to the PCB after manufacturing to correct issue level design mistakes. Changes to the modification level should not have an effect on the platform library.

5.4.3.2.5. PREG_VALUE_FACTORY_PART_NUM_T
Summary:

A structure which represents the structured data for the ECU's factory part number key,.

Members:
U16 PREG_VALUE_FACTORY_PART_NUM_T::part_num[2]

Each numeric part of the factory part number.


Range: [0, 65535]

U8 PREG_VALUE_FACTORY_PART_NUM_T::letter[2]

The identifier which separates each factory part number, represented as ASCII characters.


Range: [A, Z]

Description:

A structure which represents the structured data for the ECU's factory part number key,.

For instance, the factory part number could be '450FT1034', where '450' represents the part_num[0], 'F' represents the letter[0], 'T' represents the letter[1], and '1034' represents the part_num[1]. see PREG_KEY_FACTORY_PART_NUM.

5.4.3.2.6. PREG_VALUE_FACTORY_BUILD_TYPE_T
Summary:

A structure which represents the structured data for the ECU's factory part number build type key, see PREG_KEY_FACTORY_BUILD_TYPE.

Members:
U8 PREG_VALUE_FACTORY_BUILD_TYPE_T::build_type[2]

The factory part number build type, represented as ASCII characters.


Range: [A, Z]

5.4.3.2.7. PREG_VALUE_DEV_HW_T
Summary:

A structure which represents the structured data for the ECU's developer hardware configuration see PREG_KEY_DEV_HW.

Members:
BOOL PREG_VALUE_DEV_HW_T::xetk_present

The ETAS XETK memory emulator is present on the ECU
Range: [0, 1].

5.4.3.3.  Functions

5.4.3.3.1. preg_is_data_available()
Definition:

BOOL preg_is_data_available(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Determine whether the registry is available or not.

Note that not all ECUs have registry information available. Early builds of some ECUs have no registry information programmed.

Return:

True if registry data available, false otherwise.

5.4.3.3.2. preg_retrieve_value_from_key()
Definition:

PREG_RC_T preg_retrieve_value_from_key(
   PREG_KEY_T   pregf_key,
   void        *pregf_value_buffer);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Retrieve the value for a registry key.

Search through the registry for a matching key and if found, write the value data for the key to the supplied buffer.

The function performs a linear search and as such, should be called only when necessary to reduce CPU overhead.

Arg (data in): pregf_key

The key to retrieve information about. Must be one of the PREG_KEY_T enumerations.

Arg (data out): pregf_value_buffer

A pointer to an object declared of suitable type for the key. The object is written with the data values related to the key if the key is found in the registry.

The object for a key can be derived from the key enumeration literal. Keys that match PREG_KEY_* correspond to struct types named PREG_VALUE_*_T.

For instance, if pregf_key is set to PREG_KEY_SERIAL_NUM then pregf_value_buffer must point to an object of type PREG_VALUE_SERIAL_NUM_T.
Cannot be NULL.

Return:

5.4.3.3.3. preg_retrieve_value_generic()
Definition:

PREG_RC_T preg_retrieve_value_generic(
   U16   pregf_key,
   U8   *pregf_raw_value_buffer);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Retrieve the value for a generic registry key.

Search through the registry for a matching key and if found, write the raw value data for the key to the supplied buffer.

The function performs a linear search and as such, should be called only when necessary to reduce CPU overhead.

Arg (data in): pregf_key

The key to retrieve information about.

Arg (data out): pregf_raw_value_buffer

Pointer to an array of data bytes to be filled with the raw bytes from if the registry key is found. Cannot be NULL.

Return:

5.5. System timing feature (PTM)

5.5.1. Overview

The system timing feature provides access to second, millisecond and microsecond timers through the ptm_get_s_time(), ptm_get_ms_time() and ptm_get_us_time() functions. All timers wrap to zero when they increment past their maximum value.

The feature provides access to a timer running at the processor's clock rate (or multiple there of) through the ptm_get_sys_time() function. The return value from this function can be converted to microseconds by dividing it by PTM_SYS_TIME_TO_US.

The feature provides functions to calculate the difference in time between the current time and the return value from a previous call to read a timer (ptm_s_time_diff(), ptm_ms_time_diff(), ptm_us_time_diff() and ptm_sys_time_diff()). The results of calling these functions is undefined if more time has past than the timer can record.

5.5.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and ptm.h
Macros
 PTM_SYS_TIME_TO_US

This is the division factor to convert from system time (returned by calling ptm_get_sys_time()) into microseconds.

Functions
U32ptm_get_sys_time

Return a free running 32-bit system timer.

U32ptm_sys_time_diff

Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time().

U32ptm_sys_time_diff_update

Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time() and ptm_sys_time_diff_update(), updating the snapshot for the next call.

U32ptm_get_s_time

Return a free running 32-bit second timer.

U32ptm_s_time_diff

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time().

U32ptm_s_time_diff_update

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time() and ptm_s_time_diff_update(), updating the snapshot for the next call.

U32ptm_get_ms_time

Return a free running 32-bit millisecond timer.

U32ptm_ms_time_diff

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time().

U32ptm_ms_time_diff_update

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time() and ptm_ms_time_diff_update(), updating the snapshot for the next call.

U32ptm_get_us_time

Return a free running 32-bit microsecond timer.

U32ptm_us_time_diff

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time().

U32ptm_us_time_diff_update

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time() and ptm_us_time_diff_update(), updating the snapshot for the next call.

5.5.3. Interface detail

5.5.3.1.  Macros

5.5.3.1.1. PTM_SYS_TIME_TO_US
Definition:

#define PTM_SYS_TIME_TO_US (PTM_INT_SYS_TIME_TO_US)

Description:

This is the division factor to convert from system time (returned by calling ptm_get_sys_time()) into microseconds.

5.5.3.2.  Functions

5.5.3.2.1. ptm_get_sys_time()
Definition:

U32 ptm_get_sys_time(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return a free running 32-bit system timer.

The system timer is a free running 32-bit timer. The timer increments, and wraps to zero when it overflows rather than saturating. The timer can be converted to microseconds by dividing by PTM_SYS_TIME_TO_US.

Return:

The current value of the system timer.
Range: [0, 4294967295] ticks

5.5.3.2.2. ptm_sys_time_diff()
Definition:

U32 ptm_sys_time_diff(
   U32   ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time().

Arg (data in): ptmf_time

The result of calling ptm_get_sys_time().
Range: [0, 4294967295] ticks

Return:

The difference in time between the current value of the system timer and ptmf_time.
Range: [0, 4294967295] ticks

5.5.3.2.3. ptm_sys_time_diff_update()
Definition:

U32 ptm_sys_time_diff_update(
   U32  *ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time() and ptm_sys_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time

Pointer to the last snapshot of time (either by calling ptm_get_sys_time() initially, or ptm_sys_time_diff_update() subsequently).
Range: [0, 4294967295] ticks

Return:

The difference in time between the current value of the system timer and ptmf_time.
Range: [0, 4294967295] ticks

5.5.3.2.4. ptm_get_s_time()
Definition:

U32 ptm_get_s_time(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return a free running 32-bit second timer.

The second timer is a free running 32-bit timer. The timer increments each second and wraps to zero when it overflows rather than saturating.

Return:

The current value of the second timer.
Range: [0, 4294967295] seconds

5.5.3.2.5. ptm_s_time_diff()
Definition:

U32 ptm_s_time_diff(
   U32   ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time().

Arg (data in): ptmf_time

The result of calling ptm_get_s_time().
Range: [0, 4294967295] seconds

Return:

The difference in time between the current value of the second timer and ptmf_time.
Range: [0, 4294967295] seconds

5.5.3.2.6. ptm_s_time_diff_update()
Definition:

U32 ptm_s_time_diff_update(
   U32  *ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time() and ptm_s_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time

Pointer to the last snapshot of time (either by calling ptm_get_s_time() initially, or ptm_s_time_diff_update() subsequently).
Range: [0, 4294967295] seconds

Return:

The difference in time between the current value of the second timer and ptmf_time.
Range: [0, 4294967295] seconds

5.5.3.2.7. ptm_get_ms_time()
Definition:

U32 ptm_get_ms_time(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return a free running 32-bit millisecond timer.

The millisecond timer is a free running 32-bit timer. The timer increments each millisecond and wraps to zero when it overflows rather than saturating.

Return:

The current value of the millisecond timer.
Range: [0, 4294967295] milliseconds

5.5.3.2.8. ptm_ms_time_diff()
Definition:

U32 ptm_ms_time_diff(
   U32   ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time().

Arg (data in): ptmf_time

The result of calling ptm_get_ms_time().
Range: [0, 4294967295] milliseconds

Return:

The difference in time between the current value of the millisecond timer and ptmf_time.
Range: [0, 4294967295] milliseconds

5.5.3.2.9. ptm_ms_time_diff_update()
Definition:

U32 ptm_ms_time_diff_update(
   U32  *ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time() and ptm_ms_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time

Pointer to the last snapshot of time (either by calling ptm_get_ms_time() initially, or ptm_ms_time_diff_update() subsequently).
Range: [0, 4294967295] milliseconds

Return:

The difference in time between the current value of the millisecond timer and ptmf_time.
Range: [0, 4294967295] milliseconds

5.5.3.2.10. ptm_get_us_time()
Definition:

U32 ptm_get_us_time(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return a free running 32-bit microsecond timer.

The microsecond timer is a free running 32-bit timer. The timer increments each microsecond and wraps to zero when it overflows rather than saturating.

Return:

The current value of the microsecond timer.
Range: [0, 4294967295] microseconds

5.5.3.2.11. ptm_us_time_diff()
Definition:

U32 ptm_us_time_diff(
   U32   ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time().

Arg (data in): ptmf_time

The result of calling ptm_get_us_time().
Range: [0, 4294967295] microseconds

Return:

The difference in time between the current value of the microsecond timer and ptmf_time.
Range: [0, 4294967295] microseconds

5.5.3.2.12. ptm_us_time_diff_update()
Definition:

U32 ptm_us_time_diff_update(
   U32  *ptmf_time);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time() and ptm_us_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time

Pointer to the last snapshot of time (either by calling ptm_get_us_time() initially, or ptm_us_time_diff_update() subsequently).
Range: [0, 4294967295] microseconds

Return:

The difference in time between the current value of the microsecond timer and ptmf_time.
Range: [0, 4294967295] microseconds

5.6. Task scheduling (PKN)

The task scheduling feature has the following responsibilities:

The scheduling feature allows library and application tasks to be scheduled together. See Section 4.6.4, “Application and library tasks” for a list of the pre-defined library tasks and library resources.

5.6.1. Tasking model

The tasking model used by the feature can be represented as a series of state changes.

Figure 5.1. Tasking model states

Tasking model states

All tasks are implemented as single-shot C functions, so each time a task runs it terminates and does not wait. Tasks start by becoming ready due to the periodicity of the task (handled by the scheduler) or due to another task or interrupt making it ready. When tasks are ready to run, they are executed in order from highest to lowest priority with pre-emption if necessary.

5.6.1.1. Interrupt handling

The scheduler feature handles interrupts in a non-nested manner. As the interrupt routines are kept as short as possible, they have a small timing impact on library and application tasks and do not introduce unnecessary latency between themselves.

The scheduler uses one interrupt source as a regular 1 millisecond tick. From this tick, all tasks with timing properties as scheduled.

Note

Interrupt handling is not exposed at the C interface level.

5.6.1.2. Preemptive scheduling

Each task has a priority relative to other tasks. Tasks with a low priority can (with a few exceptions) be interrupted immediately by tasks with a higher priority when those higher priority tasks become ready to run. This scheduling scheme is called fixed pre-emptive scheduling and can be analysed for various properties if need be (e.g., will a task complete before a given dead-line all the time regardless of other task activities).

Tasks are single-shot in nature, represented by a single C function. For example, a 10 millisecond task would be handled by a C function as follows:

void application_10ms_task(void)
{
    /* Perform application processing. */
    return;
}

The task function takes no arguments and returns void. The function is invoked by the scheduler and performs the functionality of the application every 10 milliseconds before returning. On return, the scheduler determines if there are any lower priority tasks ready to run (or to continue to run) and schedules those according to their priority (highest to lowest). When no tasks are running, the scheduler allows the library background function to continue to run (the application can make use of this background function to perform its own processing if necessary).

Before a task returns, if a higher priority task becomes ready to run then the scheduler will pre-empt the task function (effectively stopping it) and start to run the function of the higher priority task, before returning to the original function to continue processing. In this fashion, processing which must occur on a more frequent basis can be assigned to a higher priority task and take precedence over less important processing.

Figure 5.2. Task pre-emption

Task pre-emption

The diagram shows the background processing function, a low and high priority task function, and the scheduler function. Shaded areas show when a function is running. Initially the background processing function is running. At time ta the low priority task becomes ready to run, the scheduler pre-empts the background function and starts the low priority task function. At time tb the high priority task becomes ready to run, the scheduler pre-empts the low priority task function and starts the high priority task function. At time tc the high priority task completes and the scheduler continues the low priority task function. At time td the low priority task completes and the scheduler continues the background processing function.

Shown on the same time-line, its easy to see how the processor is divided into running different task functions.

5.6.1.3. Stack sharing

The stack is setup during library pre-initialisation. By using a single shot function tasking model, context switch RAM usage is keep to a minimum, and all tasks share the same system stack. As a new task is scheduled to run, the context of the previous task or of the background processing function is stored on the stack, then the task function is called. This scheme makes for efficient use of stack on resource limited ECUs.

On some target ECUs, this means stack overflow can be caught immediately as an exception by the processor and handled appropriately.

5.6.1.4. Task timing

As the product is delivered as a library, the final overall task timing cannot be known in advance. To facilitate development, the feature times tasks as they run to record the last execution period and the maximum seen since power on (see pkn_task_start_time[], pkn_task_accum_time[], pkn_task_duration_time[] and pkn_max_task_duration_time[]).

The task duration may include pre-emption time from other tasks, so when the scheduler switches tasks, it adjusts the pre-empted task accordingly so that each task time recorded is the time it would have taken that task to run without pre-emption.

Note

This adjustment does not compensate for pre-emption from interrupts. As interrupts are short, no effort is made to adjust the task time to account for interrupts. Consequently, the task times will increase as the interrupt rates increase;

5.6.1.5. Task context switches

When the scheduler changes between tasks, the scheduler saves the integer and floating point processor context as defined by the application interface for the target ECU's processor. Tasks are free to use the processor's general registers as necessary.

5.6.1.6. Resource locking

The scheduler provides a mechanism for a task to lock a resource, thus preventing other tasks from accessing the same resource. The locking mechanism is implemented using the Immediate Priority Ceiling Protocol (IPCP). The protocol ensures that deadlock cannot occur if certain rules are followed (see Section 5.6.1.7, “Resource locking rules”).

The scheduler keeps track of the currently running task with a ceiling. The ceiling is initially the priority level of the task that runs. Only tasks with priority above the ceiling can pre-empt the currently running task (equal priority tasks and lower priority tasks cannot). Calls to pkn_acquire_resource() and pkn_release_resource() adjust the priority ceiling.

Figure 5.3. Task pre-emption with resource locking

Task pre-emption with resource locking

In this example, there are two tasks which both access the same resource. The diagram shows the background processing function is running initially. At time ta the low priority task becomes ready to run, the scheduler pre-empts the background function and starts the low priority task function. At time tb the low priority task locks a resource that both the high and low priority task share. At time tc the high priority task becomes ready to run but the scheduler does not start it because a resource shared by the high priority task is locked. At time td the low priority task releases the resource lock and because the high priority task is ready to run, the scheduler pre-empts the low-priority function and starts the high priority task function. The resource which was locked by the low priority function was modified by the low priority task only, the other task which could have modified the resource was prevented form running by the scheduler.

When a task wishes to lock a resource, the scheduler must ensure that only that task runs while accessing the resource. It does so by knowing in advance which tasks will access any resource. When any task requests a lock of the resource, the scheduler raises the ceiling priority to the highest priority of any task accessing that resource. This ensures that the task requesting the resource will not be pre-empted by any task also wishing to use the resource.

5.6.1.7. Resource locking rules

The IPCP only works correctly when certain rules are followed:

  • resources must be locked by a task in a nested structure, i.e., acquire r1, acquire r2, do work, release r2, release r1;

  • a task must not acquire a resource if it already holds that resource;

  • a task must not release a resource without acquiring it first.

If these rules are not followed, then it is possible that the scheduler will not honour correct resource locking.

5.6.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pkn.h
Enumerations
 PKN_ERROR_CODE_T

Error values for debugging when an error is found in a call to the scheduler feature (PKN), the scheduler calls a system error log function with an enumeration from this type.

Data types
 PKN_TASKSET_T

The type for a group of tasks.

 PKN_TASK_HANDLE_T

This type specifies a task handle.

 PKN_PERIODIC_TASK_HANDLE_T

This type specifies a periodic task handle.

 PKN_RESOURCE_HANDLE_T

This type specifies a resource handle.

 PKN_ILEVEL_T

This type specifies an atomic word large enough to hold the bit pattern for all interrupt levels.

Functions
voidpkn_acquire_resource

Acquire a resource and raise the priority of this task so that others cannot acquire the same resource.

voidpkn_release_resource

Release a resource and lower the priority to the calling task's actual priority (or dispatch any ready tasks with higher priority).

voidpkn_ready_task

Make a task ready to run.

U32pkn_get_task_duration

Return the last measured duration of a task.

U32pkn_get_max_task_duration

Return the maximum duration of a task since the scheduler was initialised.

U8pkn_get_task_overrun_count

Return the number of times the task has overrun.

5.6.3. Interface detail

5.6.3.1.  Enumerations

5.6.3.1.1. PKN_ERROR_CODE_T
Summary:

Error values for debugging when an error is found in a call to the scheduler feature (PKN), the scheduler calls a system error log function with an enumeration from this type.

Enumerations:
PKN_ERR_KERNEL_STARTED_BELOW_KERNEL_LEVEL

Error raised if the scheduler is started under the wrong interrupt conditions (internal error).

PKN_ERR_INVALID_RESOURCE_HANDLE

Error raised if the scheduler finds the resource does not exist in the internal resource array.

PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE

Error raised if the scheduler finds the calling task was not declared as acquiring the resource.

PKN_ERR_INVALID_TASK_HANDLE

Error raised if the scheduler finds the task handle does not exist in the internal task array.

PKN_ERR_INVALID_PERIODIC_TASK_HANDLE

Error raised if the scheduler finds the task handle does not exist in the internal periodic task array.

PKN_ERR_PERIODIC_TASK_HAS_NO_PERIOD

Error raised if the scheduler detected a periodic task that has a period of zero milliseconds.

PKN_ERR_UNEXPECTED_EXCEPTION

Error raised if the scheduler traps an unexpected processor exception.

PKN_ERR_UNEXPECTED_INTERRUPT

Error raised if the scheduler traps an unexpected processor interrupt.

5.6.3.2.  Data types

5.6.3.2.1. PKN_TASKSET_T
Definition:

typedef U32 PKN_TASKSET_T

Description:

The type for a group of tasks.

A task is a group of functionality that can be run when the task becomes ready. A task can become ready periodically (e.g., scheduled every x ms) or sporadically (e.g., when a sporadic interrupt is processed).

A task has a fixed priority level and tasks ready to run are executed in a pre-emptive fashion where each task release is single shot (think of nested interrupt levels).

A task set is a set of tasks with a common property, e.g., a set of tasks ready to run, or a set of tasks with priority lower than the currently running task.

A task set is represented as a bit set of task bit patterns. Each task is assigned a single bit position in the representation and can be identified by isolating the bit.

As the tasks have a priority ordering, the order of the bits assigned to tasks take the same ordering.

E.g., the highest priority task takes the MS bit (note: PPC bit numbering):

and the second highest priority task takes the second MS bit:

and so on.

A task set or more than one task is then simply the bitwise OR of each task's bit pattern.

E.g., the task set of the second highest task and fourth highest task is represented as:

The bit pattern representation makes finding the highest priority task of a task set easy to find. On the PPC architecture, the count leading zeros machine instruction cntlzw returns the bit position of the MS set bit or 32 if no set bits exist.

When running a task, pre-emption from another source can cause a higher priority task to become ready. The kernel will pre-empt the running task and start running the higher priority task.

To make it easy to determine if a new higher priority task has been make ready to run, the kernel keeps a record of the priority that the current task is running at. This is called the task's ceiling.

The ceiling is represented as a task set of the currently running task and all lower priority tasks.

E.g., if the fourth highest priority task is running, then the ceiling task set would be:

This representation of the ceiling makes it simple to determine is a higher priority task is ready to run. If the ready taskset is greater is value than the ceiling, then there is at least one task with priority higher than the ceiling.

E.g., consider a running task with the fourth highest priority level when the second highest priority task becomes ready to run.

This type specifies an atomic word large enough to hold a task set for up to 32 tasks.

5.6.3.2.2. PKN_TASK_HANDLE_T
Definition:

typedef const PKN_TASK_T* const PKN_TASK_HANDLE_T

Description:

This type specifies a task handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

The implementation of handles uses pointers for efficiency.

5.6.3.2.3. PKN_PERIODIC_TASK_HANDLE_T
Definition:

typedef const PKN_PERIODIC_TASK_T* const PKN_PERIODIC_TASK_HANDLE_T

Description:

This type specifies a periodic task handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

The implementation of handles uses pointers for efficiency.

5.6.3.2.4. PKN_RESOURCE_HANDLE_T
Definition:

typedef const PKN_RESOURCE_T* const PKN_RESOURCE_HANDLE_T

Description:

This type specifies a resource handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

The implementation of handles uses pointers for efficiency.

5.6.3.2.5. PKN_ILEVEL_T
Definition:

typedef U32 PKN_ILEVEL_T

Description:

This type specifies an atomic word large enough to hold the bit pattern for all interrupt levels.

The kernel has the concept of a suspended kernel or a running kernel.

When the kernel is suspended, there will be no API calls to the kernel from application code. This is achieved by raising the interrupt level high enough that no preemption of the kernel by an exception that calls the kernel will occur.

When the kernel is running, there will be API calls to the kernel from application code. This is achieved by lowering the interrupt level enough that preemption of tasks and non-critical kernel code can occur.

5.6.3.3.  Functions

5.6.3.3.1. pkn_acquire_resource()
Definition:

void pkn_acquire_resource(
   const PKN_RESOURCE_HANDLE_T   pknf_r_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Acquire a resource and raise the priority of this task so that others cannot acquire the same resource.

Implements part of the Immediate Priority Ceiling Protocol (IPCP) for resource control. The function locks a resource by raising the priority of the current task to the priority of the highest task that will lock the resource.

Callable by application when tasking given the following constraints:

  • resources must be locked by a task in a nested structure, i.e., acquire r1, acquire r2, ...., release r2, release r1, to satisfy the priority ceiling protocol;

  • a task must not acquire a resource if it already holds that resource;

  • a task must not release a resource without acquiring it first.

If a task finishes without releasing its acquired resources, the scheduler automatically releases any acquired.

Can raise the following errors:
PKN_ERR_INVALID_RESOURCE_HANDLE, PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE.

Arg (data in): pknf_r_hd

A pointer to a resource. The resource itself specifies which tasks can acquire this resource, the ceiling of those tasks and a pointer to a buffer to store context.
Cannot be NULL.

5.6.3.3.2. pkn_release_resource()
Definition:

void pkn_release_resource(
   const PKN_RESOURCE_HANDLE_T   pknf_r_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Release a resource and lower the priority to the calling task's actual priority (or dispatch any ready tasks with higher priority).

Implements part of the Immediate Priority Ceiling Protocol (IPCP) for resource control. It unlocks a resource by lowering the priority of the current task to the priority that locked it and if necessary, dispatches any tasks with higher priority that were made ready while the resource was locked.

Can raise the following errors:
PKN_ERR_INVALID_RESOURCE_HANDLE, PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE.

Callable in the same context as pkn_acquire_resource().

Arg (data in): pknf_r_hd

A pointer to a resource. The resource itself specifies which tasks can acquire this resource, the ceiling of those tasks and a pointer to a buffer to store context.
Cannot be NULL.

5.6.3.3.3. pkn_ready_task()
Definition:

void pkn_ready_task(
   const PKN_TASK_HANDLE_T   pknf_t_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Make a task ready to run.

Make a task ready to run when not handling an interrupt. The task will be dispatched if it has higher priority than the calling task. The task will not be dispatched immediately if the priority of the task to make ready is lower than the current, but will be dispatched after all higher priority tasks have completed.

Can raise the following errors:
PKN_ERR_INVALID_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd

A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs.
Cannot be NULL.

5.6.3.3.4. pkn_get_task_duration()
Definition:

U32 pkn_get_task_duration(
   const PKN_TASK_HANDLE_T   pknf_t_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the last measured duration of a task.

Return the last measured duration of a task in microseconds. The duration may include the duration of the task and the duration of any interrupts that occurred while the task was running, but does not include the duration of any tasks that pre-empted the task while it was running.

Can raise the following errors:
PKN_ERR_INVALID_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd

A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs.
Cannot be NULL.

Return:

The last measured duration of a task in microseconds Range: [0, 4294967295] microseconds.

5.6.3.3.5. pkn_get_max_task_duration()
Definition:

U32 pkn_get_max_task_duration(
   const PKN_TASK_HANDLE_T   pknf_t_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the maximum duration of a task since the scheduler was initialised.

Return the maximum measured duration of a task in microseconds. The duration may include the duration of the task and the duration of any interrupts that occurred while the task was running, but does not include the duration of any tasks that pre-empted the task while it was running.

Can raise the following errors:
PKN_ERR_INVALID_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd

A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs.
Cannot be NULL.

Return:

The maximum measured duration of a task in microseconds Range: [0, 4294967295] microseconds.

5.6.3.3.6. pkn_get_task_overrun_count()
Definition:

U8 pkn_get_task_overrun_count(
   const PKN_PERIODIC_TASK_HANDLE_T   pknf_pt_hd);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the number of times the task has overrun.

When a periodic task comes up to be scheduled and still running, then the overrun count for that task is incremented.

Can raise the following errors:
PKN_ERR_INVALID_PERIODIC_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_pt_hd

A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs.
Cannot be NULL.

Return:

The number of times the task has overrun.
Range: [0, 65535] count.

5.7. Library input and output configuration (PIO)

5.7.1. Overview

The PIO feature provides a set of macros to be used when calling some of the C-API functions. The macros vary based on the target the application code is written for. An example would be configuring a CAN bus during application initialisation:

/* Call the library to initialise the CAN buses, ignoring the return value. */
(void) pcx_config(PIO_CAN_A28_A43 1, PIO_CBAUD_500_KBPS 2);

1

The macro PIO_CAN_A28_A43 (for the M220 target) selects the first CAN bus. The ECU connector pins are included in the macro name (A28_A43) so there is a simple relationship between macro and pin.

2

The macro PIO_CBAUD_500_KBPS (for the M220 target) selects a baud rate of 500 kBps for the first CAN bus.

The macro names are formed so that they are easily associated with their use.

ECU configuration

Take the form PIO_CFG_[ITEM] for parameters which can be used to change the behaviour of the ECU. For instance PIO_CFG_HEGO_FILTER_160HZ selects a 160Hz filter for the HEGO analogue input pins supported by an ECU.

CAN buses and baud rates

Take the form PIO_CAN_[PIN-NAMES] for CAN buses, and the form PIO_CBAUD_[BAUD]_KBPS for baud rates.

Analogue inputs

Take the form PIO_AIN_[PIN-NAME] for connector pins, the form PIO_AIN_INT_[FUNCTION] for internal inputs, the form PIO_AIN_[PIN-NAME]_MONITOR for internal monitor inputs.

Digital inputs

Take the form PIO_DIN_[PIN-NAME] for connector pins, the form PIO_DIN_INT_[FUNCTION] for internal inputs, the form PIO_DIN_[PIN-NAME]_MONITOR for internal monitor inputs.

Frequency inputs

Take the form PIO_FIN_[PIN-NAME] for connector pins, the form PIO_FIN_INT_[FUNCTION] for internal inputs, the form PIO_FIN_[PIN-NAME]_MONITOR for internal monitor inputs.

Period inputs

Take the form PIO_PIN_[PIN-NAME] for connector pins, the form PIO_PIN_INT_[FUNCTION] for internal inputs, the form PIO_PIN_[PIN-NAME]_MONITOR for internal monitor inputs.

Quadrature inputs

Take the form PIO_QDIN_[PIN-NAME] or PIO_QFIN_[PIN-NAME] for connector pins, the form PIO_QDIN_INT_[FUNCTION] or PIO_QFIN_INT_[FUNCTION] for internal inputs, or the form PIO_QDIN_[PIN-NAME]_MONITOR or PIO_QFIN_[PIN-NAME]_MONITOR for internal monitor inputs. Pins using QDIN do not support frequency measurement, pins using QFIN support frequency measurement.

Constant current outputs

Take the form PIO_CCOT_[PIN-NAME] for connector pins, the form PIO_CCOT_INT_[FUNCTION] for internal outputs, the form PIO_CCOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Digital outputs

Take the form PIO_DOT_[PIN-NAME] for connector pins, the form PIO_DOT_INT_[FUNCTION] for internal outputs, the form PIO_DOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Ignition (angular) outputs

Take the form PIO_IGNOT_[PIN-NAME] for connector pins, the form PIO_IGNOT_INT_[FUNCTION] for internal outputs, the form PIO_IGNOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Injection (angular) outputs

Take the form PIO_INJOT_[PIN-NAME] for connector pins, the form PIO_INJOT_INT_[FUNCTION] for internal outputs, the form PIO_INJOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

PWM outputs

Take the form PIO_POT_[PIN-NAME] for connector pins, the form PIO_POT_INT_[FUNCTION] for internal outputs, the form PIO_POT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Synchronised PWM outputs

Take the form PIO_SPOT_[PIN-NAME] for connector pins, the form PIO_SPOT_INT_[FUNCTION] for internal outputs, the form PIO_SPOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Stepper motor outputs

Take the form PIO_SMOT_[PIN-NAME] for connector pins, the form PIO_SMOT_INT_[FUNCTION] for internal outputs, the form PIO_SMOT_[PIN-NAME]_[FUNCTION] for internal outputs related to connector pins.

Note

Not all targets are capable of supporting each of the input and output types listed above. In this case, the PIO header files explicitly state there is no support and do not provide any macros for that I/O type.

Unlike other features, the interface to the PIO feature varies per target. For this reason, there is no interface detail in this user guide, refer instead to the PIO header files.

5.8. Feature for specific target configuration (PCFG)

5.8.1. Overview

This feature provides a way to define ECU specific configuration settings for some ECUs that are not available on all ECUs.

5.8.2. M110, M220 and M461 targets

No target specific configuration is available for this target.

5.8.3. M250 target

The configuration of pins A32, A33 and A34 as injectors or a PWM outputs can be achieved by calling pcfg_setup_m250() during application initialisation. If the pin is configured as a PWM output then the current trip level can also be selected. The library configures pin appropriately during library post-initialisation.

5.8.4. M460 target

The configuration of pin A31 as an injector or a PWM output can be achieved by calling pcfg_setup_m460() during application initialisation. If the pin is configured as a PWM output then the current trip level can also be selected. The library configures pin appropriately during library post-initialisation.

5.8.5. M670 target

Certain frequency inputs can be configured by calling pcfg_setup_pwm_clock_m670() during application initialisation. This function will configure the pin's timebase to control the resolution of the input.

5.8.6. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pcfg.h
Enumerations
 PCFG_RC_T

An enumerated type which contains success and failure codes returned by some ECU configuration feature (PCFG) functions.

Functions
PCFG_RC_Tpcfg_setup_m250

Set the configuration for channel A32, A33 and A34 (either as injector or PWM output).

voidpcfg_softswitch_m460

Set the configuration for channel A31 (either as injector or PWM output) (deprecated).

PCFG_RC_Tpcfg_setup_m460

Set the configuration for channel A31 (either as injector or PWM output).

PCFG_RC_Tpcfg_setup_pwm_clock_m670

Set the clock configuration for frequency input channels.

5.8.7. Interface detail

5.8.7.1.  Enumerations

5.8.7.1.1. PCFG_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some ECU configuration feature (PCFG) functions.

Enumerations:
PCFG_RC_OK

Return code if everything progressed as expected.

PCFG_RC_SAMPLE_RATE_TOO_LOW

Return code if the desired sample rate is too low.

PCFG_RC_SAMPLE_RATE_TOO_HIGH

Return code if the desired sample rate is too high.

PCFG_RC_INVALID_CHAN

Return code if an internal error occurred which was the result of a software error.

PCFG_RC_BAD_ARGS_HEGO

Return code if at least one of the arguments relating to the HEGO filter selection could not be used.

PCFG_RC_BAD_ARGS_TYPE

Return code if at least one of the arguments relating to the pin type selection could not be used (M460).

PCFG_RC_BAD_ARGS_HYST

Return code if at least one of the arguments relating to the pin hysteresis selection could not be used.

PCFG_RC_BAD_ARGS_NOM_CT

Return code if at least one of the arguments relating to the spark nominal current-trip selection could not be used.

PCFG_RC_BAD_ARGS_MAX_CT

Return code if at least one of the arguments relating to the spark maximum current-trip selection could not be used.

PCFG_RC_BAD_ARGS_INJ_CT

Return code if at least one of the arguments relating to the current-trip selection or current threshold could not be used (M460, M461).

PCFG_RC_BAD_ARGS_PWM_CLK

Return code if at least one of the arguments relating to the PWM clock selection could not be used (M670).

5.8.7.2.  Functions

5.8.7.2.1. pcfg_setup_m250()
Definition:

PCFG_RC_T pcfg_setup_m250(
   PIO_CFG_OUTPUT_TYPE_T    pcfgf_output_type_a32,
   PIO_CFG_CURRENT_TRIP_T   pcfgf_current_trip_level_a32,
   PIO_CFG_OUTPUT_TYPE_T    pcfgf_output_type_a33,
   PIO_CFG_CURRENT_TRIP_T   pcfgf_current_trip_level_a33,
   PIO_CFG_OUTPUT_TYPE_T    pcfgf_output_type_a34,
   PIO_CFG_CURRENT_TRIP_T   pcfgf_current_trip_level_a34);

Supported targets:

M250-000

Required license:

None (Main library).

Description:

Set the configuration for channel A32, A33 and A34 (either as injector or PWM output).

Configure the output type for pin A32, A33 and A34 pins, either injector or PWM. When the output has PWM type, the current trip level of the output can be selected (current trip level is not selectable for injector types).

If this function is not called during initialisation, pins A32, A33 and A34 default to PWM type with a current trip level of 5A.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): pcfgf_output_type_a32

PIO_CFG_OUTPUT_TYPE_INJ to set A32 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A32 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a32

PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A32 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A32 to ~2A. Valid only if pcfgf_output_type_a32 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Arg (data in): pcfgf_output_type_a33

PIO_CFG_OUTPUT_TYPE_INJ to set A33 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A33 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a33

PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A33 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A33 to ~2A. Valid only if pcfgf_output_type_a33 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Arg (data in): pcfgf_output_type_a34

PIO_CFG_OUTPUT_TYPE_INJ to set A34 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A34 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a34

PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A34 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A34 to ~2A. Valid only if pcfgf_output_type_a34 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Return:

5.8.7.2.2. pcfg_softswitch_m460()
Definition:

void pcfg_softswitch_m460(
   BOOL   pcfgf_softswitch_state);

Supported targets:

M460-000

Required license:

None (Main library).

Description:

Set the configuration for channel A31 (either as injector or PWM output) (deprecated).

Similar in functionality to pcfg_setup_m460(). This function became deprecated in version 1.8.0 and will be removed in a future release. The function is currently retained to provide backwards compatibility to previous releases.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): pcfgf_softswitch_state

TRUE to set A31 channel as an injector output, FALSE to set A31 channel as a PWM output with a current trip level of ~5A.

5.8.7.2.3. pcfg_setup_m460()
Definition:

PCFG_RC_T pcfg_setup_m460(
   PIO_CFG_OUTPUT_TYPE_T    pcfgf_output_type_a31,
   PIO_CFG_CURRENT_TRIP_T   pcfgf_current_trip_level_a31);

Supported targets:

M460-000

Required license:

None (Main library).

Description:

Set the configuration for channel A31 (either as injector or PWM output).

Configure the output type for pin A31, either injector or PWM. When the output has PWM type, the current trip level of the output can be selected (current trip level is not selectable for injector types).

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): pcfgf_output_type_a31

PIO_CFG_OUTPUT_TYPE_INJ to set A31 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A31 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a31

PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A31 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A31 to ~2A. Valid only if pcfgf_output_type_a31 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Return:

5.8.7.2.4. pcfg_setup_pwm_clock_m670()
Definition:

PCFG_RC_T pcfg_setup_pwm_clock_m670(
   PDX_LCHAN_T                   pcfgf_pwm_chan,
   PIO_CFG_MIOS_CLOCK_SELECT_T   pcfgf_clock_select);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Set the clock configuration for frequency input channels.

For MIOS-controlled digital I/O, multiple clock speeds can be chosen:

  • Slow clock: 4.125Mhz timebase.

  • Medium Clock: 8.25Mhz timebase. For inputs 0.75 Hz to 2500 Hz with a minimum resolution of at least 0.5 Hz

  • Fast Clock: 16.5Mhz timebase. For inputs 1.6 kHz to 60 kHz with a minimum resolution of at least 218 Hz.

If this function is not called during initialisation before the channel's corresponding initialisation function is called, then it will by default use the slow clock.

Warning

The function must be called during application initialisation before the initialisation function is called for that channel.

Arg (data in): pcfgf_pwm_chan

The channel to be configured with a particular clock selection. Only eMIOS-based channels are configurable.

Arg (data in): pcfgf_clock_select

PIO_CFG_MIOS_CLOCK_SELECT_SLOW to set channel to use the slow clock PIO_CFG_MIOS_CLOCK_SELECT_MED to set channel to use the medium clock PIO_CFG_MIOS_CLOCK_SELECT_FAST to set channel to use the fast clock

Return:

5.9. Analogue input/output feature (PAX)

5.9.1. Overview

5.9.1.1. Hardware effects on signals

The functions work at the level of the micro-processor pin but the input and output circuitry of the ECU may change the characteristics of the signal. For instance, the input circuitry may include filtering. See the technical specification in Section A.1, “ECU hardware reference documentation” for a description of how the input and output circuitry works for an ECU.

5.9.1.2. Analogue input

The library supports reading the state of an analogue input as seen at the micro-processor pin (see pax_adc_input()). Across the target ECUs some A/D converters have different resolutions. To avoid ambiguity as code is ported between targets, the result of an A/D conversion is always scaled to the range [-1, 1] @ 1/4096 A/D counts per bit (i.e., as if the A/D conversion was 12-bit in range). Please see the M250 technical specification for further details regarding the scaling. The application must scale the raw A/D conversion to engineering units, and the utility functions put_cal_map_1d_f32(), put_leaky_bucket_f32(), or put_process_analog_input() can all help.

On all modules, the worst case conversion time for an A/D value is ~500μs. Thus, when the software asks for a A/D conversion, the A/D value may be up to 500μs old.

Most target ECUs provide internal signals for determining the reference voltage used for conversion, and this can be used for ratio-metric inputs.

5.9.1.3. Analogue output

The library supports writing an analog output via a SPI analogue output device. Please see pax_dac_output() for details. The analogue output functionality is currently only supported on the M221.

The analogue output function uses the SPI device to talk from the ECU to a digital potentiometer which sets the analogue output resistance. The output is set by passing a value of 0 to 1 which represents the fraction of the total output resistance range as defined by the circuit. For details on the output resistance, see the technical specification for the target hardware that you are using.

5.9.1.4. Constant current output

The library supports driving constant current output (see pax_cc_output()). Across the target ECUs some constant current output devices have different resolutions.

5.9.1.5. Constant current dither

The library supports a hardware controlled dither for TLE8242-2 outputs (see pax_cc_config_tle8242()). The dither waveform is specified by the number of dither steps and the size of each step. Each output pulse advances the dither waveform by one step. The following diagram demonstrates the relationship between the pulse period, number of dither steps, and the dither step size.

Figure 5.4. TLE8242-2 Dither

TLE8242-2 Dither

5.9.1.6. Constant current PI control

The library supports configurable hardware PI control for TLE8242-2 outputs (see pax_cc_config_tle8242()). Each channel of the TLE8242-2 device includes a separate PI controller with programmable gain values KP and KI. The Infineon TLE7242 KI KP Application note describes a method to determine acceptable KP and KI values. A summary is included here; Please refer the the Infineon application note for additional details.

Acceptable KP and KI values may be determined by modeling the control system with a linear continuous time model.

Figure 5.5. TLE8242-2 constant current control diagram

TLE8242-2 constant current control diagram

Parameters required to calculate KP and KI
VBAT

Supply voltage of the load.

Rc

Resistance of the load.

Lc

Inductance of the load measured at the pulse frequency.

Rsense

Sense resistance value. This value is determined by the OpenECU hardware. It is 100 mR for all outputs.

Fclk

Master clock frequency of the TLE8242-2 device. The frequency is set to 22 MHz by the OpenECU platform.

FPWM

Pulse frequency of the output channel.

Procedure to calculate KP and KI
Determine Pulse Frequency

Set pulse frequency to the upper limit unless some constraint of the load requires it to be lower.

Determine the damping ratio of the system

Start with 0.707. Increase toward 1 to reduce overshoot. Decrease to improve rise time. The damping ratio is denoted by zeta in the supplied equations.

Determine the undamped natural frequency

Calculate according to equation 1. Decreasing will result in longer settling time and increased dither amplitude attenuation. Increasing will lead to poor matching of the linear model to the system.

Calculate KP' and KI'

Calculate according to equations 2 and 3. If KP' is less than zero, then the pulse frequency is too low.

Calculate KP and KI

Calculate according to equations 4 and 5. If KP or KI is greater than 4095, then the undamped natural frequency must be decreased.

Figure 5.6. TLE8242-2 KP and KI equations

TLE8242-2 KP and KI equations

5.9.1.7. External devices

There are two types of I/O on OpenECU hardware: direct and indirect I/O.

Figure 5.7. Direct and indirect analogue outputs

Direct and indirect analogue outputs

Direct I/O

Direct I/O takes place on demand. The application calls the necessary function and the function takes a measurement or sets a driver accordingly.

Indirect I/O

Indirect I/O is delayed. The application calls the necessary function but the data to be read or set is actioned some time after the function returns.

Indirect I/O always occurs when there is an device between the processor and the pin. The device communicates to the processor across a serial link and it is this communication which introduces the delay. Serial communication is initiated at the end of any task which accesses the device to perform an I/O operation. This is accomplished by calling psp_spi_trigger() at the end of each application task. Only I/O channels noted as serial in the technical specification (see Section A.1, “ECU hardware reference documentation”) are affected.

5.9.1.8. Monitors

Each target ECU provides some measure of feedback for a subset of the output pins. For instance, measuring the reference voltage for A/D conversions to determine if the reference voltage generator has failed. A complete list of the monitors can be found in the technical specifications (see Section A.1, “ECU hardware reference documentation”). Each monitor is read by using one of the existing feature functions, e.g., by calling pax_adc_input() to read the analogue voltage of a monitor.

5.9.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pax.h
Enumerations
 PAX_RC_T

An enumerated type which contains success and failure codes returned by some analogue input feature (PAX) functions.

 PAX_ERROR_CODE_T

Error values for debugging when an error is found when calling the analogue input feature (PAX), the API calls a function with an enumeration from this type.

Data types
 PAX_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets.

Functions
PAX_RC_Tpax_adc_input

Function to initialise or read an analogue input channel.

PAX_RC_Tpax_cc_output

Function to initialise or drive a constant current output channel.

PAX_RC_Tpax_dac_output

Function to drive an analogue output channel.

voidpax_set_input_update_rate

Set the rate at which a serial based analogue input channel will be read (deprecated).

voidpax_set_output_update_rate

Set the rate at which a serial based analogue output channel will be updated (deprecated).

PAX_RC_Tpax_cc_config_tle8242

Configures a TLE8242-2 peripheral constant current output channel.

PAX_RC_Tpax_cc_select_meas_chan_tle8242

Selects a TLE8242-2 peripheral constant current channel for measurement.

PAX_RC_Tpax_cc_read_meas_chan_tle8242

Reports measurements for a previously selected TLE8242-2 peripheral constant current channel.

PAX_RC_Tpax_cc_autozero_tle8242

Commands a TLE8242-2 peripheral constant current channel to autozero.

5.9.3. Interface detail

5.9.3.1.  Enumerations

5.9.3.1.1. PAX_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some analogue input feature (PAX) functions.

Enumerations:
PAX_RC_OK

Return code if everything progressed as expected.

PAX_RC_SW_ERROR

Return code if an internal error occurred which was the result of a software error.

PAX_RC_HW_ERROR

Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PAX_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PAX_RC_FREQ_ERROR

Return code if the requested frequency of current modulation is out of range.

PAX_RC_OFFSET_ERROR

Return code if the requested pulse phase offset is out of range.

PAX_RC_DITHER_ERROR

Return code if the requested dither is invalid.

PAX_RC_CONTROL_LOOP_ERROR

Return code if one or more of the control loop parameters are out of range.

5.9.3.1.2. PAX_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the analogue input feature (PAX), the API calls a function with an enumeration from this type.

Enumerations:
PAX_ADC_INPUT_INVALID_ARG

Error raised if the analogue input function finds an invalid argument.

PAX_CC_OUTPUT_INVALID_ARG

Error raised if the constant current output function finds an invalid argument.

PAX_CHANNEL_INVALID

Error raised if the analogue channel 'n' is not supported.


'n' is (error_code - PAX_CHANNEL_INVALID).

PAX_ADC_INPUT_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as an analogue input.


'n' is (error_code - PAX_ADC_INPUT_CHANNEL_UNSUPPORTED).

PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as an current output.


'n' is (error_code - PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED).

PAX_AOT_OUTPUT_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as an analogue output.


'n' is (error_code - PAX_AOT_OUTPUT_CHANNEL_UNSUPPORTED).

5.9.3.2.  Data types

5.9.3.2.1. PAX_LCHAN_T
Definition:

typedef U16 PAX_LCHAN_T

Description:

This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.9.3.3.  Functions

5.9.3.3.1. pax_adc_input()
Definition:

PAX_RC_T pax_adc_input(
   PAX_LCHAN_T   paxf_lchan,
   S16          *paxf_adc,
   BOOL          paxf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or read an analogue input channel.

This function initialises or reads an analogue input channel. If the input arguments are valid, the function writes the conversion result that reflects the conversion for the specified channel through paxf_adc. If the input arguments are invalid, the function does not modify the conversion result.

Can raise the following errors:
PAX_CHANNEL_INVALID, PAX_ADC_INPUT_CHANNEL_UNSUPPORTED and PAX_ADC_INPUT_INVALID_ARG

Note

Consider hardware effects such as filtering, etc..

Arg (data in): paxf_lchan

The channel number of the analogue input channel to be read. Use the macros included by the pio.h file, of the form PIO_AIN_[NAME].

Arg (data out): paxf_adc

Pointer to the conversion result for the analogue input channel.
Can be NULL during application initialisation.
Cannot be NULL during application run.
Range: [-1, 1] @ 1/4096 A/D counts per LSB

Note

Note that some of the values supplied by the IMU on the M250-00Z have a different range of representation. The gyroscope value and gyroscope angle provide a 14-bit signed value and a 14-bit unsigned value respectively.

Arg (data in): paxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.9.3.3.2. pax_cc_output()
Definition:

PAX_RC_T pax_cc_output(
   PAX_LCHAN_T   paxf_lchan,
   S16           paxf_cc,
   BOOL          paxf_init);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to initialise or drive a constant current output channel.

This function initialises or drives a constant current output channel.

Can raise the following errors:
PAX_CHANNEL_INVALID and PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED

Note

Consider hardware effects such as low-side/high-side driven, filtering, etc..

Arg (data in): paxf_lchan

The channel number of the constant current output channel to drive. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data in): paxf_cc

The required current to be driven, given as a unit range. Consider hardware effects such as low-side/high-side driven, etc..
Range: [0, 2] A @ 1 mA per LSB (for M670 targets)

Arg (data in): paxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.9.3.3.3. pax_dac_output()
Definition:

PAX_RC_T pax_dac_output(
   PAX_LCHAN_T   paxf_lchan,
   S16           paxf_dac_level,
   BOOL          paxf_init);

Supported targets:

M110-000 and M221-000

Required license:

None (Main library).

Description:

Function to drive an analogue output channel.

Note

Consider hardware effects such as low-side/high-side driven, filtering, etc.

Arg (data in): paxf_lchan

The channel number of the analog output channel to write. Use the macros included by the pio.h file, of the form PIO_AOT_[NAME].

Arg (data in): paxf_dac_level

The required analog output level fo 12bit DAC output.
Range: [-1, 1] @ 1/4096 A/D counts per LSB

Arg (data in): paxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.9.3.3.4. pax_set_input_update_rate()
Definition:

void pax_set_input_update_rate(
   PAX_LCHAN_T   paxf_lchan);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Set the rate at which a serial based analogue input channel will be read (deprecated).

Became deprecated in version 1.8.0. This function will be removed in a future release. This function is no longer necessary, please remove from use in application code.

Arg (data in): paxf_lchan

The channel number of the analogue channel to read.
Use the macros included by the pio.h file, of the form PIO_[NAME].

5.9.3.3.5. pax_set_output_update_rate()
Definition:

void pax_set_output_update_rate(
   PAX_LCHAN_T   paxf_lchan);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Set the rate at which a serial based analogue output channel will be updated (deprecated).

Became deprecated in version 1.8.0. This function will be removed in a future release. This function is no longer necessary, please remove from use in application code.

Arg (data in): paxf_lchan

The channel number of the analogue channel to drive.
Use the macros included by the pio.h file, of the form PIO_[NAME].

5.9.3.3.6. pax_cc_config_tle8242()
Definition:

PAX_RC_T pax_cc_config_tle8242(
   PAX_LCHAN_T   paxf_lchan,
   F32           paxf_freq,
   F32           paxf_pulse_offset,
   U16           paxf_kp,
   U16           paxf_ki,
   U16           paxf_dither_steps,
   U16           paxf_dither_step_size);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Configures a TLE8242-2 peripheral constant current output channel.

The current setpoint is established through the common pax_cc_output() interface function. Additional configuration specific to the TLE8242-2 is managed through this function. The setpoint and configuration for a channel must be carried out in the same task to ensure data coherence.

Can raise the following errors:
PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan

The channel number of the constant current output channel to configure. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data in): paxf_freq

The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
Range: [10.5, 4000] Hz

Arg (data in): paxf_pulse_offset

The desired phase offset of the output relative to the TLE8242-2 phase sync signal. If the offset is initialised to a non zero value, then the outputs will hold until the phase sync signal is pulsed. The phase sync signal may be pulsed during runtime to syncronise outputs. If the software cannot match the desired pulse offset, the offset will be adjusted to as close a match as possible within 1/32 increments of the pulse period.
Range: [0, 31/32 of pulse period] ms

Arg (data in): paxf_kp

The desired proportional coefficient of the PI control loop that determines the duty cycle of the constant current output. The supplied value is passed directly to the TLE8242-2 KP register without scaling applied.
Range: [0, 4095] unitless

Arg (data in): paxf_ki

The desired integral coefficient of the PI control loop that determines the duty cycle of the constant current output. The supplied value is passed directly to the TLE8242-2 KI register without scaling applied.
Range: [0, 4095] unitless

Arg (data in): paxf_dither_steps

The desired number of dither steps (one per PWM period) between the centre current value and the maximum, at which the steps reverse direction, etc. Hence the total dither cycle waveform period is the PWM period x 4 x this parameter (see diagram in the user guide section "Constant current dither").
If the software cannot match the number of dither steps, the number of steps will be adjusted to as close a match as possible.
Range: [0, 31] steps per 1/4 dither cycle.

Arg (data in): paxf_dither_step_size

The desired dither step size. If the software cannot match the desired dither step size, the step size will be adjusted to as close a match as possible.
Range: [0, 500] mA

Return:

5.9.3.3.7. pax_cc_select_meas_chan_tle8242()
Definition:

PAX_RC_T pax_cc_select_meas_chan_tle8242(
   PAX_LCHAN_T   paxf_lchan);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Selects a TLE8242-2 peripheral constant current channel for measurement.

This interface allow the caller to select the TLE8242-2 output for measurement of minimum, maximum, and average current. TLE8242-2 channels cannot be measured in parallel.

Can raise the following errors:
PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan

The channel number of the constant current output channel to configure. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Return:

5.9.3.3.8. pax_cc_read_meas_chan_tle8242()
Definition:

PAX_RC_T pax_cc_read_meas_chan_tle8242(
   BOOL  *paxf_valid,
   F32   *paxf_min_current,
   F32   *paxf_max_current,
   F32   *paxf_avg_current);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Reports measurements for a previously selected TLE8242-2 peripheral constant current channel.

This interface fetches the measurements for a TLE8242-2 output. The results are not valid until the current dither cycle has completed. TLE8242-2 channels cannot be measured in parallel.

Arg (data out): paxf_valid

Flag indicating that the dither cycle has completed and the results are valid.

Arg (data out): paxf_min_current

Minimum current over the last dither cycle for the selected channel.
Range: [0, 2000] mA

Arg (data out): paxf_max_current

Maximum current over the last dither cycle for the selected channel.
Range: [0, 2000] mA

Arg (data out): paxf_avg_current

Average current over the last dither cycle for the selected channel.
Range: [0, 2000] mA

Return:

5.9.3.3.9. pax_cc_autozero_tle8242()
Definition:

PAX_RC_T pax_cc_autozero_tle8242(
   PAX_LCHAN_T   paxf_lchan,
   BOOL         *paxf_autozero_done);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Commands a TLE8242-2 peripheral constant current channel to autozero.

This interface allow the caller to initiate autozero of a TLE8242-2 device channel. The current setpoint must be set to zero before triggering the autozero feature. TLE8242-2 channels cannot be autozeroed in parallel.

Can raise the following errors:
PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan

The channel number of the constant current output channel to zero. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data out): paxf_autozero_done

Flag indicating that the autozero has completed. The function must be polled during subsequent task iterations to determine that autozero has completed.

Return:

5.10. Digital input/output feature (PDX)

5.10.1. Overview

The library supports various functions to access I/O pins, a summary of which is given below.

5.10.1.1. Hardware effects on signals

The functions work at the level of the micro-processor pin but the input and output circuitry of the ECU may invert the sense of the signal — see the technical specification for a description of how the input circuitry works for an ECU (Section A.1, “ECU hardware reference documentation”).

The input circuitry may include filtering which can affect the input signal. The filter may introduce a limit of frequency range (the signal may undetectable outside of the filters range) and may also introduce signal phase. For rising and falling edges of the signal, the phase may be different, hence the measured high and low time of a pulse train, for example, may not be as expected without the ECU's input circuitry. Again, see the technical specification for a description of how the input circuitry works for an ECU.

5.10.1.2. Digital input

The library supports reading the state of a digital input as seen at the micro-processor pin (see pdx_digital_input()). The utility functions put_debounce_by_cycles() and put_debounce_by_time() can be used to debounce the signal state.

5.10.1.3. Frequency input

The library supports reading the frequency of a digital input as seen at the micro-processor pin (see pdx_frequency_input()).

5.10.1.4. PWM input

The library supports reading the frequency and duty cycle of a digital input as seen at the micro-processor pin (see pdx_pwm_input()). The function measures the time of each high and low (or low and high) pulse to determine the frequency of the input signal.

Note

Whether the block measures a low pulse followed by a high pulse, or a high pulse followed by a low pulse is determined during initialisation of the input channel.

The function measures the durations of the first and second pulses and derives the duty cycle (first pulse time divided by the cycle time). Very small duty cycles (less than 1% or greater than 99%) will not be measured accurately or at all.

The function accumulates the count of complete periods modulo 21777216. The application calculated difference of counts between iterations of the block could be used to diagnose unexpected changes in the signal.

The function measures the period duration and determines whether the signal has taken longer than the timeout duration. The function accumulates the count of time out events and indicates if the signal is timed out when the function is called.

5.10.1.5. Quadrature input

The library supports the decoding of quadrature signals from a quadrature encoder (see pdx_quad_input()). A quadrature encoder generates a pulse train from two sensors which pick up markings on the encoder disk.

Figure 5.8. Quadrature encoder and generated signals

Quadrature encoder and generated signals

The sensors and markings are arranged so that when the encoder is turning, the sensor signals generate two pulse trains 90° out of phase. If the disk is turning in a forwards direction, the primary channel edges will lead the secondary channel edges. If the disk is turning in a backwards direction then the primary channel edges will lag the secondary channel edges. If there are no signal edges on either channel after a period of time, then the encoder has stopped turning (or is turning slowly enough to be considered stationary).

Figure 5.9. Direction of encoder and generated signals

Direction of encoder and generated signals

The quadrature decode functions measure the primary and secondary channels, determine the direction at each pulse and count the pulses. If the encoder is turning forwards then for each edge on the primary and secondary channels, the functions increment the count. If the encoder is turning backwards then for each edge on the primary and secondary channels, the functions decrement the count. When either function is called, the function outputs the count of pulses and resets the count to zero.

For instance, if the encoder turns forwards for nine edges between calls to the function, the pulse count from the functions will be nine. If the encoder turns forwards for six edges and then backwards for two edges between calls of the functions, the pulse count from the functions will be four.

Figure 5.10. Pulse count example

Pulse count example

Note

Some encoders provide an index signal and some encoders provide complement signals of the primary and secondary signals, both for the purposes of improving reliability. This function does not decode these signals.

A second function (see pdx_quad_freq_input()) provides the same functionality but also measures the duration of each pulse from the encoder primary and secondary channels and returns the last measured frequency of each channel.

5.10.1.6. SENT input (SAE J2716)

The library supports the decoding of SENT sensors for fast data from individual frames (see pdx_sent_input()) and for slow data from sequential frames (see pdx_sent_serial_input()). A SENT sensor encodes data into frames using variable width pulses:

Figure 5.11. SENT frame

SENT frame

The library synchronises to the calibration pulse and decodes the remaining frame pulses based on the expected calibration pulse width time and the actual pulse width time. Across sequential valid SENT frames, the library will extract any serial data from the status nibble.

The library performs various diagnostics:

  • checks the SENT sensor clock variance by allowing no more than ±25% of the expected calibration pulse width

  • checks frame to frame variability of the calibration pulse (allowing a change in width no more than 1.5625%)

  • checks the expected number of fast data nibbles is received

  • checks the frame CRC and slow serial CRC

5.10.1.7. Digital output

The library supports setting the state of a digital output (see pdx_digital_output()).

5.10.1.8. PWM output

The library supports setting the frequency and duty cycle of a PWM output (see pdx_pwm_output()), where duty cycle is defined as the High time divided by the Cycle time for a given channel.

The utility function put_dutycycle_processing() supports scaling and clipping of the duty cycle, and inversion of the PWM signal.

The channel output can be offset from other PWM channels of the same frequency. The Offset argument is used to delay the start of the PWM cycle, so that the PWM pulse will not occur at the same time as other PWM signals of the same frequency.

5.10.1.9. Synchronised PWM output

The library supports the generation of a synchronised PWM signal using two output pins (see pdx_spwm_output()). The second output pin is synchronised to the first and optionally has a programmable delay. The frequency and duty cycle are independent for each pin and can be changed between calls to the function.

The duty cycle is the High time divided by the Cycle time for a given channel.

The slave channel is generated relative to the master channel pulse (in this instance, both the master and slave channels are generated with the same frequency).

The slave pulse can be delayed relative to the master pulse by setting the parameter {Slave delay} to a non-zero value.

In all cases, only one pulse per cycle is generated by both the master and slave channels. For instance, if the frequency of the slave channel was twice that of the master channel, only one pulse would be generated by the slave channel.

The Master channel output (and thus the slave) can be offset from other PWM channels of the same frequency. The Master Offset argument is used to delay the start of the PWM cycle, so that the PWM pulse will not occur at the same time as other PWM signals of the same frequency.

5.10.1.10. Peak and hold injector output

The library supports the generation of a signal to control a peak and hold injector (see pdx_phinj_output()). This consists of a stepped current signal generated at the selected injector frequency, in which the current is firstly controlled to the peak current threshold for the duration determined by the peak duty cycle, after which it is controlled to the hold current threshold for the remaining duration of the peak-hold duty cycle (i.e. the duration of the peak-hold duty cycle minus the peak duty cycle), after which the current falls to zero until the beginning of the next cycle.

The injector frequency, peak duty cycle, peak-hold duty cycle and injector clock frequency are all passed as arguments to this function and can be changed between calls.

Figure 5.12. Peak-hold injector output

Peak-hold injector output

The injector frequency is 1 / Cycle time. The peak duty is the Peak current duration divided by the Cycle time. The peak-hold duty is the sum of the Peak current duration and the Hold current duration, divided by the Cycle time. The actual peak-hold duty is constrained to be at least as great as the peak duty.

The channel output can be offset from other injector channels of the same frequency. The Offset parameter is used to delay the start of the injector cycle, so that the injector will not activate at the same time as other injector signals of the same frequency.

The utility function put_dutycycle_processing() can be used to scale and clip the duty cycle inputs prior to calling this function, but no inversion should be applied.

5.10.1.11. H-Bridge output

The library support setting the mode, frequency and duty-cycle of H-Bridge output (see pdx_hbridge_output()), where channel pins are driven accordingly.

The H-Bridge output function controls a load connected between the two ECU pins in the desired mode. Four modes are provided allowing the H-Bridge output to have no drive (all switches open), brake (high-side switches closed), forward or reverse (one side is connected to high-side while the other is PWM'ed to ground at a programmable frequency and duty-cycle).

The duty-cycle used in forward and reverse mode is defined as the proportion of time where the load is driven (low-side switch is grounded).

The block supports 0% and 100% duty cycles.

Warning

To avoid unexpected behavior, H-bridges should be set to NO DRIVE mode before flashing the ECU. This can be done by commanding the actuators to NO DRIVE any time the engine is not turning.

Note

Some of the PWM output channels do not produce an accurate waveform when the duty cycle is either very small (e.g., 0.5%) or very large (e.g., 99.5%). All H-bridge output channels cope with 0% and 100% duty cycles correctly.

For the M250 target specifically, in order to avoid shoot-through and damage to the ECU when the mode switches, a 100us dead-time is inserted in the PWM signal for one task cycle at the beginning of mode-transition. Additionally, this dead-time insertion will only occur if the duty cycle that is commanded has a low time of less than 100us. For this reason, it will not be possible to command a 100% duty cycle during mode-transition for one task period. See diagram below for further detail.

Figure 5.13. Output of H-Bridge during mode transition

Output of H-Bridge during mode transition

5.10.1.12. External devices

There are two types of I/O on OpenECU hardware: direct and indirect I/O.

Figure 5.14. Signal update rates

Signal update rates

Direct I/O

Direct I/O takes place on demand. The application calls the necessary function and the function takes a measurement or sets a driver accordingly.

Indirect I/O

Indirect I/O is delayed. The application calls the necessary function but the data to be read or set is actioned some time after the function returns.

Indirect I/O always occurs when there is an device between the processor and the pin. The device communicates to the processor across a serial link and it is this communication which introduces the delay. Serial communication is initiated at the end of any task which accesses the device to perform an I/O operation. This is accomplished by calling psp_spi_trigger() at the end of each application task. Only I/O channels noted as in the technical specification (see Section A.1, “ECU hardware reference documentation”) are affected.

5.10.1.13. Monitors

Each target ECU provides some measure of feedback for a subset of the output pins. For instance, measuring the actual state of a digital output to determine whether the output is shorted. A complete list of the monitors can be found in the technical specifications (see Section A.1, “ECU hardware reference documentation”). Each monitor is read by using one of the existing feature functions, e.g., by calling pdx_digital_input() to read the digital state of a monitor.

5.10.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pdx.h
Enumerations
 PDX_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PDX) functions.

 PDX_ERROR_CODE_T

Error values for debugging when an error is found when calling the digital input feature (PDX), the API calls a function with an enumeration from this type.

 PDX_SENT_SERIAL_FORMAT_T

This enumeration gives the format of the SENT serial data.

Data types
 PDX_HALL_DECODE_WORKSPACE_T

This type provides storage for persistent information across calls to the hall decode input function.

 PDX_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets.

 PDX_LCHAN_MONITOR_T

This declares a type with enough value range to represent the groups of output-and-monitor channels for all targets.

 PDX_LCHAN_PHINJ_T

This declares a type with enough value range to represent logical peak and hold injector channels for all targets.

 PDX_LCHAN_HBRIDGE_T

This declares a type with enough value range to represent logical H-Bridge channel groups for all targets.

Functions
PDX_RC_Tpdx_digital_input

Function to initialise or read a digital input channel.

PDX_RC_Tpdx_digital_monitor_input

Function to initialise or read the status of a digital output monitor.

PDX_RC_Tpdx_digital_output

Function to initialise or drive a digital output channel.

PDX_RC_Tpdx_frequency_input

Function to initialise or read a frequency input channel.

PDX_RC_Tpdx_hall_decode_input

Function to initialise or read a 3 phase hall input channel.

PDX_RC_Tpdx_hbridge_output

Function to initialise or drive an H-Bridge output channel.

PDX_RC_Tpdx_phinj_output

Function to initialise or drive a peak and hold injector output channel.

PDX_RC_Tpdx_pwm_input

Function to initialise or read a PWM input channel.

PDX_RC_Tpdx_pwm_output

Function to initialise or drive a PWM output channel.

PDX_RC_Tpdx_pwm_output_with_sync_sampling

Function to initialise or drive a PWM output channel with synchronous sampling of an analog input channel.

PDX_RC_Tpdx_quad_freq_input

Function to initialise or read a quadrature and frequency input channel.

PDX_RC_Tpdx_quad_input

Function to initialise or read a quadrature input channel.

PDX_RC_Tpdx_sent_input

Function to initialise and read a SENT input channel, fast channel signals.

PDX_RC_Tpdx_sent_serial_input

Function to read a SENT input channel, slow channel signals.

PDX_RC_Tpdx_spwm_output

Function to initialise or drive a synchronised PWM output channel.

5.10.3. Interface detail

5.10.3.1.  Enumerations

5.10.3.1.1. PDX_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some digital input feature (PDX) functions.

Enumerations:
PDX_RC_OK

Return code if everything progressed as expected.

PDX_RC_SW_ERROR

Return code if an internal error occurred which was the result of a software error.

PDX_RC_HW_ERROR

Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PDX_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PDX_RC_FREQ_TOO_LOW

Return code if frequency argument is too low.

PDX_RC_FREQ_TOO_HIGH

Return code if frequency argument is too large.

PDX_RC_DUTY_OUT_OF_RANGE

Return code if duty cycle argument is out of range, [0, 1].

PDX_RC_SDM_ALLOC_ERROR

Return code if could not allocate eTPU SDM for function (internal error).

PDX_RC_INACTIVE

Return code if input or output device was unresponsive.

PDX_RC_NOT_CONFIGURED

Return code if output not configured.

PDX_RC_INVALID_MODE

Return code if mode is not supported.

PDX_RC_PEAK_HOLD_TOO_LOW

Return code if peak-hold duty cycle is less than peak duty cycle.

PDX_RC_CLIPPED_TO_RANGE

Return code if one or more arguments were clipped to range.

5.10.3.1.2. PDX_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the digital input feature (PDX), the API calls a function with an enumeration from this type.

Enumerations:
PDX_DO_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a digital output.


'n' is (error_code - PDX_DO_CHANNEL_UNSUPPORTED).

PDX_DIG_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a digital input.


'n' is (error_code - PDX_DIG_IN_CHANNEL_UNSUPPORTED).

PDX_FREQ_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a frequency input.


'n' is (error_code - PDX_FREQ_IN_CHANNEL_UNSUPPORTED).

PDX_PERIOD_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a period input.


'n' is (error_code - PDX_PERIOD_IN_CHANNEL_UNSUPPORTED).

PDX_QDEC_FREQ_IN_INVALID_ARG

Error raised if the quadrature and frequency input function has an invalid argument.

PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a quadrature and frequency input.


'n' is (error_code - PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED).

PDX_TPU_QFI_CHANNEL_DEVICE_ERROR

Error raised in quadrature and frequency input, if the primary channel 'n' and the secondary channel are not on the same device.


'n' is (error_code - PDX_TPU_QFI_CHANNEL_DEVICE_ERROR).

PDX_QDEC_IN_INVALID_ARG

Error raised if the quadrature input function has an invalid argument.

PDX_QDEC_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a quadrature input.


'n' is (error_code - PDX_QDEC_IN_CHANNEL_UNSUPPORTED).

PDX_TPU_QI_CHANNEL_DEVICE_ERROR

Error raised in quadrature input, if the primary channel 'n' and the secondary channel are not on the same device.


'n' is (error_code - PDX_TPU_QI_CHANNEL_DEVICE_ERROR).

PDX_PWM_OUT_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a PWM output.


'n' is (error_code - PDX_PWM_OUT_CHANNEL_UNSUPPORTED).

PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a synchronised PWM output.


'n' is (error_code - PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED).

PDX_TPU_SPO_CHANNEL_DEVICE_ERROR

Error raised in synchronised PWM output, if the primary channel 'n' and the secondary channel are not on the same device.


'n' is (error_code - PDX_TPU_SPO_CHANNEL_DEVICE_ERROR).

PDX_PWM_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a PWM input.


'n' is (error_code - PDX_PWM_IN_CHANNEL_UNSUPPORTED).

PDX_CHANNEL_INVALID

Error raised if the digital channel 'n' is not supported.


'n' is (error_code - PDX_CHANNEL_INVALID).

PDX_TLE4953_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a TLE-4953 input.


'n' is (error_code - PDX_TLE4953_CHANNEL_UNSUPPORTED).

PDX_HBRIDGE_INVALID_MODE

Error raised if the H-bridge mode has an invalid value.

PDX_HBRIDGE_CHANNEL_MISMATCH

Error raised if the H-bridge channels are not on the same device.

PDX_HBRIDGE_DECODE_ERROR

Error raised if something went wrong when decoding a device and/or channel necessary for H-bridge operation.

PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED

Error raised if channel group 'n' cannot be used as an H-bridge output.

'n' is (error_code - PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED).

PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a digital data input.


'n' is (error_code - PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED).

PDX_SENT_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a SENT input.


'n' is (error_code - PDX_SENT_IN_CHANNEL_UNSUPPORTED).

PDX_HD_IN_INVALID_ARG

Error raised if the hall decode input function has an invalid argument.

PDX_HD_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a hall decode input.


'n' is (error_code - PDX_HD_IN_CHANNEL_UNSUPPORTED).

PDX_HD_IN_CHANNEL_DEVICE_ERROR

Error raised in hall decode input, if channel A 'n' and channel B or channel C are not on the same device.


'n' is (error_code - PDX_HD_IN_CHANNEL_DEVICE_ERROR).

5.10.3.1.3. PDX_SENT_SERIAL_FORMAT_T
Summary:

This enumeration gives the format of the SENT serial data.

Enumerations:
PDX_SENT_SERIAL_SHORT

The serial data is short, over 16 consecutive SENT frames.

4-bits message ID and 8-bits data.

PDX_SENT_SERIAL_ENHANCED_1

The serial data is enhanced format 1, over 18 consecutive SENT frames.

8-bits message ID and 12-bits data.

PDX_SENT_SERIAL_ENHANCED_2

The serial data is enhanced format 2, over 18 consecutive SENT frames.

4-bits message ID and 16-bits data.

5.10.3.2.  Data types

5.10.3.2.1. PDX_HALL_DECODE_WORKSPACE_T
Summary:

This type provides storage for persistent information across calls to the hall decode input function.

Members:
U32 PDX_HALL_DECODE_WORKSPACE_T::last_us_time

The value of the last time the hall decode function was invoked.

U32 PDX_HALL_DECODE_WORKSPACE_T::last_count

The value of the last sector count since the hall decode function was invoked.

U32 PDX_HALL_DECODE_WORKSPACE_T::last_edge_time

The value of the last edge time since the hall decode function was invoked.

5.10.3.2.2. PDX_LCHAN_T
Definition:

typedef U16 PDX_LCHAN_T

Description:

This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.3. PDX_LCHAN_MONITOR_T
Definition:

typedef U16 PDX_LCHAN_MONITOR_T

Description:

This declares a type with enough value range to represent the groups of output-and-monitor channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.4. PDX_LCHAN_PHINJ_T
Definition:

typedef U8 PDX_LCHAN_PHINJ_T

Description:

This declares a type with enough value range to represent logical peak and hold injector channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.5. PDX_LCHAN_HBRIDGE_T
Definition:

typedef U16 PDX_LCHAN_HBRIDGE_T

Description:

This declares a type with enough value range to represent logical H-Bridge channel groups for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.3.  Functions

5.10.3.3.1. pdx_digital_input()
Definition:

PDX_RC_T pdx_digital_input(
   PDX_LCHAN_T   pdxf_lchan,
   U8           *pdxf_state,
   BOOL          pdxf_init);

Supported targets:

M110-000, M110-000, M220-000, M220-000, M220-0AU, M220-0AU, M221-000, M221-000, M250-000, M250-000, M460-000, M460-000, M461-000, M461-000, M670-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or read a digital input channel.

Note

Consider hardware effects such as inversion, etc..

Can raise the following errors:
PDX_DIG_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a digital input. Use the macros included by the pio.h file, of the form PIO_DIN_[NAME].

Arg (data out): pdxf_state

The state of the digital input is written through this pointer. Consider hardware effects such as inversion, etc..
Cannot be NULL.
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.2. pdx_digital_monitor_input()
Definition:

PDX_RC_T pdx_digital_monitor_input(
   PDX_LCHAN_T   pdxf_lchan,
   F32           pdxf_rise_time,
   BOOL         *pdxf_valid,
   U32          *pdxf_rise_fail_count,
   U32          *pdxf_fall_fail_count,
   BOOL          pdxf_init);

Supported targets:

M110-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or read the status of a digital output monitor.

Can raise the following errors:
PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The channel to use as a digital output monitor. Use the macros included by the pio.h file, of the form PIO_DMIN_[NAME].

Arg (data in): pdxf_rise_time

The time after the output has been commanded high when the state of the monitor input channel is to be tested. The value passed here is clipped to range if necessary. Note that the corresponding fall-time is hard-coded and not accessible to the application via this function. Range: [0, 2000000] us

Arg (data out): pdxf_valid

The validity flag for the monitor channel is written through this pointer. Monitors are only supported for certain output functions, and if an unsupported output function is in use on the corresponding output channel then this flag will read FALSE. Currently supported functions are spark and PWM outputs.
Cannot be NULL.
Range: [0, 16777215]

Arg (data out): pdxf_rise_fail_count

The number of times that the output failed to rise within the time specified by the pdxf_rise_time parameter is written through this pointer.
Cannot be NULL.
Range: [0, 16777215]

Arg (data out): pdxf_fall_fail_count

The number of times that the output failed to fall within the allowed time is written through this pointer.
Cannot be NULL.
Range: [0, 16777215]

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.3. pdx_digital_output()
Definition:

PDX_RC_T pdx_digital_output(
   PDX_LCHAN_T   pdxf_lchan,
   U8            pdxf_state,
   BOOL          pdxf_init);

Supported targets:

M110-000, M110-000, M220-000, M220-000, M220-0AU, M220-0AU, M221-000, M221-000, M250-000, M250-000, M460-000, M460-000, M461-000, M461-000, M670-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or drive a digital output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc..

If the output pin can be configured for either a low-side or high-side output, the polarity of the output is generally controlled by calling pdx_digital_output() using the channel with a name of the form PIO_DOT_XXX_SELECT_HIGH_SIDE. See the technical reference for the targets for specific information.

Can raise the following errors:
PDX_CHANNEL_INVALID + pdxf_lchan , or PDX_DO_CHANNEL_UNSUPPORTED + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a digital output. Use the macros included by the pio.h file, of the form PIO_DOT_[NAME].

Arg (data in): pdxf_state

The state to which the digital output should be driven. A state of 0 means the output is inactive, where 1 means active (non-inverted). For low-side outputs, active means pulled to ground; high-side, pulled to supply voltage. The inactive state is high impedence.
Consider hardware effects such as inversion, low-side/high-side driven, etc..
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.4. pdx_frequency_input()
Definition:

PDX_RC_T pdx_frequency_input(
   PDX_LCHAN_T   pdxf_lchan,
   U16           pdxf_config,
   U8            pdxf_count,
   F32          *pdxf_freq,
   U16           pdxf_last_edges,
   U16          *pdxf_this_edges,
   U32           pdxf_last_time,
   U32          *pdxf_this_time,
   U32           pdxf_timeout,
   BOOL         *pdxf_timed_out,
   BOOL          pdxf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or read a frequency input channel.

This function returns the latest measured frequency of a pulse train input. The function relies on a hardware peripheral to measure the input and present the information on request.

The frequency input is read falling edge to falling edge (unless the pdxf_config parameter specifies otherwise).

Note

Consider hardware effects such as inversion, filtering, etc..

Can raise the following errors:
PDX_FREQ_IN_CHANNEL_UNSUPPORTED + pdxf_lchan , or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a frequency input. Use the macros included by the pio.h file, of the form PIO_FIN_[NAME].

Arg (data in): pdxf_config

A configuration parameter used to initialise certain channels on some ECUs, use PIO_CONFIG_FIN.

Arg (data in): pdxf_count

A configuration parameter used to initialise certain channels on some ECUs, use PIO_COUNT_FIN.

Arg (data out): pdxf_freq

The measured frequency is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written.
The range of the frequency is limited in various ways.

  • The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

  • The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

  • The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification.
    Cannot be NULL.
    Range: [0.5, ...] Hz

Arg (data in): pdxf_last_edges

A count of edges seen by the frequency input function last time this function was called (or zero if this is the first time the function has been called). The counter wraps modulo 65536 and is used to determine whether the signal has timed out or not.
Range: [0, 65535] edges

Arg (data out): pdxf_this_edges

The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_last_edges next time the function is called.
Cannot be NULL.
Range: [0, 65535] edges

Arg (data in): pdxf_last_time

The time of the last call to this frequency input function (or zero if it is the first call). It is used to determine whether the signal has timed out or not.
Range: [0, 4294967295] microseconds

Arg (data out): pdxf_this_time

The time of this call is written through this pointer. It is the value to be passed as pdxf_last_time next time the function is called.
Cannot be NULL.
Range: [0, 4294967295] microseconds

Arg (data in): pdxf_timeout

The duration of the input signal timeout period.
Range: [100, 2000000] microseconds

Arg (data out): pdxf_timed_out

Set if the input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered.
Cannot be NULL.
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.5. pdx_hall_decode_input()
Definition:

PDX_RC_T pdx_hall_decode_input(
   PDX_LCHAN_T                          pdxf_lchan_a,
   PDX_LCHAN_T                          pdxf_lchan_b,
   PDX_LCHAN_T                          pdxf_lchan_c,
   BOOL                                 pdxf_lchan_a_invert,
   BOOL                                 pdxf_lchan_b_invert,
   BOOL                                 pdxf_lchan_c_invert,
   PIO_HDIN_SENSOR_CONFIG_T             pdxf_hall_config,
   F32                                  pdxf_timeout,
   U8                                  *pdxf_direction,
   U8                                  *pdxf_sector,
   F32                                 *pdxf_revolution_freq,
   U32                                 *pdxf_revolution_counter,
   F32                                 *pdxf_sector_freq,
   U32                                 *pdxf_sector_counter,
   BOOL                                *pdxf_timedout,
   PDX_HALL_DECODE_WORKSPACE_T *const   pdxf_hall_channel_wrk_data,
   BOOL                                 pdxf_init);

Supported targets:

M220-0AU

Required license:

None (Main library).

Description:

Function to initialise or read a 3 phase hall input channel.

This function returns the latest measured edges seen as a hall input. The function relies on a hardware peripheral to decode the input and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc..

Can raise the following errors:
PDX_HD_IN_CHANNEL_DEVICE_ERROR + pdxf_lchan_a , or PDX_HD_IN_CHANNEL_UNSUPPORTED + pdxf_lchan_a , or PDX_HD_IN_INVALID_ARG , or PDX_CHANNEL_INVALID + pdxf_lchan_a

Arg (data in): pdxf_lchan_a

The A phase digital channel to use as a 3 phase hall input. Use the macros included by the pio.h file, of the form PIO_HDIN_[NAME].

Arg (data in): pdxf_lchan_b

The B phase digital channel to use as a 3 phase hall input. Use the macros included by the pio.h file, of the form PIO_HDIN_[NAME].

Arg (data in): pdxf_lchan_c

The C phase digital channel to use as a 3 phase hall input. Use the macros included by the pio.h file, of the form PIO_HDIN_[NAME].

Arg (data in): pdxf_lchan_a_invert

Set to 1 to invert the A phase digital input signal.

Arg (data in): pdxf_lchan_b_invert

Set to 1 to invert the B phase digital input signal.

Arg (data in): pdxf_lchan_c_invert

Set to 1 to invert the C phase digital input signal.

Arg (data in): pdxf_hall_config

The hall sensor configuration to use. Any of:

  • PIO_HDIN_SENSOR_CONFIG_60_DEG - 60 degree spacing

  • PIO_HDIN_SENSOR_CONFIG_120_DEG - 120 degree spacing

Arg (data in): pdxf_timeout

The duration of the input signal timeout period.
Range: [100, 2000000] microseconds

Arg (data out): pdxf_direction

The measured direction of the 3 phase hall input is written through this pointer.
Cannot be NULL.
Range: 0 or 1

Arg (data out): pdxf_sector

The measured sector of the 3 phase hall input is written through this pointer.
Cannot be NULL.
Range: [0, 7]

Arg (data out): pdxf_revolution_freq

The measured revolution frequency of the overall 3 phase hall input updated by the last phase is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written.
The range of the frequency is limited in various ways.

  • The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

  • The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

  • The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases.
    Details of the input pin's filtering and processor timing can be found in an ECU's technical specification.
    Cannot be NULL.
    Range: [0.5, ...] Hz

Arg (data out): pdxf_revolution_counter

The count of electrical revolutions seen by the 3 phase hall input function is written through this pointer. The revolution counter is updated during phase A. It is increased when the direction is 1, and decreased when the direction is 0.
Cannot be NULL.
Range: [0, 16777215] counts

Arg (data out): pdxf_sector_freq

The measured sector frequency between phases of the 3 phase hall input updated by the last phase is written through this pointer. Cannot be NULL.
Range: [0.5, ...] Hz

Arg (data out): pdxf_sector_counter

The count of sectors seen by the 3 phase hall input function is written through this pointer. The sector counter is updated on every sector. It is increased when the direction is 1, and decreased when the direction is 0.
Cannot be NULL.
Range: [0, 16777215] counts

Arg (data out): pdxf_timedout

Set if the 3 phase hall input input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered.
Cannot be NULL.
Range: 0 or 1

Arg (data in,out): pdxf_hall_channel_wrk_data

Internal working data used by the 3 phase hall input function. The pointer must point to a variable of type PDX_HALL_DECODE_WORKSPACE_T with persistent storage across function calls. The internal structure members should not be manipulated by the application.
Cannot be NULL.

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.6. pdx_hbridge_output()
Definition:

PDX_RC_T pdx_hbridge_output(
   PDX_LCHAN_HBRIDGE_T   pdxf_lchan_hbridge,
   PIO_HBRIDGE_MODE_T    pdxf_mode,
   F32                   pdxf_freq,
   F32                   pdxf_duty,
   PIO_HBRIDGE_MODE_T   *pdxf_last_mode_ptr,
   BOOL                  pdxf_init);

Supported targets:

M220-000, M220-0AU, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or drive an H-Bridge output channel.

Note

On the M250, for the case when the mode is transitioning, a 100% duty cycle can not be achieved until one task cycle has passed. This can result in the driven duty cycle being different from the requested duty cycle. See the H-Bridge section of the user guide for further detail.

On the M250, there is a dead-time insertion on mode changes.

Can raise the following errors:
PDX_CHANNEL_INVALID , or PDX_HBRIDGE_INVALID_MODE , or PDX_HBRIDGE_CHANNEL_MISMATCH , or PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED + pdxf_lchan_hbridge

Arg (data in): pdxf_lchan_hbridge

The group of channels used to control the H-Bridge. Use the macros included by the pio.h file, of the form PIO_HBOT_[NAME]

Arg (data in): pdxf_mode

The H-bridge mode to use. Any of:

  • PIO_HBRIDGE_MODE_NO_DRIVE - No Drive

  • PIO_HBRIDGE_MODE_BRAKE - Brake

  • PIO_HBRIDGE_MODE_FORWARD - Forward drive

  • PIO_HBRIDGE_MODE_REVERSE - Reverse drive

Arg (data in): pdxf_freq

The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
Range: [0.5, 10000] Hz

Arg (data in): pdxf_duty

The desired duty cycle of the PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled when the H-Bridge is not switching sides - see Note below) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in,out): pdxf_last_mode_ptr

The value of pdxf_mode for this call is written through this pointer. It is the value to be passed as pdxf_mode next time the function is called.
Cannot be NULL.

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.7. pdx_phinj_output()
Definition:

PDX_RC_T pdx_phinj_output(
   PDX_LCHAN_PHINJ_T   pdxf_lchan_phinj,
   F32                 pdxf_inj_freq,
   F32                 pdxf_peak_duty,
   F32                 pdxf_pkhold_duty,
   F32                 pdxf_clock_freq,
   F32                 pdxf_offset,
   BOOL                pdxf_init);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Function to initialise or drive a peak and hold injector output channel.

Can raise the following errors:
PDX_CHANNEL_INVALID + pdxf_master_lchan

Arg (data in): pdxf_lchan_phinj

The logical channel associated with the peak and hold injector output. Use the macros included by the pio.h file, of the form PIO_PHINJOT_[NAME]. Note that this selects channels for the peak, peak-hold and injector clock outputs.

Arg (data in): pdxf_inj_freq

The desired frequency of the peak and hold injector output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
Range: [0.1, 1000] Hz

Arg (data in): pdxf_peak_duty

The desired peak duty cycle of the peak and hold injector output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in): pdxf_pkhold_duty

The desired peak-hold duty cycle of the peak and hold injector output. This must not be less than the peak duty cycle: if it is it will be set to match the peak duty cycle. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.

Arg (data in): pdxf_clock_freq

The desired frequency of the peak and hold injector clock. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
Range: [1, 10000] Hz

Arg (data in): pdxf_offset

The desired phase offset of the injector output, relative to other injector output channels that have been configured with the same frequency.
Range: [0, 10000] ms

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.8. pdx_pwm_input()
Definition:

PDX_RC_T pdx_pwm_input(
   PDX_LCHAN_T   pdxf_lchan,
   U8            pdxf_invert,
   F32          *pdxf_freq,
   F32          *pdxf_dc,
   U32          *pdxf_first_duration,
   U32          *pdxf_second_duration,
   U32          *pdxf_period_count,
   U32           pdxf_timeout,
   U32          *pdxf_timeout_count,
   BOOL         *pdxf_timed_out,
   BOOL         *pdxf_pin_state,
   BOOL          pdxf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or read a PWM input channel.

This function measures the time of each high and low (or low and high) pulse to determine the frequency and duty cycle of the input signal. Very small duty cycles (less than 1% or greater than 99%) will not be measured accurately or at all.

The function accumulates the count of complete periods modulo 16777216. The application calculated difference of counts between iterations of the block could be used to diagnose unexpected changes in the signal.

The function measures the period duration and determines whether the signal has taken longer than the timeout duration. The function accumulates the count of time out events and indicates if the signal is timed out when the function is called.

The function relies on a hardware peripheral to measure the signal and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc..

Can raise the following errors:
PDX_PWM_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a PWM input. Use the macros included by the pio.h file, of the form PIO_PWIN_[NAME].

Arg (data in): pdxf_invert

Set to 0 to start measuring PWM input signal on a rising edge (first pulse is high), set to 1 to start measuring PWM input signal on a falling edge (first pulse is low).
Parameter valid only during initialisation.
Range: 0 or 1

Arg (data out): pdxf_dc

The duty cycle of the last measured period. If a timeout has occurred, this remains as the duty cycle of the last measured period (or zero if a measurement has not yet been taken).
Cannot be NULL.
Range: [0, 1]

Arg (data out): pdxf_freq

The frequency of the last measured period. If a timeout has occurred, this remains as the frequency of the last measured period (or zero if a measurement has not yet been taken).
The range of the frequency is limited in various ways.

  • The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

  • The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

  • The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification.
    Cannot be NULL.
    Range: 0 Hz and [0.5, ...] Hz (minimum)

Arg (data out): pdxf_first_duration

The duration of the first pulse in the last measured period (either high or low). If a timeout has occurred, this remains as the last measured first pulse duration (or zero if a measurement has not yet been taken).
Cannot be NULL.
Range: [0, 4294967296] microseconds

Arg (data out): pdxf_second_duration

The duration of the second pulse in the last measured period (inverse of first pulse). If a timeout has occurred, this remains as the last measured second pulse duration (or zero if a measurement has not yet been taken).
Cannot be NULL.
Range: [0, 4294967296] microseconds

Arg (data out): pdxf_period_count

A count of periods seen by the PWM input function. The counter wraps modulo 16777216.
Cannot be NULL.
Range: [0, 16777216] periods

Arg (data in): pdxf_timeout

The duration of the PWM input signal timeout period.
Parameter valid only during initialisation.
Range: [100, 2000000] microseconds

Arg (data out): pdxf_timeout_count

A count of instances where the input signal has timed out. The counter wraps modulo 16777216.
Cannot be NULL.
Range: [0, 16777216] timeouts

Arg (data out): pdxf_timed_out

Set if the input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is counted in pdxf_timeout_count.
Cannot be NULL.
Range: 0 or 1

Arg (data out): pdxf_pin_state

Set if the input signal is high, clear if the input signal is low. Cannot be NULL.
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.9. pdx_pwm_output()
Definition:

PDX_RC_T pdx_pwm_output(
   PDX_LCHAN_T   pdxf_lchan,
   F32           pdxf_freq,
   F32           pdxf_duty,
   F32           pdxf_offset,
   BOOL          pdxf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or drive a PWM output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc.

On the M250 target, when driving the H-bridge arms independently, the driven signal may have dead-time inserted when changing from low-side to high-side or high-side to low-side for one task period to avoid shoot-through and damage to the ECU. This means that the actual duty cycle may be less than the requested duty cycle for one task cycle, especially at high base frequencies.

If the output pin can be configured for either a low-side or high-side output, the polarity of the output is generally controlled by calling pdx_digital_output() using the channel with a name of the form PIO_DOT_XXX_SELECT_HIGH_SIDE. See the technical reference for the targets for specific information.

Can raise the following errors:
PDX_PWM_OUT_CHANNEL_UNSUPPORTED + pdxf_lchan , or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a PWM output. Use the macros included by the pio.h file, of the form PIO_POT_[NAME].

Arg (data in): pdxf_freq

The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate.
Range: [0.5, 10000] Hz

Arg (data in): pdxf_duty

The desired duty cycle of the PWM output. This is the fraction of the period (1 / pdxf_freq) which the output will be active. For low-side outputs this is the period that the output is pulled to ground and for high-side outputs this is the time the output will be pulled to supply voltage.

When the output is inactive, the output will be in a high-impedence state.

If the software cannot match the desired duty cycle, the duty cycle will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in): pdxf_offset

The desired phase offset of the PWM output, relative to other PWM output channels that have been configured with the same frequency. Range: [0, 2000] ms

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.10. pdx_pwm_output_with_sync_sampling()
Definition:

PDX_RC_T pdx_pwm_output_with_sync_sampling(
   PDX_LCHAN_T                     pdxf_lchan,
   F32                             pdxf_freq,
   F32                             pdxf_duty,
   F32                             pdxf_offset,
   F32                             pdxf_sampling_point,
   PIO_PWM_SYNC_SAMPLING_PHASE_T   pdxf_sampling_phase,
   PAX_LCHAN_T                     pdxf_adc_lchan,
   U8                              pdxf_num_samples,
   S16                            *pdxf_adc_avg_value,
   BOOL                            pdxf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or drive a PWM output channel with synchronous sampling of an analog input channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc.

If the output pin can be configured for either a low-side or high-side output, the polarity of the output is generally controlled by calling pdx_digital_output() using the channel with a name of the form PIO_DOT_XXX_SELECT_HIGH_SIDE. See the technical reference for the targets for specific information.

Can raise the following errors:
PDX_PWM_OUT_CHANNEL_UNSUPPORTED + pdxf_lchan , or PDX_CHANNEL_INVALID + pdxf_lchan, or PAX_CHANNEL_INVALID + pdxf_adc_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a PWM output. Use the macros included by the pio.h file, of the form PIO_POT_[NAME].

Arg (data in): pdxf_freq

The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate.
Range: [0.5, 10000] Hz

Arg (data in): pdxf_duty

The desired duty cycle of the PWM output. This is the fraction of the period (1 / pdxf_freq) which the output will be active. For low-side outputs this is the period that the output is pulled to ground and for high-side outputs this is the time the output will be pulled to supply voltage.

When the output is inactive, the output will be in a high-impedence state.

If the software cannot match the desired duty cycle, the duty cycle will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in): pdxf_offset

The desired phase offset of the PWM output, relative to other PWM output channels that have been configured with the same frequency.
Range: [0, 2000] ms

Arg (data in): pdxf_sampling_point

The desired sampling point of the analog input relative to the PWM output signal. The sampling point is during the selected phase (high or low) of the PWM output signal.
Range: [0, 1] unitless

Arg (data in): pdxf_sampling_phase

The desired sampling phase of the analog input relative to the PWM output signal. The sampling phase can be any of:

  • PIO_PWM_SYNC_SAMPLING_PHASE_HIGH_TIME - sample during PWM high time

  • PIO_PWM_SYNC_SAMPLING_PHASE_LOW_TIME - sample during PWM low time

Arg (data in): pdxf_adc_lchan

The channel number of the analog input channel to be read. Use the macros included by the pio.h file, of the form PIO_AIN_[NAME].

Arg (data in): pdxf_num_samples

The number of samples to average and return by the pdxf_adc_avg_value parameter. Range: [1, 10] samples

Arg (data out): pdxf_adc_avg_value

The average value of the analog input measured synchronously to the PWM output signal is written through this pointer. Cannot be NULL during application run.
Range: [-1, 1] @ 1/4096 A/D counts per LSB

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.11. pdx_quad_freq_input()
Definition:

PDX_RC_T pdx_quad_freq_input(
   PDX_LCHAN_T   pdxf_pri_lchan,
   PDX_LCHAN_T   pdxf_sec_lchan,
   U8            pdxf_count,
   U32           pdxf_last_edges,
   S32          *pdxf_delta_edges,
   U32          *pdxf_this_edges,
   F32          *pdxf_pchan_freq,
   F32          *pdxf_schan_freq,
   U32           pdxf_pchan_last_edges,
   U32           pdxf_schan_last_edges,
   U32          *pdxf_pchan_edges,
   U32          *pdxf_schan_edges,
   U32           pdxf_pchan_last_time,
   U32           pdxf_schan_last_time,
   U32          *pdxf_pchan_time,
   U32          *pdxf_schan_time,
   F32           pdxf_timeout,
   BOOL         *pdxf_pchan_timed_out,
   BOOL         *pdxf_schan_timed_out,
   BOOL          pdxf_init);

Supported targets:

M110-000, M220-0AU, M250-000, M460-000, M461-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or read a quadrature and frequency input channel.

This function returns the latest measured edges seen as a quadrature input and the frequency of each input. The function relies on a hardware peripheral to decode the input and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc..

Can raise the following errors:
PDX_TPU_QFI_CHANNEL_DEVICE_ERROR + pdxf_pri_lchan , or PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED + pdxf_pri_lchan , or PDX_CHANNEL_INVALID + pdxf_pri_lchan

Arg (data in): pdxf_pri_lchan

The primary digital channel to use as a quadrature and frequency input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_sec_lchan

The secondary digital channel to use as a quadrature and frequency input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME]. Cannot be the same as parameter pdxf_pri_lchan.

Arg (data in): pdxf_count

The number of cycles the secondary frequency measurement is averaged over. If set to 1, the measurement is made from the latest cycle. The primary frequency measurement is taken from a single cycle.
Range: [1, 255] cycles

Arg (data in): pdxf_last_edges

This parameter should be populated with zero on the first call to this function, and subsequently with the value written last time to pdxf_this_edges
Range: [-8388608, 8388607] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_delta_edges

The signed difference in edges seen since the last call is written through this pointer. The sign determines the direction of travel of the quadrature input signal.
Cannot be NULL.
Range: [-8388608, 8388607] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_this_edges

This parameter is populated with a function-internal value which needs to be passed the next time the function is called in the pdxf_last_edges parameter.
Cannot be NULL.
Range: [N/A]

Arg (data out): pdxf_pchan_freq

The measured frequency of the primary input channel is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written.
The range of the frequency is limited in various ways.

  • The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

  • The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

  • The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification.
    Cannot be NULL.
    Range: [0.5, ...] Hz (for M250, M460 and M461 targets)

Arg (data out): pdxf_schan_freq

The measured frequency of the secondary input channel is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written.
Cannot be NULL. Range: [0.5, ...] Hz (for M250, M460 and M461 targets)

Arg (data in): pdxf_pchan_last_edges

A count of edges seen by the quadrature and frequency input function last time this function was called (or zero if this is the first time the function has been called).
The counter is used to determine whether the primary signal has timed out or not.
Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data in): pdxf_schan_last_edges

A count of edges seen by the quadrature and frequency input function last time this function was called (or zero if this is the first time the function has been called).
The counter is used to determine whether the secondary signal has timed out or not.
Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_pchan_edges

The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_pchan_last_edges next time the function is called.
Cannot be NULL.
Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_schan_edges

The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_schan_last_edges next time the function is called.
Cannot be NULL.
Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data in): pdxf_pchan_last_time

The time of the last call to this quadrature and frequency input function (or zero if it is the first call). It is used to determine whether the primary signal has timed out or not.
Range: [0, 4294967295] microseconds

Arg (data in): pdxf_schan_last_time

The time of the last call to this quadrature and frequency input function (or zero if it is the first call). It is used to determine whether the secondary signal has timed out or not.
Range: [0, 4294967295] microseconds

Arg (data out): pdxf_pchan_time

The time of this call is written through this pointer. It is the value to be passed as pdxf_pchan_last_time next time the function is called.
Cannot be NULL.
Range: [0, 4294967295] microseconds

Arg (data out): pdxf_schan_time

The time of this call is written through this pointer. It is the value to be passed as pdxf_schan_last_time next time the function is called.
Cannot be NULL.
Range: [0, 4294967295] microseconds

Arg (data in): pdxf_timeout

The duration of the input signal timeout period.
Range: [100, 2000000] microseconds (for M250, M460 and M461 targets)

Arg (data out): pdxf_pchan_timed_out

Set if the primary input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered.
Cannot be NULL.
Range: 0 or 1

Arg (data out): pdxf_schan_timed_out

Set if the secondary input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered.
Cannot be NULL.
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.12. pdx_quad_input()
Definition:

PDX_RC_T pdx_quad_input(
   PDX_LCHAN_T   pdxf_pri_lchan,
   PDX_LCHAN_T   pdxf_sec_lchan,
   U32           pdxf_last_edges,
   S32          *pdxf_delta_edges,
   U32          *pdxf_this_edges,
   BOOL          pdxf_init);

Supported targets:

M110-000, M220-0AU, M250-000, M460-000, M461-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or read a quadrature input channel.

This function returns the latest measured edges seen as a quadrature input. The function relies on a hardware peripheral to decode the input and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc..

Can raise the following errors:
PDX_TPU_QI_CHANNEL_DEVICE_ERROR + pdxf_pri_lchan , or PDX_QDEC_IN_CHANNEL_UNSUPPORTED + pdxf_pri_lchan , or PDX_CHANNEL_INVALID + pdxf_pri_lchan

Arg (data in): pdxf_pri_lchan

The primary digital channel to use as a quadrature input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_sec_lchan

The secondary digital channel to use as a quadrature input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_last_edges

A sum of edges seen by the quadrature input function on the primary and secondary input channels last time this function was called (or zero if this is the first time the function has been called).
Range: [-8388608, 8388607] edges

Arg (data out): pdxf_delta_edges

The signed difference in edges seen since the last call is written through this pointer. The sign determines the direction of travel of the quadrature input signal.
Cannot be NULL.
Range: [-8388608, 8388607] edges

Arg (data out): pdxf_this_edges

The count of edges seen this call is written through this pointer. It is the value to be passed as pdxf_last_edges next time the function is called.
Cannot be NULL.
Range: [-8388608, 8388607] edges

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.13. pdx_sent_input()
Definition:

PDX_RC_T pdx_sent_input(
   PDX_LCHAN_T          pdxf_lchan,
   F32                  pdxf_tick_length_us,
   U8                   pdxf_num_nibbles,
   PIO_PDX_SENT_CRC_T   pdxf_crc_version,
   U8                  *pdxf_num_decoded_frames,
   U8                  *pdxf_num_desyncs,
   BOOL                *pdxf_valid,
   U8                  *pdxf_status,
   U32                 *pdxf_data,
   U32                 *pdxf_timestamp,
   BOOL                *pdxf_pin_state,
   BOOL                 pdxf_init);

Supported targets:

M110-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise and read a SENT input channel, fast channel signals.

The SENT input function decodes a sensor's transmission pulses based on SAE J2716 Jan 2010, making available the sensor's status and data information. SAE J2716 describes SENT as:

The Single Edge Nibble Transmission encoding scheme (SENT) is intended for use in applications where high resolution sensor data needs to be communicated from a sensor to an Engine Control Unit (ECU). It is intended as a replacement for the lower resolution methods of 10 bit A/D converters and PWM and as a simpler low cost alternative to CAN or LIN. The implementation assumes that the sensor is a smart sensor containing a microprocessor or dedicated logic device (ASIC) to create the signal.

SENT is a unidirectional communications scheme from sensor / transmitting device to controller / receiving device which does not include a coordination signal from the controller / receiving device. The sensor signal is transmitted as a series of pulses with data encoded as falling to falling edge periods.

This SENT input function:

  • decodes a stream of SENT pulses into status and fast data nibbles;

  • retrieves the last received, decoded and verified status and data nibbles;

  • allows for a transmitter clock tick variance of +- 25% for the calibration and synchronisation pulse;

  • allows for a transmitter clock tick between [3, 90] microseconds;

  • allows for an optional pause pulse between transmissions;

  • uses the calibration and sychronisation pulse to ratiometrically adjust the status, data and CRC pulses;

  • verifies the frame size (checks the expected number of nibbles, or message edges);

  • verifies the frame CRC, either the 2008 or 2010 version;

  • verifies that successive calibration pulses differ by less than +- 1.5625%.

See the pdx_sent_serial_input() function for reading short serial or extended serial data.

Can raise the following errors:
PDX_SENT_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a SENT input. Use the macros included by the pio.h file, of the form PIO_SENTIN_[NAME].

Arg (data in): pdxf_tick_length_us

The length of the SENT sensor's transmission clock tick.
Range: [3, 90] microseconds
Resolution: 0.1 microseconds

Arg (data in): pdxf_num_nibbles

The number of data nibbles transmitted by the SENT sensor in each frame.
Range: [1, 6] nibbles

Arg (data in): pdxf_crc_version

Which CRC algorithm the SENT sensor applies to each SENT frame.
Either PIO_PDX_SENT_CRC_2008 or PIO_PDX_SENT_CRC_2010.

Arg (data out): pdxf_num_decoded_frames

A counter incremented for each frame that is successfully received, decoded and verified.
Cannot be NULL.
Range: [0, inf] frames, modulo 256

Arg (data out): pdxf_num_desyncs

A counter incremented for each loss of synchronisation with the SENT sensor pulse stream. Loss of synchronisation occurs when the pulse decoder has not seen a valid pulse for more than 125% of a calibration pulse duration (where a calibration pulse is 56 SENT ticks, see pdxf_tick_length_us); or a calibration, status, nibble or CRC pulse is too short; or the frame CRC verification fails.
Cannot be NULL.
Range: [0, inf] frames, modulo 256

Arg (data out): pdxf_valid

True if at least one SENT frame has been successfully received, decoded and verified, false otherwise. If true, then the pdxf_status and pdxf_data parameters provide the status and data received from the last frame, and the pdxf_timestamp parameter provides the time when the frame was received.
Cannot be NULL.
Range: 0 or 1

Arg (data out): pdxf_status

The status nibble of the last SENT frame that was successfully received, decoded and verified. Set to zero when a SENT frame has not been successfully received.
Cannot be NULL.

Arg (data out): pdxf_data

The data nibbles of the last SENT frame that was successfully received, decoded and verified. Set to zero when a SENT frame has not been successfully received. The data nibbles are packed into the integer right aligned.
Cannot be NULL.

Arg (data out): pdxf_timestamp

A timestamp is taken when the the last SENT frame was fully received, decoded and verified. The timestamp increments in counts of 256, wrapping approximately every 4 seconds. The timestamp can be used by the application to determine whether the SENT sensor is transmitting data at the expected period.
Cannot be NULL.
Range: [0, inf] counts, modulo 4294967296

Arg (data out): pdxf_pin_state

1 if the channel pin voltage is above the detection threshold, 0 otherwise. Can be used by the application for electrical diagnostics.
Range: 0 or 1

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.10.3.3.14. pdx_sent_serial_input()
Definition:

PDX_RC_T pdx_sent_serial_input(
   PDX_LCHAN_T                pdxf_lchan,
   U8                        *pdxf_num_messages,
   U8                        *pdxf_num_failed_crcs,
   BOOL                      *pdxf_valid,
   PDX_SENT_SERIAL_FORMAT_T  *pdxf_serial_format,
   U8                        *pdxf_message_id,
   U32                       *pdxf_data,
   U32                       *pdxf_timestamp);

Supported targets:

M110-000 and M670-000

Required license:

None (Main library).

Description:

Function to read a SENT input channel, slow channel signals.

This SENT input function:

  • decodes the status nibble from 16 or 18 consecutive SENT transmissions into message identification and data values;

  • retrieves the last received, decoded and verified serial data;

  • verifies the serial message CRC.

The application must initialise a SENT channel by calling pdx_sent_input() before calling pdx_sent_serial_input().

Can raise the following errors:
PDX_SENT_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan

The digital channel to use as a SENT input. Use the macros included by the pio.h file, of the form PIO_SENTIN_[NAME].

Arg (data out): pdxf_num_messages

A counter incremented for each serial message that is successfully received, decoded and verified.
Cannot be NULL.
Range: [0, inf] messages, modulo 256

Arg (data out): pdxf_num_failed_crcs

A counter incremented for each serial message that is received but that fails a CRC verification.
Cannot be NULL.
Range: [0, inf] messages, modulo 256

Arg (data out): pdxf_valid

True if at least one serial message has been successfully received, decoded and verified, false otherwise. If true, then the pdxf_serial_format, pdxf_message_id and pdxf_data parameters provide information about the last successfully received, decoded and verified message, and the pdxf_timestamp parameter provides the time when the message was received.
Cannot be NULL.
Range: 0 or 1

Arg (data out): pdxf_serial_format

The detected serial format of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not been received.
Cannot be NULL.

Arg (data out): pdxf_message_id

The value of the message identifier of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not yet been received.
Range: [0, 15] for short serial and enhanced serial format 2
Range: [0, 255] for enhanced serial format 1

Arg (data out): pdxf_data

The data nibbles of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not yet been received.
Cannot be NULL.
Range: [0, 255] for short serial
Range: [0, 8192] for enhanced serial format 1
Range: [0, 65535] for enhanced serial format 2

Arg (data out): pdxf_timestamp

A timestamp is taken when the the last successfully received, decoded and verified slow serial message. The timestamp increments in counts of 256, wrapping approximately every 4 seconds. The timestamp can be used by the application to determine whether the SENT sensor is transmitting data at the expected period.
Cannot be NULL.
Range: [0, inf] counts, modulo 4294967296

Return:

5.10.3.3.15. pdx_spwm_output()
Definition:

PDX_RC_T pdx_spwm_output(
   PDX_LCHAN_T   pdxf_master_lchan,
   PDX_LCHAN_T   pdxf_slave_lchan,
   F32           pdxf_master_freq,
   F32           pdxf_master_duty,
   F32           pdxf_master_offset,
   F32           pdxf_slave_freq,
   F32           pdxf_slave_duty,
   U32           pdxf_slave_delay,
   BOOL          pdxf_init);

Supported targets:

M110-000, M250-000, M460-000 and M670-000

Required license:

None (Main library).

Description:

Function to initialise or drive a synchronised PWM output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc..

Can raise the following errors:
PDX_TPU_SPO_CHANNEL_DEVICE_ERROR + pdxf_master_lchan , or PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED + pdxf_master_lchan , or PDX_CHANNEL_INVALID + pdxf_master_lchan

Arg (data in): pdxf_master_lchan

The master digital channel to use as a synchronised PWM output. Use the macros included by the pio.h file, of the form PIO_SPOT_[NAME].

Arg (data in): pdxf_slave_lchan

The slave digital channel to use as a PWM output. Use the macros included by the pio.h file, of the form PIO_SPOT_INT_SLAVE_[NAME].

Arg (data in): pdxf_master_freq

The desired frequency of the master channel output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate.
Range: [1, 10000] Hz (for the M250, M460 targets)

Arg (data in): pdxf_master_duty

The desired duty cycle of the master channel PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in): pdxf_master_offset

The desired phase offset of the master (and hence slave) channel, relative to other channels that have been configured with the same frequency.
Range: [0, 2000] ms (for the M250, M460 targets)

Arg (data in): pdxf_slave_freq

The desired frequency of the slave channel output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible.
If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate.
Range: [1, 10000] Hz (for the M250, M460 targets)

Arg (data in): pdxf_slave_duty

The desired duty cycle of the slave channel PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.
Range: [0, 1] unitless

Arg (data in): pdxf_slave_delay

The desired delay of the slave channel.
Range: [0, 1000000] microseconds.

Arg (data in): pdxf_init

True if the channel is to be initialised, false otherwise.

Return:

5.11. Digital data feature (PDD)

5.11.1. Overview

The library supports functions to access virtual data I/O.

5.11.1.1. Digital data input

The library supports reading the value of an arbitrary data inputs which are not well grouped into other interfaces (see pdd_data_input()).

An example might be the fault counters for SPI message queues. SPI message queues are not exposed to the application but the application needs to know when SPI messaging fails so the application can take remedial actions if desired.

Injector circuits can provide timing signals to specify boost recharge times. These values can be read though the pdd_data_input function for the application to process in the desired way.

5.11.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pdd.h
Enumerations
 PDD_RC_T

An enumerated type which contains success and failure codes returned by some digital data feature (PDD) functions.

 PDD_ERROR_CODE_T

Error values for debugging when an error is found when calling the digital data feature (PDD), the API calls a function with an enumeration from this type.

Data types
 PDD_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets.

Functions
PDD_RC_Tpdd_data_input

Function to initialise or read a digital data channel.

5.11.3. Interface detail

5.11.3.1.  Enumerations

5.11.3.1.1. PDD_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some digital data feature (PDD) functions.

Enumerations:
PDD_RC_OK

Return code if everything progressed as expected.

PDD_RC_SW_ERROR

Return code if an internal error occurred which was the result of a software error.

PDD_RC_HW_ERROR

Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PDD_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

5.11.3.1.2. PDD_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the digital data feature (PDD), the API calls a function with an enumeration from this type.

Enumerations:
PDD_CHANNEL_INVALID

Error raised if the digital channel 'n' is not supported.


'n' is (error_code - PDD_CHANNEL_INVALID).

PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED

Error raised if the channel 'n' cannot be used as a digital data input.


'n' is (error_code - PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED).

5.11.3.2.  Data types

5.11.3.2.1. PDD_LCHAN_T
Definition:

typedef U16 PDD_LCHAN_T

Description:

This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.11.3.3.  Functions

5.11.3.3.1. pdd_data_input()
Definition:

PDD_RC_T pdd_data_input(
   PDD_LCHAN_T   pddf_lchan,
   S32          *pddf_data,
   BOOL          pddf_init);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Function to initialise or read a digital data channel.

Can raise the following errors:
PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDD_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pddf_lchan

The digital channel to use as a digital data input. Use the macros included by the pio.h file, of the form PIO_DIN_DATA_[NAME].

Arg (data out): pddf_data

The value of the digital data is written through this pointer.
Cannot be NULL.
Range: [-2147483648, 2147483647] (the actual range may vary depending on the value read)

Arg (data in): pddf_init

True if the channel is to be initialised, false otherwise.

Return:

5.12. Output driver control feature (PSS)

5.12.1. Overview

The output driver control feature allows access to the overall output driver switch for each ECU (if an ECU supports such a switch). The overall output driver switch can enable or disable a subset of the ECU outputs in one go. The application could use the switch as a safety device if necessary. See the technical specification for the ECU for a description of how the output driver switch works for that ECU (Section A.1, “ECU hardware reference documentation”).

5.12.2. M220 target

On the M220 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection).

5.12.2.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress.

5.12.3. M250 target

On the M250 ECU, the output control circuit turns on or off the high side switch from which individual actuators can be attached. The choice of actuators which are directly controlled by the circuit is under the control of the system designer.

5.12.3.1. Initialisation

The application can call pss_set_safety_switch() to set the output control switch state during application initialisation and application run. During power up, boot, library pre-initialisation and application initialisation, the switch is forced off by the library (thus ensuring the outputs do not glitch during the power up and initialisation sequence of the ECU). During library post-initialisation the switch is set as required by the application. If the application has not set the switch state during application initialisation, then the library will force the switch off.

5.12.3.2. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress.

5.12.4. M460 target

On the M460 ECU, the output control circuit turns on or off the high side switch from which individual actuators can be attached. The choice of actuators which are directly controlled by the circuit is under the control of the system designer.

5.12.4.1. Initialisation

The application can call pss_set_safety_switch() to set the output control switch state during application initialisation and application run. During power up, boot, library pre-initialisation and application initialisation, the switch is forced off by the library (thus ensuring the outputs do not glitch during the power up and initialisation sequence of the ECU). During library post-initialisation the switch is set as required by the application. If the application has not set the switch state during application initialisation, then the library will force the switch off.

5.12.4.2. Diagnostics

The application can call pss_overcur_trip_reset_and_diagn_enable_state() during application run to enable or disable the high side weak pull-up resistor for diagnostic purposes. See Technical Specification — M460 for details.

If the function is never called to change the state of the high side weak pull-up resistor, the resistor is left disabled after library initialisation.

5.12.4.3. Over-current trip latches

The application can call pss_overcur_trip_reset_and_diagn_enable_state() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress.

5.12.5. M461 target

On the M461 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection).

5.12.5.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress.

5.12.6. M670 target

On the M670 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection). See the M670 technical specification for a complete list of protection and electical monitoring signals.

5.12.6.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress.

5.12.7. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pss.h
Functions
voidpss_overcur_trip_reset

Request that the over-current trip latches are reset.

voidpss_overcur_trip_reset_and_diagn_enable_state

Request that the over-current trip latches are reset and to set the high-side switch diagnostic enable.

voidpss_set_safety_switch

Function to set the safety switch state.

voidpss_set_switch

Function to set the safety switch state (deprecated).

5.12.8. Interface detail

5.12.8.1.  Functions

5.12.8.1.1. pss_overcur_trip_reset()
Definition:

void pss_overcur_trip_reset(
   BOOL   pssf_request_trip_reset);

Supported targets:

M220-000, M220-0AU, M221-000, M250-000, M461-000 and M670-000

Required license:

None (Main library).

Description:

Request that the over-current trip latches are reset.

Note

The OpenECU software limits requests for over-current trip reset to be at least 50ms apart. If a second request is issued within 50ms from the first one, it will be latched and delayed until the 50ms time lag has expired.

Arg (data in): pssf_request_trip_reset

Need to cause a transition from false to true to generate an over-current trip reset.

5.12.8.1.2. pss_overcur_trip_reset_and_diagn_enable_state()
Definition:

void pss_overcur_trip_reset_and_diagn_enable_state(
   BOOL   pssf_enable_diagn,
   BOOL   pssf_request_trip_reset);

Supported targets:

M460-000

Required license:

None (Main library).

Description:

Request that the over-current trip latches are reset and to set the high-side switch diagnostic enable.

Note

The OpenECU software limits requests for over-current trip reset to be at least 50ms apart. If a second request is issued within 50ms from the first one, it will be latched and delayed until the 50ms time lag has expired.

Arg (data in): pssf_enable_diagn

True if the Diagnostic Enable signal is asserted, false otherwise.

Arg (data in): pssf_request_trip_reset

Need to cause a transition from false to true to generate an over-current trip reset.

5.12.8.1.3. pss_set_safety_switch()
Definition:

void pss_set_safety_switch(
   BOOL   pssf_enable);

Supported targets:

M250-000 and M460-000

Required license:

None (Main library).

Description:

Function to set the safety switch state.

If this function is called during application initialisation, the switch state is remembered, and set during library post initialisation. If this function is called during application run, the switch state is actioned immediately. The platform may force the safety switch to stay open in case the battery voltage is detected to be too low.

Arg (data in): pssf_enable

True to enable the safety switch and enable the output drivers, false otherwise.

5.12.8.1.4. pss_set_switch()
Definition:

void pss_set_switch(
   BOOL   pssf_enable);

Supported targets:

M250-000 and M460-000

Required license:

None (Main library).

Description:

Function to set the safety switch state (deprecated).

Identical in functionality to pss_set_safety_switch(). This function became deprecated in version 1.7.3 and will be removed in a future release. The function is currently retained to provide backwards compatibility to previous releases.

Arg (data in): pssf_enable

True to enable the safety switch and enable the output drivers, false otherwise.

5.13. Serial peripheral feature (PSP)

5.13.1. Overview

The serial peripheral feature initiates and completes communication between serial devices within the ECU. The feature is largely within the library with only one function exposed to trigger the periodic functionality required.

5.13.2. Input and output processing

The application must call psp_spi_trigger() at the end of each application task. The call ensures that the library performs appropriate input and output processing for the task at the task's activation rate.

5.13.3. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and psp.h
Enumerations
 PSP_ERROR_CODE_T

Error values for debugging when an error is found when calling the serial peripheral interface feature (PSP), the API calls a function with an enumeration from this type.

Functions
voidpsp_spi_trigger

Force all SPI queues accessed by the current task set to be marked as ready for processing.

S16psp_get_fault_count

Gets the fault count for a SPI device.

5.13.4. Interface detail

5.13.4.1.  Enumerations

5.13.4.1.1. PSP_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the serial peripheral interface feature (PSP), the API calls a function with an enumeration from this type.

Enumerations:
PSP_QUEUE_OUT_OF_RANGE

Error raised if the number of transactions configured for SPI transmission is greater than the maximum allowed.

5.13.4.2.  Functions

5.13.4.2.1. psp_spi_trigger()
Definition:

void psp_spi_trigger(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Force all SPI queues accessed by the current task set to be marked as ready for processing.

Trigger all SPI queues that are read from or written to in the caller's task. This completes the serial communication cycle for passing information to and from serial peripherals.

5.13.4.2.2. psp_get_fault_count()
Definition:

S16 psp_get_fault_count(
   PIO_SPI_DEVICE_T   pspf_device);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Gets the fault count for a SPI device.

Reads values of saturating fault counter for a given SPI device.

Arg (data in): pspf_device

device for which to get fault count Range: See pio.h for list of fault-able SPI devices.

Return:

fault count
Number of faults that have been logged since that application began. Or -1 if the parameter is invalid. Range: [-1, 255] integer count or "invalid".

5.14. CJ125 device driver for UEGO measurement feature (PCJ125)

5.14.1. Overview

The CJ125 control feature allows access to the configuration of supported CJ125 devices. See the technical specification for the ECU for a description of how the CJ125 works for that ECU (Section A.1, “ECU hardware reference documentation”).

5.14.2. Initialisation

The application can call pcj125_control() to set the configuration of a specified CJ125 device.

5.14.3. Diagnostics

The library can use the PDX feature to read various diagnostic details about the CJ125 devices.

5.14.4. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pcj125.h
Enumerations
 PCJ125_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PCJ125) functions.

Data types
 PCJ125_LCHAN_T

This declares a type with enough value range to represent all logical CJ125 channels for all targets.

 PCJ125_WORKSPACE_T

This structure acts as scratch area for the CJ125 driver to save the configuration.

Functions
PCJ125_RC_Tpcj125_control

Interface to control behaviour of CJ125 device.

5.14.5. Interface detail

5.14.5.1.  Enumerations

5.14.5.1.1. PCJ125_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some digital input feature (PCJ125) functions.

Enumerations:
PCJ125_RC_OK

Return code if everything progressed as expected.

PCJ125_RC_SW_ERROR

Return code if an internal error occurred which was the result of a software error.

PCJ125_RC_HW_ERROR

Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PCJ125_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

5.14.5.2.  Data types

5.14.5.2.1. PCJ125_LCHAN_T
Definition:

typedef U8 PCJ125_LCHAN_T

Description:

This declares a type with enough value range to represent all logical CJ125 channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.14.5.2.2. PCJ125_WORKSPACE_T
Definition:

typedef struct PCJ125_WORKSPACE_T_ PCJ125_WORKSPACE_T

Description:

This structure acts as scratch area for the CJ125 driver to save the configuration.

One structure should be allocated per CJ125 driven and passed to the corresponding pcj125_control call.

5.14.5.3.  Functions

5.14.5.3.1. pcj125_control()
Definition:

PCJ125_RC_T pcj125_control(
   PCJ125_LCHAN_T            pcj125f_channel,
   PIO_CJ125_REF_CURRENT_T   pcj125f_ref_current,
   PIO_CJ125_IP_AMP_T        pcj125f_ip_amplification,
   BOOL                      pcj125f_calibration_mode,
   PCJ125_WORKSPACE_T       *pcj125f_workspace,
   BOOL                      pcj125f_init);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Interface to control behaviour of CJ125 device.

This function is called periodically during an application task to set the internal configuration of the specified CJ125 device. The function should be called in a task with the desired rate at which the device should be reconfigured.

Note

This function should only be called once per task for each CJ125 device controlled. If this assumption is violated, then the function call could be out of sync with the device communication which could cause unpredictable behaviour.

Arg (data in): pcj125f_channel

The CJ125 channel to control. Use the macros included by the pio.h file, of the form PIO_CJ125_[NAME].

Arg (data in): pcj125f_ref_current

Enumeration of the desired reference current used by the device.

Arg (data in): pcj125f_ip_amplification

Enumeration of the desired amplification.

Arg (data in): pcj125f_calibration_mode

TRUE to configure the device for calibration mode. FALSE otherwise.

Arg (data in,out): pcj125f_workspace

Reference to a memory structure used to store information between function Calls. There should be one such structure allocated and passed to this function for each CJ125 in use.

Arg (data in): pcj125f_init

True if the channel is to be initialised, false otherwise.

Return:

5.15. CAN messaging feature (PCX)

5.15.1. Overview

Reception and transmission of CAN messages, as defined by ISO 11989, is supported by the library. The library provides mechanisms to receive and transmit messages, pack and unpack data for messages, as well as handling error cases.

5.15.2. Initialisation

During application initialisation, the application must configure the CAN buses to be used by calling pcx_config() and declare any receive or transmit messages by calling pcx_declare_message(). During library post-initialisation, the library configures the ECU hardware to efficiently receive and transmit these messages.

The call to pcx_config() configures the baud rate for the CAN bus. The range of baud rates selectable is controlled by the library, as is the sample point for each CAN bit (set at 75%).

Figure 5.15. CAN bit sample point

CAN bit sample point

The call to pcx_declare_message() returns a handle which must be used when referencing the same message in any other call to this feature.

5.15.3. Receiving messages

The library buffers received CAN messages for the application, discarding messages which are not of interest (i.e., not declared during initialisation). The application can determine whether a message has been received since last time and extract the contents of the message by calling pcx_receive().

Each receive message buffer stores one CAN message. If a CAN message with the same identifier is received more than once between calls from the application, then the message buffer is overwritten with the latest received message. This ensures the latest copy of a CAN message is available to the application, but is not suitable for CAN messages which contain state information (e.g., CAN messages containing protocol information, etc.).

Each receive message buffer stores a low accuracy time taken a short period of time after the message is received. That period of time is variable depending on the load of the processor and will therefore suffer jitter, thus the classification of low accuracy. The timer used for the time stamp is a free running timer, that wraps at its maximum to zero.

The return value from calling pcx_receive() gives an indication of CAN message status. It provides an indication of whether a message has been received since the last call, whether more than one message with the same CAN identifier has been received, and whether an error occurred on reception. See PCX_RX_DATA, PCX_RX_OVERRUN and PCX_RX_ERROR for more.

To help unpack data from the contents of a CAN message, the library provides two functions: pcx_unpack_msg() and pcx_vdb_unpack_msg().

Warning

The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

5.15.4. Transmitting messages

The library transmits buffered CAN messages for the application. The application tells the library to transmit a new CAN message by calling pcx_transmit().

Each transmit message buffer stores one CAN message. If the application requests a transmit of a CAN message before the library has transmitted the last CAN message with the same identifier, then the message buffer is overwritten with the latest transmit message. This ensures the latest version of a CAN message is transmitted by the library, but is not suitable for CAN messages which contain state information (e.g., CAN messages containing protocol information, etc.).

The library buffers multiple transmit messages but as the CAN bus is serial in nature, only one message can be transmitted at a time. The library attempts to transmit the messages in the order they are presented when pcx_transmit() is called, but the library will not always adhere to this ordering.

To lessen the load experienced by the CAN bus and the ECU, after the library has transmitted one message, it will wait for 2 milliseconds before determining the next message to transmit (except for J1939 and CCP messaging which can occur more quickly than this).

To help pack data into the contents of a CAN message, the library provides two functions: pcx_pack_msg() and pcx_vdb_pack_msg().

The library provides a set of counters which can be used to determine whether a message has been transmitted or not. The pcx_get_transmit_status() function provides a count of the requests for transmission from the application, a count of the number of times the message was queued in software rather than being immediately passed to the CAN controller for immediate transmission, and a count of the number of times the message was successfully transmited on the bus. A difference in the count between the application request for transmission and successful transmission indicates a failure to successfully transmit.

Note

If a message is queued waiting for transmission and the application requests the same message is transmitted (possibly with different message data) then the queued message is overwritten with the most recent requested message.

5.15.5. CAN status

The library provides the function pcx_get_bus_state() to provide the current state of the CAN bus, one of: error-active, error-passive and bus-off. This function replaces the pcx_is_bus_unavailable() function, which is now deprecated and retained only for backwards compatibility (deprecated functions may be removed in future versions of the developer software).

5.15.6. CAN buses

The number of CAN buses available to each target ECU varies. It may be than one ECU has two buses, but another ECU has only one. The number available to the application is defined by PCX_NUM_CAN_DEVICES.

5.15.7. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

5.15.8. Library tasks

The library implements a couple of tasks to support CAN messaging. See Section 4.6.4, “Application and library tasks” for details.

5.15.9. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pcx.h
Macros
 PCX_CONFIG_ERROR

This macro declares the error value, returned from pcx_declare_message(), if the declared message could not be accepted (for whatever reason).

 PCX_ANY_CAN_ID

This macro declares a CAN message which can have any identifier when calling pcx_declare_message().

 PCX_STANDARD_ID

This macro declares a CAN message identifier to be standard (11-bit) when calling pcx_declare_message().

 PCX_EXTENDED_ID

This macro declares a CAN message identifier to be extended (29-bit) when calling pcx_declare_message().

 PCX_RX_DATA

This macro is a bitmask for the return value from calling pcx_receive().

 PCX_RX_OVERRUN

This macro is a bitmask for the return value from calling pcx_receive().

 PCX_RX_ERROR

This macro is a bitmask for the return value from calling pcx_receive().

 PCX_MSB_ORDER

This macro declares a data item that has most significant byte ordering, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

 PCX_LSB_ORDER

This macro declares a data item that has least significant byte ordering, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

 PCX_VAL_INT

This macro declares a data item to have integer type, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

 PCX_VAL_FLOAT32

This macro declares a data item to have 32-bit float type, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

 PCX_MAX_MSG_LENGTH

This is the maximum number of data bytes per CAN message.

 PCX_NUM_CAN_DEVICES

This is the number of CAN busses supported for this target.

Enumerations
 PCX_ERROR_T

Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type.

 PCX_MSG_DIR_T

This enumeration declares the different types of CAN messages, receive and transmit, when used with the pcx_declare_message() function.

 PCX_BUS_STATE_T

This enumeration declares the different CAN bus states returned by the pcx_get_bus_state() function.

 PCX_DATATYPES_T

Input and output data types for packing and unpacking CAN messages.

 PCX_RC_T

An enumerated type which contains success and failure codes returned by some CAN messaging feature (PCX) functions.

Data types
 PCX_LCHAN_T

This declares a type with enough value range to represent all logical CAN busses for all targets.

 PCX_HANDLE_T

This is the handle type given to CAN messages declared via the pcx_declare_message() function.

Variables
const PCX_HANDLE_Tpcx_tot_allow_msg_tx

This is the total number of permissible transmit messages.

const PCX_HANDLE_Tpcx_tot_allow_msg_rx

This is the total number of permissible receive messages.

PCX_TX_MSG_Tpcx_tx_msg

This is an array of transmit message structures, representing each of the declared transmit messages.

PCX_RX_MSG_Tpcx_rx_msg

This is an array of receive message structures, representing each of the declared received messages.

PCX_HANDLE_Tpcx_sorted_rx_msg

This is an array used to post sort the receive messages into CAN identifier order.

PCX_HANDLE_Tpcx_queued_tx_list

This is an array of messages queued for transmission for each CAN bus.

Functions
BOOLpcx_config

Configure the use of a CAN bus.

PCX_HANDLE_Tpcx_declare_message

Declare a CAN message prior to starting the application.

BOOLpcx_transmit

This function places a single message in a transmit-message queue and flags it to be transmitted.

U8pcx_receive

Return CAN message data if the message has been received.

PCX_RC_Tpcx_get_transmit_status

Provide status on message transmission over time.

BOOLpcx_is_bus_unavailable

Return the status of a CAN bus (deprecated).

PCX_BUS_STATE_Tpcx_get_bus_state

Return the state of a CAN bus.

voidpcx_pack_msg

Pack a series of data items into an array of CAN message bytes.

voidpcx_unpack_msg

Unpack a series of data items from an array of CAN message bytes.

voidpcx_vdb_pack_msg

Pack a series of data items into an array of CAN message bytes.

voidpcx_vdb_unpack_msg

Unpack a series of data items from an array of CAN message bytes.

5.15.10. Interface detail

5.15.10.1.  Macros

5.15.10.1.1. PCX_CONFIG_ERROR
Definition:

#define PCX_CONFIG_ERROR ((PCX_HANDLE_T)-1)

Description:

This macro declares the error value, returned from pcx_declare_message(), if the declared message could not be accepted (for whatever reason).

5.15.10.1.2. PCX_ANY_CAN_ID
Definition:

#define PCX_ANY_CAN_ID 0xFFFFFFFFUL

Description:

This macro declares a CAN message which can have any identifier when calling pcx_declare_message().

5.15.10.1.3. PCX_STANDARD_ID
Definition:

#define PCX_STANDARD_ID ((U8)0)

Description:

This macro declares a CAN message identifier to be standard (11-bit) when calling pcx_declare_message().

5.15.10.1.4. PCX_EXTENDED_ID
Definition:

#define PCX_EXTENDED_ID ((U8)1)

Description:

This macro declares a CAN message identifier to be extended (29-bit) when calling pcx_declare_message().

5.15.10.1.5. PCX_RX_DATA
Definition:

#define PCX_RX_DATA 1

Description:

This macro is a bitmask for the return value from calling pcx_receive().

The corresponding bit is set in the return value if data was received.

5.15.10.1.6. PCX_RX_OVERRUN
Definition:

#define PCX_RX_OVERRUN 2

Description:

This macro is a bitmask for the return value from calling pcx_receive().

The corresponding bit is set in the return value if the message was received more than once before pcx_receive() was called.

5.15.10.1.7. PCX_RX_ERROR
Definition:

#define PCX_RX_ERROR 4

Description:

This macro is a bitmask for the return value from calling pcx_receive().

The corresponding bit is set in the return value if data was received, but the received message length did not match the declared message length.

5.15.10.1.8. PCX_MSB_ORDER
Definition:

#define PCX_MSB_ORDER 0

Description:

This macro declares a data item that has most significant byte ordering, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

5.15.10.1.9. PCX_LSB_ORDER
Definition:

#define PCX_LSB_ORDER 1

Description:

This macro declares a data item that has least significant byte ordering, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

5.15.10.1.10. PCX_VAL_INT
Definition:

#define PCX_VAL_INT 0

Description:

This macro declares a data item to have integer type, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

5.15.10.1.11. PCX_VAL_FLOAT32
Definition:

#define PCX_VAL_FLOAT32 1

Description:

This macro declares a data item to have 32-bit float type, used when packing and unpacking messages using the pcx_vdb_pack_msg() and pcx_vdb_unpack_msg() functions.

5.15.10.1.12. PCX_MAX_MSG_LENGTH
Definition:

#define PCX_MAX_MSG_LENGTH ((U8)8)

Description:

This is the maximum number of data bytes per CAN message.

5.15.10.1.13. PCX_NUM_CAN_DEVICES
Definition:

#define PCX_NUM_CAN_DEVICES 2

Description:

This is the number of CAN busses supported for this target.

5.15.10.2.  Enumerations

5.15.10.2.1. PCX_ERROR_T
Summary:

Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type.

Enumerations:
PCX_ERR_BUS_ID_OUT_OF_RANGE

Error raised if the CAN bus argument to a function is invalid.

PCX_ERR_DATA_LENGTH_OUT_OF_RANGE

Error raised if the data length argument to a function is invalid.

PCX_ERR_STD_ID_OUT_OF_RANGE

Error raised if the CAN message identifier is out of range for a standard 11-bit identifier.

PCX_ERR_EXT_ID_OUT_OF_RANGE

Error raised if the CAN message identifier is out of range for a extended 29-bit identifier.

PCX_ERR_SAME_TX_MSG_DIFFERING_ATTRIBS

Error raised if a transmit message is declared for a subsequent time but the length of the CAN transmit message differs from the previous declaration.

PCX_ERR_TOO_MANY_TX_MSGS

Error raised if the number of declared transmit messages exceeds the build time limit of transmit messages.

PCX_ERR_DUPLICATE_RX_MSG

Error raised if a receive message is declared for a subsequent time.

PCX_ERR_TOO_MANY_RX_MSGS

Error raised if the number of declared receive messages exceeds the build time limit of receive messages.

PCX_ERR_BIT_RATE_IN_CONFIG_DIFFERS

Error raised if an inconsistent duplicate request has already occurred for a CAN bus.

PCX_ERR_UNSUPPORTED_BIT_RATE

Error raised if the baud rate requested when configuring a CAN bus is invalid.

PCX_ERR_BUS_ID_IN_CONFIG

Error raised if the referenced CAN bus is not supported for the target ECU.

PCX_ERR_NO_BITRATE_TABLE_MATCH

Error raised if a CAN bus could not be configured for a baud rate after application initialisation is complete.

An internal error, this should not occur.

PCX_ERR_PACK_MSG_INVALID_PARAM

Error raised if an invalid argument is passed to the message pack function.

PCX_ERR_PACK_MSG_FIELD_PARAM

Error raised if an invalid type code is found in the message pack data structure.

PCX_ERR_UNPACK_MSG_INVALID_PARAM

Error raised if an invalid argument is passed to the message pack function.

PCX_ERR_UNPACK_MSG_FIELD_PARAM

Error raised if an invalid type code is found in the message unpack data structure.

PCX_ERR_PACK_VDB_MSG_INVALID_PARAM

Error raised if an invalid argument is passed to the VDB message pack function.

PCX_ERR_UNPACK_VDB_MSG_INVALID_PARAM

Error raised if an invalid argument is passed to the VDB message unpack function.

PCX_ERR_RX_MSG_FOR_UNCONFIG_BUS_0

Error raised after application initialisation if a receive message has been declared for CAN bus 'n' which has not been configured.

'n' is (error_code - PCX_ERR_RX_MSG_FOR_UNCONFIG_BUS_0).

PCX_ERR_TX_MSG_FOR_UNCONFIG_BUS_0

Error raised after application initialisation if a transmit message has been declared for CAN bus 'n' which has not been configured.

'n' is (error_code - PCX_ERR_TX_MSG_FOR_UNCONFIG_BUS_0).

5.15.10.2.2. PCX_MSG_DIR_T
Summary:

This enumeration declares the different types of CAN messages, receive and transmit, when used with the pcx_declare_message() function.

Enumerations:
PCX_RX_MSG

The declared message will be received.

PCX_TX_MSG

The declared message will be transmitted.

5.15.10.2.3. PCX_BUS_STATE_T
Summary:

This enumeration declares the different CAN bus states returned by the pcx_get_bus_state() function.

Enumerations:
PCX_BUS_ERROR_ACTIVE

The initial state of the CAN bus controller.

The controller may transmit active error flags.

PCX_BUS_ERROR_PASSIVE

After an accumulation of errors, the CAN bus controller enters the error passive state.

In this state, the controller may transmit passive error flags.

PCX_BUS_OFF

After an excessive accumulation of transmission errors, the CAN bus controller enters the bus-off state.

In this stage, the controller will not transmit.

PCX_BUS_INVALID

If the referenced bus is not available for the ECU target.

5.15.10.2.4. PCX_DATATYPES_T
Summary:

Input and output data types for packing and unpacking CAN messages.

Enumerations:
PCX_TYPECODE_F32

Represents a 32-bit floating point type.

PCX_TYPECODE_BOOL

Represents a boolean type.

The physical data storage is either an 8-bit integer or 32-bit floating point depending on an argument provided to the pack and unpack functions.

PCX_TYPECODE_S8

Represents a signed 8-bit integer type.

PCX_TYPECODE_U8

Represents an unsigned 8-bit integer type.

PCX_TYPECODE_S16

Represents a signed 16-bit integer type.

PCX_TYPECODE_U16

Represents an unsigned 16-bit integer type.

PCX_TYPECODE_S32

Represents a signed 32-bit integer type.

PCX_TYPECODE_U32

Represents an unsigned 32-bit integer type.

5.15.10.2.5. PCX_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some CAN messaging feature (PCX) functions.

Enumerations:
PCX_RC_OK

Return code if everything progressed as expected.

PCX_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

5.15.10.3.  Data types

5.15.10.3.1. PCX_LCHAN_T
Definition:

typedef U8 PCX_LCHAN_T

Description:

This declares a type with enough value range to represent all logical CAN busses for all targets.

See pio.h for a list of relevant channels for a specific target.

5.15.10.3.2. PCX_HANDLE_T
Definition:

typedef S16 PCX_HANDLE_T

Description:

This is the handle type given to CAN messages declared via the pcx_declare_message() function.

5.15.10.4.  Variables

5.15.10.4.1. pcx_tot_allow_msg_tx
Definition:

const PCX_HANDLE_T pcx_tot_allow_msg_tx

Description:

This is the total number of permissible transmit messages.

The application code must declare and initialise this variable to be at least the total number of declared transmit messages in the application. It is permissible to set the variable to more than the declared total.

Range: [0, 100] messages

5.15.10.4.2. pcx_tot_allow_msg_rx
Definition:

const PCX_HANDLE_T pcx_tot_allow_msg_rx

Description:

This is the total number of permissible receive messages.

The application code must declare and initialise this variable to be at least the total number of declared receive messages in the application. It is permissible to set the variable to more than the declared total.

Range: [0, 100] messages

5.15.10.4.3. pcx_tx_msg
Definition:

PCX_TX_MSG_T pcx_tx_msg[]

Description:

This is an array of transmit message structures, representing each of the declared transmit messages.

Indexed by message handle.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pcx_tot_allow_msg_tx (or one if there are no transmit messages). The array is not to be accessed by application code.

5.15.10.4.4. pcx_rx_msg
Definition:

PCX_RX_MSG_T pcx_rx_msg[]

Description:

This is an array of receive message structures, representing each of the declared received messages.

Indexed by message handle.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pcx_tot_allow_msg_rx (or one if there are no receive messages). The array is not to be accessed by application code.

5.15.10.4.5. pcx_sorted_rx_msg
Definition:

PCX_HANDLE_T pcx_sorted_rx_msg[]

Description:

This is an array used to post sort the receive messages into CAN identifier order.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pcx_tot_allow_msg_rx (or one if there are no receive messages). The array is not to be accessed by application code.

5.15.10.4.6. pcx_queued_tx_list
Definition:

PCX_HANDLE_T pcx_queued_tx_list[][PCX_NUM_CAN_DEVICES]

Description:

This is an array of messages queued for transmission for each CAN bus.

The array for messages is one larger than the number of transmit messages to distinguish between queue empty and queue full. The queue for each CAN bus is circular in nature, where the start and end of the queue is defined by pcxl_start_queue[] and pcxl_end_queue[]. Indexed by queue position, then CAN bus.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the first index must equal pcx_tot_allow_msg_tx + 1 (or two if there are no transmit messages). The array is not to be accessed by application code.

5.15.10.5.  Functions

5.15.10.5.1. pcx_config()
Definition:

BOOL pcx_config(
   PCX_LCHAN_T           pcxf_bus_id,
   PIO_CAN_BAUD_RATE_T   pcxf_bit_rate_kbit_s);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Configure the use of a CAN bus.

Called by application code during initialisation to indicate that application code wishes to receive or transmit a messages on the CAN bus indicated (i.e., that the CAN bus will be used).

It is not an error for two or more calls to occur with the same information, but it is an error to get two requests with different bit rates specified for the same bus.

Can raise the following errors:
PCX_ERR_BUS_ID_IN_CONFIG, PCX_ERR_UNSUPPORTED_BIT_RATE, PCX_ERR_BIT_RATE_IN_CONFIG_DIFFERS.

Note

Must be called during application initialisation. Do not call after initialisation is complete.

Arg (data in): pcxf_bus_id

Which CAN bus the message is communicated on. Use the macros included by the pio.h file, of the form PIO_CAN_[NAME].

Arg (data in): pcxf_bit_rate_kbit_s

Requested baud rate of CAN bus. Use the macros included by the pio.h file, of the form PIO_CBAUD_[RATE]_KBPS.

Return:

True if configuration was accepted, false otherwise.

5.15.10.5.2. pcx_declare_message()
Definition:

PCX_HANDLE_T pcx_declare_message(
   PCX_MSG_DIR_T   pcxf_direction,
   PCX_LCHAN_T     pcxf_bus_id,
   U8              pcxf_use_extended_id,
   U8              pcxf_msg_length,
   U32             pcxf_msg_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Declare a CAN message prior to starting the application.

Declare a receive or transmit CAN message prior to starting the application. Called by application code for each CAN message of interest during initialisation.

Transmit messages can be declared more than once if necessary. If the data length of the transmit message differs from the previous declaration, an error will be raised. If the data length is greater than the previous declaration, the larger data length will be remembered as the expected length. If the data length is smaller than the previous declaration, the smaller data length is discarded.

Receive messages must only be declared once. Subsequent declarations of the same receive message are discarded.

Can raise the following errors:
PCX_ERR_BUS_ID_OUT_OF_RANGE, PCX_ERR_DATA_LENGTH_OUT_OF_RANGE, PCX_ERR_STD_ID_OUT_OF_RANGE, PCX_ERR_EXT_ID_OUT_OF_RANGE, PCX_ERR_SAME_TX_MSG_DIFFERING_ATTRIBS, PCX_ERR_TOO_MANY_TX_MSGS, PCX_ERR_DUPLICATE_RX_MSG, PCX_ERR_TOO_MANY_RX_MSGS.

Note

Must be called during application initialisation. Do not call after initialisation is complete.

Arg (data in): pcxf_direction

Set to PCX_TX_MSG if the message to declare is a transmit message, set to PCX_RX_MSG if its a receive message.

Arg (data in): pcxf_bus_id

Which CAN bus the message is communicated on.
Use the macros included by the pio.h file, of the form PIO_CAN_[NAME].

Arg (data in): pcxf_use_extended_id

Set to PCX_EXTENDED_ID if pcxf_msg_id is an extended identifier, set to PCX_STANDARD_ID if pcxf_msg_id is a standard identifier.

Arg (data in): pcxf_msg_length

The length of the CAN message data.
Range: [0, 8]

Arg (data in): pcxf_msg_id

The CAN message identifier.
Range: [0, 2047] if standard identifier
Range: [0, 536870911] if extended identifier
Or: PCX_ANY_CAN_ID if declaring the CAN bus can receive or transmit a CAN message with any message identifier.

Return:

An integer handle if the message was accepted or PCX_CONFIG_ERROR if the message was rejected. If rejected, the CAN message will not be transmitted or received for the specified bus (pcxf_bus_id).

The message is rejected if any of the following conditions arises:

  • pcxf_bus_id is outside its valid range

  • pcxf_msg_length is outside its valid range

  • if the message ID is standard but outside its valid range

  • if the message ID is extended but outside its valid range

  • too many transmit messages have been declared

  • too many receive messages have been declared

5.15.10.5.3. pcx_transmit()
Definition:

BOOL pcx_transmit(
   PCX_HANDLE_T   pcxf_msg_handle,
   const U8      *pcxf_msg_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function places a single message in a transmit-message queue and flags it to be transmitted.

Request that a CAN message, identified by the message handle pcxf_msg_handle, be transmitted as soon as possible. If a CAN message hardware buffer is free, the message is queued in the hardware. Otherwise, the message is queued in a software buffer and the message is transmitted later.

If a transmit message stored in the software buffer has not yet been transmitted when a subsequent request to transmit the same message occurs, the data from the previous request is overwritten with the data from this request before the message is sent. This mechanism ensures the latest information is sent (but be careful, if a message must be delivered (e.g., the message contains state protocol information) then the caller must ensure the message has been transmitted before attempting another request).

Counters that can be used to determine successful transmission over time can be retrieved using the pcx_get_transmit_status() function.

Arg (data in): pcxf_msg_handle

Handle to message to queue (as returned by calling pcx_declare_message()).
Range: [0, length(pcx_tx_msg) - 1]

Arg (data in): pcxf_msg_data

Pointer to location of CAN message transmit data.
Cannot be NULL.

Return:

True if no error in transmission, false otherwise.

5.15.10.5.4. pcx_receive()
Definition:

U8 pcx_receive(
   PCX_HANDLE_T   pcxf_msg_handle,
   U8            *pcxf_msg_data,
   U32           *pcxf_msg_timestamp);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return CAN message data if the message has been received.

Extract the data from a received CAN message and place it in the caller's array (pcxf_msg_data).

  • If the message has never been received, then the caller's buffer is set with zeros and the time stamp set to zero.

  • If the message has been received, then the caller's buffer is set to the contents of the message and the time stamp set to the message reception time.

  • If the message has been received, but a new message has not been received since the last time pcx_receive() was called (message overrun), then the caller's buffer is set to the contents of the last received message and the time stamp set to the last received message reception time.

The time stamp is a low accuracy time stamp, taken a short period of time after the message is received. That period of time is variable depending on the load of the processor and will therefore suffer jitter. The timer used for the time stamp is a free running timer, that wraps at its maximum to zero.

WARNING: The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Arg (data in): pcxf_msg_handle

The message handle that refers to the CAN message to be received (as returned from calling pcx_declare_message()).
Range: [0, length(pcx_rx_msg) - 1]

Arg (data out): pcxf_msg_data

Pointer to array of data bytes to be filled from the most recently received CAN message. The array pointed to must be PCX_MAX_MSG_LENGTH bytes in length.
Cannot be NULL. The message data is always filled with the data from the most recent received message, even if the return value indicates PCX_RX_ERROR

Arg (data out): pcxf_msg_timestamp

Pointer to variable to be written with the low accuracy time stamp of the message reception.
Cannot be NULL.
Range: [0, 4294967295] microseconds

Return:

Returns a bitmap of status information:

  • PCX_RX_DATA - set if a message has been received since the last call

  • PCX_RX_OVERRUN - set if multiple messages has been received since the last call

  • PCX_RX_ERROR - set if the most recently received message differs in length from the declared length

5.15.10.5.5. pcx_get_transmit_status()
Definition:

PCX_RC_T pcx_get_transmit_status(
   PCX_HANDLE_T   pcxf_msg_handle,
   U16           *pcxf_tx_requests,
   U16           *pcxf_tx_overwrites,
   U16           *pcxf_tx_acks);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Provide status on message transmission over time.

The function provides a set of counters which can be used to determine whether a message has been transmitted or not, including a count of the requests for transmission from the application, a count of the number of times the message was queued in software rather than being immediately passed to the CAN controller for immediate transmission, and a count of the number of times the message was successfully transmited on the bus.

A difference in the count between the application request for transmission and successful transmission indicates a failure to successfully transmit.

Arg (data in): pcxf_msg_handle

The message handle that refers to the transmit CAN message (as returned from calling pcx_declare_message()).
Range: [0, length(pcx_rx_msg) - 1]

Arg (data out): pcxf_tx_requests

Pointer to storage written with the count of transmission requests made by the application for this message.
The counter wraps modulo 65536 and does not saturate.
Cannot be NULL.
Range: [0, 65535] events

Arg (data out): pcxf_tx_overwrites

Pointer to storage written with the count of transmission requests which were queued by the software for later transmission because the CAN controller could not immediately accept the message for transmission.
The counter wraps modulo 65536 and does not saturate.
Cannot be NULL.
Range: [0, 65535] events

Arg (data out): pcxf_tx_acks

Pointer to storage written with the count of message transmissions successfully made by the CAN controller (i.e., those transmit messages which were acknowledged by at least one CAN node on the bus, not including the transmitting node).
The counter wraps modulo 65536 and does not saturate.
Cannot be NULL.
Range: [0, 65535] events

Return:

5.15.10.5.6. pcx_is_bus_unavailable()
Definition:

BOOL pcx_is_bus_unavailable(
   PCX_LCHAN_T   pcxf_bus_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the status of a CAN bus (deprecated).

Similar in functionality to pcx_get_bus_state(). This function became deprecated in version 1.8.4 and will be removed in a future release. The function is currently retained to provide backwards compatibility to previous releases.

Arg (data in): pcxf_bus_id

The CAN bus to inspect.
Use the macros included by the pio.h file, of the form PIO_CAN_[NAME].

Return:

True if the CAN bus is in an error condition (bus off), false otherwise.

5.15.10.5.7. pcx_get_bus_state()
Definition:

PCX_BUS_STATE_T pcx_get_bus_state(
   PCX_LCHAN_T   pcxf_bus_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the state of a CAN bus.

Arg (data in): pcxf_bus_id

The CAN bus to inspect.
Use the macros included by the pio.h file, of the form PIO_CAN_[NAME].

Return:

One of the PCX_BUS_STATE_T enumerations.

5.15.10.5.8. pcx_pack_msg()
Definition:

void pcx_pack_msg(
   U8                 *pcxf_msg_data,
   const void *const  *pcxf_item_ptr,
   const U8           *pcxf_field_start,
   const U8           *pcxf_field_width,
   const U8           *pcxf_is_signed,
   const U8           *pcxf_type_code,
   const U8            pcxf_use_bool_type,
   const U8            pcxf_num_fields);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Pack a series of data items into an array of CAN message bytes.

Pack a series of data items (of various value types) into an array of CAN message data bytes (e.g., convert a floating point data item to a 3 bit integer, and then pack it into an arbitrary bit position in the array). The array can be passed to pcx_transmit() as CAN data to be transmitted.

The packing sequence works as follows:

  • for each element in pcxf_item_ptr

    1. read the data value from pcxf_item_ptr based on the type from pcxf_type_code and convert to an integer
      (clip to maximum of a 32-bit integer if converting from a float)

    2. clip the integer to the field width as given by pcxf_field_width taking into account the sign given by pcxf_is_signed

    3. write bits to pcxf_msg_data based with most significant byte ordering and the bit position given by pcxf_field_start

Can raise the following errors:
PCX_ERR_PACK_MSG_INVALID_PARAM, or PCX_ERR_PACK_MSG_FIELD_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_vdb_pack_msg().

Arg (data out): pcxf_msg_data

Pointer to an array of data bytes to be set (the array must be 8 bytes in length, if it is too small, this function will write off the end of the array). Unspecified fields are set to zero.
Cannot be NULL.

Arg (data in): pcxf_item_ptr

Pointer to array of pointers to data to be packed, the type of the final pointed to data is defined by the array pcxf_type_code.
Cannot be NULL.

Arg (data in): pcxf_field_start

Pointer to array of field start bit numbers. For each item to pack into pcxf_msg_data, the function determines where to place the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. For items whose bit length entry exceeds 7, the bit length must be one of: 0, 8, 16, 24, 32, 40, 48, 56.
For fields with lengths ranging from 1 to 15 bits, the start address defines where the message's least significant bit is stored.
For fields with lengths more than or equal to 16 bits, the start address defines where the message's most significant bit is stored.
Cannot be NULL.

Note

If the fields overlap (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_field_width

Pointer to array of field bit widths. For each item to pack into pcxf_msg_data, the function determines how many bits to place into the array using the corresponding element from this array. The following values are allowed: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24 and 32. Items of 8 bits or fewer may not be defined so as to straddle CAN byte boundaries.
Cannot be NULL.

Arg (data in): pcxf_is_signed

Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to pack into pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not. If the item is negative but specified in this array as unsigned, the item is clipped to zero.
Cannot be NULL.

Arg (data in): pcxf_type_code

Pointer to array of data type codes. Each element determines the data type of each element in pcxf_item_ptr. The type of each element is one of: PCX_TYPECODE_F32, PCX_TYPECODE_BOOL, PCX_TYPECODE_S8, PCX_TYPECODE_U8, PCX_TYPECODE_S16, PCX_TYPECODE_U16, PCX_TYPECODE_S32, PCX_TYPECODE_U32. The data storage for a boolean type depends on the pcxf_use_bool_type argument.
Cannot be NULL.

Arg (data in): pcxf_use_bool_type

True if boolean types are stored as 8-bit integers, false clear if boolean types are stored as 32-bit floating point.

Arg (data in): pcxf_num_fields

Number of fields in each of pcxf_item_ptr, pcxf_field_start, pcxf_field_width, pcxf_is_signed, and pcxf_type_code. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.
Range: [1, 255] fields

5.15.10.5.9. pcx_unpack_msg()
Definition:

void pcx_unpack_msg(
   void *const  *pcxf_item_ptr,
   const U8     *pcxf_msg_data,
   const U8     *pcxf_field_start,
   const U8     *pcxf_field_width,
   const U8     *pcxf_is_signed,
   const U8     *pcxf_type_code,
   const U8      pcxf_use_bool_type,
   const U8      pcxf_num_fields);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Unpack a series of data items from an array of CAN message bytes.

Unpack a series of integer data items from an array of CAN message data bytes (e.g., unpack a 3 bit data value from an arbitrary bit position in the array). The array can be filled by calling pcx_receive().

The unpacking sequence works as follows:

  • for each element in pcxf_item_ptr

    1. read the data from the buffer pcxf_msg_data, based on the item's field start position pcxf_field_start, and bit width pcxf_field_width, most significant byte first

    2. if the item is signed as given by pcxf_is_signed, then perform sign extension

    3. convert the value to the appropriate type as given by pcxf_type_code

    4. write the converted value to the store given by pcxf_item_ptr

Note

An alternative of this function with differing functionality is available as pcx_vdb_unpack_msg().

Can raise the following errors:
PCX_ERR_UNPACK_MSG_INVALID_PARAM, or PCX_ERR_UNPACK_MSG_FIELD_PARAM.

Arg (data in): pcxf_msg_data

Pointer to an array of data bytes to be read from (the array must be large enough to bound the unpacking, if it is too small, this function will read off the end of the array).
Cannot be NULL.

Arg (data in): pcxf_item_ptr

Pointer to array of pointers to data to be unpacked, the type of the final pointed to data is defined by the array pcxf_type_code.
Cannot be NULL.

Arg (data in): pcxf_field_start

Pointer to array of field start bit numbers. For each item to unpack from pcxf_msg_data, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. For items whose bit length entry exceeds 7, the bit length must be one of: 0, 8, 16, 24, 32, 40, 48, 56.
For fields with lengths ranging from 1 to 15 bits, the start address defines where the message's least significant bit is stored.
For fields with lengths more than or equal to 16 bits, the start address defines where the message's most significant bit is stored.
Cannot be NULL.

Arg (data in): pcxf_field_width

Pointer to array of field bit widths. For each item to unpack from pcxf_msg_data, the function determines how many bits to retrieve from the array using the corresponding element from this array. The following values are allowed: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24 and 32. Items of 8 bits or fewer may not be defined so as to straddle CAN byte boundaries.
Cannot be NULL.

Note

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed

Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack from pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not. If the item is negative but specified in this array as unsigned, the item is clipped to zero.
Cannot be NULL.

Arg (data in): pcxf_type_code

Pointer to array of data type codes. Each element determines the data type of each element in pcxf_item_ptr. The type of each element is one of: PCX_TYPECODE_F32, PCX_TYPECODE_BOOL, PCX_TYPECODE_S8, PCX_TYPECODE_U8, PCX_TYPECODE_S16, PCX_TYPECODE_U16, PCX_TYPECODE_S32, PCX_TYPECODE_U32. The data storage for a boolean type depends on the pcxf_use_bool_type argument.
Cannot be NULL.

Arg (data in): pcxf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

Arg (data in): pcxf_num_fields

Number of fields in each of pcxf_item_ptr, pcxf_field_start, pcxf_field_width, pcxf_is_signed, and pcxf_type_code. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.

5.15.10.5.10. pcx_vdb_pack_msg()
Definition:

void pcx_vdb_pack_msg(
   const F32 *const  *pcxf_item_ptr,
   U8                *pcxf_msg_data,
   const U8          *pcxf_field_start,
   const U8          *pcxf_field_width,
   const U8          *pcxf_is_signed,
   const U8          *pcxf_valtype,
   const U8          *pcxf_order,
   const F32         *pcxf_eng_min,
   const F32         *pcxf_eng_max,
   const F32         *pcxf_scale,
   const F32         *pcxf_offset,
   const U8           pcxf_clip_scaled,
   const U8           pcxf_use_bool_type,
   const U8           pcxf_num_fields);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Pack a series of data items into an array of CAN message bytes.

Pack a series of floating point data items into an array of CAN message data bytes (e.g., convert a floating point data item to a 32 bit integer, and then pack it into an arbitrary bit position in the array). The array can be passed to pcx_transmit() as CAN data to be transmitted.

The packing sequence works as follows:

  • for each element in pcxf_item_ptr

    1. clip to engineering min and max given by pcxf_eng_min and pcxf_eng_max, if pcxf_clip_scaled is true

    2. convert to value type given by pcxf_valtype
      (if converting to integer value type, scale based on pcxf_scale and pcxf_offset)

    3. clip to bit width of field in CAN message bytes based on pcxf_field_width

    4. write bits to pcxf_msg_data based on the byte order given in pcxf_order
      and the bit position given by pcxf_field_start

Can raise the following errors:
PCX_ERR_PACK_VDB_MSG_INVALID_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_pack_msg().

Arg (data in): pcxf_item_ptr

Pointer to array of pointers to data to be packed. Each data item is stored as a 32-bit float.
Cannot be NULL.

Arg (data out): pcxf_msg_data

Pointer to an array of data bytes to be set (the array must be 8 bytes in length, if it is too small, this function will write off the end of the array). All unwritten fields are set to zero.
Cannot be NULL.

Arg (data in): pcxf_field_start

Pointer to array of field start bit numbers. For each item to pack into pcxf_msg_data, the function determines where to place the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist.
Cannot be NULL.

The ordering of the bytes (see pcxf_order) determines how the start position is specified. If the ordering is specified as LSB then the start position is the least significant message bit of the least significant message byte.

If the ordering is specified as MSB then the start position is the most significant message bit of the most significant message byte.

Note

If the fields overlap (due to overlapping start and width parameters) then the functionality is undefined.

Arg (data in): pcxf_field_width

Pointer to array of field bit widths. For each item to pack into pcxf_msg_data, the function determines how many bits to place into the array using the corresponding element from this array.
Cannot be NULL.
Element range: [1, 32] bits

Note

If the fields overlap (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed

Unused. Set to NULL.

Arg (data in): pcxf_valtype

Pointer to array of data type codes. Each element can be one of: PCX_VAL_INT, and PCX_VAL_FLOAT32.
Cannot be NULL.

Arg (data in): pcxf_order

Pointer to array of data type byte storage order. Each element can be one of: PCX_MSB_ORDER, and PCX_LSB_ORDER.
Cannot be NULL.

Arg (data in): pcxf_use_bool_type

Unused. Set to false.

Arg (data in): pcxf_eng_min

Pointer to array of engineering minimum values. For each item to pack into pcxf_msg_data, the function clips the item to the corresponding minimum element from this array if pcxf_clip_scaled is true.
Cannot be NULL.

Arg (data in): pcxf_eng_max

Pointer to array of engineering maximum values. For each item to pack into pcxf_msg_data, the function clips the item to the corresponding maximum element from this array if pcxf_clip_scaled is true.
Cannot be NULL.

Arg (data in): pcxf_scale

Pointer to array of divisors. For each integer item to pack into pcxf_msg_data, the function subtracts an offset specified by pcxf_offset and scales the item by the corresponding divisor in this array.
Cannot be NULL.

Note

If the divisor is zero, then the integer item is set to zero.

Arg (data in): pcxf_offset

Pointer to array of adders. For each integer item to pack into pcxf_msg_data, the function subtracts the offset specified by this array and scales the item by the corresponding divisor in pcxf_scale.
Cannot be NULL.

Arg (data in): pcxf_clip_scaled

True if each data item should be clipped to the minimum and maximum specified by pcxf_eng_min and pcxf_eng_max, otherwise false if no clipping is to be performed.

Note

If the representation of the data item value (from pcxf_item_ptr, after clipping (if clipping is applied)) is larger in bit width than the field to pack into, then the packed value is clipped to the bit width of the field to pack into.

Arg (data in): pcxf_num_fields

Number of fields in each of pcxf_item_ptr, pcxf_field_start, pcxf_field_width, pcxf_is_signed, pcxf_valtype, pcxf_order, pcxf_eng_min, pcxf_eng_max, pcxf_scale and pcxf_offset. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.

5.15.10.5.11. pcx_vdb_unpack_msg()
Definition:

void pcx_vdb_unpack_msg(
   F32 *const  *pcxf_item_ptr,
   U32 *const  *pcxf_item_raw_ptr,
   const U8    *pcxf_msg_data,
   const U8    *pcxf_field_start,
   const U8    *pcxf_field_width,
   const U8    *pcxf_is_signed,
   const U8    *pcxf_valtype,
   const U8    *pcxf_order,
   const F32   *pcxf_eng_min,
   const F32   *pcxf_eng_max,
   const F32   *pcxf_scale,
   const F32   *pcxf_offset,
   const U8     pcxf_clip_scaled,
   const U8     pcxf_use_bool_type,
   const U8     pcxf_num_fields);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Unpack a series of data items from an array of CAN message bytes.

Unpack a series of data items of various types from an array of CAN message data bytes (e.g., unpack a 32 bit data value from an arbitrary bit position in the array). The array can be filled by calling pcx_receive().

The unpacking sequence works as follows:

  • for each element in pcxf_item_ptr

    1. read the data from the buffer pcxf_msg_data, based on the item's field start position pcxf_field_start, and bit width pcxf_field_width, where the byte order of the data is given by pcxf_order

    2. convert to a floating point value, performing sign extension if necessary as specified by pcxf_is_signed

    3. scale the value as given by pcxf_scale and pcxf_offset

    4. if clipping is enabled pcxf_clip_scaled, then clip the value based on the engineering minimum and maximum (pcxf_eng_min and pcxf_eng_max)

    5. write the resulting value to the store given by pcxf_item_ptr

Can raise the following errors:
PCX_ERR_UNPACK_VDB_MSG_INVALID_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_unpack_msg().

Arg (data in): pcxf_item_ptr

Pointer to array of pointers to data to be unpacked. Each data item is stored as a 32-bit float.
Cannot be NULL.

Arg (data in): pcxf_item_raw_ptr

Pointer to array of pointers to data to be unpacked. Each data item is stored as a 32-bit integer, taken from the CAN message without clipping and scaling.
If the pointer is NULL, raw data items are not written.

Arg (data out): pcxf_msg_data

Pointer to an array of data bytes to be read (the array must be large enough to bound the unpacking, if it is too small, this function will read off the end of the array).
Cannot be NULL.

Arg (data in): pcxf_field_start

Pointer to array of field start bit numbers. For each item to unpack from pcxf_item_ptr, the function determines where to read the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist.
Cannot be NULL.

The ordering of the bytes (see pcxf_order) determines how the start position is specified. If the ordering is specified as LSB then the start position is the least significant message bit of the least significant message byte.

If the ordering is specified as MSB then the start position is the most significant message bit of the least significant message byte.

Arg (data in): pcxf_field_width

Pointer to array of field bit widths. For each item to unpack from pcxf_msg_data, the function determines how many bits to read into the array using the corresponding element from this array.
Cannot be NULL.
Element range: [1, 32] bits

Note

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed

Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack into pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not.
Cannot be NULL.

Arg (data in): pcxf_valtype

Pointer to array of data type codes. Each element can be one of: PCX_VAL_INT, and PCX_VAL_FLOAT32.
Cannot be NULL.

Arg (data in): pcxf_order

Pointer to array of data type byte storage order. Each element can be one of: PCX_MSB_ORDER, and PCX_LSB_ORDER.
Cannot be NULL.

Arg (data in): pcxf_use_bool_type

Unused. Set to false.

Arg (data in): pcxf_eng_min

Pointer to array of engineering minimum values. For each item to unpack from pcxf_msg_data, the function clips the item to the corresponding minimum element from this array if pcxf_clip_scaled is true.
Cannot be NULL.

Arg (data in): pcxf_eng_max

Pointer to array of engineering maximum values. For each item to unpack from pcxf_msg_data, the function clips the item to the corresponding maximum element from this array if pcxf_clip_scaled is true.
Cannot be NULL.

Arg (data in): pcxf_scale

Pointer to array of multipliers. For each integer item to unpack from pcxf_msg_data, the function scales the item by the corresponding multiplier in this array and adds an offset specified by pcxf_offset.
Cannot be NULL.

Arg (data in): pcxf_offset

Pointer to array of adders. For each integer item to unpack from pcxf_msg_data, the function scales the item by the corresponding multiplier in pcxf_scale and adds the offset specified by this array.
Cannot be NULL.

Arg (data in): pcxf_clip_scaled

True if each data item should be clipped to the minimum and maximum specified by pcxf_eng_min and pcxf_eng_max, otherwise false if no clipping is to be performed.

Arg (data in): pcxf_num_fields

Number of fields in each of pcxf_item_ptr, pcxf_field_start, pcxf_field_width, pcxf_is_signed, pcxf_valtype, pcxf_order, pcxf_eng_min, pcxf_eng_max, pcxf_scale and pcxf_offset (and for pcxf_item_raw_ptr if it is not NULL). The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.

5.16. CAN Calibration Protocol (CCP) messaging feature (PCP)

5.16.1. Overview

The CAN Calibration Protocol (CCP — as defined by ASAM MCD-MC1) is a simple CAN based messaging system for communicating between a PC based tool and the ECU. The PC based tool could be used for reprogramming, or calibration, or servicing (see Appendix C, Supporting tools for an introduction to a few of these tools) through the use of an ASAP2 file (see Target ASAP2 file for more).

Figure 5.16. ASAM MCD-MC1 interaction

ASAM MCD-MC1 interaction

The messaging used to implement CCP is defined by ASAM MCD-1MC (ASAP1), where ASAM MCD-1a covers the ECU and ASAM MCD-1b covers the PC tool. The implementation of CCP messages by OpenECU is detailed in Appendix F, CCP compliance.

5.16.1.1. Messaging

The CCP implementation uses a small number of CAN identifiers for transporting messages to and from the ECU.

Figure 5.17. CCP messaging

CCP messaging

CRO — Command Return Object

The CAN message used by the reprogramming or calibration tool when sending a request to the ECU.

DTO — Data Transmission Object

The CAN message used by the ECU when replying to a CRO.

DAQ — Data Acquisition Queue

The CAN message used to transmit DAQ information from the ECU to the calibration tool.

Unlike CRO and DTO messages, which are response based, the DAQ messages are sent on a periodic basis (rather than on request from the calibration tool). DAQ messages are sent by the library in bursts.

The OpenECU implementation of CCP uses the same CAN identifier for DAQ messages as DTO messages.

The CAN identifiers to be used are defined by the application during build time.

Note

Certain targets, which are not on general release, support CCP parameters which can themselves be calibrated. Using this feature requires caution as the act of reprogramming them with altered values changes subsequent communications using the very interface just used for reprogramming.

On those targets pcpc_tx_id and pcpc_rx_id set the DTO and CRO CAN IDs used by the ECU respectively; pcpc_bus is the zero-based CAN bus index to use for CCP; pcpc_station_addr is the station address for the ECU; and pcpc_baud is the baud rate selected (in kbit/s) used in reprogramming mode, though this may be set differently by user initialisation of the CAN bus in application mode.

5.16.1.2. CCP during reprogramming mode

During reprogramming mode, CCP is used for reprogramming of the ECU. See Section 3.3.11, “Program the ECU” for details.

5.16.1.3. CCP during application mode

During application mode, CCP is used for a number of purposes:

To initiate reprogramming

While in application mode, the ECU can accept or reject reprogramming requests. In some cases, it is convenient to accept reprogramming requests because it removes the need to put the ECU into reprogramming mode through a power reset. In some other cases, it is essential that an accidental reprogramming request does not cause application mode to stop when it is controlling the system (e.g., controlling a motor or set of injectors). For this reason, the application can tell the library when to accept and reject reprogramming requests through the pcp_inhibit_reprogramming() function.

To write application calibration variables

If the ECU is a developer unit, then the library will accept requests to change calibration data while the application is running. Developer units have additional RAM which allows the calibration which is usually stored in ROM to be stored in RAM and modified while the application is running.

To read application variables

The library's CCP implementation supports DAQ lists. A DAQ list is a list of addresses to read and transmit on a periodic basis. The PC based tool creates the DAQ lists and requests the ECU to transmit them periodically. The library supports 4 DAQ lists with 16 ODTs each (each ODT can have up to 7 addresses for reading). For further information about DAQ lists and ODTs, see the ASAM MCD-MC1 specification.

Extract manufacturer's information using EXCHANGE_ID command

The extended EXCHANGE_ID message can be used to extract manufacturer's information. More information on how EXCHANGE_ID is set up on OpenECU see the Section F.1, “EXCHANGE_ID message handling” section.

Whether CCP is enabled during application mode can be controlled by setting the pcp_ccpenabled variable at build time.

5.16.1.4. CCP seed/key security

To prevent third parties recalibrating or reprogramming modules, manufacturers typically enable CCP seed/key security for production modules. This requires a valid seed/key exchange to take place with the calibration tool, where the module generates a seed (usually at random) and the calibration tool must respond with the correct key value corresponding to that seed, calculated by a secret algorithm known to the module and the calibration tool.

The pcp_seed_key_config array (and the corresponding array size pcp_num_seed_key_configs) configures CCP seed/key security. Each element of this array specifies whether security is required for a CCP privilege level, and if so, what functions are used to generate the seed and to validate the key returned by the calibration tool. Note that seed generation functions are optional; if omitted, the platform will simply generate 32-bit random seeds for CCP seed/key exchanges for this privilege level.

To ensure that CCP seed/key security is also used during reprogramming mode, the functions used to generate the seed (if required) and validate the key are copied to non-volatile storage by the application. The reprogramming mode software retrieves the functions from non-volatile storage, and copies them to RAM for execution.

There are three CCP privilege levels: calibration, data acquisition, and programming. These privilege levels can be individually enabled or disabled. For instance, it is possible to enable reprogramming access whilst calibration and data acquisition access remains disabled. The calibration tool may impose further restrictions on how levels can be accessed.

CCP seed/key security is a standard feature of the protocol; however configuring it on different calibration/programming tools requires some knowledge of that tool's operation. Support will currently only be given for CCP seed/key security on PiSnoop (see Section C.2, “PiSnoop”), Vector CANape (see Section C.5, “Vector CANape”), and ATI Vision (see Section C.3, “ATI Vision”)

5.16.1.4.1. Specifying functions for use with CCP seed/key security
5.16.1.4.1.1. Seed generator function

The seed generator function must be of the form:

void seed_generator(const U8 privilege_level, U8 *const seed)

privilege_level specifies the privilege level for which a seed is being requested. Values are fixed by the CCP standard as:

  • 0x01 (1): Calibration
  • 0x02 (2): Data acquisition
  • 0x40 (64): Programming

seed is a four-byte array. This will initially contain values generated by a 32-bit random number algorithm within the OpenECU platform. The seed generator function may choose to leave these values intact, or may choose to set its own values in the seed array.

5.16.1.4.1.2. Key validator function

The key validator function must be of the form:

BOOL key_validator(const U8 privilege_level, const U8 *const seed, const U8 *const key, const U8 key_size)

privilege_level specifies the privilege level for which a seed is being requested (see Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for details).

seed is a four-byte array containing the last seed value passed to the calibration tool.

key is an array of up to six bytes whose length is specified by key_size. This contains the key passed back by the calibration tool.

The CCP 2.1 specification for the CCP_UNLOCK command has a six-byte field for the key, although in practice most implementations only use four bytes. The contents of the remaining bytes are often undefined, so the key validator must take care to match the expected seed-key algorithm.

The function must return TRUE if the key is valid for the seed, or FALSE if it is not.

5.16.1.4.1.3. Implementing seed/key functions

Because the seed generator and key validator functions will be relocated and run during reprogramming mode, it is ESSENTIAL that these functions do NOT access any global or static storage OR call any functions. If this is not the case, relocating and invoking the function in reprogramming mode will have unexpected consequences, because the function will read/write/execute memory at addresses which are not valid when in reprogramming mode. These consequences may include stuck outputs resulting in physical damage to hardware or electrical damage to the ECU, and/or complete permanent disablement of the ECU.

Diab implementation considerations

If the application is built using the Diab compiler, then the file containing these functions should be specified for compilation as normal. It is frequently the case that seed/key functions are supplied only as object or library code for security reasons, in which case the file must have been compiled with PowerPC variable bit length (VLE) instructions.

GCC implementation considerations

If the application is built using GCC, then the file containing these functions must also contain section attribute specifiers to place the code in sections that correspond to the names of the security functions. The attribute specifiers must be applied to the function prototypes in the form:

void seed_generator(const U8 privilege_level, U8 *const seed) __attribute__ ((section (".seed_generator")));

It is frequently the case that seed/key functions are supplied only as object or library code for security reasons, in which case the file must have been compiled without PowerPC variable bit length (VLE) instructions.

Note however that linkage of these functions requires special handling. Since compilers/linkers do not provide information about the sizes of functions, and since relocation of a function requires the function size to be known, extra symbols must be generated to report the end of each of these functions. These must be linked according to specific rules. To implement this, a suitable linker definition file excerpt is generated automatically, and this must be inserted at the correct point in the main linker definition file. See --diab-ldfile=FILE and --gcc-ldfile=FILE for further details about generating the linker excerpt. See --output-linker-file=FILE and --ld-excerpt-file=FILE for details about inserting the excerpt into the main linker definition file.

5.16.1.5. Library tasks

The library implements a single task to support CCP messaging. See Section 4.6.4, “Application and library tasks” for details. Excessive delay of this task by application tasks can cause CCP messages to miss their timing deadlines and this may be reported by PC based support tools.

5.16.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pcp.h
Macros
 PCP_PL_CAL

Mask value for CCP calibration privilege level.

 PCP_PL_DAQ

Mask value for CCP data acquisition privilege level.

 PCP_PL_PGM

Mask value for CCP reprogramming privilege level.

 PCP_PL_ALL

Mask value for all CCP privilege levels.

Data types
 PCP_SEED_KEY_CONFIG_T

Structure configuring security for one or more CCP privilege levels.

 PCP_SEED_GENERATOR_T

Typedef for the callback function used to generate a seed for a CCP seed-key exchange.

 PCP_KEY_VALIDATOR_T

Typedef for the callback function used to validate a key for a CCP seed-key exchange.

Variables
const PCP_SEED_KEY_CONFIG_Tpcp_seed_key_config

CCP seed-key configuration for application.

const U8pcp_num_seed_key_configs

Number of array elements in pcp_seed_key_config.

const U8pcp_ccpenabled

True if CCP messaging is enabled during application run, false otherwise.

Functions
U32pcp_get_rx_count

Return the number of CCP CRO messages received since the last reset.

voidpcp_inhibit_reprogramming

Enable or disable CCP reprogramming requests while running application mode.

voidpcp_client_task

The CAN calibration protocol (CCP) messaging task.

5.16.3. Interface detail

5.16.3.1.  Macros

5.16.3.1.1. PCP_PL_CAL
Definition:

#define PCP_PL_CAL 0x01

Description:

Mask value for CCP calibration privilege level.

5.16.3.1.2. PCP_PL_DAQ
Definition:

#define PCP_PL_DAQ 0x02

Description:

Mask value for CCP data acquisition privilege level.

5.16.3.1.3. PCP_PL_PGM
Definition:

#define PCP_PL_PGM 0x40

Description:

Mask value for CCP reprogramming privilege level.

5.16.3.1.4. PCP_PL_ALL
Definition:

#define PCP_PL_ALL (PCP_PL_CAL | PCP_PL_DAQ | PCP_PL_PGM)

Description:

Mask value for all CCP privilege levels.

5.16.3.2.  Data types

5.16.3.2.1. PCP_SEED_KEY_CONFIG_T
Summary:

Structure configuring security for one or more CCP privilege levels.

Members:
U8 PCP_SEED_KEY_CONFIG_T::privilege_levels

Bitwise mask specifying which privilege levels this applies to.

This mask may be set using the literals PCP_PL_CAL (calibration), PCP_PL_DAQ (data acquisition), PCP_PL_PGM (reprogramming) or PCP_PL_ALL (all three).

BOOL PCP_SEED_KEY_CONFIG_T::security_required

If security_required is set FALSE, no seed-key exchange is required for the specified privilege level(s).

They may be invoked by the calibration tool at any time. The callback structure elements are ignored.

If security_required is set TRUE, the callbacks provided are used to unlock the specified privilege levels. Activities for these privilege levels may not be invoked by the CCP master until they have been unlocked.

If security_required is set TRUE but either callback is NULL, it will not be possible to unlock these privilege levels and the calibration tool will be permanently prohibited from invoking activities for these privilege levels.

PCP_SEED_GENERATOR_T PCP_SEED_KEY_CONFIG_T::seed_request_callback

Pointer to callback function which is called to request a seed value for the specified privilege level(s) when the calibration tool attempts to unlock the privilege level(s).

Set this value to NULL if security is not required.

U8* PCP_SEED_KEY_CONFIG_T::seed_request_callback_end_addr

Address of location immediately after seed_request_callback function.

This allows the platform to calculate the size of the function.

PCP_KEY_VALIDATOR_T PCP_SEED_KEY_CONFIG_T::key_validation_callback

Pointer to callback function which is called to validate a key value for the returned by the calibration tool, where the key is generated from the seed returned by the previously-called seed_request_callback function.

Set this value to NULL if security is not required.

U8* PCP_SEED_KEY_CONFIG_T::key_validation_callback_end_addr

Address of location immediately after key_validation_callback function.

This allows the platform to calculate the size of the function.

5.16.3.2.2. PCP_SEED_GENERATOR_T
Definition:

typedef void(* PCP_SEED_GENERATOR_T)(const U8 pcpf_privilege_level, U8 *const pcpf_seed)

Description:

Typedef for the callback function used to generate a seed for a CCP seed-key exchange.

The function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

The platform software may copy the callback function to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg (data in): pcpf_privilege_level

The privilege level for this request will be one of the bit-mask values PCP_PL_CAL, PCP_PL_DAQ or PCP_PL_PGM, representing a request for calibration, data acquisition or programming privilege levels respectively.

Return:

The function must return a 32-bit seed value. Typically this will be generated through a random or pseudo-random process. This seed must be stored for later use by the corresponding key validation function when the calibration tool returns a key.

5.16.3.2.3. PCP_KEY_VALIDATOR_T
Definition:

typedef BOOL(* PCP_KEY_VALIDATOR_T)(const U8 pcpf_privilege_level, const U8 *const pcpf_seed, const U8 *const pcpf_key, const U8 pcpf_key_size)

Description:

Typedef for the callback function used to validate a key for a CCP seed-key exchange.

The function must generate the expected key from the last seed value returned by the corresponding seed request callback function and compare this to the key calculated by the calibration tool.

The function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

The platform software may copy the callback function to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg (data in): pcpf_privilege_level

The privilege level for this request will be one of the bit-mask values PCP_PL_CAL, PCP_PL_DAQ or PCP_PL_PGM, representing a request for calibration, data acquisition or programming privilege levels respectively.

Arg (data in): pcpf_key

The key is an array of bytes returned by the calibration tool, generated from the seed returned by the corresponding seed request callback function.

Arg (data in): pcpf_key_size

Size of key array in bytes. The array may be between zero and 6 bytes long. Typically the key will be a 32-bit value (4 bytes), i.e. the same size as the seed, but there is no requirement for this to be the case. The size must be checked by the function to ensure that out-of-bounds array accesses do not take place.

Return:

The function must return TRUE if the key is correct, or FALSE if not.

5.16.3.3.  Variables

5.16.3.3.1. pcp_seed_key_config
Definition:

const PCP_SEED_KEY_CONFIG_T pcp_seed_key_config[]

Description:

CCP seed-key configuration for application.

Each array element specifies the CCP seed-key security to be applied to one or more CCP privilege levels.

The code tolerates multiple array entries existing which specify the same CCP privilege level. If this occurs, the code carries out processing only for the first array element with a matching CCP privilege level. Any or all subsequent array entries are ignored.

5.16.3.3.2. pcp_num_seed_key_configs
Definition:

const U8 pcp_num_seed_key_configs

Description:

Number of array elements in pcp_seed_key_config.

5.16.3.3.3. pcp_ccpenabled
Definition:

const U8 pcp_ccpenabled

Description:

True if CCP messaging is enabled during application run, false otherwise.

5.16.3.4.  Functions

5.16.3.4.1. pcp_get_rx_count()
Definition:

U32 pcp_get_rx_count(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the number of CCP CRO messages received since the last reset.

Return:

A count of CCP CRO messages received since the last reset. The counter wraps modulo 4294967295.
Range: [0, 4294967295] messages

5.16.3.4.2. pcp_inhibit_reprogramming()
Definition:

void pcp_inhibit_reprogramming(
   U8   pcpf_inhibit);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Enable or disable CCP reprogramming requests while running application mode.

The ECU uses the CAN calibration protocol for reprogramming. Reprogramming requests are always honoured while the ECU is in reprogramming mode. In application mode, reprogramming requests can be enabled or disabled. For instance, the application might enable reprogramming requests only while it is in an idle and safe state.

If uncalled by the application, reprogramming is allowed by default.

Arg (data in): pcpf_inhibit

True if reprogramming should be inhibited, false otherwise.

5.16.3.4.3. pcp_client_task()
Definition:

void pcp_client_task(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

The CAN calibration protocol (CCP) messaging task.

This is the entry point for the CCP messaging task. The task handles enabling or disabling messaging based on pcp_ccpenabled. If messaging is enabled, then the task manages CCP CAN messages (reception and transmission) and scheduling of DAQ message processing (transmission).

Note

The CCP messaging task must be scheduled every 5 milliseconds.

5.17. J1939 (SAE) messaging feature (PJ1939)

5.17.1. Overview

J1939 is a SAE communications protocol, based on CAN, largely defined by the following documents:

SAE J1939/21

Defines the data link layer, including how J1939 messages map to the CAN specification, definition of Parameter Groups (PG), and definition of the transport protocol (for sending J1939 messages with more than 8 data bytes).

The library directly supports the transport protocol and has facilities to handle PG messages: on request (from another node on the network); periodically (ECU periodically transmits a PG); and on event (ECU transmits PG when a condition becomes true).

SAE J1939/71

Defines the vehicle application layer, essentially a list of predetermined messages and their contents.

SAE J1939/73

Defines the application layer diagnostics, which includes (amongst other things) support for Diagnostic Trouble Codes (DTC).

The core library supports the following basic diagnostic messages (to deal with Diagnostic Trouble Codes):

DM1

All active Diagnostic Trouble Codes

DM2

All previously active Diagnostic Trouble Codes

SAE J1939/81

Defines the network management protocol, a mechanism for allocating addresses to nodes on the J1939 network dynamically.

For the moment, the library only provides support for fixed address J1939 networks. The library will participate in messaging required to claim an address for the ECU, but the library will not dynamically change address when it loses negotiation, nor will the library track the address of other nodes.

It is assumed throughout this document, that the reader is familiar with the SAE J1939 specifications.

5.17.2. Node addressing

All nodes on a J1939 network have a unique identifier and a preferred network address. This information can be specified by setting the parameters in each channel compound statement (Section 8.1.4.20, “Compound statement: channel”).

For every J1939 channel, a pj1939l_node_name_* array is populated from the J1939 name fields (see SAE J1939/81 section 4.2 for further details). For example, pj1939l_node_name_0 corresponds to channel id 0. Each array can be viewed with a calibration tool and is populated as follows:

ElementBit number
00IG2IG1IG0VSI3VSI2VSI1VSI0
1VS6VS5VS4VS3VS2VS1VS01
2F7F6F5F4F3F2F1F0
3FI4FI3FI2FI1FI0EI2EI1EI0
4MC10MC9MC8MC7MC6MC5MC4MC3
5MC2MC1MC0IN20IN19IN18IN17IN16
6IN15IN14IN13IN12IN11IN10IN9IN8
7IN7IN6IN5IN4IN3IN2IN1IN0

Where:

IG

Industry Group

VSI

Vehicle System Instance

VS

Vehicle System

F

Function

FI

Function Instance

EI

ECU Instance

MC

Manufacturer code

IN

Identity Number

For now, the library does not support dynamic addressing. Applications must use a fixed network address. If that address is claimed, then the ECU will claim the NULL address (254) and only process network messages (see J1939/81).

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications. When the ECU has a network address (has claimed a non-NULL address without conflict), then the ECU can participate in all communications.

5.17.3. Messaging

J1939 supports long messages. Long messages contain more than 8 data bytes (and hence require more than one CAN message to be transmitted) and can be up to 1785 bytes long. Not all J1939 networks will have messages this long, and as RAM memory is precious on most of the target ECUs, the application can specify the largest message to be received through the pj1939_size_j1939_rx_buf variable.

The application can also define the number of receive and transmit long messages through the pj1939_num_rx_tx_bufs variable, allowing some balance in RAM use against application responsiveness.

Similarly, as RAM is precious, the number of receive and transmit messages to be buffered between processing by the J1939 stack is configurable by the application through the pj1939_num_trx and pj1939_num_ttx variables. As the CAN link baud rate will be known, and the time between processing by the application will be known, the worst case number of J1939 CAN messages could be derived by the application at build time, and an automatic number of buffers allocated.

5.17.4. Message bit and byte numbering

The library follows the bit and byte numbering convention laid out by the J1939 specifications.

Data byteBit number
LSMS      LS
187654321
2161514131211109
......
17851428014279142781427714276142751427414273
MSMS      LS

where byte 1 corresponds to the first received data byte in the first CAN message for the PG message. This numbering scheme, matches the J1939 specification but differs from the existing CAN feature (e.g., like pcx_receive() which refers to the first byte as byte 0). It is felt that although this may cause some confusion, it is better to present the bit ordering according to J1939.

A field which starts at bit 5 and has 10 bits of width is identified as follows:

Data byteBit number
18765----
2--14131211109

J1939 message fields are generally packed LSB first, so the bits would be interpreted as:

MSLS
Data byte 2Data byte 1
------141312111098765
ssssssxxxxxxxxxx

where x is the corresponding bit taken from the J1939 message data bytes, and s is the sign extension of the data. In this case, bit 14 may be considered the sign bit, if the data in the J1939 message data is signed.

However, if the J1939 message field was packed MSB first, the bits would be interpreted as:

MSLS
Data byte 1Data byte 2
------651413121110987
ssssssxxxxxxxxxx

where x is the corresponding bit taken from the J1939 message data bytes, and s is the sign extension of the data. In this case, bit 6 may be considered the sign bit, if the data in the J1939 message data is signed.

5.17.5. PGNs

The library makes use of PGN values. A PGN is a 17 bit wide integer, having either PDU1 or PDU2 format (see SAE J1939/21 for more):

Bits
161514131211109876543210
PDU1 format
DP0PF7PF6PF5PF4PF3PF2PF1PF0DA7DA6DA5DA4DA3DA2DA1DA0
PDU2 format
DP0PF7PF6PF5PF4PF3PF2PF1PF0PS7PS6PS5PS4PS3PS2PS1PS0

Where:

DP

Data page

PF

PDU format — the PGN has PDU1 format when the value of PDU format is less than 240, and has PDU2 format when greater than or equal to 240.

PS

PDU specific

DA

Destination address

A common action when using the J1939 protocol is responding to requests, and the library provides support for trapping specific PGs and filtering out others by populating the _pgn_table and pj1939_num_pgns variables. The library will automatically generate a NACK if a PG request message is received but does not match one of the PGNs in _pgn_table (unless of course, the request was sent to the global address, in which case, the library does not generate a NACK).

To determine if a PGN has been requested, the library provides the pj1939_was_pgn_requested() function.

5.17.6. Receive messages

The library buffers received J1939 messages for the application, discarding messages which are not of interest. The application can determine whether a message has been received since last time and extract the contents of the message by calling pj1939_pg_receive().

Each receive message buffer stores one J1939 message. If a J1939 message with the same PGN is received more than once between calls from the application, then the message buffer is overwritten with the latest received message. This ensures the latest copy of a J1939 message is available to the application, but is not suitable for J1939 messages which contain state information (e.g., J1939 messages containing protocol information, etc.).

The pj1939_pg_receive() function gives an indication of J1939 message status by writing to various status flags. The function provides an indication of whether a message has been received since the last call, whether more than one message with the same CAN identifier has been received, and whether an error occurred on reception. The function also provides a timestamp of the last valid message received.

To help unpack data from the contents of a J1939 message, the function takes data detailing the fields of the message contents, extracts the fields and writes them to application variables.

Warning

The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

5.17.7. Transmit messages

The library transmits buffered J1939 messages for the application. The application tells the library to transmit a new J1939 message by calling pj1939_pdu_transmit().

Each transmit message buffer stores one J1939 message. If the application requests a transmit of a J1939 message before the library has transmitted the last CAN message with the same identifier, then the message buffer is overwritten with the latest transmit message. This ensures the latest version of a J1939 message is transmitted by the library, but is not suitable for J1939 messages which contain state information (e.g., J1939 messages containing protocol information, etc.).

The library buffers multiple J1939 transmit messages but as the CAN bus is serial in nature, only one message can be transmitted at a time. The library attempts to transmit the messages in the order they are presented when pj1939_pdu_transmit() is called, but the library will not always adhere to this ordering.

Unlike the CAN feature (PCX) which attempts to lessen the load experienced by the CAN bus and the ECU, after the library has transmitted one J1939 message, it will attempt to transmit the next as soon as possible to make it more likely that all protocol message deadlines will be met. However, this may not be possible depending on the current CAN bus loading and the ECU processor loading.

To help pack data into the contents of a J1939 message, the function takes data detailing the fields of the message contents and values of those fields, and writes them to J1939 message (setting all unspecified bits to one).

5.17.8. Core Diagnostic messages

The core library provides functions to help deal with basic diagnostic messaging, specifically DM1 and DM2 messages through the functions pj1939_dm1_transmit(), pj1939_dm1_receive(), pj1939_dm1_decode_dtc(), pj1939_dm2_transmit(), pj1939_dm2_receive() and pj1939_dm2_decode_dtc()

The J1939/73 specification, section 5.7.1, details the transmission rate of the DM1 message (both on request, and periodic transmission). The examples included in that section show the frequency of transmission and the need to limit bandwidth.

5.17.9. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

5.17.10. Library tasks

The library implements a single task to support J1939 messaging. See Section 4.6.4, “Application and library tasks” for details.

5.17.11. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pj1939.h
Enumerations
 PJ1939_ERROR_T

Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type.

Data types
 J1939_TX_MESSAGE_T

This is the definition of a J1939 transmit message.

 J1939_RX_MESSAGE_T

This is the definition of a J1939 receive message.

 CAN_PACKET_T

This is the structure of a single CAN packet.

 PJ1939_RX_BUF_T

This is the structure for buffering received J1939 messages.

 PGN_T

This is a typedef for the PGN (parameter group number).

Variables
const U8pj1939_enabled

Set true if J1939 functionality is enabled, set false otherwise.

const U8pj1939c_node_addr_0

This is an array that sets the desired J1939 node addresses.

const PGN_T_pgn_table

This is an array of receive PGNs the library must filter.

const U32pj1939_num_pgns

This is the number of receive PGNs in _pgn_table[].

const PGN_Tpj1939_pgn_requested_table

This is the list of expected PGN requests to filter.

const U32pj1939_num_requested_pgns

This is the number of expected PGN requests in the pj1939_pgn_requested_table[] array.

U8pj1939_pgn_requested_src_addr

This is the buffer of source addresses for each PGN request message.

U8pj1939_pgn_requested_dest_addr

This is the buffer of destination addresses for each PGN request message.

U32pj1939_pgn_requested_timestamp

This is the buffer of timestamps for each PGN request message.

U8pj1939_pgn_requested_bitmap

This is the buffer of priority for each PGN request message.

U16pj1939_pgn_rx_buf_data_size

This is the size of the data portion to each J1939 receive buffer.

U8 *constpj1939_pgn_rx_buf_data

This is an array of pointers to each data buffer for each J1939 receive message.

PJ1939_RX_BUF_T *constpj1939_pgn_rx_buf

This is an array of pointers to each J1939 receive message.

const U8pj1939_num_ttx

This is the number of transport transmit buffers that can run in parallel.

const U8pj1939_num_trx

This is the number of transport receive buffers that can run in parallel.

const U16pj1939_size_j1939_rx_buf

This is the maximum data size of any J1939 message (both reception and transmission).

const U8pj1939_num_rx_tx_bufs

This is the number of receive and transmit CAN buffers allocated for J1939 message processing.

struct NS_J1939_CHANNEL_T_ *pj1939_tx_usedby_channels

This is an array determining which (if any) J1939 channel is currently using a transport-protocol TX buffer.

J1939_TX_MESSAGE_Tpj1939_ttx_buf

This is an array of J1939 transmit messages.

U8 *pj1939_ttx_error_ptr

This is an array of pointers to counters for delayed transmit errors.

U8pj1939_ttx_buf_data

This is the buffer space allocated for all J1939 transmit messages.

U8pj1939_msg_buffer

This is the buffer space allocated for all J1939 receive messages.

const U8pj1939_num_channels

The number of configured logical J1939 channels.

struct NS_J1939_CHANNEL_T_pj1939_channels

This is the array of J1939 channel definitions.

J1939_TRANSPORT_TX_INFOtx_state

This is the state of the transmission messages that require transport support (i.e., messages that have a data length greater than 8 bytes).

J1939_MESSAGErx_message

This is the state of the receive messages that require transport support (i.e., messages that have a data length greater than 8 bytes)

CAN_PACKET_Tin_queue

This is the queue of received messages.

CAN_PACKET_Tout_queue

This is the queue of transmit messages.

const BOOLpj1939_use_common_mf_priority

This is a flag to determine whether to use a common priority for all J1939 multi-frame diagnostic message transmissions.

const U8pj1939_common_multiframe_priority

This is the common priority used for all J1939 multi-frame diagnostic message transmissions.

PJ1939_DM1_DM2_BUF_T *pj1939_dm1_rx_cfg

This is the array of pointers to configuration structures for DM1 messages.

PJ1939_DM1_DM2_BUF_T *pj1939_dm2_rx_cfg

This is the array of pointers to configuration structures for DM2 messages.

U8pj1939_state

This is an array of states for each DTC.

U8pj1939_sent

This is an array of sent flags for each DTC.

U8pj1939_transient

This is an array of transient fault states for each DTC.

U8pj1939_transient_sent

This is an array of transient sent flags for each DTC.

Functions
U8pj1939_dm1_receive

This function indicates if and when a J1939 DM1 message was received.

voidpj1939_dm1_decode_dtc

This function decodes part of a received J1939 DM1 message.

U8pj1939_dm2_receive

This function indicates if and when a J1939 DM2 message was received.

voidpj1939_dm2_decode_dtc

This function decodes part of a received J1939 DM2 message.

voidpj1939_dm1_transmit

This function attempts to transmit a J1939 DM1 message.

voidpj1939_dm2_transmit

This function attempts to transmit a J1939 DM2 message.

voidpj1939_was_pgn_requested

Determine whether a PGN has been requested from this node.

voidpj1939_pg_receive

Determine if a PGN has been received and extract its contents if required.

voidpj1939_pdu_transmit

Construct a J1939 message and attempt to send it.

5.17.12. Interface detail

5.17.12.1.  Enumerations

5.17.12.1.1. PJ1939_ERROR_T
Summary:

Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type.

Enumerations:
PJ1939_WAS_REQ_PGN_INVALID_ARG

Error raised if the PGN requested function finds an invalid function argument.

PJ1939_PG_RECEIVE_INVALID_ARG

Error raised if the PG receive function finds an invalid function argument.

PJ1939_PG_TRANSMIT_INVALID_ARG

Error raised if the PG transmit function finds an invalid function argument.

PJ1939_DM1_DECODE_INVALID_ARG

Error raised if the DM1 decode function finds an invalid function argument.

PJ1939_DM2_DECODE_INVALID_ARG

Error raised if the DM2 decode function finds an invalid function argument.

PJ1939_DM1_TRANSMIT_INVALID_ARG

Error raised if the DM1 transmit function finds an invalid function argument.

PJ1939_DM2_TRANSMIT_INVALID_ARG

Error raised if the DM2 transmit function finds an invalid function argument.

PJ1939_DM4_TRANSMIT_INVALID_ARG

Error raised if the DM4 transmit function finds an invalid function argument.

PJ1939_DM5_TRANSMIT_INVALID_ARG

Error raised if the DM5 transmit function finds an invalid function argument.

PJ1939_DM6_TRANSMIT_INVALID_ARG

Error raised if the DM6 transmit function finds an invalid function argument.

PJ1939_DM7_COMMANDED_TEST_INVALID_ARG

Error raised if the DM7 commanded test function finds an invalid function argument.

PJ1939_DM8_TRANSMIT_INVALID_ARG

Error raised if the DM8 transmit function finds an invalid function argument.

PJ1939_DM10_TRANSMIT_INVALID_ARG

Error raised if the DM10 transmit function finds an invalid function argument.

PJ1939_DM12_TRANSMIT_INVALID_ARG

Error raised if the DM12 transmit function finds an invalid function argument.

PJ1939_DM14_DECODE_INVALID_ARG

Error raised if the DM14 decode function finds an invalid function argument.

PJ1939_DM15_TRANSMIT_INVALID_ARG

Error raised if the DM15 transmit function finds an invalid function argument.

PJ1939_DM16_DECODE_INVALID_ARG

Error raised if the DM16 decode function finds an invalid function argument.

PJ1939_DM20_TRANSMIT_INVALID_ARG

Error raised if the DM20 transmit function finds an invalid function argument.

PJ1939_DM21_TRANSMIT_INVALID_ARG

Error raised if the DM21 transmit function finds an invalid function argument.

PJ1939_DM23_TRANSMIT_INVALID_ARG

Error raised if the DM23 transmit function finds an invalid function argument.

PJ1939_DM24_TRANSMIT_INVALID_ARG

Error raised if the DM24 transmit function finds an invalid function argument.

PJ1939_DM25_TRANSMIT_INVALID_ARG

Error raised if the DM25 transmit function finds an invalid function argument.

PJ1939_DM26_TRANSMIT_INVALID_ARG

Error raised if the DM26 transmit function finds an invalid function argument.

PJ1939_DM27_TRANSMIT_INVALID_ARG

Error raised if the DM27 transmit function finds an invalid function argument.

PJ1939_DM28_TRANSMIT_INVALID_ARG

Error raised if the DM28 transmit function finds an invalid function argument.

PJ1939_DM29_TRANSMIT_INVALID_ARG

Error raised if the DM29 transmit function finds an invalid function argument.

PJ1939_DM30_TRANSMIT_INVALID_ARG

Error raised if the DM30 transmit function finds an invalid function argument.

PJ1939_DM31_TRANSMIT_INVALID_ARG

Error raised if the DM31 transmit function finds an invalid function argument.

PJ1939_DM32_TRANSMIT_INVALID_ARG

Error raised if the DM32 transmit function finds an invalid function argument.

PJ1939_DM33_TRANSMIT_INVALID_ARG

Error raised if the DM33 transmit function finds an invalid function argument.

PJ1939_DM34_TRANSMIT_INVALID_ARG

Error raised if the DM34 transmit function finds an invalid function argument.

PJ1939_DM35_TRANSMIT_INVALID_ARG

Error raised if the DM35 transmit function finds an invalid function argument.

PJ1939_DM36_TRANSMIT_INVALID_ARG

Error raised if the DM36 transmit function finds an invalid function argument.

PJ1939_DM37_TRANSMIT_INVALID_ARG

Error raised if the DM37 transmit function finds an invalid function argument.

PJ1939_DM38_TRANSMIT_INVALID_ARG

Error raised if the DM38 transmit function finds an invalid function argument.

PJ1939_DM39_TRANSMIT_INVALID_ARG

Error raised if the DM39 transmit function finds an invalid function argument.

PJ1939_DM40_TRANSMIT_INVALID_ARG

Error raised if the DM40 transmit function finds an invalid function argument.

PJ1939_DM41_TRANSMIT_INVALID_ARG

Error raised if the DM41 transmit function finds an invalid function argument.

PJ1939_DM42_TRANSMIT_INVALID_ARG

Error raised if the DM42 transmit function finds an invalid function argument.

PJ1939_DM43_TRANSMIT_INVALID_ARG

Error raised if the DM43 transmit function finds an invalid function argument.

PJ1939_DM44_TRANSMIT_INVALID_ARG

Error raised if the DM44 transmit function finds an invalid function argument.

PJ1939_DM45_TRANSMIT_INVALID_ARG

Error raised if the DM45 transmit function finds an invalid function argument.

PJ1939_DM46_TRANSMIT_INVALID_ARG

Error raised if the DM46 transmit function finds an invalid function argument.

PJ1939_DM47_TRANSMIT_INVALID_ARG

Error raised if the DM47 transmit function finds an invalid function argument.

PJ1939_DM48_TRANSMIT_INVALID_ARG

Error raised if the DM48 transmit function finds an invalid function argument.

PJ1939_DM49_TRANSMIT_INVALID_ARG

Error raised if the DM49 transmit function finds an invalid function argument.

PJ1939_DM50_TRANSMIT_INVALID_ARG

Error raised if the DM50 transmit function finds an invalid function argument.

PJ1939_DM51_TRANSMIT_INVALID_ARG

Error raised if the DM51 transmit function finds an invalid function argument.

PJ1939_DM52_TRANSMIT_INVALID_ARG

Error raised if the DM52 transmit function finds an invalid function argument.

PJ1939_PGN_TRANSMIT_INVALID_ARG

Error raised if the PGN transmit function finds an invalid function argument.

PJ1939_DM1_RECEIVE_INVALID_ARG

Error raised if the DM1 receive function finds an invalid function argument.

PJ1939_DM2_RECEIVE_INVALID_ARG

Error raised if the DM2 receive function finds an invalid function argument.

PJ1939_INVALID_CHANNEL

Error raised if a J1939 operation was requested on an invalid J1939 channel.

PJ1939_DTC_TRANSMIT_INVALID_PARAMS

Error raised if a DTC or DTC Explicit transmit operation is requested with invalid parameters.

5.17.12.2.  Data types

5.17.12.2.1. J1939_TX_MESSAGE_T
Summary:

This is the definition of a J1939 transmit message.

Members:
PGN_T J1939_TX_MESSAGE_T::PGN

This is the message Parameter Group Number.

U8* J1939_TX_MESSAGE_T::data_ptr

This is a pointer to the data bytes contained in the J1939 message.

If the data pointer is NULL, the message should be considered invalid.

U16 J1939_TX_MESSAGE_T::byte_count

This is the number of data bytes in the J1939 message.

Range: [0, 1785] bytes

U8 J1939_TX_MESSAGE_T::priority

This is the J1939 message priority (0 is the highest priority, 7 the lowest).

Priorities requested outside this range will be clipped to 7. Range: [0, 7]

U8 J1939_TX_MESSAGE_T::dest_addr

This is the network address of the intended destination node.

This field is ignored for PDU2 format messages with eight or fewer data bytes since they are always broadcast globally. PDU2 format messages with more than eight bytes of data can be broadcast globally or sent to a specific destination. A destination address (global or specific) is required for all PDU1 formats.

U8 J1939_TX_MESSAGE_T::source_addr

This is the network address of the node that transmitted the message.

S8 J1939_TX_MESSAGE_T::status

This is used to define transport layer error and acknowledgment.

U8 J1939_TX_MESSAGE_T::channel_id

The J1939 channel ID from which the message was received.

Description:

This is the definition of a J1939 transmit message.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.2. J1939_RX_MESSAGE_T
Summary:

This is the definition of a J1939 receive message.

Members:
PGN_T J1939_RX_MESSAGE_T::PGN

This is the message Parameter Group Number.

U8* J1939_RX_MESSAGE_T::data_ptr

This is a pointer to the data bytes contained in the J1939 message.

If the data pointer is NULL, the message should be considered invalid.

U16 J1939_RX_MESSAGE_T::byte_count

This is the number of data bytes in the J1939 message.

Range: [0, 1785] bytes

U8 J1939_RX_MESSAGE_T::source_addr

This is the network address of the node that transmitted the message.

U8 J1939_RX_MESSAGE_T::dest_addr

This is the network address of the node to which the message was sent.

Description:

This is the definition of a J1939 receive message.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.3. CAN_PACKET_T
Summary:

This is the structure of a single CAN packet.

Members:
U32 CAN_PACKET_T::identifier

This is the 29-bit CAN identifier contained in an extended format packet.

The identifier is right justified within the 32-bit field so that the upper three bits are always zero.

U8 CAN_PACKET_T::data[CAN_MAX_BYTE_COUNT]

This is the data bytes contained in the CAN packet.

The value of unused data bytes is undefined.

U8 CAN_PACKET_T::byte_count

This is the number of valid data bytes in the CAN packet.

Range: [0, 8] bytes

Description:

This is the structure of a single CAN packet.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.4. PJ1939_RX_BUF_T
Summary:

This is the structure for buffering received J1939 messages.

Members:
U32 PJ1939_RX_BUF_T::timestamp

This timestamp records when the J1939 message was received.

Range: [0, 4294967295] microseconds

U8 PJ1939_RX_BUF_T::source_addr

This is the source address of a received J1939 message.

Range: [0, 255]

U8 PJ1939_RX_BUF_T::dest_addr

This is the destination address of the received J1939 message.

Range: [0, 255]

U16 PJ1939_RX_BUF_T::byte_count

This is the number of data bytes in the received J1939 message.

Range: [0, 1785] bytes

U8 PJ1939_RX_BUF_T::flags

This is a bitfield of status information.

If bit 0 is set, the message has been received at least once since the bit was last cleared. If bit 1 is set, the message has been received more than once since the bit was last cleared. If bit 2 is set, an error was trapped on the last receive.

U8 PJ1939_RX_BUF_T::channel_id

The J1939 channel ID from which the message was received.

Description:

This is the structure for buffering received J1939 messages.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.5. PGN_T
Definition:

typedef U32 PGN_T

Description:

This is a typedef for the PGN (parameter group number).

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.3.  Variables

5.17.12.3.1. pj1939_enabled
Definition:

const U8 pj1939_enabled

Description:

Set true if J1939 functionality is enabled, set false otherwise.

5.17.12.3.2. pj1939c_node_addr_0
Definition:

volatile const U8 pj1939c_node_addr_0[]

Description:

This is an array that sets the desired J1939 node addresses.

It can be altered by calibration. However, it is used only during ECU initialisation, so any calibration change must be programmed into flash to take effect on the next power-up.

This array must have at least pj1939_num_channels elements, where each element corresponds to the channel with the same index.

Range: [0, 253]

5.17.12.3.3. _pgn_table
Definition:

const PGN_T _pgn_table[]

Description:

This is an array of receive PGNs the library must filter.

Must be declared in ascending order and each element must have a unique value. If the application must respond to DM1, DM2, DM3 or DM11 messages, then the PGNs for these must be added to this array.

5.17.12.3.4. pj1939_num_pgns
Definition:

const U32 pj1939_num_pgns

Description:

This is the number of receive PGNs in _pgn_table[].

Values outside of the defined range will result in undefined behaviour.

Range: [1, 2147483647]

5.17.12.3.5. pj1939_pgn_requested_table
Definition:

const PGN_T pj1939_pgn_requested_table[]

Description:

This is the list of expected PGN requests to filter.

Must be declared in ascending order and be unique.

5.17.12.3.6. pj1939_num_requested_pgns
Definition:

const U32 pj1939_num_requested_pgns

Description:

This is the number of expected PGN requests in the pj1939_pgn_requested_table[] array.

5.17.12.3.7. pj1939_pgn_requested_src_addr
Definition:

U8 pj1939_pgn_requested_src_addr[]

Description:

This is the buffer of source addresses for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.8. pj1939_pgn_requested_dest_addr
Definition:

U8 pj1939_pgn_requested_dest_addr[]

Description:

This is the buffer of destination addresses for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.9. pj1939_pgn_requested_timestamp
Definition:

U32 pj1939_pgn_requested_timestamp[]

Description:

This is the buffer of timestamps for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.10. pj1939_pgn_requested_bitmap
Definition:

U8 pj1939_pgn_requested_bitmap[]

Description:

This is the buffer of priority for each PGN request message.

Indexes are the same as pj1939_pgn_requested_table[], but applied per bit, rather than per byte.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal { pj1939_num_channels * ((pj1939_num_requested_pgns + 7) / 8) } (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.11. pj1939_pgn_rx_buf_data_size
Definition:

U16 pj1939_pgn_rx_buf_data_size[]

Description:

This is the size of the data portion to each J1939 receive buffer.

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is the number of data bytes for the corresponding PGN message.

Range: [0, 1785] bytes

5.17.12.3.12. pj1939_pgn_rx_buf_data
Definition:

U8* const pj1939_pgn_rx_buf_data[]

Description:

This is an array of pointers to each data buffer for each J1939 receive message.

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is a pointer to an area of memory large enough to store the data bytes for the corresponding PGN message.

5.17.12.3.13. pj1939_pgn_rx_buf
Definition:

PJ1939_RX_BUF_T* const pj1939_pgn_rx_buf[]

Description:

This is an array of pointers to each J1939 receive message.

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is a pointer to a variable of type PJ1939_RX_BUF_T.

5.17.12.3.14. pj1939_num_ttx
Definition:

const U8 pj1939_num_ttx

Description:

This is the number of transport transmit buffers that can run in parallel.

The more transmit buffers there are, the larger the number of destination nodes can be communicated with at the same time. At the same time, the more transmit buffers there are, the larger the amount of RAM required to accommodate the parallel information. Values outside of the defined range will result in undefined behaviour.

Range: [1, 127] buffers.

5.17.12.3.15. pj1939_num_trx
Definition:

const U8 pj1939_num_trx

Description:

This is the number of transport receive buffers that can run in parallel.

The more receive buffers there are, the larger the number of destination nodes can be communicated with at the same time. At the same time, the more receive buffers there are, the larger the amount of RAM required to accommodate the parallel information.

Range: [1, 255] buffers.

5.17.12.3.16. pj1939_size_j1939_rx_buf
Definition:

const U16 pj1939_size_j1939_rx_buf

Description:

This is the maximum data size of any J1939 message (both reception and transmission).

Any J1939 message with data larger than this variable is rejected by the library.

Range: [8, 1785] bytes.

5.17.12.3.17. pj1939_num_rx_tx_bufs
Definition:

const U8 pj1939_num_rx_tx_bufs

Description:

This is the number of receive and transmit CAN buffers allocated for J1939 message processing.

Range: [1, 255]

5.17.12.3.18. pj1939_tx_usedby_channels
Definition:

struct NS_J1939_CHANNEL_T_* pj1939_tx_usedby_channels[]

Description:

This is an array determining which (if any) J1939 channel is currently using a transport-protocol TX buffer.

It must be declared and sized by the application but is not to be accessed by the application code. The size of the array must equal pj1939_num_ttx (minimum 1).

5.17.12.3.19. pj1939_ttx_buf
Definition:

J1939_TX_MESSAGE_T pj1939_ttx_buf[]

Description:

This is an array of J1939 transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.20. pj1939_ttx_error_ptr
Definition:

U8* pj1939_ttx_error_ptr[]

Description:

This is an array of pointers to counters for delayed transmit errors.

The index is the same as for the pj1939_ttx_buf[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx. The array is not to be accessed by application code.

5.17.12.3.21. pj1939_ttx_buf_data
Definition:

U8 pj1939_ttx_buf_data[]

Description:

This is the buffer space allocated for all J1939 transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal {pj1939_num_ttx * pj1939_size_j1939_rx_buf}. The array is not to be accessed by application code.

5.17.12.3.22. pj1939_msg_buffer
Definition:

U8 pj1939_msg_buffer[]

Description:

This is the buffer space allocated for all J1939 receive messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal {pj1939_num_trx * pj1939_size_j1939_rx_buf}. The array is not to be accessed by application code.

5.17.12.3.23. pj1939_num_channels
Definition:

const U8 pj1939_num_channels

Description:

The number of configured logical J1939 channels.

Present in the C-API description for build-time size requirements. This defines the size of the pj1939_channel array.

5.17.12.3.24. pj1939_channels
Definition:

struct NS_J1939_CHANNEL_T_ pj1939_channels[]

Description:

This is the array of J1939 channel definitions.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_channels. The array is not to be accessed by application code.

5.17.12.3.25. tx_state
Definition:

J1939_TRANSPORT_TX_INFO tx_state[]

Description:

This is the state of the transmission messages that require transport support (i.e., messages that have a data length greater than 8 bytes).

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx. The array is not to be accessed by application code.

5.17.12.3.26. rx_message
Definition:

J1939_MESSAGE rx_message[]

Description:

This is the state of the receive messages that require transport support (i.e., messages that have a data length greater than 8 bytes)

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_trx. The array is not to be accessed by application code.

5.17.12.3.27. in_queue
Definition:

CAN_PACKET_T in_queue[]

Description:

This is the queue of received messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_rx_tx_bufs * pj1939_num_channels. The array is not to be accessed by application code.

5.17.12.3.28. out_queue
Definition:

CAN_PACKET_T out_queue[]

Description:

This is the queue of transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_rx_tx_bufs * pj1939_num_channels. The array is not to be accessed by application code.

5.17.12.3.29. pj1939_use_common_mf_priority
Definition:

const BOOL pj1939_use_common_mf_priority

Description:

This is a flag to determine whether to use a common priority for all J1939 multi-frame diagnostic message transmissions.

If true then the priority for such messages is taken from pj1939_common_multiframe_priority. If false, the priority is as defined in the argument to the appropriate message transmit function. Note that that function argument always determines priority for single-frame messages.

5.17.12.3.30. pj1939_common_multiframe_priority
Definition:

const U8 pj1939_common_multiframe_priority

Description:

This is the common priority used for all J1939 multi-frame diagnostic message transmissions.

It is only used when the pj1939_use_common_mf_priority flag is true.

Range: [0, 7]

5.17.12.3.31. pj1939_dm1_rx_cfg
Definition:

PJ1939_DM1_DM2_BUF_T* pj1939_dm1_rx_cfg[]

Description:

This is the array of pointers to configuration structures for DM1 messages.

These structures includes the specification of valid source addresses. Addresses should be declared in ascending order with each address being unique. DM1 messages sent from other addresses are ignored by the library.

Note

The structure is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized a build time.

5.17.12.3.32. pj1939_dm2_rx_cfg
Definition:

PJ1939_DM1_DM2_BUF_T* pj1939_dm2_rx_cfg[]

Description:

This is the array of pointers to configuration structures for DM2 messages.

These structures includes the specification of valid source addresses. Addresses should be declared in ascending order with each address being unique. DM2 messages sent from other addresses are ignored by the library.

Note

The structure is private to the library and should only be defined by the application.

5.17.12.3.33. pj1939_state
Definition:

U8 pj1939_state[]

Description:

This is an array of states for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM1 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.34. pj1939_sent
Definition:

U8 pj1939_sent[]

Description:

This is an array of sent flags for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM1 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.35. pj1939_transient
Definition:

U8 pj1939_transient[]

Description:

This is an array of transient fault states for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM35 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.36. pj1939_transient_sent
Definition:

U8 pj1939_transient_sent[]

Description:

This is an array of transient sent flags for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM35 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.4.  Functions

5.17.12.4.1. pj1939_dm1_receive()
Definition:

U8 pj1939_dm1_receive(
   const U8   pj1939f_dm1_src,
   U8        *pj1939f_lamp_malfunction,
   U8        *pj1939f_lamp_red,
   U8        *pj1939f_lamp_amber,
   U8        *pj1939f_lamp_protect,
   U32       *pj1939f_timestamp,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function indicates if and when a J1939 DM1 message was received.

Examines a received J1939 DM1 message and decodes lamp information and provides a receive timestamp and counter per power cycle. Can be used in conjunction with pj1939_dm1_decode_dtc to determine when a certain diagnostic trouble code becomes active.

WARNING: The PCX feature takes precedence over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors:
PJ1939_DM1_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_dm1_src

Source address identifying the DM1 message.
Range: [0, 253]

Arg (data out): pj1939f_lamp_malfunction

Pointer to location to write the 'lamp malfunction' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_red

Pointer to location to write the 'lamp red' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_amber

Pointer to location to write the 'lamp amber' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_protect

Pointer to location to write the 'lamp protect' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_timestamp

A pointer to the location to write with the timestamp of the received message.
Cannot be NULL.
Range: [0, 4294967295] us

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to receive the message Range: [0,pj1939_num_channels)

Return:

One or more flags may be set in the return value to indicate:

5.17.12.4.2. pj1939_dm1_decode_dtc()
Definition:

void pj1939_dm1_decode_dtc(
   const U8   pj1939f_dm1_src,
   U32        pj1939f_spn,
   U8         pj1939f_fmi,
   U8         pj1939f_cm,
   U8        *pj1939f_active,
   U8        *pj1939f_oc,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function decodes part of a received J1939 DM1 message.

Examine a received J1939 DM1 message for a specific diagnostic trouble code (given by a combination of pj1939f_spn, pj1939f_fmi and pj1939f_cm) and report what is found.

Can be used in conjunction with pj1939_dm1_receive to determine when a certain diagnostic trouble code becomes active.

Can raise the following errors:
PJ1939_DM1_DECODE_INVALID_ARG.

Arg (data in): pj1939f_dm1_src

Source address identifying the DM1 message.
Range: [0, 253]

Arg (data in): pj1939f_spn

The 'suspect parameter number' value to search for.
Range: [0, 524287]

Arg (data in): pj1939f_fmi

The SPN 'failure mode indicator' value to search for.
Range: [0, 31]

Arg (data in): pj1939f_cm

The SPN 'conversion method' value to search for.
Range: [0, 1]

Arg (data out): pj1939f_active

Pointer to location to write the status of the SPN/FMI/CM diagnostic trouble code. Written TRUE if the diagnostic trouble code is reported in the message (i.e. Active, for DM1), or written FALSE otherwise.
Cannot be NULL.

Arg (data out): pj1939f_oc

Pointer to the location to write the occurrence count of the diagnostic trouble code.
Cannot be NULL.
Range: [0, 127]

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to receive the message Range: [0,pj1939_num_channels)

5.17.12.4.3. pj1939_dm2_receive()
Definition:

U8 pj1939_dm2_receive(
   const U8   pj1939f_dm2_src,
   U8        *pj1939f_lamp_malfunction,
   U8        *pj1939f_lamp_red,
   U8        *pj1939f_lamp_amber,
   U8        *pj1939f_lamp_protect,
   U32       *pj1939f_timestamp,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function indicates if and when a J1939 DM2 message was received.

Examines a received J1939 DM2 message and decodes lamp information and provides a receive timestamp and counter per power cycle. Can be used in conjunction with pj1939_dm2_decode_dtc to determine when a certain diagnostic trouble code becomes inactive (or previously active).

WARNING: The PCX feature takes precedence over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors:
PJ1939_DM2_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_dm2_src

Source address identifying the DM2 message.
Range: [0, 253]

Arg (data out): pj1939f_lamp_malfunction

Pointer to location to write the 'lamp malfunction' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_red

Pointer to location to write the 'lamp red' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_amber

Pointer to location to write the 'lamp amber' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_protect

Pointer to location to write the 'lamp protect' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs.
Cannot be NULL.
Range: [0, 3]
One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_timestamp

A pointer to the location to write with the timestamp of the received message.
Cannot be NULL.
Range: [0, 4294967295] us

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to transmit the message Range: [0,pj1939_num_channels)

Return:

One or more flags may be set in the return value to indicate:

5.17.12.4.4. pj1939_dm2_decode_dtc()
Definition:

void pj1939_dm2_decode_dtc(
   const U8   pj1939f_dm2_src,
   U32        pj1939f_spn,
   U8         pj1939f_fmi,
   U8         pj1939f_cm,
   U8        *pj1939f_previously_active,
   U8        *pj1939f_oc,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function decodes part of a received J1939 DM2 message.

Examine a received J1939 DM2 message for a specific diagnostic trouble code (given by a combination of pj1939f_spn, pj1939f_fmi and pj1939f_cm) and report what is found.

Can be used in conjunction with pj1939_dm2_receive to determine when a certain diagnostic trouble code becomes inactive (previously active).

Can raise the following errors:
PJ1939_DM2_DECODE_INVALID_ARG.

Arg (data in): pj1939f_dm2_src

Source address identifying the DM2 message.
Range: [0, 253]

Arg (data in): pj1939f_spn

The 'suspect parameter number' value to search for.
Range: [0, 524287]

Arg (data in): pj1939f_fmi

The SPN 'failure mode indicator' value to search for.
Range: [0, 31]

Arg (data in): pj1939f_cm

The SPN 'conversion method' value to search for.
Range: [0, 1]

Arg (data out): pj1939f_previously_active

Pointer to location to write the status of the SPN/FMI/CM diagnostic trouble code. Written TRUE if the diagnostic trouble code is reported in the message (i.e. Previously Active, for DM2), or written FALSE otherwise.
Cannot be NULL.

Arg (data out): pj1939f_oc

Pointer to the location to write the occurrence count of the diagnostic trouble code.
Cannot be NULL.
Range: [0, 127]

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to receive the message Range: [0,pj1939_num_channels)

5.17.12.4.5. pj1939_dm1_transmit()
Definition:

void pj1939_dm1_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_force_transmission,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   BOOL                        pj1939f_use_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function attempts to transmit a J1939 DM1 message.

Request that a J1939 DM1 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM1 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

The transmission of a DM1 message can involve many CAN packets and to avoid overloading the CAN bus, the J1939 specification provides some guidance for transmission rates. This can be overridden if necessary.

  • forced transmission - causes the function to attempt to transmit a DM1 message regardless of the changing state of the DTCs.

  • unforced transmission - causes the function to attempt to transmit a DM1 message:

    • once every second plus on state change regardless of the presence or absence of any DTC.

Can raise the following errors:
PJ1939_DM1_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM1 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_force_transmission

Set true if the DM1 message should be transmitted regardless of DTC state changes, set false if the DM1 message should be transmitted according to the general guidelines laid out in SAE J1939-73.

Arg (data in): pj1939f_priority

The priority of the DM1 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM1 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to transmit the message Range: [0,pj1939_num_channels)

5.17.12.4.6. pj1939_dm2_transmit()
Definition:

void pj1939_dm2_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_transmit,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   BOOL                        pj1939f_use_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

This function attempts to transmit a J1939 DM2 message.

Request that a J1939 DM2 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM2 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

Unlike DM1 messages, DM2 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM2_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM2 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_transmit

Set true if the DM2 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority

The priority of the DM2 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM2 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to transmit the message Range: [0,pj1939_num_channels)

5.17.12.4.7. pj1939_was_pgn_requested()
Definition:

void pj1939_was_pgn_requested(
   const U32   pj1939f_pgn_idx,
   U32        *pj1939f_timestamp,
   U8         *pj1939f_requested,
   U8         *pj1939f_source_addr,
   U8         *pj1939f_dest_addr,
   const U8    pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Determine whether a PGN has been requested from this node.

Search through the list of PGN requests which have been made either to this node's address or to the broadcast address. If a request has been made then clear the PGN request from the list and return details relating to the request.

Can raise the following errors:
PJ1939_WAS_REQ_PGN_INVALID_ARG.

Note

If a PG request message is received, but the requested PG does not match any requested PGN, then the library shall respond with a NACK to the sender of the PG request message, unless the request for PG was sent to the global address, in which case, the NACK is not transmitted.

Arg (data in): pj1939f_pgn_idx

The index into the pj1939_pgn_requested_table[] array, thus identifying the requested PGN to work with.
Use the macros included by the header file generated from the interface tool, of the form PJ1939_PGN_TABLE_IDX_[PGN-NUMBER].
Range: [0, pj1939_num_requested_pgns - 1]

Arg (data out): pj1939f_timestamp

A pointer to the location to write the timestamp of the received message.
Cannot be NULL.
Range: [0, 4294967295] us

Arg (data out): pj1939f_requested

A pointer to the location to write the result of searching for the PGN. Written true if the PGN has been requested, written false otherwise. The request status is cleared after the search.
Cannot be NULL.

Arg (data out): pj1939f_source_addr

A pointer to the location to write the source address of the J1939 message requesting the PGN.
Cannot be NULL.
Range of source address: [0, 253]

Arg (data out): pj1939f_dest_addr

A pointer to the location to write the destination address of the J1939 message requesting the PGN.
Cannot be NULL.
Range of destination address: [0, 253 or 255]

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

5.17.12.4.8. pj1939_pg_receive()
Definition:

void pj1939_pg_receive(
   const U32     pj1939f_pgn_idx,
   U32          *pj1939f_timestamp,
   U8           *pj1939f_error_flag,
   U8           *pj1939f_rx_trig_flag,
   U8           *pj1939f_overrun_flag,
   U8           *pj1939f_source_addr,
   U8           *pj1939f_dest_addr,
   const U16     pj1939f_message_len,
   const U16     pj1939f_num_fields,
   void *const  *pj1939f_item_ptr,
   const U16    *pj1939f_field_start_pos,
   const U8     *pj1939f_field_width,
   const U8     *pj1939f_field_sign,
   const U8     *pj1939f_field_packing,
   const U8      pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Determine if a PGN has been received and extract its contents if required.

If a PGN has been received, then unpack the contents of the received message. If a PGN has not been received, then unpack the contents of the received message as if all message data was zero.

The unpacking sequence works as follows:

  • for each element in pj1939f_item_ptr

    1. read the data from the PGN receive message buffer given by pj1939f_pgn_idx, based on the item's field start position pj1939f_field_start, and bit width pj1939f_field_width, based on the byte ordering of the item given by pj1939f_field_packing

    2. if the item is signed as given by pj1939f_field_sign, then perform sign extension

    3. write the converted value to the store given by pj1939f_item_ptr

In addition, the function sets various flags to indicate the state of message reception (received since last call, received more than once since last call, received in error).

WARNING: The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors:
PJ1939_PG_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_pgn_idx

The index into the _pgn_table[] and pj1939_pgn_rx_buf[] arrays, thus identifying the received PGN message to work with.
Use the macros included by the header file generated from the interface tool, of the form PJ1939_PGN_TABLE_IDX_[PGN-NUMBER].
Range: [0, pj1939_num_pgns - 1]

Arg (data out): pj1939f_timestamp

A pointer to the location to write the timestamp of the received message.
Cannot be NULL.
Range: [0, 4294967295] us

Arg (data out): pj1939f_error_flag

A pointer to the location to write the error status of receiving the J1939 message. Written true if there was an error when receiving the message last time, written false otherwise. An error occurs if the length of the J1939 message data contents does not match pj1939f_message_len, or if this node has lost its address claim, or if this node is currently bus-off.
Cannot be NULL.

Arg (data out): pj1939f_rx_trig_flag

A pointer to the location to write the status of receiving the J1939 message. Written true if the message was received since the last call, written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_overrun_flag

A pointer to the location to write the status of receiving the J1939 message. Written true if the message was received more than once since the last call, written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_source_addr

A pointer to the location to write the source address of the received J1939 message. Range of source address: [0, 253] Cannot be NULL.

Arg (data out): pj1939f_dest_addr

A pointer to the location to write the destination address of the received J1939 message.
Can be NULL (in which case, it is not written).
Range of destination address: [0, 253 or 255]

Arg (data in): pj1939f_message_len

The expected length of the data contents of the received J1939 message.
Range: [0, 1785] bytes

Arg (data in): pj1939f_num_fields

Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width, pj1939f_field_sign, and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.
Range: [0, 65535] fields

Arg (data in): pj1939f_item_ptr

Pointer to array of pointers to data to be unpacked from the receive buffer. Each item in this array should point to 32-bit signed or unsigned integer.
Cannot be NULL.

Arg (data in): pj1939f_field_start_pos

Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist.
Cannot be NULL.

Arg (data in): pj1939f_field_width

Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array.
Cannot be NULL.
Range: [1, 32]

Note

If a field extends beyond the length of the data contents of the received message (given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_sign

Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack from the J1939 message, the function determines whether to use the MSB of the packed data as a sign bit or not.
Cannot be NULL.

Arg (data in): pj1939f_field_packing

Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

5.17.12.4.9. pj1939_pdu_transmit()
Definition:

void pj1939_pdu_transmit(
   const U32     pj1939f_pgn,
   U8            pj1939f_priority,
   const U8      pj1939f_dest_addr,
   BOOL          pj1939f_use_dest_addr,
   U8           *pj1939f_error_flag,
   U8           *pj1939f_transport_error,
   const U16     pj1939f_message_len,
   const U16     pj1939f_num_fields,
   void *const  *pj1939f_item_ptr,
   const U16    *pj1939f_field_start_pos,
   const U8     *pj1939f_field_width,
   const U8     *pj1939f_field_packing,
   const U8      pj1939f_channel_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Construct a J1939 message and attempt to send it.

Pack a set of data fields into a J1939 message and attempt to send it using PDU1 format.

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications.

If the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off, then the software shall set the output pj1939f_error_flag parameter true and not attempt to buffer the message for transmission.

When the ECU has a network address (has claimed a non-NULL address without conflict), then the ECU can participate in all communications.

The library transmits the buffered message when possible. If the message has a data length greater than 8 bytes, then the message is transmitted using the transport protocol. The protocol includes various timeouts and abort conditions, and these are accumulated by the function and presented to the application on the next call to this function via pj1939f_transport_error.

When the application completes initialisation, the library sets the PG message's transport error count to zero.

If an error occurs while transmitting the message using the transport protocol, then the library increments the message's transport error count (saturating at 255).

The packing sequence works as follows:

  • set the data contents of the PGN transmit message buffer given by pj1939f_pgn to all bits set

  • for each element in pj1939f_item_ptr

    1. read the integer data value from pj1939f_item_ptr

    2. clip the integer to the field width as given by pj1939f_field_width

    3. write bits to PGN transmit buffer identified by pj1939f_msg_data based with the byte ordering given by pj1939f_field_packing and the bit position given by pj1939f_field_start

Can raise the following errors:
PJ1939_PG_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_pgn

The PGN value of the J1939 transmit message. Range: [0, 130816]

Arg (data in): pj1939f_priority

The priority of the J1939 message to transmit. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the error status of transmitting the J1939 message. Written true if there was an error when transmitting the message this time, written false otherwise. An error occurs if there are no free buffers to store the transmit message, or if the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A saturated count of the transport transmit errors encountered while transmitting a J1939 message. The transport layer is only involved if the message must be broken into more than one CAN message (i.e., the data content of the message exceeds 8 data bytes).
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_message_len

The length of the data contents of the J1939 transmit message.
Range: [0, 1785] bytes

Arg (data in): pj1939f_item_ptr

Pointer to array of pointers to data to be packed into the transmit buffer.
Cannot be NULL.

Arg (data in): pj1939f_num_fields

Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.
Range: [0, 65535] fields

Arg (data in): pj1939f_field_start_pos

Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 1 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist.
Cannot be NULL.

Arg (data in): pj1939f_field_width

Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array.
Cannot be NULL.
Range: [1, 32]

Note

If a field overlaps (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

If a field extends beyond the length of the transmit data contents (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_packing

Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

5.18. Diagnostic Trouble Code (DTC) feature (PDTC)

5.18.1. Overview

The library's diagnostic trouble code feature provides a mechanism to declare basic DTCs, manipulate them and store them persistently across power cycles. It is not suitable for emissions related DTCs which need to meet specific legislated requirements. In that case see the Extended Diagnostic Functions section.

The library groups DTCs into tables. Each table can contain one or more DTC, and a DTC can exist in one table only. DTC tables allow the application to act on a group of DTCs as one action (and though not currently supported by the library, allows the application emulate more than one node on the same J1939 network).

This library concentrates on J1939 DTCs. However, a DTC may be reported over ISO 15765-2 based protocols, or J1939, or both. The emissions related functions of ISO 15765-2 and J1939 are available in the Extended Diagnostic Functions.

5.18.2. Diagnostic trouble codes — generic

The application declares the DTCs of interest during build time by defining the feature variables, including pdtc_num_dtc_tables and pdtc_table_list. Individual DTCs are declared in the interface file (see Section 8.1.4.28, “Compound statement: dtc-data”).

The information for DTCs is recalled from non-volatile store after application initialisation occurs. If DTC data cannot be recalled from non-volatile store, then all DTCs are reset to Clear state.

None of the target ECUs have the capability to time-stamp information. For this reason, DTCs do not have an associated time-stamp stored with them.

5.18.3. Diagnostic trouble codes — J1939

The library maintains an internal state for a J1939 DTC based on the pdtcf_active_in parameter to the function pdtc_update_j1939_dtc() as given in the following state diagram:

Figure 5.18. J1939 activation state machine

J1939 activation state machine

Note: DTCs can also adopt a pending state, used for reporting over ISO diagnostic protocols but not J1939.

When the DTC's internal state changes from clear to active, or from inactive to active, the library increases the DTC's internal count (saturating at 126).

Not shown in Figure 5.18, “J1939 activation state machine”, is that the DTC state can be forcefully set to clear through the use of the pdtc_clear_all(), pdtc_clear_all_if_active() or pdtc_clear_all_if_inactive() functions.

5.18.4. Storage of data across power cycles

On start-up, the library attempts to retrieve the DTC table data prior to running the application. It will only do so if the user-specified application version number matches that of the saved DTCs, and if the expected total data size matches what is stored. Otherwise, any previous DTC data are ignored.

While the application is running, changes to DTC states are written to non-volatile storage when function pdtc_commit_to_store() is called by the application. This will typically be carried out by the application on shutdown and at periodic intervals during execution. Note that the application has full responsibility for invoking writes to non-volatile storage; the platform will never initiate this itself.

If DTCs have not changed since the last write to non-volatile storage, calls to function pdtc_commit_to_store() will not result in additional writes to non-volatile storage. This maximises the lifespan of the non-volatile storage device and may reduce the time taken to shut down the ECU.

The DTC table data is check-summed using a 16-bit CRC. Failure to match the check-sum against the table data during library initialisation means that the data cannot be recovered. In this case, DTC table data is reverted to default start-up conditions. These are:

Table 5.4. DTC initialisation values

DTC informationInitial value
StateClear
Lamp StatesAll off

There are two types of non-volatile memory dedicated to DTCs:

Battery backed RAM

Storage that requires an external power source when the ECU is powered down (not available on all target ECUs).

Flash

Storage that requires no external power supply when the ECU is powered down (not available on all target ECUs).

See Section A.1, “ECU hardware reference documentation” for details of what non-volatile memory stores are available for each target ECU.

5.18.5. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

5.18.6. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pdtc.h
Macros
 PDTC_STORE_IN_BBRAM

This macro defines the value for pdtc_store when DTCs are to be stored in battery backed RAM across power cycles.

 PDTC_STORE_IN_FLASH

This macro defines the value for pdtc_store when DTCs are to be stored in Flash across power cycles.

Enumerations
 PDTC_STATE_T

This enumeration declares the different types of DTCs available.

 PDTC_ERROR_CODE_T

Error values when an error is found by the diagnostic trouble code feature (PDTC), the feature calls a system error log function with an enumeration from this type.

Data types
 PDTC_DTC_NV_T

This structure declares the run-time data to be stored with each DTC.

 PDTC_DTC_T

This structure declares the constant data to be stored with each DTC type.

 PDTC_TABLE_VAR_T

This structure declares all per-DTC-table variable data.

 PDTC_TABLE_T

This structure declares a table of DTCs.

Variables
U16pdtc_nv_chksum

This is the CRC checksum of the DTC store in non-volatile memory.

const U8pdtc_store

This defines which memory type will be used to store non-volatile DTCs.

const U16pdtc_num_dtc_tables

This is the total number of DTC tables the library will maintain.

const PDTC_TABLE_T *constpdtc_table_list

This is a list of the DTC tables the library will maintain.

Functions
voidpdtc_commit_to_store

Commit DTC data, and freeze frame data if supported, to non-volatile store.

BOOLpdtc_is_store_intact

Test whether there are DTC changes not yet committed to NV store.

voidpdtc_clear_all

Clear the state of each DTC of matching type in a DTC table.

voidpdtc_clear_all_if_active

Clear the state of each DTC of matching type in a DTC table, if the DTC state is active.

voidpdtc_clear_all_if_inactive

Clear the state of each DTC of matching type in a DTC table, if the DTC state is inactive.

voidpdtc_enable_periodic_lamp_updates

Allows an application to enable or disable periodic processing of the pdtc lamp status.

voidpdtc_update_j1939_dtc

Update the status and data of a J1939 DTC.

5.18.7. Interface detail

5.18.7.1.  Macros

5.18.7.1.1. PDTC_STORE_IN_BBRAM
Definition:

#define PDTC_STORE_IN_BBRAM 0

Description:

This macro defines the value for pdtc_store when DTCs are to be stored in battery backed RAM across power cycles.

5.18.7.1.2. PDTC_STORE_IN_FLASH
Definition:

#define PDTC_STORE_IN_FLASH 1

Description:

This macro defines the value for pdtc_store when DTCs are to be stored in Flash across power cycles.

5.18.7.2.  Enumerations

5.18.7.2.1. PDTC_STATE_T
Summary:

This enumeration declares the different types of DTCs available.

Enumerations:
PDTC_STATE_CLEAR

The clear state for a DTC.

PDTC_STATE_ACTIVE

The active state for a DTC.

PDTC_STATE_PREVIOUSLY_ACTIVE
PDTC_STATE_INACTIVE

The inactive (or CARB "previously active") state for a DTC.

PDTC_STATE_PENDING

The pending state for a DTC.

5.18.7.2.2. PDTC_ERROR_CODE_T
Summary:

Error values when an error is found by the diagnostic trouble code feature (PDTC), the feature calls a system error log function with an enumeration from this type.

Enumerations:
PDTC_OK

No error.

PDTC_UPDATE_INVALID_ARG

Error raised if the DTC update function finds an invalid argument.

PDTC_CLEAR_ALL_INVALID_ARG

Error raised if the DTC clear all function finds an invalid argument.

PDTC_CLEAR_ALL_IF_ACT_INVALID_ARG

Error raised if the DTC clear all if active function finds an invalid argument.

PDTC_CLEAR_ALL_IF_INACT_INVALID_ARG

Error raised if the DTC clear all if inactive function finds an invalid argument.

PDTC_GET_DTC_STATUS_INVALID_ARG

Error raised if the DTC clear all if inactive function finds an invalid argument.

PDTC_MATCH_EXISTS_INVALID_ARG

Error raised if the match exists function finds an invalid argument.

PDTC_CLEAR_DTCS_INVALID_ARG

Error raised if the DTC clear function finds an invalid argument.

PDTC_BAD_LICENSE

Error raised if function call not licensed.

5.18.7.3.  Data types

5.18.7.3.1. PDTC_DTC_NV_T
Summary:

This structure declares the run-time data to be stored with each DTC.

Members:
PDTC_STATE_T PDTC_DTC_NV_T::state

This is the current state of the DTC.

One of PDTC_STATE_CLEAR, PDTC_STATE_ACTIVE, PDTC_STATE_INACTIVE or PDTC_STATE_PENDING.

U8 PDTC_DTC_NV_T::count

This is the (saturated) number of times the DTC has changed to the PDTC_STATE_ACTIVE state.

Range: [0, 127] counts - 0 to 126 (The value 127 is reserved for indicating not available)

U8 PDTC_DTC_NV_T::lamp_states

This is a bit pattern of states for 4 lamps.

Bits 7:6 correspond to the malfunction lamp, bits 5:4 correspond to the red lamp, bits 3:2 correspond to the amber lamp and bits 1:0 correspond to the protect lamp. The bit pattern for each lamp state is determined by the J1939 specification.

Note that this is only used by the legacy (deprecated) interface for J1939 DTCs, to allow backwards compatibility for existing applications, and may be removed in a future version of the API.

Description:

This structure declares the run-time data to be stored with each DTC.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.3.2. PDTC_DTC_T
Summary:

This structure declares the constant data to be stored with each DTC type.

Members:
PIO_DTC_TYPE_T PDTC_DTC_T::type

This is the enumeration for a diagnostic trouble code.


Range: [1, 2]

U32 PDTC_DTC_T::spn

This is the suspect parameter number associated with a J1939 DTC.


Range: [0, 524287]

U8 PDTC_DTC_T::fmi

This is the failure mode indicator associated with a J1939 DTC.


Range: [0, 31]

U8 PDTC_DTC_T::cm

This is the conversion method associated with a J1939 DTC.


Range: [0, 1]

PDTC_DTC_NV_T* PDTC_DTC_T::nv_data

This points to the non-volatile storage structure for this DTC.

May not be NULL.

PDTC_DTC_VAR_T* PDTC_DTC_T::var_data

This points to the volatile (RAM) storage structure for this DTC.

May not be NULL.

Description:

This structure declares the constant data to be stored with each DTC type.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.3.3. PDTC_TABLE_VAR_T
Summary:

This structure declares all per-DTC-table variable data.

Members:
PDTC_COMBINED_LAMP_STATE_T PDTC_TABLE_VAR_T::lamp_states[4]

This is an array of lamp states (sized by PDTC_NUM_LAMPS) for all lamps whose status is set by DTCs in this table.

Description:

This structure declares all per-DTC-table variable data.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.3.4. PDTC_TABLE_T
Summary:

This structure declares a table of DTCs.

Members:
U16 PDTC_TABLE_T::num_dtcs

This is the number of DTCs referenced by the table.

Range: [0, 65535] dtcs

U16 PDTC_TABLE_T::dtc_offset

This is the bit offset into pj1939_state[] and pj1939_sent[], used to track the state of a DTC for DM1 message transmit rules.

The DTCs are allocated to these arrays in a contiguous fashion per table. Range: [0, 65535]

const PDTC_DTC_T* const* PDTC_TABLE_T::dtcs

This is a pointer to an array of const pointers (sized by num_dtcs) to DTCs referenced by this table.

PDTC_TABLE_VAR_T* PDTC_TABLE_T::per_table_data

This is a pointer to per-DTC-table variable data.

Description:

This structure declares a table of DTCs.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.4.  Variables

5.18.7.4.1. pdtc_nv_chksum
Definition:

U16 pdtc_nv_chksum

Description:

This is the CRC checksum of the DTC store in non-volatile memory.

The CRC checksum of the DTC store is updated prior to storing DTC data in non-volatile memory when calling pdtc_commit_to_store().

Range: [0, 65535] unitless

5.18.7.4.2. pdtc_store
Definition:

const U8 pdtc_store

Description:

This defines which memory type will be used to store non-volatile DTCs.

If set to PDTC_STORE_IN_BBRAM then DTCs are stored in battery backed RAM, and if set to PDTC_STORE_IN_FLASH then the DTCs are stored in Flash.

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

5.18.7.4.3. pdtc_num_dtc_tables
Definition:

const U16 pdtc_num_dtc_tables

Description:

This is the total number of DTC tables the library will maintain.

5.18.7.4.4. pdtc_table_list
Definition:

const PDTC_TABLE_T* const pdtc_table_list[]

Description:

This is a list of the DTC tables the library will maintain.

5.18.7.5.  Functions

5.18.7.5.1. pdtc_commit_to_store()
Definition:

void pdtc_commit_to_store(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Commit DTC data, and freeze frame data if supported, to non-volatile store.

Warning

This function merely queues the saving of data and returns, so application execution is unaffected. If the data must be committed to memory as part of a power-down sequence, follow this by a call to pfs_flush_all to ensure the data write is complete before powering off.

Note

Old DTC data is reused so long as it has the expected total data size and was written by an application with the same user-specified version number. Otherwise the values revert to defaults. If the usage of DTCs has changed in a new software version, increase the application sub-minor version number to ensure that any old values are not used, as they may not map appropriately to the DTCs in the new application even if the total data size happens to match.

5.18.7.5.2. pdtc_is_store_intact()
Definition:

BOOL pdtc_is_store_intact(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Test whether there are DTC changes not yet committed to NV store.

Return:

True if there are no DTC changes since last commit to non-volatile store (from calling pdtc_commit_to_store()), false otherwise

5.18.7.5.3. pdtc_clear_all()
Definition:

void pdtc_clear_all(
   const PDTC_TABLE_T *const   pdtcf_table,
   const PIO_DTC_TYPE_T        pdtcf_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Clear the state of each DTC of matching type in a DTC table.

For the DTC table (pdtcf_table) the function to clear all DTCs is called.

Freeze frame data associated with the cleared DTCs is also cleared. Monitor (DME and DTE) data is also cleared other than persistent data which is never cleared (e.g. numerators and denominators). As the platform does not know which DME/DTE objects are associated with which DTCs in an application, it is assumed that the table being cleared applies to all emissions-relevant monitors.

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

5.18.7.5.4. pdtc_clear_all_if_active()
Definition:

void pdtc_clear_all_if_active(
   const PDTC_TABLE_T *const   pdtcf_table,
   const PIO_DTC_TYPE_T        pdtcf_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Clear the state of each DTC of matching type in a DTC table, if the DTC state is active.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type, and the DTC state is PDTC_STATE_ACTIVE, then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Any freeze frame data associated with cleared DTCs is also erased, but not monitor data. See also pdtc_clear_all.

Can raise the following errors:
PDTC_CLEAR_ALL_IF_ACT_INVALID_ARG

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

5.18.7.5.5. pdtc_clear_all_if_inactive()
Definition:

void pdtc_clear_all_if_inactive(
   const PDTC_TABLE_T *const   pdtcf_table,
   const PIO_DTC_TYPE_T        pdtcf_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Clear the state of each DTC of matching type in a DTC table, if the DTC state is inactive.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type, and the DTC state is PDTC_STATE_INACTIVE, then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Any freeze frame data associated with cleared DTCs is also erased, but not monitor data. See also pdtc_clear_all.

This function would normally be called only in response to a J1939 DM3 request (not intended for emissions-related systems).

Can raise the following errors:
PDTC_CLEAR_ALL_IF_INACT_INVALID_ARG

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

5.18.7.5.6. pdtc_enable_periodic_lamp_updates()
Definition:

void pdtc_enable_periodic_lamp_updates(
   BOOL   pdtcf_en);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Allows an application to enable or disable periodic processing of the pdtc lamp status.

Note

Periodic processing is enabled by default so this function is not required to enable processing.

Arg (data in): pdtcf_en

Flag indicating if periodic updates should be enabled (TRUE) or disabled (FALSE).

5.18.7.5.7. pdtc_update_j1939_dtc()
Definition:

void pdtc_update_j1939_dtc(
   const PDTC_DTC_T *const   pdtcf_dtc,
   U8                        pdtcf_active_in,
   U8                        pdtcf_lamp_bitmap,
   U8                       *pdtcf_active_out,
   U8                       *pdtcf_state,
   U8                       *pdtcf_count);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Update the status and data of a J1939 DTC.

Updates the status and data of a J1939 DTC. When the DTC's internal state changes from clear to active, or from inactive to active, the function increases the DTC's internal activation count (saturating at 127).

Can raise the following errors:
PDTC_UPDATE_INVALID_ARG.

Arg (data in,out): pdtcf_dtc

Pointer to DTC to update. Cannot be NULL.

Arg (data in): pdtcf_active_in

True if the DTC should become active, false otherwise.

Arg (data in): pdtcf_lamp_bitmap

Bitmap of lamp information (for J1939 DTCs). For future software, this must always be set to PDTC_LAMPS_OFF, which selects lamp state as calibrated for the DTC. For legacy software this may be set to a bitmap where bits 7:6 correspond to the malfunction lamp, bits 5:4 correspond to the red lamp, bits 3:2 correspond to the amber lamp and bits 1:0 correspond to the protect lamp. The bit pattern for each lamp state is determined by the J1939 specification.

Arg (data out): pdtcf_active_out

Pointer to where the boolean result of whether the DTC is active or not is to be stored.
Cannot be NULL.

Arg (data out): pdtcf_state

Pointer to where the current DTC state will be written. Cannot be NULL.
Range: 1 = Clear, 2 = Active, 3 = Inactive

Arg (data out): pdtcf_count

Pointer to where the current DTC activation count will be written.
Cannot be NULL.
Range: [0, 127] counts

5.19. Adaptive non-volatile memory feature (PNV)

5.19.1. Overview

The library's non-volatile memory feature provides a mechanism to declare non-volatile data, manipulate the data and store the data persistently across power cycles.

The library supports the following data types:

Non-volatile array

The library provides access to an array of non-volatile data through the pnv_array() function. The data can be modified, reset and stored to memory to be recalled during the next library initialisation. The entire array can be output using the pnv_array_dump() function

Adaptive scalar

The library provides access to a single non-volatile variable through the pnv_adap_scalar_f32() function. The scalar can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Adaptive 1-d look-up map

The library provides access to a non-volatile adaptive 1-d look-up map through the pnv_adap_map_1d_f32() function. The map can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Prior to looking up the map and performing interpolation to determine the output value (as done by put_cal_map_1d_f32()), the application can request that the map is modified: either reset to its default, or adjusted by an increment.

The library adjusts the map's Z-data as follows:

xa and xb bound pnvf_adapt_xx (see exceptions below), while za and zb are the corresponding elements pnvf_pz, both parameters to function pnv_adap_map_1d_f32().

There are some exceptions, see the function documentation for more.

Adaptive 2-d look-up map

The library provides access to a non-volatile adaptive 2-d look-up map through the pnv_adap_map_2d_f32() function. The map can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Prior to looking up the map and performing interpolation to determine the output value (as done by put_cal_map_2d_f32()), the application can request that the map is modified: either reset to its default, or adjusted by an increment.

The library adjusts the map's Z-data as follows:

xa and xb bound pnvf_adapt_xx, ya and yb bound pnvf_adapt_yy, zaa, zab, zba and zbb are the corresponding elements in pnvf_pz, all parameters to function pnv_adap_map_1d_f32().

There are some exceptions, see the function documentation for more.

pnv_is_ram_adap_csum_valid()

The library provides access to the status of the adaptive RAM checksum through the pnv_is_ram_adap_csum_valid() function. The function returns true if the checksum is valid and false otherwise.

pnv_is_flash_adap_csum_valid()

The library provides access to the status of the adaptive RAM checksum through the pnv_is_flash_adap_csum_valid() function. The function returns true if the checksum is valid and false otherwise.

5.19.2. Storage of data across power cycles

On start-up, the library attempts to retrieve adaptive data prior to running the application. While the application is running, the time at which the adaptive data is stored back to non-volatile memory is determined by the application itself.

The adaptive data is check-summed using a 16-bit CRC. Failure to match the check-sum against the adaptive data during library initialisation means that the data cannot be recovered. In this case, adaptive data is reverted to the default for each adaptive element (the defaults can be specified by the application).

There are two types of non-volatile memory dedicated to adaptive data:

Battery backed RAM

Storage that requires an external power source when the ECU is powered down (not available on all target ECUs),

Flash

Storage that requires no external power supply when the ECU is powered down (not available on all target ECUs).

See Section A.1, “ECU hardware reference documentation” for details of what non-volatile memory stores are available for each target ECU.

The application starts a commit of adaptive data to non-volatile store by calling pnv_commit_to_store().

Note

If the non-volatile memory store is Flash, then the library will halt the application while committing adaptive data to non-volatile memory. This is to prevent any higher-rate tasks interrupting and attempting to access the Flash device (which will generally be unavailable at that time).

The worst case scenario is for the application to be stopped for about 1.8 seconds. It is the responsibility of the application to ensure that there will be no detrimental side effects to stopping the application for this length of time, e.g., the application should ensure all coil and injector outputs are turned off if applicable for that ECU.

It should also be noted that, once started, it is not possible to interrupt the Flash commit process. So if, for example, a user of the ECU requests that the ECU start-up before the process has completed, the ECU will not try to start until control is passed back to the application.

The application can determine if the adaptive data requires a commit to non-volatile memory through the pnv_is_store_intact() function. When the ECU decides to power down, if this function returns true, there will be no need to store the data to non-volatile memory again; this is important for a Flash-based solution as this means there is no need to write the data to Flash, thus minimising shutdown time and reducing the number of Flash write cycles.

5.19.3. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pnv.h
Macros
 PNV_STORE_IN_BBRAM

This macro defines the value for pnv_store when non-volatile data is to be stored in battery backed RAM across power cycles.

 PNV_STORE_IN_FLASH

This macro defines the value for pnv_store when non-volatile data is to be stored in Flash across power cycles.

Enumerations
 PNV_ERROR_CODE_T

Error values for debugging when an error is found when calling the PNV API, the API calls a function with an enumeration from this type.

 PNV_RC_T

An enumerated type which contains success and failure codes returned by the adaptive map lookup and interpolation functions.

Data types
 PNV_ADAP_T

This typedef defines a structure which is used to locate all of the adaptive parameters.

Variables
const U8pnv_store

This defines which memory type will be used to store non-volatile adaptive data.

U8pnv_adap_csum

This is a checksum of the non-volatile memory objects stored in RAM.

Functions
voidpnv_commit_to_store

Commit RAM data to non-volatile store.

BOOLpnv_is_store_intact

Test whether there are adaptive data changes not yet committed to NV store.

PNV_RC_Tpnv_adap_map_1d_f32

1D table adaption, lookup and interpolation.

PNV_RC_Tpnv_adap_map_2d_f32

2D table adaption, lookup and interpolation.

voidpnv_adap_scalar_f32

Adaptive scalar update.

BOOLpnv_is_ram_adap_csum_valid

Return the state of RAM adaptive checksum.

BOOLpnv_is_flash_adap_csum_valid

Return the state of Flash adaptive checksum.

voidpnv_array

Non-volatile array read and write functionality.

voidpnv_array_dump

Non-volatile array output facility.

5.19.4. Interface detail

5.19.4.1.  Macros

5.19.4.1.1. PNV_STORE_IN_BBRAM
Definition:

#define PNV_STORE_IN_BBRAM 0

Description:

This macro defines the value for pnv_store when non-volatile data is to be stored in battery backed RAM across power cycles.

5.19.4.1.2. PNV_STORE_IN_FLASH
Definition:

#define PNV_STORE_IN_FLASH 1

Description:

This macro defines the value for pnv_store when non-volatile data is to be stored in Flash across power cycles.

5.19.4.2.  Enumerations

5.19.4.2.1. PNV_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the PNV API, the API calls a function with an enumeration from this type.

Enumerations:
PNV_ADAPMAP_INVALID_ARG

Error raised if one of the adaptive table lookup and interpolation functions finds an invalid argument.

PNV_ADAPSCALAR_INVALID_ARG

Error raised if the adaptive scalar function find an invalid argument.

PNV_ARRAY_INVALID_ARG

Error raised if the array function finds an invalid argument.

PNV_ARRAY_DUMP_INVALID_ARG

Error raised if the array dump function finds an invalid argument.

5.19.4.2.2. PNV_RC_T
Summary:

An enumerated type which contains success and failure codes returned by the adaptive map lookup and interpolation functions.

Enumerations:
PNV_RC_OK

Return code if everything progressed as expected.

PNV_RC_BAD_ARGS

Return code if at least one of the arguments points to null.

PNV_RC_INSUFFICIENT_ELEMENTS

Return code if there are insufficient elements to use the function.

5.19.4.3.  Data types

5.19.4.3.1. PNV_ADAP_T
Summary:

This typedef defines a structure which is used to locate all of the adaptive parameters.

Members:
void* PNV_ADAP_T::adap_ptr

A pointer to the RAM version of the object.

Used during run-time for read and write purposes, it is initialised from the non-volatile copy of the same object (or the constant copy if non-volatile memory fails). The RAM version is copied to non-volatile memory (if possible) when pnv_commit_to_store() is called. Cannot point to NULL.

const void* PNV_ADAP_T::def_ptr

A pointer to a constant version of the object, used to restore a default value if the non-volatile copy of the same object could not be recovered from non-volatile memory during initialisation.

Cannot point to NULL.

U32 PNV_ADAP_T::size

The size of the object pointed to by adap_ptr and def_ptr in bytes.

Cannot be zero.

Description:

This typedef defines a structure which is used to locate all of the adaptive parameters.

During initialisation, if the adaptive data cannot be recalled, the default adaptive data is used instead.

5.19.4.4.  Variables

5.19.4.4.1. pnv_store
Definition:

const U8 pnv_store

Description:

This defines which memory type will be used to store non-volatile adaptive data.

If set to PNV_STORE_IN_BBRAM then non-volatile adaptive data is stored in battery backed RAM, and if set to PNV_STORE_IN_FLASH then the non-volatile adaptive data is stored in Flash.

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

5.19.4.4.2. pnv_adap_csum
Definition:

U8 pnv_adap_csum[]

Description:

This is a checksum of the non-volatile memory objects stored in RAM.

The checksum is the CCITT CRC. The checksum must be the first linked variable in the RAM memory area dedicated to non-volatile memory. It is allocated by the linker.

5.19.4.5.  Functions

5.19.4.5.1. pnv_commit_to_store()
Definition:

void pnv_commit_to_store(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Commit RAM data to non-volatile store.

Update the checksum for the non-volatile data, and if the data is stored in Flash, then write the data to Flash.

Warning

This function merely queues the saving of data and returns, so application execution is unaffected. If the data must be committed to memory as part of a power-down sequence, follow this by a call to pfs_flush_all to ensure the data write is complete before powering off.

Note

Old adaptive data is reused so long as it has the expected total data size and was written by an application with the same user-specified version number. Otherwise the values revert to defaults. If the usage of adaptive parameters has changed in a new software version, increase the application sub-minor version number to ensure that any old values are not used, as they may not map appropriately to the parameters in the new application even if the total data size happens to match.

5.19.4.5.2. pnv_is_store_intact()
Definition:

BOOL pnv_is_store_intact(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Test whether there are adaptive data changes not yet committed to NV store.

Return:

True if there are no adaptive data changes since the last commit to the non-volatile store (from calling pnv_commit_to_store()), false otherwise

5.19.4.5.3. pnv_adap_map_1d_f32()
Definition:

PNV_RC_T pnv_adap_map_1d_f32(
   F32                  pnvf_adapt_xx,
   F32                  pnvf_adapt_increment,
   BOOL                 pnvf_adapt,
   BOOL                 pnvf_reset,
   S32                  pnvf_n,
   volatile const F32  *pnvf_px,
   volatile const F32  *pnvf_pz_default,
   F32                 *pnvf_pzz);

Supported targets:

All targets

Required license:

None (Main library).

Description:

1D table adaption, lookup and interpolation.

Linearly interpolates between map elements when input is within the map's range (possibly adapting or resetting the table data before the lookup and interpolation). Clips to the x-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors:
PNV_ADAPMAP_INVALID_ARG.

Note

The 1d lookup is of function z(x). The use of z as the function name, rather than y, is chosen to be consistent with the 2d lookup function.

See pnv_adapmap_2d_f32() for 2d table adaptive lookup.

See put_calmap_1d_f32() and put_calmap_2d_f32() for table lookups without adaption.

Arg (data in): pnvf_adapt_xx

The argument to z(x), a point on the x-axis for interpolation.

Arg (data in): pnvf_adapt_increment

The adaption increment, applied proportionately over interpolated values.

Arg (data in): pnvf_adapt

Set true to adapt the adaptive table based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset

Set true to reset the adaptive table to its default (pnvf_pz_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_n

The number of elements in the x-axis and z-data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_scalar_f32() for a scalar function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_px

Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): pnvf_pz_default

Pointer to array of the map's default z-data. The default z-data is used to overwrite the adaptive map's z-data if the pnvf_reset parameter is true.
The map which this pointer references must be declared with the OE_ADAP macro.
Cannot be NULL.

Arg (data out): pnvf_pzz

Pointer to interpolated output (possibly adapted or reset).
Cannot be NULL.

Return:

5.19.4.5.4. pnv_adap_map_2d_f32()
Definition:

PNV_RC_T pnv_adap_map_2d_f32(
   F32                  pnvf_adapt_xx,
   F32                  pnvf_adapt_yy,
   F32                  pnvf_adapt_increment,
   BOOL                 pnvf_adapt,
   BOOL                 pnvf_reset,
   S32                  pnvf_nx,
   S32                  pnvf_ny,
   volatile const F32  *pnvf_px,
   volatile const F32  *pnvf_py,
   volatile const F32  *pnvf_pz_default,
   F32                 *pnvf_pzz);

Supported targets:

All targets

Required license:

None (Main library).

Description:

2D table adaption, lookup and interpolation.

Bilinearly interpolates between map elements when input is within the map's range (possibly adapting or resetting the table data before the lookup and interpolation). Clips to the x-axis and y-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors:
PNV_ADAPMAP_INVALID_ARG.

Note

See put_adapmap_1d_f32() for 1d table lookup with adaption.

See pnv_calmap_1d_f32() and pnv_calmap_2d_f32() for table lookups without adaption.

Arg (data in): pnvf_adapt_xx

The argument to z(x,y), a point on the x-axis for interpolation.

Arg (data in): pnvf_adapt_yy

The argument to z(x,y), a point on the y-axis for interpolation.

Arg (data in): pnvf_adapt_increment

The adaption increment, applied proportionately over interpolated values.

Arg (data in): pnvf_adapt

Set true to adapt the adaptive table based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset

Set true to reset the adaptive table to its default (pnvf_pz_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_nx

The number of elements in the x-axis and z(x,) data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_map_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_ny

The number of elements in the y-axis and z(,y) data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_map_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the y-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_px

Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): pnvf_py

Pointer to array of the map's y-axis. The values stored in the y-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): pnvf_pz_default

Pointer to array of the map's default z-data. The default z-data is used to overwrite the adaptive map's z-data if the pnvf_reset parameter is true.
The map which this pointer references must be declared with the OE_ADAP macro.
Cannot be NULL.

Arg (data out): pnvf_pzz

Pointer to interpolated output (possibly adapted or reset).
Cannot be NULL.

Return:

5.19.4.5.5. pnv_adap_scalar_f32()
Definition:

void pnv_adap_scalar_f32(
   F32                  pnvf_adapt_increment,
   BOOL                 pnvf_adapt,
   BOOL                 pnvf_reset,
   volatile const F32  *pnvf_adapt_default,
   F32                 *pnvf_adapted);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Adaptive scalar update.

Returns a scalar held in non-volatile memory after possibly adapting its value.

Can raise the following errors:
PNV_ADAPSCALAR_INVALID_ARG.

Arg (data in): pnvf_adapt_increment

The adaption increment to be applied to the scalar value.

Arg (data in): pnvf_adapt

Set true to adapt the adaptive scalar based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset

Set true to reset the adaptive scalar to its default (pnvf_adapt_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_adapt_default

Pointer to scalar's default value. The default value is used to overwrite the adaptive scalar's value if the pnvf_reset parameter is true.
The calibration which this pointer represents must be declared with the OE_ADAP macro.
Cannot be NULL.

Arg (data out): pnvf_adapted

Pointer to adapted output.
Cannot be NULL.

5.19.4.5.6. pnv_is_ram_adap_csum_valid()
Definition:

BOOL pnv_is_ram_adap_csum_valid(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the state of RAM adaptive checksum.

Return:

True if RAM checksum intact, false otherwise.

5.19.4.5.7. pnv_is_flash_adap_csum_valid()
Definition:

BOOL pnv_is_flash_adap_csum_valid(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Return the state of Flash adaptive checksum.

Return:

True if Flash checksum intact, false otherwise.

5.19.4.5.8. pnv_array()
Definition:

void pnv_array(
   U32                   pnvf_index,
   volatile const void  *pnvf_new_value,
   BOOL                  pnvf_change,
   BOOL                  pnvf_reset,
   U32                   pnvf_elem_size,
   S32                   pnvf_n,
   volatile const void  *pnvf_array_default,
   BOOL                 *pnvf_valid_index,
   void                 *pnvf_value);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Non-volatile array read and write functionality.

Detailed description of functionality:
This block is similar to the pnv_adaptive_map1d block. It can store an array of values in non-volatile memory, change individual elements of the array and read individual elements out of the array (but does not interpolate entries as the pnv_adaptive_map1d block does). The DDE type for arrays use the v character in the DDE naming scheme (similar to the use of the c character when declaring scalar calibrations).

Can raise the following errors:
PNV_ARRAY_INVALID_ARG.

Arg (data in): pnvf_index

The index to the array element to access. Range: [0, { pnvf_n - 1 }]

Arg (data in): pnvf_new_value

A pointer to the new value to write to the array index. Written only if pnvf_change is true and pnvf_reset is false. As the parameter is a void pointer, the size in bytes of the new value to write is given by pnvf_elem_size.
Cannot be NULL.

Arg (data in): pnvf_change

Set true to change the adaptive based on the new value (pnvf_new_value), set false for no change. If both pnvf_change and pnvf_reset are set true, then no change occurs.

Arg (data in): pnvf_reset

Set true to reset the adaptive to its default (pnvf_array_default), set false for no reset. If both pnvf_change and pnvf_reset are set true, then no change occurs.

Arg (data in): pnvf_elem_size

The size of each array element in bytes. Must be greater than zero.

Arg (data in): pnvf_n

The number of elements in the adaptive array. Must be greater than zero.

Arg (data in): pnvf_array_default

Pointer to array's default contents. The contents are used to overwrite the adaptive array's contents if the pnvf_reset parameter is true.
The array which this pointer represents must be declared with the OE_ADAP macro.
Cannot be NULL.

Arg (data out): pnvf_valid_index

Pointer to boolean to be written with the result of whether the array index (pnvf_index) is valid or not.
Cannot be NULL.

Arg (data out): pnvf_value

Pointer to memory to be written with the array element referenced by pnvf_index. If the array index (pnvf_index) is invalid, then the first element of the array is written to the memory pointed to by pnvf_value.
Cannot be NULL.

5.19.4.5.9. pnv_array_dump()
Definition:

void pnv_array_dump(
   U32                   pnvf_elem_size,
   S32                   pnvf_num_elems,
   volatile const void  *pnvf_array_default,
   void                 *pnvf_output);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Non-volatile array output facility.

Detailed description of functionality:
This function will dump the entire contents of the adaptive array specified by the third argument to a memory location specified by the fourth argument. The size of the array in bytes is inferred from the first two arguments here, namely the number of bytes per element in the array, and the total number of elements in the array. Note that the DDE type for calibratable arrays uses the v character in the DDE naming scheme (similar to the use of the c character when declaring scalar calibrations).

Can raise the following errors:
PNV_ARRAY_DUMP_INVALID_ARG

Arg (data in): pnvf_elem_size

The size of each array element in bytes.

Arg (data in): pnvf_num_elems

The number of elements in the adaptive array.

Arg (data in): pnvf_array_default

Pointer to array's default contents. This is just used to identify the true adaptive array.
Cannot be NULL.

Arg (data out): pnvf_output

Pointer to memory to be written with the entire contents of the adaptive array.
Cannot be NULL.

5.20. Non-volatile Filesystem feature (PFS)

5.20.1. Overview

The library's nonvolatile filesystem feature manages the storage of data persistently across power cycles. It is used by the library to store data such as DTCs and adaptive parameters, but can also be used by application code. To achieve this it emulates the operations of a simple disk drive, with operations to read, write and delete files at run time.

The filesystem feature is only available on the targets: All targets.

On these targets it uses particular features of the microcontroller's flash memory to allow "background" operations, so writing of data can continue while the application executes as normal. This means that operations such as file writing or deletion do not occur immediately when requested, but are queued to take place in parallel with other application processing. Facilities are provided to allow the application to determine when a queued operation is complete.

5.20.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pfs.h
Macros
 PFS_FTYPE_PLATFORM

File IDs with this bit set are reserved for platform use.

 PFS_FTYPE_RESERVED

The use of this bit in file IDs is reserved for future use.

 PFS_FTYPE_READONLY

The use of this bit in file IDs indicates a file which must not be deleted in any future 'delete all' operation.

 PFS_ORIGIN_YEAR

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

 PFS_DATESTAMP_SEC_PER_BIT

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

Enumerations
 PFS_ERROR_T

Error values for debugging when an error is found in a call to the PFS API, the feature calls a function with an enumeration from this type.

Data types
 PFS_FILESYS_STATS_T

Structure which conveys statistical information about the current status of the non-volatile filesystem.

 PFS_FILE_STATS_T

Structure which conveys statistical information about the current status of one file in the filesystem.

 PFS_REVISION_T

The type used to store file revision (version) number.

 PFS_FILE_ID_T

The type used to represent a file ID (equivalent to a filename, but simply a compact numerical type).

Variables
const U16pfs_max_num_user_files

Maximum number of simultaneous application-specific files supported.

Functions
PFS_RC_Tpfs_fread

Reads all or part of a file and places data at client-provided location.

BOOLpfs_is_newer

Determines if one revision number is newer than another, taking account of integer wraparound.

PFS_RC_Tpfs_fwrite_queue

Queues a file for writing, where the source data is provided as a contiguous region of memory identified by a start pointer and length.

PFS_RC_Tpfs_get_filesystem_stats

Obtains statistical information on the current state of the filesystem.

PFS_RC_Tpfs_get_file_id_by_idx

Obtains the file ID of the file currently at the provided index position in the sorted directory listing of files maintained by the filesystem.

PFS_RC_Tpfs_fstat

Obtains statistical information on a file.

PFS_RC_Tpfs_fdelete_queue

Queues a request to mark a file as deleted.

U32pfs_encode_time

Converts a calendar time and date into the compact form used in files.

voidpfs_flush_all

Enures all file write and delete operations are complete before returning.

voidpfs_lock_filesystem

Suspends filesystem operations including the copying of client data during file writes.

voidpfs_unlock_filesystem

Resumes filesystem operations including the copying of client data during file writes.

5.20.3. Interface detail

5.20.3.1.  Macros

5.20.3.1.1. PFS_FTYPE_PLATFORM
Definition:

#define PFS_FTYPE_PLATFORM 0x8000

Description:

File IDs with this bit set are reserved for platform use.

User applications may not write or delete such files.

5.20.3.1.2. PFS_FTYPE_RESERVED
Definition:

#define PFS_FTYPE_RESERVED 0x4000

Description:

The use of this bit in file IDs is reserved for future use.

User applications may not write or delete files with this bit set in the file ID.

5.20.3.1.3. PFS_FTYPE_READONLY
Definition:

#define PFS_FTYPE_READONLY 0x2000

Description:

The use of this bit in file IDs indicates a file which must not be deleted in any future 'delete all' operation.

User applications may create files with this ID set. A specific request to delete such a file will succeed however.

5.20.3.1.4. PFS_ORIGIN_YEAR
Definition:

#define PFS_ORIGIN_YEAR 2010

Description:

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

A zero value corresponds to 00:00 on 1 January of this year.

5.20.3.1.5. PFS_DATESTAMP_SEC_PER_BIT
Definition:

#define PFS_DATESTAMP_SEC_PER_BIT 180

Description:

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

This constant defines the resolution of the timestamp values.

5.20.3.2.  Enumerations

5.20.3.2.1. PFS_ERROR_T
Summary:

Error values for debugging when an error is found in a call to the PFS API, the feature calls a function with an enumeration from this type.

Enumerations:
PFS_ECC_ERROR_DURING_FLASH_OP

Error raised if the PGN requested function finds an invalid function argument.

PFS_RUNTIME_CORRUPT_FILE_FOUND

Error raised if the PG receive function finds an invalid function argument.

5.20.3.3.  Data types

5.20.3.3.1. PFS_FILESYS_STATS_T
Summary:

Structure which conveys statistical information about the current status of the non-volatile filesystem.

Members:
S32 PFS_FILESYS_STATS_T::byte_capacity

The total raw space available for file storage.

This includes the overhead of storing metadata and padding, but does not include the duplication of space in different flash memory blocks.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_used

The total raw space currently used by files, metadata and padding.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_total_size

The total raw space allocated to the non-volatile filesystem, summing all the space in the flash memory blocks allocated to it.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_bad

The total space which has been found to contain invalid data or for which flash programming operations failed.

This is reset to zero on power-up, and then any invalid data found already present in the system contributes to this total before any file writes are attempted.

Range: [0, 262143] bytes

U32 PFS_FILESYS_STATS_T::lifetime_erases

The total number of times that a flash erase operation has been started on any block allocated to the filesystem.

Range: [0, 16777215] erases

PFS_REVISION_T PFS_FILESYS_STATS_T::head_revision

The revision number of the most recent event (file write, delete, erase etc) that has been attempted in the filesystem.

Range: [0, 65535]

S16 PFS_FILESYS_STATS_T::user_files

The number of valid, completely written files currently present in the filesystem belonging to the application.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::platform_files

The number of valid, completely written files currently present in the filesystem with platform-reserved IDs.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::total_files

The total number of valid, completely written files currently present in the filesystem.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::failed_writes

The number of times since the most recent power-on that the system failed to successfully write a file.

Range: [0, 32767]

S16 PFS_FILESYS_STATS_T::discarded_files

The number of times since the most recent power-on that the system ignored a file it found on disk because its directory space was already full.

As different versions of the file may be found on disk, this may be larger than the number of unique files which were discarded.

Range: [0, 32767]

S16 PFS_FILESYS_STATS_T::runtime_corrupt_files

The number of files that have been detected by runtime processing to be corrupt since power-on.

Range: [0, 32767]

S8 PFS_FILESYS_STATS_T::blocks

The number of separate flash memory blocks used by the filesystem to achieve redundant storage.

Range: [2, 7]

S8 PFS_FILESYS_STATS_T::active_block_idx

The zero-based index of the flash memory block to which file writes are currently being made.

Range: [0, 7]

Description:

Structure which conveys statistical information about the current status of the non-volatile filesystem.

See also pfs_get_filesystem_stats().

5.20.3.3.2. PFS_FILE_STATS_T
Summary:

Structure which conveys statistical information about the current status of one file in the filesystem.

Members:
S32 PFS_FILE_STATS_T::size_bytes

The size of the actual useful data contained in the file, excluding any overhead or padding.

Range: [0, 262143] bytes

S32 PFS_FILE_STATS_T::disk_bytes

The size of flash memory consumed by this file in the filesystem, including metadata overhead and any padding.

Range: [0, 262143] bytes

U32 PFS_FILE_STATS_T::encoded_build_time

The timestamp of the application software build responsible for the last write of this file.

See also PFS_DATESTAMP_SEC_PER_BIT and PFS_ORIGIN_YEAR.

Range: [0, 16777215]

PFS_REVISION_T PFS_FILE_STATS_T::revision

The revision number of the file stored in the system.

Range: [0, 65535]

U16 PFS_FILE_STATS_T::user_data

Data provided by the client when the file was written.

This can be used for example to define a use-specific layout version, such that the client can interpret old files correctly if the format has changed. This is kept separate from the actual file data to allow that to consist of equal-sized records (see pfs_fwrite_simple_queue()).

Range: [0, 65535]

U8 PFS_FILE_STATS_T::app_ver_major

The major version number of the application software build responsible for the last write of this file, e.g.

"2" in version "2.7.13".

Range: [0, 255]

U8 PFS_FILE_STATS_T::app_ver_minor

The minor version number of the application software build responsible for the last write of this file, e.g.

"7" in version "2.7.13".

Range: [0, 255]

U8 PFS_FILE_STATS_T::app_ver_subminor

The sub-minor version number of the application software build responsible for the last write of this file, e.g.

"13" in version "2.7.13".

Range: [0, 255]

BOOL PFS_FILE_STATS_T::on_disk

Whether this file is already safely stored in the filesystem.

For a new file, this becomes TRUE when the write process has completed.

BOOL PFS_FILE_STATS_T::write_queued

Whether this file has a write or delete operation queued or in progress.

BOOL PFS_FILE_STATS_T::this_build_wrote

Whether this file was written by software matching the build timestamp of the currently executing application software.

BOOL PFS_FILE_STATS_T::this_ver_wrote

Whether this file was written by software matching the build version (e.g.

"2.3.17") of the currently executing application software.

Description:

Structure which conveys statistical information about the current status of one file in the filesystem.

Except where stated otherwise, each statistic refers to the file already stored on disk, and not to any new version for which a write operation is in progress.

See also pfs_fstat().

5.20.3.3.3. PFS_REVISION_T
Definition:

typedef U16 PFS_REVISION_T

Description:

The type used to store file revision (version) number.

Revision numbers eventually wrap around to zero and start counting up again from there. The revision number applies to the whole filesystem (similar to the use in the Subversion system). See also pfs_is_newer().

5.20.3.3.4. PFS_FILE_ID_T
Definition:

typedef U16 PFS_FILE_ID_T

Description:

The type used to represent a file ID (equivalent to a filename, but simply a compact numerical type).

5.20.3.4.  Variables

5.20.3.4.1. pfs_max_num_user_files
Definition:

const U16 pfs_max_num_user_files

Description:

Maximum number of simultaneous application-specific files supported.

This is currently fixed, but could in future be a C-API specified item to support applications that need to write a large number of different files.

5.20.3.5.  Functions

5.20.3.5.1. pfs_fread()
Definition:

PFS_RC_T pfs_fread(
   PFS_FILE_ID_T   pfsf_file_id,
   U32             pfsf_byte_offset,
   U8             *pfsf_dest_ptr,
   U32             pfsf_max_bytes,
   U32            *pfsf_actual_bytes);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Reads all or part of a file and places data at client-provided location.

Arg (data in): pfsf_file_id

ID of file to read (numeric equivalent of filename)
Range: [0, 65535]

Arg (data in): pfsf_byte_offset

Byte offset from start of file at which to start reading; zero to start from beginning of file
Range: [0, 16777215]

Arg (data in,out): pfsf_dest_ptr

Location to write the file data to; cannot be NULL

Arg (data in): pfsf_max_bytes

Maximum size of data to read from file, or zero to read whole file
Range: [0, 16777215]

Arg (data in,out): pfsf_actual_bytes

Pointer to location in which to place the number of bytes that were read from the file; can be NULL
Range: [0, 16777215]

Return:

PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.2. pfs_is_newer()
Definition:

BOOL pfs_is_newer(
   PFS_REVISION_T   pfsf_old_revision,
   PFS_REVISION_T   pfsf_new_revision);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Determines if one revision number is newer than another, taking account of integer wraparound.

Arg (data in): pfsf_new_revision

The revision number which is expected to be older.
Range: [0, 65535]

Arg (data in): pfsf_old_revision

The revision number which is expected to be newer.
Range: [0, 65535]

Return:

TRUE if the expected newer revision was indeed newer than the expected older revision, otherwise FALSE.

5.20.3.5.3. pfs_fwrite_queue()
Definition:

PFS_RC_T pfs_fwrite_queue(
   PFS_FILE_ID_T   pfsf_file_id,
   const U8       *pfsf_src_ptr,
   S32             pfsf_byte_len,
   U16             pfsf_user_data,
   S16             pfsf_coherent_copy_size);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Queues a file for writing, where the source data is provided as a contiguous region of memory identified by a start pointer and length.

This function returns immediately and the file write continues in the background. Use pfs_fstat to determine when the file write has completed successfully.

Arg (data in): pfsf_file_id

ID of file to write (numeric equivalent of filename)
Range: [0, 65535]

Arg (data in): pfsf_src_ptr

First byte location containing data to be written to file

Arg (data in): pfsf_byte_len

Number of bytes to write
Range: [0, 16777215]

Arg (data in): pfsf_user_data

User-specific data to store as part of file metadata; for example, this might convey format information relating to the content of the file. It can be retrieved using pfs_fstat(). This is separate from the actual file content, so that the latter can consist of equal-sized records (where appropriate) for coherent writing.
Range: [0, 65535]

Arg (data in): pfsf_coherent_copy_size

The filesystem will copy the provided data in multiples of this size, and prevent execution of the client task during the copy operation. For example, if the data to be saved consists of an array of structures each of 6 bytes in size, set this to 6 to ensure the filesystem always reads a whole struct at a time. A value of zero means "don't care".

If a write is in progress, the client can temporarily suspend it by using pfs_lock_filesystem while updating its data.

Together these facilities mean it is possible to ensure that the data saved to a file never consists of an incoherent copy containing both 'old' and 'new' data, as updated by the client, so long as the data is organised in equal-sized records like this.
Range: [0, 16]

Return:

PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.4. pfs_get_filesystem_stats()
Definition:

PFS_RC_T pfs_get_filesystem_stats(
   PFS_FILESYS_STATS_T  *pfsf_stats);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Obtains statistical information on the current state of the filesystem.

See also documentation for PFS_FILESYS_STATS_T.

Arg (data in,out): pfsf_stats

Pointer to structure provided by caller into which the statistics should be placed. Cannot be NULL.

Return:

PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.5. pfs_get_file_id_by_idx()
Definition:

PFS_RC_T pfs_get_file_id_by_idx(
   U16             pfsf_file_idx,
   PFS_FILE_ID_T  *pfsf_file_id_ptr);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Obtains the file ID of the file currently at the provided index position in the sorted directory listing of files maintained by the filesystem.

Client code can use this function to discover what files are available in the filesystem for reading.

Return:

PFS_RC_OK if successful, PFS_RC_OUT_OF_RANGE if no file exists at that index in the list, or another PFS_RC_T value for other error conditions.

5.20.3.5.6. pfs_fstat()
Definition:

PFS_RC_T pfs_fstat(
   PFS_FILE_ID_T      pfsf_file_id,
   PFS_FILE_STATS_T  *pfsf_file_stats);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Obtains statistical information on a file.

See also documentation for PFS_FILE_STATS_T.

Arg (data in): pfsf_file_id

ID of file of interest (numeric equivalent of filename)
Range: [0, 65535]

Arg (data in,out): pfsf_file_stats

Pointer to structure provided by caller into which the statistics should be placed. Cannot be NULL.

Return:

PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.7. pfs_fdelete_queue()
Definition:

PFS_RC_T pfs_fdelete_queue(
   PFS_FILE_ID_T   pfsf_file_id);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Queues a request to mark a file as deleted.

This function returns immediately and the file delete process continues in the background. Use pfs_fstat to determine when the file deletion has completed successfully.

Arg (data in): pfsf_file_id

ID of file to delete (numeric equivalent of filename)
Range: [0, 65535]

Return:

PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.8. pfs_encode_time()
Definition:

U32 pfs_encode_time(
   U16   pfsf_sec,
   U16   pfsf_min,
   U16   pfsf_hour,
   U16   pfsf_day,
   U16   pfsf_month,
   U16   pfsf_year);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Converts a calendar time and date into the compact form used in files.

See also documentation for PFS_FILE_STATS_T.

Arg (data in): pfsf_sec

Seconds value of time to encode
Range: [0, 59]

Arg (data in): pfsf_min

Minutes value of time to encode
Range: [0, 59]

Arg (data in): pfsf_hour

Hour value (in 24 hour system) of time to encode
Range: [0, 23]

Arg (data in): pfsf_day

Day of month of date to encode
Range: [1, 31]

Arg (data in): pfsf_month

Month of date to encode
Range: [1, 12]

Arg (data in): pfsf_year

Year value of date to encode
Range: [2010, 2099]

Return:

Encoded compact timestamp. Always succeeds, as all input values are forced to comply with their allowed range.

5.20.3.5.9. pfs_flush_all()
Definition:

void pfs_flush_all(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Enures all file write and delete operations are complete before returning.

Warning

This function suspends normal application execution until it returns. It is suitable only for calling as part of a managed power-down operation, or in applications with no hard real-time constraints.

5.20.3.5.10. pfs_lock_filesystem()
Definition:

void pfs_lock_filesystem(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Suspends filesystem operations including the copying of client data during file writes.

This can be used together with the coherent copy size parameter of pfs_fwrite_queue to ensure that the filesystem does not write a file containing an incoherent mixture of old and new data in one record, should the client need to update a record during a file write.

Warning

Do not use this function unnecessarily, because it will suspend the execution of all other application tasks until pfs_unlock_filesystem is called.

Note

This is also used internally by the filesystem feature to ensure integrity of the data structures during operations that modify the queue of write operations or the directory list of files.

5.20.3.5.11. pfs_unlock_filesystem()
Definition:

void pfs_unlock_filesystem(void);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Resumes filesystem operations including the copying of client data during file writes.

See pfs_lock_filesystem() for further details.

5.21. On-board external flash (PEF)

5.21.1. Overview

The library's on-board external (serial) flash feature manages the storage of data persistently across power cycles. It can be used by application code for the storage and retrieval of data. The flash memory can be bulk erased or sector erased when required by the application.

The PEF feature is not currently supported.

5.21.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pef.h
Functions
BOOLpef_get_lock

Get the access lock, but only if already free (unlocked).

voidpef_release_lock

Releases the access lock, regardless if already locked.

BOOLpef_is_available

Gets the flash device availability status.

voidpef_get_identification

Gets the flash device identification information.

PEF_RC_Tpef_read_status

Read the status register from the external serial flash device.

BOOLpef_busy

Determines if the device is busy, should be used primarily to confirm the completion of an erase or write operation.

PEF_RC_Tpef_read

Read data from the external serial flash device.

PEF_RC_Tpef_write

Write data to the external serial flash device.

PEF_RC_Tpef_erase_sector

Erase a sector of external serial flash memory.

PEF_RC_Tpef_erase_all

Erase all the external serial flash memory.

5.21.3. Interface detail

5.21.3.1.  Functions

5.21.3.1.1. pef_get_lock()
Definition:

BOOL pef_get_lock(void);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Get the access lock, but only if already free (unlocked).

If the lock is not available the caller MUST not access any pef functions, they should wait and try again later!

Return:

TRUE if lock was available, FALSE otherwise

5.21.3.1.2. pef_release_lock()
Definition:

void pef_release_lock(void);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Releases the access lock, regardless if already locked.

Therefore this should only be done if the caller has the lock!

5.21.3.1.3. pef_is_available()
Definition:

BOOL pef_is_available(void);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Gets the flash device availability status.

Return:

TRUE if the expected flash device is detected

5.21.3.1.4. pef_get_identification()
Definition:

void pef_get_identification(
   PEF_IDENTIFICATION_T  *peff_identification);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Gets the flash device identification information.

Arg (data out): peff_identification

Identification information read from the flash device, 0xFFs returned if not present

5.21.3.1.5. pef_read_status()
Definition:

PEF_RC_T pef_read_status(
   U8  *peff_status);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Read the status register from the external serial flash device.

Arg (data out): peff_status

Set to the status byte read from the device, use the PEF_STATUS_xxx macros to mask the required bits

Return:

PEF_RC_OK - if status read ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected

Note

The access lock should be obtained prior to calling this function and then released.

5.21.3.1.6. pef_busy()
Definition:

BOOL pef_busy(void);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Determines if the device is busy, should be used primarily to confirm the completion of an erase or write operation.

Return:

TRUE if the device is busy, ie a write or erase operation is in progress. FALSE otherwise, or no device is present!

Note

The access lock should be obtained prior to calling this function and then released.

5.21.3.1.7. pef_read()
Definition:

PEF_RC_T pef_read(
   U32   peff_addr,
   U16   peff_size,
   U8   *peff_data);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Read data from the external serial flash device.

Arg (data in): peff_addr

Address in the device for data to be read from Range: [0, 2097150]

Arg (data in): peff_size

Size of data to read, in bytes Range: [2, 2097152]

Arg (data in): peff_data

Pointer to data structure to populate

Return:

PEF_RC_OK - if data read ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress PEF_RC_ERR - peff_data is a NULL pointer PEF_RC_ERR_SIZE - if the size is not a multiple of 2 bytes PEF_RC_ERR_ALIGNMENT - if the address is not word aligned PEF_RC_ERR_ADDR_RANGE - if address is or would go out of range

Note

The access lock should be obtained prior to calling this function and then released.

Can only read in multiples of 2, therefore the size must be an even number and the address must be word aligned!

This function blocks the client until all the data has been read. This operation will potentially be slow for large data transfers.

5.21.3.1.8. pef_write()
Definition:

PEF_RC_T pef_write(
   U32        peff_addr,
   U16        peff_size,
   const U8  *peff_data);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Write data to the external serial flash device.

Arg (data in): peff_addr

Address in the device to write data to Range: [0, 2097150]

Arg (data in): peff_size

Size of data to write, in bytes Range: [2, 2097152]

Arg (data out): peff_data

Pointer to data to copy to flash memory

Return:

PEF_RC_OK - if data written ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress PEF_RC_ERR - peff_data is a NULL pointer, or a timeout occurred when writing PEF_RC_ERR_SIZE - if the size is not a multiple of 2 bytes PEF_RC_ERR_ALIGNMENT - if the address is not word aligned PEF_RC_ERR_ADDR_RANGE - if address is or would go out of range

Note

The access lock should be obtained prior to calling this function and then released.

Can only write in multiples of 2, therefore the size must be an even number and the address must be word aligned!

This function blocks the client until all the data has been written. This operation will potentially be slow for large data transfers.

5.21.3.1.9. pef_erase_sector()
Definition:

PEF_RC_T pef_erase_sector(
   U32   peff_addr);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Erase a sector of external serial flash memory.

Arg (data in): peff_addr

Address in the sector of the device to erase Range: [0, 2097151]

Return:

PEF_RC_OK - if sector erase request sent ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress PEF_RC_ERR_ADDR_RANGE - if address is out of range

Note

The access lock should be obtained prior to calling this function and then released.

The given address can be anywhere within the sector to be erased.

5.21.3.1.10. pef_erase_all()
Definition:

PEF_RC_T pef_erase_all(void);

Supported targets:

None at the moment

Required license:

None (Main library).

Description:

Erase all the external serial flash memory.

Return:

PEF_RC_OK - if bulk erase request sent ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress

Note

The access lock should be obtained prior to calling this function and then released.

5.22. General utilities feature (PUT)

5.22.1. Overview

5.22.1.1. CRC calculation

The library provides a function to efficiently calculate a CRC on a section of memory, put_calc_crc(). The implemented CRC matches the CCITT 16-bit polynomial: x16 + x12 + x5 + 1. Broken sections of memory can be check-summed by chaining together calls to put_calc_crc().

5.22.1.2. Table look-up and interpolation

The library provides two basic map look-up and interpolation functions. The 1-D version is accessed by calling put_cal_map_1d_f32(). The function works by interpreting the data its given as a simple 1-D map.

Figure 5.19. Map look-up

Map look-up

There is a direct correspondence between the X-axis data points and the Z-data points (for instance, between x1 and z1). The function searches through the X-axis data points to find a bounding pair for the look-up value, then calculates the output value by linearly interpolating between the corresponding Z-data bounding pair.

Figure 5.20. Map look-up with interpolation

Map look-up with interpolation

The 2-D version is accessed by calling put_cal_map_2d_f32(). It works in a similar fashion to the 1-D version, but performs bi-linear interpolation instead.

5.22.1.3. Range checking

The library provides a set of range checking functions: put_range_check_f32(), put_range_check_s8(), put_range_check_s16(), put_range_check_s32(), put_range_check_u8(), put_range_check_u16() and put_range_check_u32().

5.22.1.4. Signal debounce

The library provides two functions to debounce a logical signal: put_debounce_by_cycles() and put_debounce_by_time(). The debounce functions work by checking to see if the raw input signal is steady over a number of cycles (function calls) or over a duration of time. If the signal is steady, then the debounce function passes through the steady signal state. If the signal is unsteady, then the debounce functions passes through the last steady state.

The debounce functions might be used for removing glitches on external switches.

5.22.1.5. Slew rate checking

The library provides the put_slew_rate_check() function to detect a change in signal value over time, greater than might be expected.

The slew rate check function might be used for detecting a failed temperature sensor, where the rate of change of temperature is greater than possible.

5.22.1.6. Leaky bucket fault detection

The library provides two fault integration functions: put_leaky_bucket_u8() and put_leaky_bucket_f32(). The functions are modelled on the idea of a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly. When the bucket fills, the integration is complete and the fault is considered confirmed.

The leaky bucket fault detection function might be used to filter out sporadic transient fault conditions, in effect, ensuring that a fault has been present for long enough to be considered real.

5.22.2. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and put.h
Enumerations
 PUT_ERROR_CODE_T

Error values for debugging when an error is found when calling the utility API (PUT), the API calls a function with an enumeration from this type.

 PUT_LIST_OPTIONS_T

Enumeration for specifying the monotonicity of an ordered array when searching for a closest match.

Data types
 PUT_DEBOUNCE_CYCLE_T

This type provides storage for persistent information across calls to the debounce-by-cycles function.

 PUT_DEBOUNCE_TIME_T

This type provides storage for persistent information across calls to the debounce-by-time function.

 PUT_LEAKY_BUCKET_T

This type provides storage for persistent information across calls to the leaky bucket function.

 PUT_SLEW_RATE_CHECK_T

This type provides storage for persistent information across calls to the slew rate check function.

 PUT_ANALOGUE_WORKSPACE_T

Structure to hold values for the analogue input processing function that requires persistence.

 PUT_ENH_ANALOGUE_WORKSPACE_T

Structure to hold values for the analogue input processing function that requires persistence.

 PUT_ANALOGUE_CAL_DATA_T

Structure to hold all items that are calibratable when calling the analogue input processing function.

Functions
voidput_array_search_f32

Given an F32 value and an ordered array of F32 values, return the index of the array value closest to the requested value.

voidput_cal_map_1d_f32

1D table lookup and interpolation.

voidput_cal_map_2d_f32

2D table lookup and interpolation.

U16put_calc_crc

Calculate a 16-bit CRC value for a given memory block.

U8put_calc_crc_j1850

Calculate an 8-bit SAE-J1850 CRC value for a given memory block.

voidput_debounce_by_cycles_init

Initialisation routine for logical signal debounce (by cycles).

U8put_debounce_by_cycles

Logical signal debounce (by cycles).

voidput_debounce_by_time_init

Initialisation routine for logical signal debounce (by time).

voidput_debounce_by_time

Logical signal debounce (over time).

voidput_dutycycle_processing

Duty cycle scaling and inversion.

voidput_enh_process_analog_input_init

Enhanced Analogue input fault filter initialisation.

voidput_enh_process_analog_input

Enhanced Analogue input fault filter processing.

U16put_calc_ipv4_checksum

Calculate a 16-bit checksum value using the IPv4 header checksum algorithm.

voidput_leaky_bucket_f32

Fault filtering using a leaky bucket analogy.

voidput_leaky_bucket_f64

Fault filtering using a leaky bucket analogy.

voidput_leaky_bucket_init

Initialisation of leaky bucket fault filtering.

voidput_leaky_bucket_u8

Fault filtering using a leaky bucket analogy.

voidput_process_analog_input_init

Analogue input fault filter initialisation.

voidput_process_analog_input

Analogue input fault filter processing.

voidput_range_check_f32

Vector range check (min and max) function for F32 types.

voidput_range_check_s16

Vector range check (min and max) function for S16 types.

voidput_range_check_s32

Vector range check (min and max) function for S32 types.

voidput_range_check_s8

Vector range check (min and max) function for S8 types.

voidput_range_check_u16

Vector range check (min and max) function for U16 types.

voidput_range_check_u32

Vector range check (min and max) function for U32 types.

voidput_range_check_u8

Vector range check (min and max) function for U8 types.

voidput_slew_rate_check_init

Initialisation routine for slew rate checking.

BOOLput_slew_rate_check

Slew rate checking.

voidput_state_processing

State fault processing and inversion.

5.22.3. Interface detail

5.22.3.1.  Enumerations

5.22.3.1.1. PUT_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the utility API (PUT), the API calls a function with an enumeration from this type.

Enumerations:
PUT_CALMAP_INVALID_ARG

Error raised if the one of the table lookup and interpolation functions find an invalid argument.

PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG

Error raised if the debounce-by-cycles functions find an invalid argument.

PUT_LEAKY_BUCKET_INVALID_ARG

Error raised if one of the leaky bucket functions find an invalid argument.

PUT_SLEW_RATE_CHECK_INVALID_ARG

Error raised if one of the slew rate check functions find an invalid argument.

PUT_RANGE_CHECK_INVALID_ARG

Error raised if one of the range check functions find an invalid argument.

PUT_DEBOUNCE_BY_TIME_INVALID_ARG

Error raised if the debounce-by-time functions find an invalid argument.

PUT_DUTYCYCLE_PROCESSING_INVALID_ARG

Error raised if the duty cycle processing function finds an invalid argument.

PUT_STATE_PROCESSING_INVALID_ARG

Error raised if the state processing function finds an invalid argument.

PUT_ANALOG_INPUT_FILTER_INVALID_ARG

Error raised if the analogue input filter function finds an invalid argument.

PUT_ARRAY_SEARCH_INVALID_ARG

Error raised if the array search function finds an invalid argument.

5.22.3.1.2. PUT_LIST_OPTIONS_T
Summary:

Enumeration for specifying the monotonicity of an ordered array when searching for a closest match.

Enumerations:
PUT_LIST_ASCENDING

Search an array of values in ascending order.

PUT_LIST_DESCENDING

Search an array of values in descending order.

PUT_NUM_LIST_OPTIONS

5.22.3.2.  Data types

5.22.3.2.1. PUT_DEBOUNCE_CYCLE_T
Summary:

This type provides storage for persistent information across calls to the debounce-by-cycles function.

Members:
U8 PUT_DEBOUNCE_CYCLE_T::last_state

The state of the input last time the debounce function was invoked.


Range: 0 or 1

U8 PUT_DEBOUNCE_CYCLE_T::steady_state

The debounced steady state of the input.


Range: 0 or 1

U16 PUT_DEBOUNCE_CYCLE_T::cycle

The number of cycles the input has been steady for.


Range: [0, 65535] cycles

5.22.3.2.2. PUT_DEBOUNCE_TIME_T
Summary:

This type provides storage for persistent information across calls to the debounce-by-time function.

Members:
F32 PUT_DEBOUNCE_TIME_T::set_sum

Persistent accumulator used to set the debounced output state.

F32 PUT_DEBOUNCE_TIME_T::reset_sum

Persistent accumulator used to reset the debounced output state.

U8 PUT_DEBOUNCE_TIME_T::steady_state

Debounced output signal.


Range: 0 or 1

5.22.3.2.3. PUT_LEAKY_BUCKET_T
Summary:

This type provides storage for persistent information across calls to the leaky bucket function.

Members:
F32 PUT_LEAKY_BUCKET_T::bucket_level

This is the level of the bucket for a given fault last time the leaky bucket function was called for that fault.

BOOL PUT_LEAKY_BUCKET_T::last_cff

True if the fault was confirmed last time the leaky bucket function was called for that fault.

5.22.3.2.4. PUT_SLEW_RATE_CHECK_T
Summary:

This type provides storage for persistent information across calls to the slew rate check function.

Members:
F32 PUT_SLEW_RATE_CHECK_T::last_input

This is the value of the input last time the slew check function was invoked.

U8 PUT_SLEW_RATE_CHECK_T::first_call

True if the slew check function has not been called previously, false otherwise.

5.22.3.2.5. PUT_ANALOGUE_WORKSPACE_T
Summary:

Structure to hold values for the analogue input processing function that requires persistence.

Members:
F32 PUT_ANALOGUE_WORKSPACE_T::last_raw_value

Last raw value read in by the analogue channel.

This is used to establish if there is a slew rate fault on the input. It is initialised to 0.0.

F32 PUT_ANALOGUE_WORKSPACE_T::latched_engineering_value

Latched engineering value for transient faults.

This is the last good engineering value output by the analogue input before a transient fault is detected. This value is output until the transient fault is no longer present. It is initialised to 0.0.

U8 PUT_ANALOGUE_WORKSPACE_T::confirmed_fault_present

Flag to indicate if a confirmed fault has been detected.

This flag indicates if one or more transient faults have persisted long enough to be registered as a confirmed fault in the analogue input. A value of zero indicates that no fault is present whilst a value of one indicates that a fault has been detected.
Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_max_raw_range_tff

Flag to indicate the latched value of a transient fault flag for the raw value being greater than allowed.

If a confirmed fault is detected, this flag indicates if the raw input value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero.
Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_min_raw_range_tff

Flag to indicate the latched value of a transient fault flag for the raw value being less than allowed.

If a confirmed fault is detected, this flag indicates if the raw input value was currently less than the minimum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero.
Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_slew_rate_tff

Flag to indicate the latched value of a transient fault flag for the slew rate being greater than allowed.

If a confirmed fault is detected, this flag indicates if the slew rate of the raw input value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero.
Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_max_eng_range_tff

Flag to indicate the latched value of a transient fault flag for the engineering value being greater than allowed.

If a confirmed fault is detected, this flag indicates if the engineering value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero.
Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_min_eng_range_tff

Flag to indicate the latched value of a transient fault flag for the engineering value being less than allowed.

If a confirmed fault is detected, this flag indicates if the engineering value was currently less than the minimum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero.
Range: [0, 1] unitless flag

PUT_SLEW_RATE_CHECK_T PUT_ANALOGUE_WORKSPACE_T::slew_rate_data

Structure to handle slew rate input check.

This structure contains the variable data required by the slew rate check.

PUT_LEAKY_BUCKET_T PUT_ANALOGUE_WORKSPACE_T::leaky_bucket_data

Structure to handle leaky bucket fault filtering.

This structure contains the variable data required by the leaky bucket filtering.

5.22.3.2.6. PUT_ENH_ANALOGUE_WORKSPACE_T
Summary:

Structure to hold values for the analogue input processing function that requires persistence.

Members:
F32 PUT_ENH_ANALOGUE_WORKSPACE_T::last_raw_value

Last raw value read in by the analogue channel.

This is used to establish if there is a slew rate fault on the input. It is initialised to 0.0.

F32 PUT_ENH_ANALOGUE_WORKSPACE_T::latched_engineering_value

Latched engineering value for transient faults.

This is the last good engineering value output by the analogue input before a transient fault is detected. This value is output until the transient fault is no longer present. It is initialised to 0.0.

F32 PUT_ENH_ANALOGUE_WORKSPACE_T::leaky_bucket_levels[PUT_EPAI_NUM_LEAKY_BUCKETS]

Arrays to handle leaky bucket fault filtering.

Note, memory is at a premium so we havent created an array of PUT_LEAKY_BUCKET_T here as there is excessive packing.

PUT_SLEW_RATE_CHECK_T PUT_ENH_ANALOGUE_WORKSPACE_T::slew_rate_data

Structure to handle slew rate input check.

This structure contains the variable data required by the slew rate check.

5.22.3.2.7. PUT_ANALOGUE_CAL_DATA_T
Summary:

Structure to hold all items that are calibratable when calling the analogue input processing function.

Members:
volatile const F32* PUT_ANALOGUE_CAL_DATA_T::min_raw_value

Minimum allowable raw value for the channel.

Pointer to the minimum allowable value of the raw measurement.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_raw_value

Maximum allowable raw value for the channel.

Pointer to the maximum allowable value of the raw measurement.

volatile const S32* PUT_ANALOGUE_CAL_DATA_T::num_eng_lookup_elements

Number of elements in the engineering map table.

Pointer to the number of elements in the lookup map that converts the raw measurement into an engineering value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::eng_lookup_x_axis

Engineering lookup table X Axis array.

Pointer to the array that holds the x axis lookup values for converting the raw measurement into an engineering value. These correspond to a monotonically increasing or decreasing array of raw input values.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::eng_lookup_z_axis

Engineering lookup table Z Axis array.

Pointer to the array that holds the z axis lookup values for converting the raw measurement into an engineering value. These correspond to a monotonically increasing or decreasing array of engineering output values.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::min_eng_value

Minimum allowable engineering value for the channel.

Pointer to the minimum allowable value of the engineering value that has been derived from the raw value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_eng_value

Maximum allowable engineering value for the channel.

Pointer to the maximum allowable value of the engineering value that has been derived from the raw value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_rise_rate

Leaky bucket rise rate for the channel.

Pointer to the rise rate for the leaky bucket used for fault filtering. This amount, multiplied by the sample rate for the channel, is added to the leaky bucket contents each time a transient fault is present. The bucket is clipped to a maximum value of 1.0.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_fall_rate

Leaky bucket fall rate for the channel.

Pointer to the fall rate for the leaky bucket used for fault filtering. This amount, multiplied by the sample rate for the channel, is subtracted from the leaky bucket contents at each iteration of the function. The bucket is clipped to a minimum value of 0.0.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_fault_clear_level

Leaky bucket value at which a confirmed fault is cleared.

Pointer to the clear fault level for the leaky bucket fault filter. Once a confirmed fault has been detected on the channel, the content of the leaky bucket must fall to less than this value in order to clear the fault.
Range: [0.0, 1.0] unitless

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::default_output_value

The value output by the channel if a confirmed fault is present.

Pointer to the engineering value that is output by the filter logic as long as a confirmed fault is present. This can be outside the range of the minimum and maximum engineering values used to determine if a transient fault is present.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_slew_rate

The maximum slew rate allowed for the raw value.

Pointer to the maximum allowed slew rate of the raw value.

5.22.3.3.  Functions

5.22.3.3.1. put_array_search_f32()
Definition:

void put_array_search_f32(
   const F32           *putf_array,
   const S32            putf_array_size,
   const F32            putf_input_value,
   S32                 *putf_index_return,
   PUT_LIST_OPTIONS_T   putf_search_order);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Given an F32 value and an ordered array of F32 values, return the index of the array value closest to the requested value.

Can raise the following errors:
PUT_ARRAY_SEARCH_INVALID_ARG.

Arg (data in): putf_array

Pointer to array of 32-bit floating point variables.
Cannot be NULL.

Arg (data in): putf_array_size

Number of elements in the putf_array array.
Range: [1, 2147483647] elements

Arg (data in): putf_input_value

The value for which the closest match is to be identified.
Cannot be NULL.

Arg (data out): putf_index_return

Pointer through which the index of the closest match is returned.
Cannot be NULL.

Arg (data in): putf_search_order

Indicates whether the array is a list of values that are increasing with index number or decreasing with index number. PUT_LIST_ASCENDING - values increase with index number PUT_LIST_DESCENDING - values decrease with index number

5.22.3.3.2. put_cal_map_1d_f32()
Definition:

void put_cal_map_1d_f32(
   F32                         putf_x,
   S32                         putf_n,
   volatile const F32 *const   putf_px,
   volatile const F32 *const   putf_pz,
   F32                        *putf_pzz);

Supported targets:

All targets

Required license:

None (Main library).

Description:

1D table lookup and interpolation.

Linearly interpolates between map elements when input is within the map's range. Clips to the x-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors:
PUT_CALMAP_INVALID_ARG.

Note

The 1d lookup is of function z(x). The use of z as the function name, rather than y, is chosen to be consistent with the 2d lookup function.

See put_calmap_2d_f32() for 2d table lookup.

See pnv_adapmap_1d_f32() and pnv_adapmap_2d_f32() for table lookups with adaption.

Arg (data in): putf_x

The argument to z(x), a point on the x-axis for interpolation.

Arg (data in): putf_n

The number of elements in the x-axis and z-data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1, the output it set to the only z-data value. If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_px

Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): putf_pz

Pointer to array of the map's z-data.
Cannot be NULL.

Arg (data out): putf_pzz

Pointer to interpolated output.
Cannot be NULL.

5.22.3.3.3. put_cal_map_2d_f32()
Definition:

void put_cal_map_2d_f32(
   F32                  putf_x,
   F32                  putf_y,
   S32                  putf_nx,
   S32                  putf_ny,
   volatile const F32  *putf_px,
   volatile const F32  *putf_py,
   volatile const F32  *putf_pz,
   F32                 *putf_pzz);

Supported targets:

All targets

Required license:

None (Main library).

Description:

2D table lookup and interpolation.

Bilinearly interpolates between map elements when input is within the map's range. Clips to the x-axis and y-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors:
PUT_CALMAP_INVALID_ARG.

Note

See put_calmap_1d_f32() for 1d table lookup.

See pnv_adapmap_1d_f32() and pnv_adapmap_2d_f32() for table lookups with adaption.

Arg (data in): putf_x

The argument to z(x,y), a point on the x-axis for interpolation.

Arg (data in): putf_y

The argument to z(x,y), a point on the y-axis for interpolation.

Arg (data in): putf_nx

The number of elements in the x-axis and z(x,) data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1 (i.e., a 1d lookup if putf_ny is greater than one), the output it set to the first z-data value (call put_calmap_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_ny

The number of elements in the y-axis and z(,y) data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1 (i.e., a 1d lookup if putf_nx is greater than one), the output it set to the first z-data value (call put_calmap_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the y-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_px

Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): putf_py

Pointer to array of the map's y-axis. The values stored in the y-axis array must be monotonically increasing or decreasing.
Cannot be NULL.

Arg (data in): putf_pz

Pointer to array of the map's z-data. The array lookup is performed as { putf_pz[(x-index * putf_ny) + y-index] } and the data definition must correspond.
Cannot be NULL.

Arg (data out): putf_pzz

Pointer to interpolated output.
Cannot be NULL.

5.22.3.3.4. put_calc_crc()
Definition:

U16 put_calc_crc(
   U16        putf_shift_reg,
   const U8  *putf_addr,
   U32        putf_len);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Calculate a 16-bit CRC value for a given memory block.

The CRC polynomial is taken from the CCITT standard (x^16 + x^12 + x^5 + x^0), assumes that the initial value for the CRC register is 0xFFFF and that the bit-stream is reflected.

Note

Can be used to calculate a single CRC for multiple memory blocks - first call to put_calc_crc() should set the shift register to 0xFFFFu; subsequent calls should set the shift register to the return value of the previous call.

Arg (data in): putf_shift_reg

The initial value of the CRC.
Range: [0, 65535] unitless

Arg (data in): putf_addr

Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len

Length of memory block in bytes.
Range: [0, 4294967295] bytes

Return:

The calculated CRC.
Range: [0, 65535] unitless

5.22.3.3.5. put_calc_crc_j1850()
Definition:

U8 put_calc_crc_j1850(
   U8         putf_shift_reg,
   BOOL       putf_start,
   BOOL       putf_finish,
   const U8  *putf_addr,
   U32        putf_len);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Calculate an 8-bit SAE-J1850 CRC value for a given memory block.

The CRC polynomial is taken from the J1850 standard (x^8 + x^4 + x^3 + x^2 + x^0), with an intial value of 0xFF and a final one's complement.

Note

This can be used to calculate a single CRC for multiple memory blocks. To do this, in the first call to put_calc_crc_j1850() set putf_start=TRUE and putf_finish=FALSE; in intermediate calls, set both FALSE, passing the previous return value in through putf_shift_reg; and in the final call set setputf_start=FALSE and putf_finish=TRUE.

Arg (data in): putf_shift_reg

The initial value of the CRC. Ignored if putf_start=TRUE.
Range: [0, 255] unitless

Arg (data in): putf_start

Whether to intialise the CRC to the standard value before starting, in which case the input value putf_shift_reg is ignored. Usually TRUE, but use FALSE if the function is being called again to continue an existing checksum over a further region of memory.

Arg (data in): putf_finish

Whether to apply the final J1850-required one's complement operation to the computed CRC. Usually TRUE, but use FALSE if the function is to be called again to checksum an additional region of memory to include in the same overall calculation.

Arg (data in): putf_addr

Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len

Length of memory block in bytes.
Range: [0, 4294967295] bytes

Return:

The calculated CRC.
Range: [0, 255] unitless

5.22.3.3.6. put_debounce_by_cycles_init()
Definition:

void put_debounce_by_cycles_init(
   PUT_DEBOUNCE_CYCLE_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Initialisation routine for logical signal debounce (by cycles).

Initialise the debounce state information that persists between calls to put_debounce_by_cycles().

Can raise the following errors:
PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG.

Arg (data in,out): putf_store

A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_debounce_by_cycles_init().
Cannot be NULL.

5.22.3.3.7. put_debounce_by_cycles()
Definition:

U8 put_debounce_by_cycles(
   U8                            putf_input,
   U16                           putf_cycle_threshold,
   PUT_DEBOUNCE_CYCLE_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Logical signal debounce (by cycles).

Debounce the state of a logical input signal over a number of cycles (calls to this function). When the logical input signal is unchanged for the cycle threshold the signal is deemed steady and the debounced output state changes to the steady logical input state.

On the first call, the debounced output state is set to the logical input state.

Can raise the following errors:
PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG.

Arg (data in): putf_input

The current state.
Range: [0, 1] unitless

Arg (data in): putf_cycle_threshold

The number of cycles of unchanging input required before the input state (putf_input) is deemed steady. Set to zero or one for no debounce.
Range: [0, 65535] cycles

Arg (data in,out): putf_store

A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_debounce_by_cycles_init().
Cannot be NULL.

Return:

The debounced state.
Range: [0, 1] unitless

5.22.3.3.8. put_debounce_by_time_init()
Definition:

void put_debounce_by_time_init(
   PUT_DEBOUNCE_TIME_T  *putf_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Initialisation routine for logical signal debounce (by time).

This function initialises any persistent data for a logical signal prior to it first being called.

Can raise the following errors:
PUT_DEBOUNCE_BY_TIME_INVALID_ARG.

Arg (data out): putf_channel_wrk_data

Pointer to logical input signal workspace data structure. This provides persistence for data in between calls to the filter function.

5.22.3.3.9. put_debounce_by_time()
Definition:

void put_debounce_by_time(
   U8                    putf_raw_state,
   F32                   putf_sample_rate,
   U8                    putf_invert,
   F32                   putf_set_dead_time,
   F32                   putf_reset_dead_time,
   U8                   *putf_debounced_state,
   PUT_DEBOUNCE_TIME_T  *putf_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Logical signal debounce (over time).

Debounce the state of a logical input signal over time. When the logical input signal is unchanged for the time threshold the signal is deemed steady and the debounced output state changes to the steady logical input state.

The time for becoming steady set (value 1) and for becoming steady reset (value 0) are parameters to the function.

On the first call, the debounced output state is set to the logical input state.

Can raise the following errors:
PUT_DEBOUNCE_BY_TIME_INVALID_ARG.

Arg (data in): putf_raw_state

The value of the logical input signal (e.g., as obtained from a call to the pdx_digital_input() function).
Range: 0 or 1.

Arg (data in): putf_sample_rate

The rate at which this function is called for debounce computation (effectively the amount of time since the last call). Ideally this function should be called at the same rate as the input state sampling but the function can be called less frequently if necessary. As an example, if an input state must be checked 5 times within a debounce period of 1 second (for both set and reset steady states) then the function could be called every 200 milliseconds.
Range: [0.001, 3600] seconds

Arg (data in): putf_invert

Channel inversion. If inversion is set, then a logical NOT operation is applied to the input value before further processing.

Arg (data in): putf_set_dead_time

Set dead time. The time in seconds the input will have to be high, before the function switches its output from 0 to 1. A zero or negative value causes the debounced state to be set to the input state without delay.

Arg (data in): putf_reset_dead_time

Reset dead time. The time in seconds the input will have to be low, before the function switches its output from 1 to 0. A zero or negative value causes the debounced state to be set to the input state without delay.

Arg (data out): putf_debounced_state

Pointer to the value that will represent the output of the logical input debounced state.
Cannot be NULL.

Arg (data in,out): putf_channel_wrk_data

Pointer to logical signal channel workspace data structure. This provides persistence for data in between calls to the filter function.
Cannot be NULL.

5.22.3.3.10. put_dutycycle_processing()
Definition:

void put_dutycycle_processing(
   F32   putf_inp_duty_cycle,
   U8    putf_invert,
   U8    putf_fault,
   F32   putf_default,
   F32   putf_min,
   F32   putf_max,
   F32  *putf_out_duty_cycle);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Duty cycle scaling and inversion.

This function provides a scaling of the input duty cycle as follows: scaled_duty_cycle = (input_duty_cycle * (max - min)) + min

If inversion is set the scaled duty cycle is converted as follows: scaled_duty_cycle = 1.0 - scaled_duty_cycle

If fault is set the output duty cycle is set to the default value.

Can raise the following errors:
PUT_DUTYCYCLE_PROCESSING_INVALID_ARG.

Arg (data in): putf_inp_duty_cycle

The input duty cycle value.
Range: [0, 1] unitless

Arg (data in): putf_invert

If inversion is set the scaled duty cycle is converted as follows:
scaled_duty_cycle = 1.0 - scaled_duty_cycle
Range: [0, 1] unitless flag

Arg (data in): putf_fault

If true it forces the output value to be equal to putf_default, no effect otherwise.
Range: [0, 1] unitless flag

Arg (data in): putf_default

Used to set the output value when putf_fault is true, no effect otherwise.
Range: [0, 1] unitless

Arg (data in): putf_min

Lower threshold value in scaling the input duty cycle.
Range: [0, 1] unitless

Arg (data in): putf_max

Upper threshold value in scaling the input duty cycle.
Range: [0, 1] unitless

Arg (data out): putf_out_duty_cycle

Pointer to the value that will represent the output duty cycle.
Cannot be NULL.
Range: [0, 1] unitless

5.22.3.3.11. put_enh_process_analog_input_init()
Definition:

void put_enh_process_analog_input_init(
   PUT_ENH_ANALOGUE_WORKSPACE_T *const   putf_adc_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Enhanced Analogue input fault filter initialisation.

This function initialises any persistent data for an analogue channel prior to it first being called.

Can raise the following errors:
PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_adc_channel_wrk_data

Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function.
Cannot be NULL.

5.22.3.3.12. put_enh_process_analog_input()
Definition:

void put_enh_process_analog_input(
   F32                                    putf_raw_adc_value,
   F32                                    putf_adc_sample_rate,
   F32 *const                             putf_analogue_value,
   U8 *const                              putf_confirmed_min_raw_range_fault,
   U8 *const                              putf_confirmed_max_raw_range_fault,
   U8 *const                              putf_confirmed_slew_rate_fault,
   U8 *const                              putf_confirmed_min_eng_range_fault,
   U8 *const                              putf_confirmed_max_eng_range_fault,
   U8 *const                              putf_transient_fault_flag,
   const PUT_ANALOGUE_CAL_DATA_T *const   putf_adc_channel_cal_data,
   PUT_ENH_ANALOGUE_WORKSPACE_T *const    putf_adc_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Enhanced Analogue input fault filter processing.

This function is an enhanced version of put_process_analog_input(). Like that function, it is provided with a raw A/D value, details about the fault filtering that should be applied to it and pointers to an output value and a series of fault flags. The raw value is converted into an engineering value for output. This function differs in its processing of transient faults. The put_process_analog_input() function has the concept of a confirmed fault status, which is based on the status of all transient fault. This function monitors each transient fault individually and can provide more accurate information as to which faults are currently confirmed or not. Both the transient and any confirmed fault flags are made available to the calling function.

Can raise the following errors:
PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_raw_adc_value

The raw A/D value as obtained from a call to the basic analogue input code.
Range: [-4096, 4096] A/D counts

Arg (data in): putf_adc_sample_rate

The rate at which this function is called for fault filtering on the given A/D channel raw values.
Range: [0.001, 3600] seconds

Arg (data out): putf_analogue_value

Pointer to the value that will represent the output of the A/D conversion to an engineering value once the fault filtering has taken place.
Cannot be NULL.

Arg (data out): putf_confirmed_min_raw_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being below the minimum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_max_raw_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being above the maximum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_slew_rate_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value changing faster than the maximum allowed slew rate value.
Cannot be NULL.

Arg (data out): putf_confirmed_min_eng_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being below the minimum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_max_eng_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being above the maximum allowed value.
Cannot be NULL.

Arg (data out): putf_transient_fault_flag

Pointer to the flag that will indicate if a transient fault has been detected. This will cause the output analogue value to be latched at the last valid engineering value or zero if the fault is present on the first iteration.
Cannot be NULL.

Arg (data in): putf_adc_channel_cal_data

Pointer to A/D channel calibration data structure.
Cannot be NULL.

Arg (data in): putf_adc_channel_wrk_data

Pointer to enhanced A/D channel workspace data structure. This provides persistence for data in between calls to the filter function.
Cannot be NULL.

5.22.3.3.13. put_calc_ipv4_checksum()
Definition:

U16 put_calc_ipv4_checksum(
   U16        putf_sum_reg,
   BOOL       putf_start,
   BOOL       putf_finish,
   const U8  *putf_addr,
   U32        putf_len);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Calculate a 16-bit checksum value using the IPv4 header checksum algorithm.

The IPv4 checksum is fast to compute, as it is based on simple 16-bit addition. However, it wraps overflowing bits back into the low-order bits of the sum, making it much stronger against undetected errors in the high bit than a simple sum.

Note

This can be used to calculate a single checksum for multiple memory blocks. To do this, in the first call set putf_start=TRUE and putf_finish=FALSE; in intermediate calls, set both FALSE, passing the previous return value in through putf_sum_reg; and in the final call set putf_start=FALSE and putf_finish=TRUE.

Arg (data in): putf_sum_reg

The initial value of the checksum. Ignored if putf_start=TRUE.
Range: [0, 65535] unitless

Arg (data in): putf_start

Whether to initialise the checksum to the standard value before starting, in which case the input value putf_sum_reg is ignored. Usually TRUE, but use FALSE if the function is being called again to continue an existing checksum over a further region of memory.

Arg (data in): putf_finish

Whether to apply the final one's complement operation to the computed checksum. Usually TRUE, but use FALSE if the function is to be called again to checksum an additional region of memory to include in the same overall calculation.

Arg (data in): putf_addr

Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len

Length of memory block in bytes.
Range: [0, 4294967295] bytes

Return:

The calculated checksum.
Range: [0, 65535] unitless

5.22.3.3.14. put_leaky_bucket_f32()
Definition:

void put_leaky_bucket_f32(
   F32                         putf_fall_rate,
   F32                         putf_rise_rate,
   F32                         putf_hyst,
   F32                         putf_delta_time,
   U32                         putf_n,
   volatile const F32 *const   putf_tff,
   F32 *const                  putf_cff,
   PUT_LEAKY_BUCKET_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state Value
level 0
confirmed-fault-condition false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Transient fault condition Change in level
true level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)
false level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level Confirmed fault condition
>= 1 true
< hysteresis false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate

The leak rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_rise_rate

The fill rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_hyst

The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent.
Range: [-1, 1] unitless

Arg (data in): putf_delta_time

The difference in time since the last call to this function for all faults in this call.
Units: seconds

Arg (data in): putf_n

Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff

Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Arg (data out): putf_cff

Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store

A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_u8()

5.22.3.3.15. put_leaky_bucket_f64()
Definition:

void put_leaky_bucket_f64(
   F32                  putf_fall_rate,
   F32                  putf_rise_rate,
   F32                  putf_hyst,
   F32                  putf_delta_time,
   U32                  putf_n,
   volatile const F64  *putf_tff,
   F64                 *putf_cff,
   PUT_LEAKY_BUCKET_T  *putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state Value
level 0
confirmed-fault-condition false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Transient fault condition Change in level
true level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)
false level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level Confirmed fault condition
>= 1 true
< hysteresis false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate

The leak rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_rise_rate

The fill rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_hyst

The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent.
Range: [-1, 1] unitless

Arg (data in): putf_delta_time

The difference in time since the last call to this function for all faults in this call.
Units: seconds

Arg (data in): putf_n

Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff

Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Arg (data out): putf_cff

Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store

A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_u8(), put_leaky_bucket_f32()

5.22.3.3.16. put_leaky_bucket_init()
Definition:

void put_leaky_bucket_init(
   U32                         putf_n,
   PUT_LEAKY_BUCKET_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Initialisation of leaky bucket fault filtering.

Initialise the leaky bucket to empty.

Arg (data in): putf_n

Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data out): putf_store

A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. This function initialises the stores.

5.22.3.3.17. put_leaky_bucket_u8()
Definition:

void put_leaky_bucket_u8(
   F32                  putf_fall_rate,
   F32                  putf_rise_rate,
   F32                  putf_hyst,
   F32                  putf_delta_time,
   U32                  putf_n,
   volatile const U8   *putf_tff,
   U8                  *putf_cff,
   PUT_LEAKY_BUCKET_T  *putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state Value
level 0
confirmed-fault-condition false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Transient fault condition Change in level
true level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)
false level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level Confirmed fault condition
>= 1 true
< hysteresis false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate

The leak rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_rise_rate

The fill rate of the buckets applied to all faults in this call.
Range: [0, 1000] units per second

Arg (data in): putf_hyst

The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent.
Range: [-1, 1] unitless

Arg (data in): putf_delta_time

The difference in time since the last call to this function for all faults in this call.
Units: seconds

Arg (data in): putf_n

Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff

Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Arg (data out): putf_cff

Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store

A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_f32()

5.22.3.3.18. put_process_analog_input_init()
Definition:

void put_process_analog_input_init(
   PUT_ANALOGUE_WORKSPACE_T *const   putf_adc_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Analogue input fault filter initialisation.

This function initialises any persistent data for an analogue channel prior to it first being called.

Can raise the following errors:
PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_adc_channel_wrk_data

Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function.
Cannot be NULL.

5.22.3.3.19. put_process_analog_input()
Definition:

void put_process_analog_input(
   F32                                    putf_raw_adc_value,
   F32                                    putf_adc_sample_rate,
   F32 *const                             putf_analogue_value,
   U8 *const                              putf_confirmed_min_raw_range_fault,
   U8 *const                              putf_confirmed_max_raw_range_fault,
   U8 *const                              putf_confirmed_slew_rate_fault,
   U8 *const                              putf_confirmed_min_eng_range_fault,
   U8 *const                              putf_confirmed_max_eng_range_fault,
   U8 *const                              putf_transient_fault_flag,
   const PUT_ANALOGUE_CAL_DATA_T *const   putf_adc_channel_cal_data,
   PUT_ANALOGUE_WORKSPACE_T *const        putf_adc_channel_wrk_data);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Analogue input fault filter processing.

This function is provided with a raw A/D value, details about the fault filtering that should be applied to it and pointers to an output value and a series of fault flags. The raw value is converted into an engineering value for output. If transient faults persist for long enough, a confirmed fault is generated. Both the transient and any confirmed fault flags are made available to the calling function.

Can raise the following errors:
PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_raw_adc_value

The raw A/D value as obtained from a call to the basic analogue input code.
Range: [-4096, 4096] A/D counts, [-5, 5] volts

Arg (data in): putf_adc_sample_rate

The rate at which this function is called for fault filtering on the given A/D channel raw values.
Range: [0.001, 3600] seconds

Arg (data out): putf_analogue_value

Pointer to the value that will represent the output of the A/D conversion to an engineering value once the fault filtering has taken place.
Cannot be NULL.

Arg (data out): putf_confirmed_min_raw_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being below the minimum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_max_raw_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being above the maximum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_slew_rate_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value changing faster than the maximum allowed slew rate value.
Cannot be NULL.

Arg (data out): putf_confirmed_min_eng_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being below the minimum allowed value.
Cannot be NULL.

Arg (data out): putf_confirmed_max_eng_range_fault

Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being above the maximum allowed value.
Cannot be NULL.

Arg (data out): putf_transient_fault_flag

Pointer to the flag that will indicate if a transient fault has been detected. This will cause the output analogue value to be latched at the last valid engineering value or zero if the fault is present on the first iteration.
Cannot be NULL.

Arg (data in): putf_adc_channel_cal_data

Pointer to A/D channel calibration data structure.
Cannot be NULL.

Arg (data in): putf_adc_channel_wrk_data

Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function.
Cannot be NULL.

5.22.3.3.20. put_range_check_f32()
Definition:

void put_range_check_f32(
   U32                  putf_n,
   volatile const F32  *putf_value,
   volatile const F32  *putf_max,
   volatile const F32  *putf_min,
   void                *putf_gt,
   void                *putf_lt,
   U8                   putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for F32 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.21. put_range_check_s16()
Definition:

void put_range_check_s16(
   U32                  putf_n,
   volatile const S16  *putf_value,
   volatile const S16  *putf_max,
   volatile const S16  *putf_min,
   void                *putf_gt,
   void                *putf_lt,
   U8                   putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for S16 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.22. put_range_check_s32()
Definition:

void put_range_check_s32(
   U32                  putf_n,
   volatile const S32  *putf_value,
   volatile const S32  *putf_max,
   volatile const S32  *putf_min,
   void                *putf_gt,
   void                *putf_lt,
   U8                   putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for S32 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.23. put_range_check_s8()
Definition:

void put_range_check_s8(
   U32                 putf_n,
   volatile const S8  *putf_value,
   volatile const S8  *putf_max,
   volatile const S8  *putf_min,
   void               *putf_gt,
   void               *putf_lt,
   U8                  putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for S8 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.24. put_range_check_u16()
Definition:

void put_range_check_u16(
   U32                  putf_n,
   volatile const U16  *putf_value,
   volatile const U16  *putf_max,
   volatile const U16  *putf_min,
   void                *putf_gt,
   void                *putf_lt,
   U8                   putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for U16 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.25. put_range_check_u32()
Definition:

void put_range_check_u32(
   U32                  putf_n,
   volatile const U32  *putf_value,
   volatile const U32  *putf_max,
   volatile const U32  *putf_min,
   void                *putf_gt,
   void                *putf_lt,
   U8                   putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for U32 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.26. put_range_check_u8()
Definition:

void put_range_check_u8(
   U32                 putf_n,
   volatile const U8  *putf_value,
   volatile const U8  *putf_max,
   volatile const U8  *putf_min,
   void               *putf_gt,
   void               *putf_lt,
   U8                  putf_use_bool_type);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Vector range check (min and max) function for U8 types.

For each element in the vectors, i, the function sets the output vectors as:
putf_gt[i] = putf_value[i] > putf_max[i]
putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors:
PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n

Number of elements in vectors putf_value, putf_max, putf_min, putf_gt and putf_lt.
Range: [1, 4294967295] elements

Arg (data in): putf_value

Pointer to array of values.
Cannot be NULL.

Arg (data in): putf_max

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_min

Pointer to array of values. Each value is compared against the corresponding element in putf_value.
Cannot be NULL.

Arg (data in): putf_gt

Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_lt

Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min[i]. The type of each flag is determined by putf_use_bool_type.
Cannot be NULL.

Arg (data in): putf_use_bool_type

True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.27. put_slew_rate_check_init()
Definition:

void put_slew_rate_check_init(
   PUT_SLEW_RATE_CHECK_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Initialisation routine for slew rate checking.

Initialise the slew rate check information that persists between calls to put_slew_rate_check().

Can raise the following errors:
PUT_SLEW_RATE_CHECK_INVALID_ARG.

Arg (data in,out): putf_store

A pointer to a store of information relating to the input signal. Not to be accessed by the application.
Cannot be NULL.

5.22.3.3.28. put_slew_rate_check()
Definition:

BOOL put_slew_rate_check(
   F32                            putf_input,
   F32                            putf_slew_rate_limit,
   F32                            putf_delta_time,
   PUT_SLEW_RATE_CHECK_T *const   putf_store);

Supported targets:

All targets

Required license:

None (Main library).

Description:

Slew rate checking.

Return whether the rate of change of the input variable (putf_input) exceeds the slew rate limit or not. On the first call to this function, there is not enough information to determine if the rate of change has exceeded the limit or not, and the function returns false.

Can raise the following errors:
PUT_SLEW_RATE_CHECK_INVALID_ARG.

Arg (data in): putf_input

The current value of the input.
Units: none

Arg (data in): putf_slew_rate_limit

The rate of change limit. Negative values are clipped to zero.
Units: /second

Arg (data in): putf_delta_time

The difference in time since the last call to this function. On the first call to this function, this parameter is ignored.
Units: seconds

Arg (data in,out): putf_store

A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_slew_rate_check_init().
Cannot be NULL.

Return:

True if the input rate of change exceeds the limit, false otherwise.

5.22.3.3.29. put_state_processing()
Definition:

void put_state_processing(
   U8   putf_inp_state,
   U8   putf_invert,
   U8   putf_fault,
   U8   putf_default,
   U8  *putf_out_state);

Supported targets:

All targets

Required license:

None (Main library).

Description:

State fault processing and inversion.

If putf_fault is true, the output the putf_default value. Otherwise, output the putf_state value (with inversion if putf_invert is true).

Can raise the following errors:
PUT_STATE_PROCESSING_INVALID_ARG.

Arg (data in): putf_inp_state

The input state.
Range: 0 or 1, unitless

Arg (data in): putf_invert

If inversion is set the input state is converted as follows:
output_state = 1 - input_state
Range: 0 or 1, unitless

Arg (data in): putf_fault

If true the function forces the output value to be equal to putf_default, no effect otherwise.
Range: 0 or 1, unitless

Arg (data in): putf_default

Used to set the output value when putf_fault is true, no effect otherwise.
Range: [0, 1] unitless

Arg (data out): putf_out_state

Pointer to the value that will represent the output state.
Cannot be NULL.
Range: [0, 1] unitless

Chapter 6.  Library interface — Engine

This section describes the engine, or angular functionality of the OpenECU platform library, covering:

6.1. Engine position sensor processing

Many of the engine and angular functions of the ECU occur at specific angles relative to a specific position of the engine. In order for the ECU to determine the engine position, the ECU processes signals from one crankshaft position sensor and one or more optional camshaft position sensors.

6.1.1. Crankshaft position sensor processing

A crank sensor is an electronic device used to monitor the position the crankshaft. Typically, the crankshaft has an attached trigger wheel with teeth protruding around the circumference. The crank sensor detects these teeth and produces a varying electrical signal that matches the teeth. The digital state of the crank signal can be measured by calling the pan_get_crank_pin_state() function. The signal is processed by the ECU to determine the position of the crankshaft.

6.1.1.1. Variable reluctance signal

The ECU processes a differential VR signal to decode a crank position:

Processing the variable reluctance sensor results in a series of digital edges for further signal processing (see Section 6.1.2.4, “Crank decoding”) at the center of a physical tooth. The differential signal is amplified, processed to determine an adaptive threshold used in noise reduction, and then processed to determine zero crossings representing the center of teeth.

Once the positive differential input signal voltage rises above an adaptive threshold, the zero crossing comparator is armed. Arming the comparator this way provides robust noise immunity to the input VR signal, preventing false triggers from occurring due to a broken tooth or an off-center tooth wheel.

The peak threshold level is set to a third of the peak of the previous cycle of the input VR signal. As the sensor signal peak voltage rises, the adaptive peak threshold voltage also increases by the same ratio. Similarly as the signal peak voltage falls. If the input signal voltage remains lower than the adaptive peak threshold for more than 85 milliseconds, an internal watchdog timer drops the threshold level to a default minimum threshold. This ensures pulse recognition recovers even in the presence of intermittent sensor connection.

Once armed, the zero crossing detection logic generates a digital edge on the falling slope of the positive pair of the VR input. The zero-voltage level of the VR sensor signal corresponds to the center of the gear-tooth and is the most reliable marker for position/angle-sensing applications.

The crank VR input circuitry introduces a phase offset as an artifact of signal filtering. The phase shift causes the digital tooth edge representing the tooth center to occur some time after the actual tooth center. The time between the digital tooth edge and the actual tooth center increases as the frequency of the input signal increases.

Note

The application must take the phase shift introduced by filter circuits into account explicitly if required. The phase shift is typically accommodated implicitly by calibratable look-up tables for general calculations such as spark advance. However cylinder balancing and other application strategies may wish to take the phase shift into account explicitly.

6.1.1.2. Hall-effect signal

Further details to be added in a later release.

6.1.1.3. Hall-effect signal — directional

A directional Hall-effect crank sensor generates a digital signal to track the position of a crank trigger wheel, and further encodes the direction of the crankshaft by varying the length of the digital pulses. OpenECU does not currently support directional Hall-effect crank sensors.

6.1.1.4. Quadrature encoded signal

A quadrature encoding crank sensor generates two signals to track the position of a crank trigger wheel and the direction of movement. OpenECU does not currently support quadrature encoding crank sensors.

6.1.1.5. Noise rejection

Crank teeth edge processing includes a blanking window to help reject noise that occurs around the zero crossing (can occur at low crank speeds where the signal amplitude is low). The blanking window size is calculated as a ratio of the time between the last two teeth. The noise-reject ratio limits detectable acceleration of the crank wheel.

The application can accept the defaults or call the pan_config_crank_wheel_mtg_ext() function to set them explicitly. The noise rejection window can be calibrated out.

6.1.2. Crankshaft position detection

OpenECU supports crank trigger wheels with missing teeth or an extra tooth. Common crank trigger wheels, such as 12+1 and 36-1 are supported:

As are less common wheel patterns, such as 24-1-1-1 or 36-1-2-3:

Throughout this document, a crank trigger wheel with one group of missing teeth uses the notation N-M, where N represents the number of physical and missing teeth, and M represents the number of missing teeth. Similarly, a crank trigger wheel with an extra tooth uses the notation N+1, where N represents the number of physical teeth minus the extra tooth. If there are more than one group of missing teeth, or more than one extra tooth, then the notation is extended by adding further -M or +1 symbols as necessary. For example, 60-2-2-2 represents a crank wheel with 54 physical teeth and three groups of two missing teeth.

Each crank wheel input must be configured by calling the pan_config_crank_wheel_mtg() function. With the exception of the missing or extra teeth, the teeth must be regular in size and angular distance, α° per tooth.

For a crank trigger wheel with an extra tooth, the leading edge of the extra tooth must be evenly spaced by half α°.

Similarly, for a crank trigger wheel with missing teeth, the missing tooth region must be N α°, where N is an integer greater than zero.

6.1.2.1. Crank wheel movement and stall detection

Crank teeth edge processing includes a timeout after which, if a crank tooth edge has not been detected, the crank wheel is declared stalled. The timeout is calculated as a ratio of the time between the last two teeth, offset by the position of the next expected tooth edge. The stall-detect ratio limits detectable deceleration of the crank wheel.

The crank stall detection mechanism cannot be calibrated out (in contrast to the noise rejection mechanism, see Section 6.1.1.5, “Noise rejection”).

When the crank trigger wheel decoding first detects two teeth before stall is detected, then the ECU considers the crankshaft to be moving. The detection of a moving crankshaft is used by the port injection functionality to deliver a priming pulse if configured to do so. The application can retrieve movement information by calling the pan_get_crank_wheel_movement() function.

6.1.2.2. Crank wheel sync points

The missing or extra teeth areas are referred to as sync points. As the crank trigger wheel turns, the crank sensor signal will vary with regular frequency as each tooth passes the crank sensor until a sync point occurs. When the sync point is detected, the position of the crank shaft can be determined.

For a crank trigger wheel with one or more extra tooth sync points, the crank region (shown in blue) extends from the end of the sync point to the end of the next sync point. The sync point itself (shown in red), differs from the rest of the crank region with a change in pattern that the ECU can detect (in this case, an extra tooth).

The crank region and sync point are defined similarly for missing teeth.

Multiple sync points in a crank trigger wheel are supported but all sync points must be of the same type. For instance, if the crank trigger wheel has one extra tooth sync point, then any additional sync points must also be of the extra tooth variety.

6.1.2.3. Sync point detection

As the crankshaft speed varies over time, sync points are detected by looking at the ratio of time between teeth.

In the case of a sync point with an extra tooth, the time between teeth prior to the extra tooth, A, the time between the extra tooth and the prior tooth, B, and the time between teeth as if the extra tooth were not there, a, are used. The model can accept the default ratio values or use the by calling the pan_config_crank_wheel_mtg_ext() function to set them explicitly.

In the case of missing teeth, the time between teeth prior to the gap, A, the time across the gap, B, and the time between teeth after the gap, a, are used to detect a sync point.

There are some limits on crank trigger wheel processing. In particular, the total number of teeth on the crank trigger wheel, the number of teeth between sync points, the number of of extra teeth and the the number of missing teeth, must fall within the limits defined by the pan_config_crank_wheel_mtg() function.

Note

Some care is required when configuring the orientation of the crankshaft trigger wheel sync points relative to cylinder events. For example, if a sync point lines up with an area of the engine revolution with high acceleration, then it may be hard for the ECU to correctly decode sync point information. Align crankshaft trigger wheel sync points with regions of the engine rotation which see the least variation in speed.

6.1.2.4. Crank decoding

The signal from the crankshaft sensor is decoded by a state machine. The current decoding state can be retrieved by calling the pan_get_crank_wheel_decoding_state() function. Many of the decoding parameters can be adjusted by the application by calling the pan_config_crank_wheel_mtg_ext() function during application initialisation. There are three main parts to the decoding:

  • Initialisation — used to ignore electrical noise generated during initialisation of the electrical system.

  • Find crank region synchronisation — used to find the missing tooth region when synchronisation was not previously gained, or had been lost

  • Keep crank region synchronisation — used to maintain synchronisation with the crank wheel once synchronisation has been found

Within each group, a series of states decodes the crank signal over time.

Ignore-crank-signal

Occurs once during initialisation of the ECU, after reset.

The state ignores crank edges for 10 milliseconds, letting any electronics settle during power up.

Skip-crank-teeth

Occurs once the ignore-crank-signal state is complete.

Ignores the first n processed teeth edges, further letting any electronics settle during power up.

First-edge

Occurs once the skip-crank-teeth state is complete, or loss of crank synchronisation occurred, or the crank signal is declared stalled.

If a tooth edge occurs within first-tooth-timeout milliseconds since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise, the crank signal is declared as stalled. This sets the minimum speed at which the crank decode logic will start to look for crank synchronisation.

Second-edge

Occurs if the first-edge state did not timeout.

If a tooth edge occurs within a timeout since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise the crank signal is declared stalled. For example, a crank trigger wheel with missing teeth sync points has a timeout as follows:

Detect-AB:

Occurs if the second-edge state did not timeout; or if the detect-ab state did not detect a sync point; or if the detect-ba state did not confirm a sync point.

If a tooth edge occurs within a timeout since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise the crank signal is declared as stalled.

The state buffers the time of teeth edges in a cyclic fashion, where t0 is the time of the most recent tooth, t-1 is the time of the tooth before t0, and t-2 the time of the tooth before that. The state uses a AB ratio test from Section 6.1.2.3, “Sync point detection” to detect the sync point. For example, a crank trigger wheel with missing teeth sync points has a timeout as follows:

Detect-Ba

Occurs if the detect-ab state found a sync point.

If a tooth edge occurs within a window since the last tooth edge then the time of the tooth edge is remembered for later processing (as in state detect-ab). Otherwise the crank signal is declared stalled.

The state uses a Ba ratio test from Section 6.1.2.3, “Sync point detection” to detect the sync point. For example, a crank trigger wheel with missing teeth sync points has a timeout as follows:

If the ratio test passes, the ECU declares region sync to the crank trigger wheel (see Section 6.1.9, “Engine synchronisation modes”).

Count-teeth

Occurs if the detect-ba state or confirm-sync-point state detected a sync point.

If a tooth edge occurs within a timeout since the last tooth edge then the number of teeth since the gap is counted and the angle clock is maintained (see Section 6.1.4, “Angle clock”). Otherwise the crank signal is declared stalled. For example, a crank trigger wheel with missing teeth sync points has noise rejection and stall detect / timeout processing as follows:

Confirm-sync-point

Occurs if the count-teeth state counted the number of physical crank teeth for the current crank region without timeout.

Works as the detect-ab state does with the addition of noise rejection. For example, a crank trigger wheel with missing teeth sync points has noise rejection and stall detect / timeout processing as follows:

6.1.2.5. Maintaining crank synchronisation

For crank wheels that have one sync point, the ECU will maintain synchronisation to the crank wheel using the decoding state machine and the parameters supplied by calling the pan_config_crank_wheel_mtg() function.

For crank wheels that have multiple sync points, the application must provide information about the next crank region at the end of each detected sync point (decoding states detect-ba and confirm-sync-point). At the end of each successfully decoded sync point, the ECU triggers the corresponding crank wheel crank-sync-point task, defined by the application, on the second tooth in the subsequent crank region.

In response, the application must look at the information about the sync point and provide information about the next crank region. Information about the sync point can be retrieved calling the pan_get_crank_wheel_sync_point_data() function. The information includes the number of teeth detected since the last sync point, and the durations of the teeth involved in the sync point (see Section 6.1.2.3, “Sync point detection”, sync point durations A, B and a). Information about the next crank region can be set calling the pan_set_crank_wheel_sync_point_data() function.

As an example, consider a 60-1-2 crank trigger wheel. Lets say this represents two crank regions:

  • Crank region X: 29 physical teeth, 1 missing tooth

  • Crank region Y: 28 physical teeth, 2 missing teeth

When a sync point has been found and verified, the application will be invoked. If the application retrieves information about the sync point showing there was 28 physical teeth seen, then the application would assume that crank region X follows next and provide details about region X. Similarly, if the application retrieves information showing there was 29 physical teeth seen, then the application would assume that crank region Y follows next and provide details about region Y.

Note

Due to other processing that the ECU performs, there may be a delay between the sync point trigger being recognised by the ECU and ECU running the corresponding application task. See Table 4.3, “Library and application tasks” for an overview of the ECU's tasks, including those of higher priority than the crank sync point tasks, which might cause delays.

6.1.3. Crankshaft zero degrees

Crank zero degrees is a reference point on the crank trigger wheel that the ECU assigns. Other angular operations, such as the angle at which to run the model for a cylinder's TDC-firing event, or the angle at which to start a spark pulse.

The process for determining crank zero degrees starts when the ECU has not gained synchronisation to the crank trigger wheel. The ECU monitors the crank signal for a possible sync point. When the first sync point is found and verified then the tooth at the end of the sync point is assigned to correspond to crank zero degrees. When the ECU loses synchronisation to the crank trigger wheel, this process starts again.

The following diagram shows crank zero degrees for two crank trigger wheels, one for a single extra tooth sync point, and one for a single missing teeth sync point.

In both the extra and missing cases, the crank wheel starts to move, the sync point (highlighted in red) is detected and crank zero degrees is assigned to the following tooth. When there is more than one sync point, the process is the same. The first sync point detected is used to assign crank zero degrees.

However, as there is more than one sync point on the crank wheel, each time the crank wheel starts to turn and a sync point is found and verified, crank zero degrees can change positions, as shown in the following diagram for a 12-1-1 crank trigger wheel.

The application must determine which sync point was first detected and apply an angle offset to compensate by calling the pan_declare_engine_sync() function. The application can determine the sync point by looking at the camshaft trigger wheel tooth angles if available, or some other method, such as the crank tooth acceleration curve.

Note that in the previous examples, crank zero degrees is assigned to the start of the physical tooth at the end of the sync point. This occurs when using a Hall-effect sensor, which generates a digital pulse corresponding to each physical tooth. When using a VR sensor, the crank sensor processing results in a digital signal with an offset (see Section 6.1.1.1, “Variable reluctance signal” for more).

In this case, crank zero degrees is assigned to the center of the tooth at the end of the sync point. The application must account for the difference between using a Hall-effect or VR crank sensor.

6.1.4. Angle clock

Once crank synchronisation has been achieved by detecting a sync point, the ECU tracks the crankshaft and engine position with an angle clock. The clock provides a high resolution angle reference that can be used to schedule angular events, such as the start of an injection pulse. The angle clock can be read by calling the pan_get_crank_wheel_angle() function.

The angle clock is synchronised to the crank teeth. When a tooth is detected, the frequency of the angle clock is based on the duration of time between the last two teeth (ignoring sync points). The frequency of the clock is chosen to achieve a resolution of at least 0.1 crank degrees. The angle clock then ticks at that rate for the number of degrees per tooth, α°, providing an interpolated estimate of the position between teeth.

For example, let A represent the time between the last two detected teeth (excluding sync points). When the crankshaft is spinning at a constant speed, A will remain constant.

When a new tooth is detected, the angle clock frequency is adjusted to achieve the minimum resolution. The angle clock then ticks up at that rate (shown in blue) and stops after α°. As the crankshaft is spinning at a constant speed, the angle clock will stop just before a new tooth is detected. In this way, the angle clock provides an estimate of the crankshaft position between teeth.

When the crankshaft decelerates between teeth, the angle clock will stop before the next tooth is detected, as depicted below (in red). When the next tooth is detected, the frequency of the angle clock is recalculated and the angle clock starts to tick up at that rate.

When the crankshaft accelerates between teeth, the angle clock will not have completed α° of ticks before the next tooth is detected, as depicted below (in purple). To compensate, when the next tooth is detected the angle clock switches to a high frequency to catch up. Once α° of ticks have been completed, the frequency of the angle clock is adjusted as before and clock starts to tick up at that rate.

Note that the angle clock accuracy depends on the number of crank trigger wheel teeth. The larger the number of teeth, the better the accuracy of the angle clock.

6.1.5. Crank tooth identification

Decoding of the crank trigger wheel involves counting teeth between sync points. The tooth counts are used to verify sync points when maintaining crank synchronisation, and for recording the time of each tooth for other functionality. The application can retrieve the current tooth count by calling the pan_get_crank_wheel_tooth_region() and pan_get_crank_wheel_tooth() functions.

Crank region tooth identification

At the start of a crank region, the crank region tooth count is reset to one. Each tooth is counted until the next crank region starts. Any extra teeth in a sync point are ignored.

Crank revolution tooth identification

The first tooth counted per crank revolution corresponds to the tooth the ECU assigns to crank zero degrees (see Section 6.1.3, “Crankshaft zero degrees”). If the crank trigger wheel has more than one sync point, then tooth one may change positions depending on which sync point is detected first. Each tooth is counted until the crank has turned a complete revolution, then the count is reset to one. Any extra teeth in a sync point are ignored.

6.1.6. Crankshaft speed

The rotational speed of the crank trigger wheel is determined by the time captured for each tooth (ignoring the extra tooth involved in any sync point). The use of tooth times gives more accurate results than times captured at angles between teeth. The speed can be retrieved by calling the pan_get_crank_speed_per_tooth() or pan_get_crank_speed_per_rev() functions.

Speed is calculated by the ECU in different ways.

  • A per-tooth calculation provides instantaneous speed. During a sync point, the speed calculation compensates for any missing teeth. Note that the higher the number of missing teeth, the less accurate the speed calculation will be if the engine rotation is accelerating or decelerating across the sync point.

  • A per-crank-revolution calculation provides an averaged speed. For a more precise speed calculation, it is possible to retrieve the times of individual teeth for features such as cylinder balancing.

6.1.7. Multiple crankshaft sensor inputs

The ECU can measure the phase in rotational position between the primary crank sensor input and a number of secondary crank sensor inputs. The crank trigger wheel pattern need not be the same for the primary and secondary inputs. The phase is measured on each tooth of a secondary input, as the difference between the angle clock of the primary crank input and the angle of the secondary crank input tooth. The phase can be read by calling the pan_get_crank_secondary_phase() function.

Currently there is no support for redundant crank trigger wheel inputs.

6.1.8. Camshaft position sensor processing

There are two common engine types in use today:

  • A two-stroke engine is an internal combustion engine which performs a complete cylinder cycle in 360 crank degrees (one crank revolution). A two-stroke engine completes its combustion stroke and starts the compression stroke simultaneously, whilst performing the intake and exhaust processes at the same time. A two-stroke engine does not have a camshaft.

  • A four-stroke engine is an internal combustion engine which performs a complete cylinder cycle in 720 crank degrees (two crank revolutions). Unlike the two-stroke engine, a four-stroke engine has separate intake, compression, combustion and exhaust cycles. Typically, four-stroke engines have a cam trigger wheel attached to one or more camshafts to determine engine position, but some engines are configured for cam sensor-less approaches.

In comparison to crank trigger wheel processing, little processing occurs for cam trigger wheels. Depending on the circuit configuration for an ECU, the ECU will support VR or Hall-effect camshaft sensors. See the ECU's technical specification for details relating to VR signal processing (processing for crank and cam shaft sensor processing typically differs). And except for filtering implemented by the input circuit, there is no support to reject noise as there is for crankshaft sensor processing.

Typically, the cam trigger wheel has at least one unique tooth edge which can be used to determine the overall engine position (i.e., to determine between two halves of a four-stroke engine cycle). But the ECU's camshaft sensor processing does not require this. The pattern of expected cam trigger wheel teeth are not supplied to the ECU and need not be equally spaced (unlike the crankshaft trigger wheel). Cam trigger wheel patterns, such as a half moon or more complex, are treated the same.

However, the application must specify the number of cam trigger wheel teeth by calling the pan_config_cam_wheel() function for each camshaft.

Once the angle clock is running, the ECU records the angle of tooth edges, in the order of detection, from the cam trigger wheel into a vector or array. The ECU supports recording both sensor edges of a tooth, or just the leading or trailing sensor edge. Tooth angles are recorded relative to crank zero degrees. The application can retrieve the tooth angles by calling the pan_get_cam_wheel_teeth_angles() function.

Cam trigger wheel tooth edge information is recorded by the ECU. The application uses this information to determine the overall engine position and adjust crank zero degrees (see Section 6.1.3, “Crankshaft zero degrees”). In turn, the ECU adjusts the angle clock and any scheduled events based on the angle clock, as described in more detail in Section 6.1.9, “Engine synchronisation modes”.

Some engines do not have a camshaft (e.g., two-stroke), or do not attach a sensor to the camshaft (e.g., four-stroke motorbike engine). In the two-stroke case, there is no need to utilise the ECU's camshaft processing. In the case of sensor-less camshaft system, the application will need to utilise other input processing to determine the overall engine position. See Section 6.3, “Analogue input processing” for input processing of analogue inputs to detect pressure patterns or Section 6.2, “Engine TDC-firing events” for input processing of engine speed to detect acceleration patterns.

6.1.9. Engine synchronisation modes

The engine synchronisation mode controls what angular functionality is enabled. The modes represent states in which the ECU and application know about the overall engine position. For example, without any engine position information, it is not possible to schedule a drive signal to an actuator just before a cylinder's TDC-firing angle.

In the crank and cam signal processing outlined so far, the ECU will automatically handle engine synchronisation up to crank region sync. The application must then determine the overall engine position from the crank sync point information, the cam tooth edge information (if configured), or any other source such as manifold pressure or crank accelerations, then request a switch to half or full engine modes by calling the pan_declare_engine_sync() function. The current engine synchronisation state can be read by calling the pan_get_engine_sync() function.

No crank synchronisation

Occurs during initialisation of the ECU, after reset, or when crank signal processing times out (stall), or when crank signal processing cannot detect an expected sync point (loss of sync), or when the application forces loss of crank sync.

When the ECU has no crank sync all angular functions except crank and cam trigger wheel processing are turned off.

Crank moving

Occurs when the engine sync mode was previously no crank sync and the ECU has processed at least two crank teeth without timeout (stall).

When the ECU first detects the crankshaft to be moving, the crank moving state becomes active and if configured, the ECU will generate a priming fueling pulse on each port-injection output pin.

Crank region sync

Occurs when the engine sync mode was previously crank moving and the ECU has successfully found at least one sync point.

The ECU will remain in the crank region sync mode trying to maintain synchronisation to the crank trigger wheel. The ECU will trigger the application at the end of each sync point. The application must determine the overall engine position, then request a change to either the half engine sync mode or the full engine sync mode.

Half engine sync mode

Occurs when the engine sync mode was previously crank region sync or full engine sync and the application has requested half engine sync.

In half engine sync mode the application has determined the position of a four-stroke engine with evenly spaced TDC-firing events, to one of two engine halves, but does not know which half yet. The cylinder TDC-calculation trigger, port injection, spark and digital output functions support running an engine in this mode.

Full engine sync mode

Occurs when the engine sync mode was previously crank region sync or half engine sync and the application has requested full engine sync.

In full engine sync mode the application has determined the position of a two-stroke or four-stroke engine. Most angular functions are enabled in full engine sync mode.

Each of the synchronisation modes enables different sets of angular functionality. When a function is disabled, input processing ceases and output drivers are turned off.

Table 6.1. Function availability based on engine synchronisation mode


6.2. Engine TDC-firing events

Most engine strategies work on the basis that there is some symmetry between cylinders. For instance, the cylinders in a four stroke engine all exhibit the same intake, compression, power and exhaust stroke, but the engine angle range over which each of these occurs is different from cylinder to cylinder, so that power is evenly spread across a complete engine cycle.

For the purposes of reading sensors or driving actuators related to a cylinder, it is useful to define events relative to a common position for each cylinder. This user guide uses the following terms:

  • TDC-firing — the engine angle when the cylinder's piston is at top dead center (TDC) prior to fuel burning, relative to crank zero degrees.

  • BTDC-firing — the relative angle before the cylinder's TDC-firing angle.

  • ATDC-firing — the relative angle after the cylinder's TDC-firing angle.

  • TDC-calculation — the relative angle to the cylinder's TDC-firing angle when the ECU triggers an application task, to calculate per-cylinder data.

6.2.1. Relative angles to TDC-firing

Most of the angular functionality relies on specifying angles relative to a cylinder's TDC-firing angle. With the exception of the knock and spark/coil functionality, the ECU treats positive angles relative to TDC-firing as happening after TDC-firing (ATDC-firing), and negative angles relative to TDC-firing as happening before TDC-firing (BTDC-firing).

As ignition timing is normally specified as crank degrees before TDC-firing, and knock processing related to ignition timing, the angle convention is the opposite for knock and spark/coil functionality, where the ECU treats positive angles relative to TDC-firing as happening before TDC-firing (BTDC-firing), and negative angles relative to TDC-firing as happening after TDC-firing (ATDC-firing).

6.2.2. Cylinder TDC-firing angles

Most of the angular functionality, such as injection or knock processing, are referenced by angle relative to each cylinder's TDC-firing angle. The application defines the number of cylinders and the TDC-firing angle of each by calling the pan_config_engine() function. The TDC-firing angles are defined relative to crank zero degrees. If the application adjusts crank zero degrees, then the TDC-firing angle is adjusted accordingly. For example, an asymmetrical engine with 2 cylinders, may have TDC-firing angles relative to crank zero degrees of 90° for cylinder 1 and 630° for cylinder 2:

Note that the crank diagram has been drawn to show two crank revolutions, covering 720 crank degrees. Also note that depending on which crank sync point is found first, the definition of crank zero degrees can change. The TDC-firing angles are always relative to crank zero degrees. The TDC-firing angles provided to the pan_config_engine() function are in cylinder order, i.e., “[90, 630]” in this case.

Another example might be a symmetric 4-cylinder inline engine, with TDC-firing angles relative to crank zero degrees of 46°, 406°, 226° and 586° for cylinders 1 through 4.

6.2.3. Cylinder TDC-calculation application events

The ECU invokes the application for each TDC-firing event. The application defines an angular offset from each TDC-firing event by calling the pan_config_engine() function. When the engine position is the cylinder's TDC-firing angle plus the offset, the TDC-calculation angle, the ECU triggers the corresponding engine tdc-firing task, defined by the application. The current cylinder and current engine angle can be retrieved by the application by calling the pan_get_engine_cyl() and pan_get_engine_angle() functions.

For example, taking the same symmetric 4-cylinder inline engine diagram as before, with an angular offset of -90° (shown in purple), the engine revolution is split into regions, each assigned to a cylinder.

When the application retrieves the current cylinder at angle 500°, the ECU will indicate cylinder 4. When the application retrieves the current cylinder at angle 480°, the ECU will indicate cylinder 2.

Note

Due to other processing that the ECU performs, there may be a delay between the cylinder's TDC-calculation angle being recognised by the ECU and ECU running the corresponding application task. See Table 4.3, “Library and application tasks” for an overview of the ECU's tasks, including those of higher priority than the TDC-calculation task, which might cause delays.

6.2.4. Engine angle offset

Depending on which crank sync point is found first, crank zero degrees will change as will the TDC-firing angles. As described in Section 6.1.9, “Engine synchronisation modes” the application must determine the overall engine position and adjust crank zero degrees to match by calling the pan_declare_engine_sync() function. Take a four cylinder engine configuration with TDC-firing angles at 0°, 360°, 180° and 540°.

If the ECU identified the crank sync point and crank zero degrees lines up with the engine configuration, then the application need not apply an engine angle offset. But if the ECU identifies another crank sync point so that crank zero degrees does not line up with the engine configuration:

then the application must determine how the two differ. In this case, an engine angle offset of -180° realigns crank zero degrees with the engine configuration:

6.2.4.1. Determining engine angle offset

The ECU supports a number of common techniques the application can apply to determine the engine position:

6.2.4.2. By crankshaft trigger wheel pattern

For a two-stroke engine configuration, when a crankshaft trigger wheel has one sync point, then this sync point can be used to determine the position precisely.

Once the sync point has been detected, the ECU will change to crank region synchronisation and then the application can request a switch to full engine synchronisation with an engine angle offset of zero (or a specific angle to adjust crank zero degrees to suit the application's needs). The application can trigger a sub-system for each detected sync point through the corresponding crank wheel crank-sync-point task, defined by the application.

For a four-stroke engine configuration, when a crankshaft trigger wheel has one sync point, then a sync point can be used to identify one of the two engine cycle halves.

Once the sync point has been detected, the ECU will change to crank region synchronisation and the application can request a switch to half engine synchronisation. For gasoline port injected engines, this engine synchronisation mode supports injection and spark every 360 crank degrees, facilitating engine start. The application can run the engine in this mode until the application determines which half of the engine cycle is active, before requesting a switch to full engine synchronisation mode.

Crankshaft trigger wheels with more than one sync point offer alternatives to waiting up to a full crank revolution to declare half or full engine synchronisation. The application can use the call the pan_get_crank_wheel_sync_point_data() function to identify information about the last crank region. If the crank region has a varying number of missing teeth per sync point, then the application can determine the crankshaft position by decoding the timing provided by that block.

Similarly, if there is a varying number of physical teeth between crank regions (ignoring any extra teeth), then the application can determine the crankshaft position by reading the number of detected teeth between crank regions provided by that block.

Note that some care is required when utilising these types of techniques. The position of crankshaft trigger wheel sync points relative to cylinder events must be taken into consideration. If a sync point lines up with an area of the engine revolution with high acceleration, say on starting, then it may be hard for the ECU and the application to correctly decode sync point information.

6.2.4.3. By camshaft trigger wheel pattern

Digital state

A common technique is to arrange the camshaft wheel pattern so that reading the digital state of the camshaft wheel input channel at key crankshaft positions. For example, a half moon camshaft wheel pattern can be arranged so that the camshaft wheel input reads high during one crank sync point and low during the other.

The red portion (marked 1 and 2) shows approximately where the application might sample the camshaft wheel input if triggered from a crank sync point. The application can read the digital state of a camshaft wheel input by calling the pan_get_cam_pin_state() function, at any time, e.g., periodically or after a sync point. The application can trigger a corresponding task crank-sync-point task related to the crankshaft wheel.

Often an engine configuration has a more complex camshaft wheel pattern, typically one tooth, or one tooth edge, per cylinder.

In the example above for an 4 cylinder engine, reading the digital state of the camshaft wheel input after each sync point would be sufficient (shown in red, marked 1 and 2). However, engine configurations that adjust cam timing will introduce a phase, such that the camshaft wheel turns relative to the crankshaft wheel.

Here, a 77° phase has been introduced. The camshaft wheel pattern remains the same but the teeth edge angles have been offset. In this circumstance, the technique of reading the digital state of the camshaft wheel after each sync point does not work, as both readings show the same high state (shown in red, marked 1 and 2).

Windowed — single edge

An alternative technique to reading the digital state of the camshaft wheel input looks for one tooth edge in regions of the crank revolution. The technique relies on there being at least one unique tooth edge that occurs across two crank revolutions. For example, in the previous diagram taking the cam angles and comparing them to the cam angles offset by 360° shows that some edges are unique and some are not.

Tooth
edge
Edge
polarity
Edge
angle
Edge angle
offset by 360°
Comment
1rising77437Unique edge
2falling117477Not unique edge, matches index 6
3rising257617Unique edge
4falling297657Not unique edge, matches index 8
5rising337697Unique edge
6falling477117Not unique edge, matches index 2
7rising517157Unique edge
8falling657297Not unique edge, matches index 4

Entries 2, 4, 6 and 8 cannot be used to determine the engine position, because those entries occur at the same angle (modulo 360) on each crank revolution. Entries 1, 3, 5 and 7 occur only once every second crank revolution and can therefore be used to determine the engine position.

Given a phasing range of 77°, each unique tooth edge can be windowed. Allowing for 1° of mechanical play, each unique edge can be identified with the following angle ranges:

Tooth edge Edge window Edge window
offset by 360°
1719, 78359, 438
3179, 258539, 618
5259, 338619, 698
7439, 51879, 158

Shown in the same form of diagram as before, the unique cam tooth edges (highlighted in red) are enclosed in angular windows (highlighted in green, marked 1, 3, 5 and 7 after the edge index). Each window in green has a corresponding window in yellow, offset by 360°. If a rising edge is found in any of the green windows then the application can declare full engine synchronisation with an offset of zero degrees. If a rising edge is found in any of the yellow windows then the application can declare full engine synchronisation with an offset of 360°.

The application can retrieve the edges of camshaft trigger wheel teeth by calling the pan_get_cam_wheel_teeth_angles() function. The tooth edge information is updated as new edges are detected, so the application can either periodically retrieve and process cam angle information, or retrieve and process cam angle details after each crank sync point through the corresponding crank wheel crank-sync-point task defined by the application.

Windowed — edge count

A variation on the single edge windowed approach, is to count teeth edges in a window. Take a camshaft trigger wheel for a four cylinder engine, where the teeth are arranged so that one half of the camshaft trigger wheel (360° of crank revolution) has two groups of single teeth, whilst the other half has two groups of double teeth.

Assuming a similar phasing of 77°, then the pattern can be broken up into four windows, two for the single tooth groups (highlighted in green, marked 2) and two for the double tooth groups (highlighted in yellow, marked 4). The windows are arranged to be identical across crank revolutions.

The application retrieves the camshaft trigger wheel tooth edge angles, counts the number found in the most recent window. If the expected number of edges are found in the window then the application can declare engine synchronisation with zero engine angle offset. Otherwise, if the number of edges matches the expected number for the next crank revolution then the application can declare engine synchronisation with 360° of engine angle offset.

Windowed — by crank region

The method relies on there being a unique camshaft trigger wheel tooth edge for each crank region. This works well when there are multiple crank regions, as each crank region can be processed on an event driven basis.

In this example, each tooth edge is offset by 10° from the previous crank region.

Tooth edge Edge angle Edge angle
modulo 120°
17070
214020
327030
441040
554050
667060

For an engine configuration without variable camshaft timing, the application can decode the overall engine position within two crank regions (between 140 and 240 crank degrees) by retrieving and processing one cam tooth edge after each sync point.

For an engine configuration with variable camshaft timing, the application will need to control the camshaft phase during engine start and process two cam teeth edges to know the overall engine position.

Delta angle between teeth

Arranging the camshaft trigger wheel teeth edges so that the difference in angle between each edge is unique, can be decoded by the application to identify the engine position.

6.2.4.4. By crank speed monitoring

Further details to be added in a later release.

6.2.4.5. By engine or cylinder pressure monitoring

Further details to be added in a later release.

6.2.5. Engine tooth identification

Engine tooth identification follows from decoding of the crank trigger wheel in Section 6.1.5, “Crank tooth identification”. At the start of crank zero degrees, the engine tooth count is reset to one. Each tooth is counted until the crank zero degrees occurs again. Any extra teeth in sync points are ignored.

In the diagram above, the outer circle of numbers represents the first crank revolution. If the configuration of the engine is two-stroke, then the inner circle of numbers can be ignored (the engine tooth identification is the same as the crank tooth identification for two-stroke engines). The inner circle of numbers represents the second crank revolution for four-stroke engines. The application can retrieve the most recently decoded engine tooth by calling the pan_get_engine_tooth() function.

6.2.6. Engine speed

The rotational speed of the engine is determined by the time captured for each tooth (ignoring the extra tooth involved in any crank sync point). Like crank speed, the use of tooth times gives more accurate results than times captured at angles between crank teeth. The speed can be retrieved by calling the pan_get_engine_speed_per_tooth(), pan_get_engine_speed_per_rev() or pan_get_engine_speed_per_cyl() functions.

Engine speed is calculated by the ECU in different ways:

  • A per-tooth calculation provides instantaneous speed (and is identical to the per-tooth crank speed calculation). During a crank sync point, the speed calculation compensates for any missing teeth. Note that the higher the number of missing teeth, the less accurate the speed calculation will be if the engine rotation is accelerating or decelerating across the sync point.

  • A per-cylinder calculation provides an averaged engine speed between the last two TDC-calculation events.

  • A per-engine-revolution calculation provides an averaged engine speed.

  • A tooth-range-absolute calculation provides an engine speed between engine teeth, where Section 6.2.5, “Engine tooth identification” identifies teeth by number.

  • A tooth-range-absolute calculation provides an engine speed between engine teeth, where teeth are identified relative to the TDC-firing angle.

6.3. Analogue input processing

Engine control strategies have the need to sample input sensors relative to each cylinder's TDC-firing angle. For instance, speed density systems use a manifold absolute pressure (MAP) sensor to determine manifold pressure information. The readings are used to calculate air charge ingested into each cylinder from knowledge of the partial pressure of air in the manifold, engine speed and an assume volumetric efficiency model. In turn, this determines the required fuel metering for optimum combustion and influences the advance or retard of ignition timing. The MAP sensor is typically sampled at set angles prior to each cylinder's TDC-firing angle, based on engine speed.

The ECU will take measurements of multiple analogue input channels at specific engine positions and make them available to the application. The application defines which analogue input pins to read on an angular basis by calling the pan_config_angular_ad_var() function.

When an appropriate engine synchronisation mode is achieved, angular analogue input sampling starts. The ECU samples each analogue input pin at a regular angle, at least every 6 crank degrees. The application can retrieve these samples, or an average of the samples, relative to each cylinder's TDC-firing angle by calling the pan_get_angular_ad_samples_var() function to retrieve individual samples, or pan_get_angular_ad_avg_var() function to retrieve an average of the samples taken. Alternatively, the application can retrieve specific samples relative to crank zero degrees by calling the pan_get_angular_ad_samples_abs() function to retrieve individual samples, or pan_get_angular_ad_avg_abs() function to retrieve an average of the samples taken.

Note that not all analogue input pins can be used for angular sampling. Any marked as serial by the ECU's technical specification cannot be used, as these inputs require serial communication to devices within the IC. The communication leads to large jitter in sampling angle and are thus excluded.

6.4. Knock sensor processing

A cylinder, or engine, knocks when fuel starts to burn at the wrong time and/or in the wrong area within the cylinder. Knock can lead to engine damage due to hot spots (e.g., to the piston head) or mechanical stress (e.g., to the piston rods). Knock is commonly associated with gasoline engines as an abnormal event, something to be avoided. But knock in diesel engines is common and partly accounted for in the mechanical design.

Knock can be detected by listening to the frequency of the engine block using one or more acoustic sensors. The sensors are placed at carefully selected locations in the block, and processed during regions around each cylinder's TDC-firing angle. Knock produces a characteristic pinging noise and can be picked out by filtering the acoustic signal for key frequencies. See the ECU's technical specification for details relating to knock signal processing.

To configure the ECU to perform knock sensor signal processing, the application must identify the regions around each cylinder's TDC-firing angle when processing will take place. A region is defined by a starting angle relative to each cylinder's TDC-firing angle. A region is terminated when the next region starts. The application does this by calling the pan_config_knock() function.

When an appropriate engine synchronisation mode is achieved, knock signal processing starts. The application defines an angular window within the cylinder's region where the knock sensor signal is fed through various buffers, filters and integrators (dependent on ECU type). The window is set by the application by calling the pan_set_knock_window() function. and the signal processing parameters are set by the application by calling the pan_set_knock_filter_hip901x() and pan_convert_knock_filter_hip901x_values() functions. Shortly after the end of each knock window, knock signal processing is completed by the ECU and can be retrieved by the application by calling the pan_get_knock_feedback() function.

6.5. Scheduling injector outputs

Running an engine efficiently relies on injecting fuel in precise quantities through out the engine cycle. The ECU supports this by associating injector output pins to each cylinder. The application must identify the output drive pins by calling the pan_config_injector() function. This associates an injector identifier, to an injector output pin and to a cylinder. If there is one injector per cylinder, then the application can associate injector output to a cylinder by assigning the injector identifier to be the same as the cylinder number. However, any association of injector identifier to cylinder number can be applied by the application and the ECU will support multiple injectors per cylinder.

As a convenience, the ECU provides the pan_config_injectors() function which can be used to map a number of injectors to cylinders when there is one injector per cylinder.

Different ECUs support different injection drive methods:

  • Saturating — this type of driver works by supplying the battery's positive voltage to the injector's high-side and connecting the injector's low-side to the ECU's injector pin that connects to the battery's negative terminal through a switch. Turning on and off the switch controls fuel injection by lifting or returning the injector needle.

    These drivers expect an injector with a relatively high internal resistance (typically 10 or 20 ohms) where the current through the resistor saturates when turned on for sufficiently long enough. The current flow in the driver and injector circuit stays low keeping the components cool for long life.

    Engines with saturating injectors typically supply fuel to the injectors with low pressure. Due to the low fuel supply pressure, injection durations can occur for a sizable duration of the cylinder cycle. See Section 6.5.1, “Port injection” for details on how the ECU can drive these types of injectors.

  • Peak-and-hold — this type of driver works in a similar fashion to a saturating driver but includes current sensing circuitry. The ECU controls two phases of injection. The first phase, peak, draws more current to pull back the injector needle quickly. The second phase, hold, draws less current to hold the needle in position to allow fuel to flow.

    These drivers expect an injector to have lower internal resistance than saturating injectors, and therefore supply higher current. The current sensing circuitry helps meet the injector and ECU component life requirements.

    Engines with peak-and-hold injectors typically supply fuel to the injectors with higher pressure. Due to the higher fuel supply pressure, injection durations are short and more precisely controlled. See Section 6.5.2, “Direct injection” for details on how the ECU can drive these types of injectors.

  • Boosted peak-and-hold — this type of driver works in a similar fashion to the peak-and-hold driver but includes a phase of injection prior to the peak phase, where the supplied voltage to the injector is boosted. This boosted phase increases the rate at which the injector needle is lifted, allowing for higher fuel supply pressure and more precise injection timing. See Section 6.5.2, “Direct injection” for details on how the ECU can drive these types of injectors.

6.5.1. Port injection

For port injection, the ECU will generate drive signals to injectors based on a start angle and a duration when the application calls the pan_set_injection_pi() function. This schedules the drive signal to occur some time in the future. To support tip-in or back-out, where the rate of change in the engine speed is required to occur as quickly as possible, the ECU can adjust the schedule when the application calls the pan_update_injection_pi() function. If the main injection signal has not yet been generated, then the application can request both the start angle and duration be adjusted. If the main injection signal is being generated, then the application can request the duration be adjusted, both to lengthen (in the case of tip-in) and shorten (in the case of back-out). If the main injection signal has completed, and the next cylinder cycle has not yet started, then the application can request one or more post injection signals (sometimes termed make-up injection signals) be generated.

In high load and/or cold conditions, the engine strategy may request long injections. To help prevent injection when the inlet valve is closing (or has closed), the application sets a drop-dead angle that the ECU uses to stop any on-going injection.

Port injection is enabled in half engine or full engine synchronisation.

  • In full engine synchronisation, either two-stroke or four-stroke, there is one injection schedule for one cylinder cycle.

  • In half engine synchronisation, for a four-stroke engine, the injection schedule is repeated every half engine cycle, each with half the requested duration of injection. This mode will run an engine without knowing which half of the engine cycle is current, and can be used for quicker starts or limp home mode depending on cam trigger wheel information, or lack of. In half engine synchronisation, for a two-stroke engine, port injection works as if full engine synchronisation has been declared by the application.

Although not commonly used, due to higher emissions, the ECU supports a priming injection. The priming injection is intended to get fuel into the cylinders as quickly as possible in cold environmental conditions. The ECU starts the priming injection when crank moving synchronisation has been achieved (see Section 6.1.2.4, “Crank decoding”). To request a priming injection signal the application calls the pan_set_initial_injection_pi() function. prior to crank moving synchronisation.

The application can retrieve information about delivered injection pulses calls the pan_get_injection_pi_feedback() function.

6.5.2. Direct injection

For direct injection, the ECU will generate drive signals to injectors based on a set of start angles and amount when the application calls the pan_set_injection_di() function. This schedules the drive signal to occur some time in the future. Unlike the port injection method, direction injection events are short lived relative to the duration of a cylinder cycle. Thus, once the ECU starts to generate the injection signals for a cylinder cycle, any schedule updates from the application are buffered until the next cylinder cycle.

The amount to injection can be expressed in units of time or volume of fuel. When the amount is provided in volume, the ECU will sample the fuel-rail pressure sensor just before each injection event, and convert volume to time through a 2D table provided by the application by calling the pan_config_injectors_comp_di() function.

The application is responsible for checking that the fuel-rail pressure signal is valid. The application reads the fuel-rail pressure sensor by calling the pax_adc_input() function. on a periodic basis, along with any other sensor required to infer correct operation, and must override the fuel-rail pressure signal by calling the pan_set_injection_comp_frp_di() function. when the application determines the sensor is generating an invalid signal. Overriding the fuel-rail pressure signal may also be useful when validating the application fueling strategy.

Regardless of the units of the injection amount, once converted to time, each injection event has an injection compensation duration added prior to injection. The compensation duration allows the application to fine tune injection events based on the micro mechanical differences between injectors. The application sets the compensation duration calls the pan_set_injection_di() function.

The injection schedule is made up of multiple injection events. The application can enumerate each event as needed, e.g., pilot, main, post. The only restriction is that each injection event occurs later in the cylinder cycle than the previous event, i.e., injection events may not overlap. Due to conversion from volume to time, or due to changes in the engine speed, events may end up overlapping even if the schedule from the application did not. In these circumstances, the ECU delays the later of two overlapping events and inserts a delay between them. The application can specify the delay by calling the pan_config_injections_di() function. Note that if using an external injection signal conditioning box, the circuitry of the conditioning box may impose requirements on the minimum time between injection events. For example, this might be required to ensure the boost voltage is sufficiently high for each injection event, or that the conditioning circuitry stays below a critical temperature.

The application can retrieve information about delivered injection pulses calls the pan_get_injection_di_feedback() function.

6.5.3. Injection waveform configuration

Section 6.5, “Scheduling injector outputs” described the different types of injection waveforms supported by different ECUs. Some ECUs can generate injection signals with waveforms that are configured by the application. See the ECU's technical specification for what waveforms an ECU can support.

For ECUs which have configurable waveforms, the total duration of the injection signal, T5, is set by the application by calling the pan_set_injection_pi() function or pan_set_injection_di() function. Within that time-frame, the application can specify one or more injection phases, and within each phase, the desired current, voltage source and switch time by calling the prop_set_phase_for_waveform_33816() function. For example, with the M670 ECU, it is possible to shape the injection signal into three phases. High pressure diesel engine configurations typically have a boosted phase to quickly lift the injection needle free of mechanical and pressure forces, a peak phase to complete the needle lift and a hold phase to complete fuel delivery.

The desired hold current for a stage is specified by Cn. For each stage, the application can select between battery voltage, VPWR, or boost voltage, VBOOST. The application can set the VBOOST control point by calling the prop_configure_boost() function. The higher boost voltage is typically used to energise a coil quickly, thus providing fine control over short digital pulses.

The application can defined multiple waveforms and individually assign a waveform to an injector output pin by calling the prop_set_waveform_for_output() function.

6.6. Scheduling coil outputs

There are two main types of spark plugs in use, inductive and smart. Inductive spark plugs are controlled by directly driving the coil from the ECU with a high voltage, high current signal (perhaps through the use of IGBTs). Smart spark plugs, or smart coils, are controlled indirectly by driving a low-voltage, low-current logic signal to the smart spark plug (where the IGBT is embedded in the plug assembly).

The purpose of the coil is to discharge energy accumulated during a dwell period, causing a spark between the plug's electrically isolated shell and electrode. The spark ignites the cylinder's fuel/air mixture.

Like injector output pins, the application must associate a spark output pin to a cylinder. The application does so by calling the pan_config_sparks() function.

Spark pulse generation is enabled in half and full engine synchronisation modes. In these modes, the application can schedule a spark signal with a start and end angle by calling the pan_set_spark() function.

  • In full engine synchronisation mode, the application can select between a single spark signal per cylinder cycle, commonly referred to as coil-on-plug, or two spark signals per cylinder cycle to support wasted spark, where one coil is used to spark in two cylinders.

  • In half engine synchronisation mode, the application can select between no spark signals, or two spark signal per cylinder cycle. The latter mode supports half engine synchronisation mode for port injection without knowing which half of the engine cycle is current.

The application can retrieve information about delivered spark pulses calls the pan_get_spark_feedback() function.

Note that measurement of current for optimal dwell time is not yet supported.

6.7. Scheduling digital outputs

The ECU supports application requests to control a digital output in the angular domain in a fairly generic way. For example, to control a fuel control valve with a time based digital signal prior to half or full engine synchronisation, and a angle based PWM digital signal once engine synchronisation has been achieved. The application selects which digital output pins to use by calling the pan_config_angular_output() function.

The application specifies the start and end actions by calling the pan_set_angular_output() function. The start actions are always specified to occur at a start angle, while the end actions are specified to occur at some duration after the start angle. The duration can be either an angle or a time depending on the output mode selected. Possible actions are setting the pin-state to active or inactive, toggling the state or leaving the state unchanged.

In addition to controlling the output in the angular domain, the ECU allows an immediate action to be specified. This allows a relatively crude level of purely time-based control to occur at the resolution of the application's task period.

The start actions are always specified to occur at a start angle with the panf_ang_out_start_angle argument, while the end actions are specified to occur at some duration after the start angle with the panf_ang_out_duration argument. The duration can be either an angle or a time depending on the output mode selected, with the panf_ang_out_mode argument. Note that the output mode is a fixed property of the output that is specified by the corresponding pan_config_angular_output() function. Possible actions are setting the pin state to active or inactive, toggling the state, or leaving the state unchanged.

In addition to controlling the output in the angular domain, this function allows an immediate action to be specified, by the panf_ang_out_action_now argument. This allows a relatively crude level of purely time-based control to occur at the resolution of the task time in which this function resides. An application thus might control an output using this immediate action prior to achieving crank synchronization, and then use the angular control once crank sync has been attained.

Some illustrations of this function in action are given below.

Figure 6.1. Output pulse - Angle-Time Duration (turn-on/turn-off)

Output pulse - Angle-Time Duration (turn-on/turn-off)

Figure 6.2. Output pulse - Angle-Time Duration (turn-on/no-action)

Output pulse - Angle-Time Duration (turn-on/no-action)

Figure 6.3. Output pulse - Angle-Angle Duration (turn-off/toggle)

Output pulse - Angle-Angle Duration (turn-off/toggle)

Figure 6.4. Output pulse - Angle-Angle Duration (turn-on/turn-off)

Output pulse - Angle-Angle Duration (turn-on/turn-off)

The start angle is interpreted either relative to crank-zero, or relative to the TDC-firing angle of a specified cylinder. The specified start event will then occur at the next such start angle to occur. For a two-stroke engine (as specified in the pan_config_engine() function), the start angle is interpreted modulo 360°. For a four-stroke engine, it is interpreted modulo 360° before full engine synchronisation, and modulo 720° after full engine synchronisation.

When OpenECU is unsynchronised with the crank wheel, the outputs can be scheduled but will not be driven as the crank position will be unknown. If crank synchronisation is lost, then the pin state is set to the value specified in the panf_ang_out_stall_action argument of the corresponding pan_config_angular_output() function. This also determines the initial output state before the first time the function is called.

The sequence of events can be repeated automatically every engine cycle by setting the panf_ang_out_allow_cycle_repeat argument to TRUE (non-zero). If the panf_ang_out_allow_cycle_repeat argument is set to FALSE (zero), then a single sequence of events will be scheduled, and a further function call is required to generate further events. If the function is called before the next scheduled event has started, and the start angle of the new data is still in the future, then the new data will supersede the previous data. If the start angle of the new data is in the past, and the previous data is in the future, then the previous data will be used for only the next event instead of scheduling the event for the next engine cycle. The preference being that it is better to keep the previously scheduled event, than to skip the event for the current engine cycle.

Each index in the array of values is treated as a separate event. If the function is called while an event is underway and the data for the the current event in the array of values is modified, then the behaviour is determined by the panf_ang_out_allow_end_mod argument value. If this is FALSE (0), then the data will be buffered and take effect on the next instance of that event. On the other hand, if the panf_ang_out_allow_end_mod argument value is TRUE (non-zero), then the end of the event will be updated according to the newly provided duration and end action values (and the start action and start angle values are ignored). If the newly provided duration has already elapsed, then the end action is applied immediately. (Note that in this case it will be applied immediately after any immediate action that has been specified.)

Figure 6.5. Output data updated during an event, end modification allowed

Output data updated during an event, end modification allowed

Figure 6.6. Output data updated during an event, end modification not allowed

Output data updated during an event, end modification not allowed

If the duration for an event is zero, then that event will be skipped for the schedule of events. If the duration for all events in the schedule are set to zero, then at the start angle of the event in the first index of the schedule, a single action will be performed corresponding to the result of applying the start action followed by the end action. For example, if both actions specify that the output pin state should be toggled, then no change to the pin state will occur. If an update occurs when an event is underway with duration of zero and panf_ang_out_allow_end_mod argument is set to TRUE, then the newly specified end action is applied immediately.

If two events in a schedule overlap, the first pulse will be terminated at the start angle of the next pulse with a single action corresponding to the result of applying the end action of the first event followed by the start action of the next event. The schedule will then continue normally with the duration of the next event, resulting in the correct timing of the next event from that event's start angle.

Figure 6.7. Output event with overlap between two events

Output event with overlap between two events

If an event start action occurs within the last panf_ang_out_min_off_time argument after the end action of a previous event, the second event will be delayed to ensure the minimum off time is maintained between the two events. The minimum off time can be set to zero to prevent the subsequent pulse from being delayed.

Figure 6.8. Output event starting within minimum off time

Output event starting within minimum off time

The possible values for the arguments panf_ang_out_action_now, panf_ang_out_start_action, and panf_ang_out_end_action are enumerated as:

Table 6.2. Angular digital output pin actions

Value Description
0 Turn-off - the output pin will be modified to the non-driven state.
1 Turn-on - the output pin will be modified to the driven state.
2 Toggle - the output pin will be toggled.
3 No-action - the output pin will not change driven state.

6.8. Angular function feature (PAN)

6.8.1. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pan.h
Enumerations
 PAN_RC_T

An enumerated type which contains success and failure codes returned by some angular feature (PAN) functions.

Data types
 PAN_DEVICE_KNOCK_T

This declares a type with enough value range to represent all logical knock devices for all targets.

 PAN_LCHAN_KNOCK_T

This declares a type with enough value range to represent all logical knock devices for all targets.

Functions
PAN_RC_Tpan_config_angular_ad_var

Function to configure an analogue input channel to sample on an angular basic.

PAN_RC_Tpan_get_angular_ad_avg_var

Function to read the average of sampling an analogue input channel relative to the TDC-firing angle of a cylinder at specific angles.

PAN_RC_Tpan_get_angular_ad_samples_var

Function to read the individual samples taken from an analogue input channel relative to the TDC-firing angle for the given cylinder at specific angles.

PAN_RC_Tpan_get_angular_ad_avg_abs

Function to read the average of sampling an analogue input channel relative to crank zero degrees at specific angles.

PAN_RC_Tpan_get_angular_ad_samples_abs

Function to read the individual samples taken from an analogue input channel relative to crank zero degrees at specific angles.

PAN_RC_Tpan_config_angular_output

Function to configure a generic angular output.

PAN_RC_Tpan_set_angular_output

Function to control a generic angular output.

PAN_RC_Tpan_config_crank_wheel_mtg

Function to configure a crankshaft wheel encoder input channel.

PAN_RC_Tpan_config_crank_wheel_mtg_ext

Function to configure the extended parameters for decoding a crankshaft trigger wheel, including missing tooth detection, noise rejection and stall detection.

PAN_RC_Tpan_get_crank_wheel_angle

Function to retrieve the current crankshaft wheel angle.

PAN_RC_Tpan_get_crank_wheel_movement

Function to determine if the crankshaft wheel is moving or not.

PAN_RC_Tpan_get_crank_speed_per_rev

Function to determine the speed of the crankshaft wheel on a per revolution basis.

PAN_RC_Tpan_get_crank_speed_per_tooth

Function to determine the speed of the crank wheel on a per tooth basis.

PAN_RC_Tpan_get_crank_wheel_sync

Function to retrieve the synchronisation state for a crankshaft wheel.

PAN_RC_Tpan_get_crank_wheel_tooth_region

Function to retrieve the current crankshaft region tooth identifier.

PAN_RC_Tpan_get_crank_wheel_tooth

Function to retrieve the current crankshaft revolution tooth identifier.

PAN_RC_Tpan_get_crank_wheel_decoding_state

Function to retrieve the last error detected and current state of decoding a crankshaft wheel input.

PAN_RC_Tpan_get_crank_wheel_sync_point_data

Function to retrieve information about the last successfully decoded crankshaft wheel sync point.

PAN_RC_Tpan_set_crank_wheel_sync_point_data

Function to provide information about the next crank region to the ECU.

PAN_RC_Tpan_get_crank_secondary_phase

Function to retrieve the phase angle of a secondary crankshaft wheel relative to the primary wheel.

PAN_RC_Tpan_get_crank_pin_state

Function to read the immediate digital state of a crankshaft wheel input pin.

PAN_RC_Tpan_config_cam_wheel

Function to configure a camshaft trigger wheel input channel.

PAN_RC_Tpan_get_cam_wheel_movement

Function to determine whether a camshaft wheel is moving or not.

PAN_RC_Tpan_get_cam_wheel_teeth_angles

Function to retrieve the measured angles of camshaft wheel teeth (rising edges, falling edges or both).

PAN_RC_Tpan_get_cam_pin_state

Function to reads the immediate digital state of a camshaft wheel input pin.

PAN_RC_Tpan_config_engine

Function to specify information about the engine configuration.

PAN_RC_Tpan_get_engine_cyl

Function to retrieve the current cylinder identifier.

PAN_RC_Tpan_get_engine_angle

Function to retrieve the current engine angle.

PAN_RC_Tpan_get_engine_tooth

Function to retrieve the current engine tooth identifier from the primary crankshaft position.

PAN_RC_Tpan_get_engine_speed_per_cyl

Function to calculate the rotational speed of the engine measured between two adjacent cylinder TDC-calculation events.

PAN_RC_Tpan_get_engine_speed_per_rev

Function to calculate the rotational speed of the engine measured over the last two primary crankshaft revolutions.

PAN_RC_Tpan_get_engine_speed_per_tooth

Function to calculate the rotational speed of the engine measured over the last two primary crankshaft teeth.

PAN_RC_Tpan_get_engine_speed_tr_abs

Function to calculate the rotational speed of the engine measured between crank teeth relative to the first primary crank tooth (for the engine cycle).

PAN_RC_Tpan_get_engine_speed_tr_rel

Function to calculate the rotational speed of the engine measured between crank teeth relative to a cylinder's TDC-firing angle.

PAN_RC_Tpan_get_engine_sync

Function to retrieve the current engine synchronisation mode.

PAN_RC_Tpan_declare_engine_sync

Function to declare synchronisation with the overall engine position.

PAN_RC_Tpan_lose_engine_sync

Function to force loss of engine synchronisation.

PAN_RC_Tpan_config_injectors

Function to configure injector channels and drive type.

PAN_RC_Tpan_config_injector

Function to configure a single injector.

BOOLpan_injection_config_successful

Function to discover if injection configuration was successful.

PAN_RC_Tpan_config_injectors_comp_di

Function to configure the volume conversion for direct injection.

PAN_RC_Tpan_set_injection_comp_frp_di

Function to override the fuel rail pressure input.

PAN_RC_Tpan_config_injections_di

Function to configure constraints for direct injection.

PAN_RC_Tpan_set_injection_di

Function to request injections for a given injector.

PAN_RC_Tpan_set_injection_di_dd

Function to request injections for a given injector.

PAN_RC_Tpan_get_injection_di_setpoint

Function to read back direct injection parameters for a given injector.

PAN_RC_Tpan_get_injection_di_feedback

Function to retrieve direct injection feedback information for a given injector.

PAN_RC_Tpan_set_initial_injection_pi

Function to specify the duration of the initial injection (the priming fuel pulse).

PAN_RC_Tpan_set_injection_pi

Function to set the injector pulse schedule for a cylinder (angle-duration).

PAN_RC_Tpan_update_injection_pi

Function to update a cylinder's injector pulse schedule (angle-duration).

PAN_RC_Tpan_get_injection_pi_setpoint

Function to read back port injection parameters for a given injector.

PAN_RC_Tpan_get_injection_pi_feedback

Function to retrieve port injection feedback information for a given injector/cylinder.

PAN_RC_Tpan_config_knock

Function to configure the parameters used to sample a knock sensor.

PAN_RC_Tpan_get_knock_feedback

Function to retrieve the result of the last processed knock signal for a cylinder.

PAN_RC_Tpan_set_knock_window

Function to schedule the angular region used to process a knock sensor signal for a cylinder.

PAN_RC_Tpan_set_knock_filter_hip901x

Function to update the scheduled knock signal filtering parameters for a cylinder for the HIP901x family of engine knock signal processors.

PAN_RC_Tpan_convert_knock_filter_hip901x_values

Convert real values for HIP901x filter values into enumeration values.

PAN_RC_Tpan_config_sparks

Function to configure a set of spark channels for running an engine.

PAN_RC_Tpan_set_spark

Function to update the requested schedule of spark pulses for one spark channel.

BOOLpan_spark_config_successful

Function to discover if spark configuration was successful.

PAN_RC_Tpan_get_spark_feedback

Function to retrieve spark feedback information for a given cylinder.

6.8.2. Interface detail

6.8.2.1.  Enumerations

6.8.2.1.1. PAN_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some angular feature (PAN) functions.

Enumerations:
PAN_RC_OK

Return code if everything progressed as expected.

PAN_RC_SW_ERROR

Return code if an internal error occurred which was the result of a software error.

PAN_RC_HW_ERROR

Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PAN_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PAN_RC_CLIPPED_ARGS

Return code if at least one of the arguments was clipped to its valid range.

PAN_RC_SDM_ALLOC_ERROR

Return code if could not allocate eTPU SDM for function (internal error).

PAN_RC_BAD_IO_CHAN

Return code if a given I/O channel cannot be used.

PAN_RC_ENGINE_NOT_CONFIGURED

Return code if basic engine configuration hasn't happened yet.

PAN_RC_CRANK_NOT_CONFIGURED

Return code if basic crank configuration hasn't happened yet.

PAN_RC_CAM_NOT_CONFIGURED

Return code if basic cam configuration hasn't happened yet.

PAN_RC_INJ_NOT_CONFIGURED

Return code if basic injection output configuration hasn't happened yet.

PAN_RC_SPARK_NOT_CONFIGURED

Return code if basic spark output configuration hasn't happened yet.

PAN_RC_ANGULAR_AD_NOT_CONFIGURED

Return code if basic angular analogue input configuration hasn't happened yet.

PAN_RC_ENGINE_NOT_SYNCED

Return code if engine sync hasn't happened yet.

PAN_RC_CRANK_NOT_SYNCED

Return code if crank sync hasn't happened yet.

PAN_RC_CAM_NOT_SYNCED

Return code if cam sync hasn't happened yet.

PAN_RC_CAM_DATA_UNAVAILABLE

Return code if cam data is unavailable.

PAN_RC_CAM_WINDOW_CONFIG_INVALID

Return code if the cam window is defined across an engine gap.

PAN_RC_CAM_WINDOW_TOO_WIDE

Return code if the cam window too large.

PAN_RC_CONFIGURATION_INCOMPLETE

Return code if basic engine configuration hasn't happened yet.

PAN_RC_CONFIG_MISMATCH

Return code if there is a configuration mismatch, e.g., the number of injectors != the number of cylinders configured or the primary crank wheel required by the injection functionality has not been configured.

PAN_RC_BAD_AXIS

Return code if an axis is not monotonically incrementing as expected.

PAN_RC_ANGULAR_SAMPLE_TOO_FAR

Return code if one of the angular A/D sample angles is too far from the TDC calculation point.

PAN_RC_ENGINE_SPEED_DATA_INCOMPLETE

Return code if the data used to calculate engine speed is incomplete.

PAN_RC_INVALID

An invalid value, used to when indicated that a valid value has not yet been set.

PAN_RC_KNOCK_NOT_CONFIGURED

Return code if knock configuration hasn't happened yet or has not been successful.

6.8.2.2.  Data types

6.8.2.2.1. PAN_DEVICE_KNOCK_T
Definition:

typedef U16 PAN_DEVICE_KNOCK_T

Description:

This declares a type with enough value range to represent all logical knock devices for all targets.

See pio.h for a list of relevant devices for a specific target.

6.8.2.2.2. PAN_LCHAN_KNOCK_T
Definition:

typedef U16 PAN_LCHAN_KNOCK_T

Description:

This declares a type with enough value range to represent all logical knock devices for all targets.

See pio.h for a list of relevant devices for a specific target.

6.8.2.3.  Functions

6.8.2.3.1. pan_config_angular_ad_var()
Definition:

PAN_RC_T pan_config_angular_ad_var(
   PAX_LCHAN_T      panf_lchan,
   PIO_AD_GROUP_T   panf_group);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure an analogue input channel to sample on an angular basic.

The application must call this function for each input channel to be sampled on an angular basis. Without configuration, other angular analogue input related functions will not operate.

The function identifies the analogue input channel to be sampled. The ECU samples this analogue input channel across the engine cycle, buffering the conversions. The results relative to a cylinder's TDC-firing angle can be retrieved by calling either pan_get_angular_ad_avg_var() or pan_get_angular_ad_samples_var(). The results relative to crank zero degrees can be retrieved by calling pan_get_angular_ad_avg_abs() or pan_get_angular_ad_samples_abs().

The function associates the channel with a sample group. Other analogue input functions must refer to the same group name to access the analogue input channel configured by this function.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): panf_lchan

The channel number of the analogue input channel to be read at an angular rate. Use the macros included by the pio.h file, of the form PIO_AIN_[NAME].

Arg (data in): panf_group

The group number to configure for the angular input channel. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Return:

6.8.2.3.2. pan_get_angular_ad_avg_var()
Definition:

PAN_RC_T pan_get_angular_ad_avg_var(
   U8                   panf_cyl,
   PIO_AD_GROUP_T       panf_group,
   S16                 *panf_adc,
   U8                   panf_num_sample,
   volatile const F32  *panf_sample_angles);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read the average of sampling an analogue input channel relative to the TDC-firing angle of a cylinder at specific angles.

The application configures the analogue input channels to sample on an angular basis by calling the pan_config_angular_ad_var() function during application initialisation.

During application run-time, this function retrieves an average of a set of sampled analogue input conversions taken by the ECU relative to the TDC-firing angle of a cylinder. The application can vary the sample angles during application run-time.

The angular samples are buffered by the ECU when the TDC-calculation event occurs. See the earlier section "Engine TDC-firing events" for a definition of TDC-calculation. If the angles at which the samples are taken are both before and after the TDC-calculation angle, then those samples prior to the TDC-calculation angle will be from the current cycle, but the angles after the TDC-calculation angle will be from one cycle earlier.

The sample angles are resolved to the closest sample (samples occur every 6 degrees throughout the engine cycle).

Arg (data in): panf_cyl

The cylinder to retrieve the samples for.

Arg (data in): panf_group

The group number to read the angular input value for the given cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc

Pointer to the averaged conversion result for the angular analogue input.
Cannot be NULL.
Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample

The number of elements in panf_sample_angles
Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles

An array of angle offsets relative to TDC-firing angle per cylinder. A positive value indicates a sample after TDC-firing.
Cannot be NULL.
Range: (-720, 720) degrees

Return:

6.8.2.3.3. pan_get_angular_ad_samples_var()
Definition:

PAN_RC_T pan_get_angular_ad_samples_var(
   U8                   panf_cyl,
   PIO_AD_GROUP_T       panf_group,
   S16                 *panf_adc,
   U8                   panf_num_sample,
   volatile const F32  *panf_sample_angles);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read the individual samples taken from an analogue input channel relative to the TDC-firing angle for the given cylinder at specific angles.

The application configures the analogue input channels to sample on an angular basis by calling the pan_config_angular_ad_var() function during application initialisation.

During application run-time, this function retrieves a set of sampled analogue input conversions taken by the ECU relative to the TDC-firing angle of a cylinder. The application can vary the sample angles during application run-time.

The angular samples are buffered by the ECU when the TDC-calculation event occurs. See the earlier section "Engine TDC-firing events" for a definition of TDC-calculation. If the angles at which the samples are taken are both before and after the TDC-calculation angle, then those samples prior to the TDC-calculation angle will be from the current cycle, but the angles after the TDC-calculation angle will be from one cycle earlier.

The sample angles are resolved to the closest sample (samples occur every 6 degrees throughout the engine cycle).

Arg (data in): panf_cyl

The cylinder to retrieve the samples for.

Arg (data in): panf_group

The group number to read the angular input value for the current cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc

Pointer to an array where this function stores the conversion results for the angular analogue input channel. The array must have size panf_num_sample or larger. Cannot be NULL.
Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample

The number of elements in panf_sample_angles
Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles

An array of angle offsets relative to TDC-firing angle per cylinder. A positive value indicates a sample after TDC-firing.
Cannot be NULL.
Range: (-720, 720) degrees

Return:

6.8.2.3.4. pan_get_angular_ad_avg_abs()
Definition:

PAN_RC_T pan_get_angular_ad_avg_abs(
   PIO_AD_GROUP_T       panf_group,
   S16                 *panf_adc,
   U8                   panf_num_sample,
   volatile const F32  *panf_sample_angles);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read the average of sampling an analogue input channel relative to crank zero degrees at specific angles.

The application configures the analogue input channels to sample on an angular basis by calling the pan_config_angular_ad_var() function during application initialisation.

During application run-time, this function retrieves an average of a set of sampled analogue input conversions taken by the ECU relative to crank zero degrees. The application can vary the sample angles during application run-time.

The angular samples are buffered by the ECU when the TDC-calculation event occurs. See the earlier section "Engine TDC-firing events" for a definition of TDC-calculation. If the angles at which the samples are taken are both before and after the TDC-calculation angle, then those samples prior to the TDC-calculation angle will be from the current cycle, but the angles after the TDC-calculation angle will be from one cycle earlier.

The sample angles are resolved to the closest sample (samples occur every 6 degrees throughout the engine cycle).

Arg (data in): panf_group

The group number to read the angular input value for the given angles. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc

Pointer to the averaged conversion result for the angular analogue input.
Cannot be NULL.
Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample

The number of elements in panf_sample_angles
Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles

An array of angle offsets relative to TDC-firing angle per cylinder. A positive value indicates a sample after TDC-firing.
Cannot be NULL.
Range: (-720, 720) degrees

Return:

6.8.2.3.5. pan_get_angular_ad_samples_abs()
Definition:

PAN_RC_T pan_get_angular_ad_samples_abs(
   PIO_AD_GROUP_T       panf_group,
   S16                 *panf_adc,
   U8                   panf_num_sample,
   volatile const F32  *panf_sample_angles);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read the individual samples taken from an analogue input channel relative to crank zero degrees at specific angles.

The application configures the analogue input channels to sample on an angular basis by calling the pan_config_angular_ad_var() function during application initialisation.

During application run-time, this function retrieves a set of sampled analogue input conversions taken by the ECU relative to crank zero degrees. The application can vary the sample angles during application run-time.

The angular samples are buffered by the ECU when the TDC-calculation event occurs. See the earlier section "Engine TDC-firing events" for a definition of TDC-calculation. If the angles at which the samples are taken are both before and after the TDC-calculation angle, then those samples prior to the TDC-calculation angle will be from the current cycle, but the angles after the TDC-calculation angle will be from one cycle earlier.

The sample angles are resolved to the closest sample (samples occur every 6 degrees throughout the engine cycle).

Arg (data in): panf_group

The group number to read the angular input value for the current cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc

Pointer to an array where this function stores the conversion results for the angular analogue input channel. The array must have size panf_num_sample or larger.
Cannot be NULL.
Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample

The number of elements in panf_sample_angles
Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles

An array of angle offsets relative to TDC-firing angle per cylinder. A positive value indicates a sample after TDC-firing.
Cannot be NULL.
Range: (-720, 720) degrees

Return:

6.8.2.3.6. pan_config_angular_output()
Definition:

PAN_RC_T pan_config_angular_output(
   PDX_LCHAN_T                     panf_ang_out_channel,
   PIO_ANG_OUTPUT_MODE_T           panf_ang_out_mode,
   PIO_ANG_OUTPUT_STALL_ACTION_T   panf_ang_out_stall_action);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to configure a generic angular output.

This function is used to configure a channel to be a generic angular output.

Warning

The function must be called during application initialisation and never during application run-time.

Arg (data in): panf_ang_out_channel

The output channel. Use the macros included by the pio.h file, of the form PIO_ANGOT_[NAME].

Arg (data in): panf_ang_out_mode

The angular output mode, angle-angle or angle-time. Use the PIO_ANG_OUTPUT_MODE_T macros included by the pio.h file.

Arg (data in): panf_ang_out_stall_action

The action to take on a stall. This also specifies the initial output state. Use the PIO_ANG_STALL_ACTION_T macros included by the pio.h file.

Return:

6.8.2.3.7. pan_set_angular_output()
Definition:

PAN_RC_T pan_set_angular_output(
   PDX_LCHAN_T                              panf_ang_out_channel,
   U32                                      panf_ang_out_cyl_id,
   PIO_ANG_OUTPUT_ACTION_T                  panf_ang_out_action_now,
   U8                                       panf_ang_out_num_pulses,
   volatile const PIO_ANG_OUTPUT_ACTION_T  *panf_ang_out_start_action,
   volatile const PIO_ANG_OUTPUT_ACTION_T  *panf_ang_out_end_action,
   volatile const F32                      *panf_ang_out_start_angle,
   volatile const F32                      *panf_ang_out_duration,
   BOOL                                     panf_ang_out_allow_end_mod,
   BOOL                                     panf_ang_out_allow_cycle_repeat,
   F32                                      panf_ang_out_min_off_time);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to control a generic angular output.

This function is used to control a generic angular output.

Note

pan_config_angular_output() must be called during application initialisation in order to use this functionality.

Arg (data in): panf_ang_out_channel

The output channel. Use the macros included by the pio.h file, of the form PIO_ANGOT_[NAME].

Arg (data in): panf_ang_out_cyl_id

This parameter specifies how to interpret the start angle. If the value passed here is zero then the value passed in panf_ang_out_start_angle is interpreted as an angle relative to crank zero degrees. If the value passed is a valid cylinder number (starting from 1) then the start angle is intepreted relative to that cylinder's TDC angle.
Range: 0 or [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_ang_out_action_now

The action to be taken with immediate effect. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file. It is expected that this will usually be set to no change, which makes it effectively invisible. However, this allows an application to drive an output at an approximate periodic rate (e.g. called from a periodic task) when crank sync has not be attained.

Arg (data in): panf_ang_out_num_pulses

The number of elements in the arrays containing the pulse start angles, durations, start actions, and end actions. Each array must be of the same length. Range: [1, PIO_NUM_ANG_OUTPUT_MAX_PULSES]

Arg (data in): panf_ang_out_start_action

An array of panf_ang_out_num_pulses actions to be taken at the start of each pulse event. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file.

Arg (data in): panf_ang_out_end_action

An array of panf_ang_out_num_pulses actions to be taken at the end of each pulse event. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file.

Arg (data in): panf_ang_out_start_angle

An array of panf_ang_out_num_pulses angles at which each pulse event starts. This can be crank-relative or TDC-firing-relative depending on the value of panf_ang_out_cyl_id. Positive angles are interpreted as after TDC-firing. The angle is folded to the range [0 720] degrees or [0 360] degrees as appropriate, and an event is then scheduled for the next such angle to occur. For a two-stroke engine in either half or full engine synchronisation mode, the range [0 360] degrees is used. For a four-stroke engine in half engine synchronisation mode, the range [0 360] degrees is used. For a four-stroke engine in full engine synchronisation mode, the range [0 720] degrees is used.
Range: [-720, 720] degrees

Arg (data in): panf_ang_out_duration

An array of panf_ang_out_num_pulses durations of each event which can be either an angle or a time, depending on the mode of operation, as specified by the panf_ang_out_mode parameter in a prerequisite call to pan_config_angular_output(). A duration of zero is allowed, in which case the pulse is skipped, and the next non-zero pulse is used.
Range: [0, 360000] degrees or [0, 2000] milliseconds

Arg (data in): panf_ang_out_allow_end_mod

A flag used to specify whether or not the event currently underway at the same index in the array of events should be adjusted according to the new input data. If this function is called after an event has started and before it has finished, then if this flag is set the end of the event will be adjusted to reflect the new duration and end action. If the duration would place the end point in the past, then the event is terminated immediately. Note that in this case, if any immediate action has been requested, the immediate action will be closely followed by the end action.
On the other hand, if this function is called while an event is underway and this flag is clear, then the current event is not affected, and the data is used to schedule a subsequent event once the current event is over. Any immediate action is still honoured, however.
Range: FALSE or TRUE

Arg (data in): panf_ang_out_allow_cycle_repeat

A flag used to specify whether or not the schedule of pulses should be repeated automatically in the next engine cycle using the same values.
Range: FALSE or TRUE

Arg (data in): panf_ang_out_min_off_time

This parameter can be used to mandate a minimum time between pulse events after the end action of one event and the start action of the next event. Note a value out of range will be clipped at the endpoints.
Range: [PIO_TIME_ANG_OUTPUT_MIN_OFF_TIME_MIN, PIO_TIME_ANG_OUTPUT_MIN_OFF_TIME_MAX] milliseconds

Return:

6.8.2.3.8. pan_config_crank_wheel_mtg()
Definition:

PAN_RC_T pan_config_crank_wheel_mtg(
   PDX_LCHAN_T              panf_lchan,
   PIO_CRANK_WHEEL_T        panf_wheel,
   PIO_CRANK_WHEEL_SYNC_T   panf_wheel_sync_scheme,
   U16                      panf_teeth_per_crank_rev,
   S16                      panf_teeth_in_sync_point,
   PIO_CRANK_TOOTH_EDGE_T   panf_tooth_edge);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure a crankshaft wheel encoder input channel.

The application must call this function during application initialisation for each input channel to be attached to a crankshaft trigger wheel. The function identifies the teeth arrangement for one crankshaft sensor input, including the number of teeth, sync points and their type.

The function supports crank trigger wheels with missing teeth or an extra tooth. Common crank trigger wheels, such as 12+1 and 36-1 are supported:

As are less common wheel patterns, such as 24-1-1-1 or 36-1-2-3:

Where supported, the application can call the pan_config_crank_wheel_mtg_ext() function to further configure how the crankshaft signal is processed for electrical noise, sync point detection and more.

See the earlier section "Crankshaft position sensor processing" for a general description of how the ECU processes different crank sensor signals, and see the ECU's Technical Specification for details specific to an ECU. In particular, note that some ECUs (such as the M670) invert the crankshaft sensor signal in circuitry, which must be taken in to account with the panf_tooth_edge parameter. Please see the crank sensor input section of the ECU's Technical Specification to determine polarity settings. The ECU does not diagnose an inverted crank signal.

The block makes a distinction between primary and secondary crankshaft encoding wheels. A primary wheel can drive the angle clock, as described in the earlier section "Angle clock". A secondary wheel cannot drive the angle clock but can be used to determine phasing between the primary wheel and itself.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any other crank related functions.

Arg (data in): panf_lchan

The channel number of the digital input channel to be used for the crank input.
Use the macros included by the pio.h file, of the form PIO_DIN[NAME].

Arg (data in): panf_wheel

The wheel to configure for the crank input channel.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data in): panf_wheel_sync_scheme

The synchronisation scheme to use when syncing to the crank wheel.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL_SYNC[NAME].

Arg (data in): panf_teeth_per_crank_rev

The number of teeth on the crankshaft encoding wheel, plus any missing teeth but ignoring an extra teeth. For example, use 60 for a 60-2 wheel, 36 for a 36-1-1 wheel, 12 for a 12+1 wheel, and 12 for a 12+1+1 wheel. Range: [PIO_CRANK_TEETH_MIN, PIO_CRANK_TEETH_MAX] teeth

Arg (data in): panf_teeth_in_sync_point

The number of teeth involved in one of the sync points of the crankshaft wheel encoder. Negative integers indicate missing teeth, positive integers represent extra teeth.
Range: [PIO_CRANK_EXTRA_MIN, PIO_CRANK_EXTRA_MAX] extra teeth
Range: [PIO_CRANK_MISSING_MIN, PIO_CRANK_MISSING_MAX] missing teeth

Arg (data in): panf_tooth_edge

The polarity of the input signal to be used as the tooth indication when decoding the crankshaft wheel. Note that this polarity refers to the processed signal to the microprocessor, and therefore its meaning with respect to the polarity on the external pin varies between target ECUs. Use the enum included by the pio.h file, of the form PIO_CRANK_TOOTH_EDGE[NAME].

  • DEFAULT uses the default edge for the ECU.
    With this choice, for a Hall-effect signal, a falling edge is the tooth indication. For a VR signal, the tooth indication always corresponds to the zero crossing point where the positive signal falls below the negative signal. Note that for a VR signal, the default selection should always be preferred, since the other edge of the processed signal will correspond to the arming point (when the voltage rises above a threshold that depends on the previous peak values) and is less accurate as a reference point. Since a variable reluctance sensor typically has two output signals, one can always ensure that the positive-to-negative zero crossing point matches the desired tooth indication by swapping the connections if necessary.

  • RISING sets the edge to rising edge detection.
    For the M220 and M670 targets, rising is the same as default. For all other targets, rising is the inverse of default.

  • FALLING sets the edge to falling edge detection.
    For the M220 and M670 targets, falling is the inverse of default. For all other targets, falling is the same as default.

Return:

6.8.2.3.9. pan_config_crank_wheel_mtg_ext()
Definition:

PAN_RC_T pan_config_crank_wheel_mtg_ext(
   PIO_CRANK_WHEEL_T   panf_wheel,
   U8                  panf_skip_crank_teeth,
   F32                 panf_first_tooth_timeout,
   F32                 panf_ratio_sp_short_long,
   F32                 panf_ratio_sp_long_short,
   F32                 panf_ratio_across_sp_nr_window,
   F32                 panf_ratio_across_sp_sd_window,
   F32                 panf_ratio_after_sp_nr_window,
   F32                 panf_ratio_after_sp_sd_window,
   F32                 panf_ratio_normal_nr_window,
   F32                 panf_ratio_normal_sd_window,
   F32                 panf_ratio_timeout_nr_window,
   F32                 panf_ratio_timeout_sd_window);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure the extended parameters for decoding a crankshaft trigger wheel, including missing tooth detection, noise rejection and stall detection.

The function details the missing tooth detection, noise rejection and stall detection parameters for decoding one or more crankshaft sensor inputs. A detailed explanation of the parameters is given in the earlier section "Crank decoding".

If the application does not call this function then the ECU uses a set of default parameters. See the argument list below for the defaults.

The application must have a matching call to pan_config_crank_wheel_mtg() otherwise this function has no effect.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): panf_wheel

The wheel to configure for the crank input channel.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data in): panf_skip_crank_teeth

The number of processed teeth edges to ignore when the ECU initialises. Used to ignore noise when the ECU electronics power up. A value of zero disables this functionality.
Default: 10
Range: [0, 255] teeth

Arg (data in): panf_first_tooth_timeout

When crank synchronisation has not been achieved or is lost, this parameter defines the maximum length of time between teeth used to start looking for crank synchronisation. In effect, this defines the minimum speed the crankshaft must be turning before the library starts to look for crank synchronisation.
Default: 60
Range: [0, 1000] milliseconds

Arg (data in): panf_ratio_sp_short_long

The ratio between the tooth before the missing region and the missing region itself, used by the library determine crank synchronisation. See the user guide for further details.
Default: 0.7
Range: [0, 1) unitless

Arg (data in): panf_ratio_sp_long_short

The ratio between the tooth after the missing region and the missing region itself, used by the library determine crank synchronisation. See the user guide for further details.
Default: 0.7
Range: [0, 1) unitless

Arg (data in): panf_ratio_across_sp_nr_window

The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies only to the last tooth before the missing tooth region. See the user guide for further details.
Default: 0.3
Range: [0, 1) unitless

Arg (data in): panf_ratio_across_sp_sd_window

The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies only to the last tooth before the missing tooth region. See the user guide for further details.
Default: 0.7
Range: [0, 4) unitless

Arg (data in): panf_ratio_after_sp_nr_window

The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies only to the first tooth after the missing tooth region. See the user guide for further details.
Default: 0.3
Range: [0, 1) unitless

Arg (data in): panf_ratio_after_sp_sd_window

The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies only to the first tooth after the missing tooth region. See the user guide for further details.
Default: 0.7
Range: [0, 4) unitless

Arg (data in): panf_ratio_normal_nr_window

The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies to teeth that do no occur immediately before or after the missing tooth region. See the user guide for further details.
Default: 0.3
Range: [0, 1) unitless

Arg (data in): panf_ratio_normal_sd_window

The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies to teeth that do no occur immediately before or after the missing tooth region (normal teeth). See the user guide for further details.
Default: 0.7
Range: [0, 4) unitless

Arg (data in): panf_ratio_timeout_nr_window

The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies to the situation where the previous normal tooth did not arrive in time and crank stall is being considered. See the user guide for further details.
Default: 0.3
Range: [0, 1) unitless

Arg (data in): panf_ratio_timeout_sd_window

The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies to the situation where the previous normal tooth did not arrive in time and crank stall is being considered. See the user guide for further details.
Default: 0.7
Range: [0, 4) unitless

Return:
  • PAN_RC_OK if successful

  • one of the other enumerations otherwise

6.8.2.3.10. pan_get_crank_wheel_angle()
Definition:

PAN_RC_T pan_get_crank_wheel_angle(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_valid,
   F32                *panf_crank_angle);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current crankshaft wheel angle.

The function retrieves the current angle of the crankshaft trigger wheel, relative to crank zero degrees (see the earlier section "Crankshaft zero degrees").

For the primary crankshaft trigger wheel input, the retrieved value is taken from the angle clock, which is an estimate of crank decoding and position identification process (see the earlier section "Angle clock" for more). For a secondary crankshaft trigger wheel input, the retrieved value is updated each tooth (thus with much lower resolution than the angle taken from the primary crank input).

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_crank_angle is valid. Written to zero when the ECU cannot provide a crank angle (for instance, the ECU has not gained region synchronisation with the crankshaft trigger wheel). Written to one when the panf_crank_angle value is valid.
Cannot be NULL.

Arg (data out): panf_crank_angle

Pointer to where the current crank angle will be written. If the crank wheel is primary, then the value is taken from the angle clock (which is itself an estimate of the wheel position between teeth). If the crank wheel is secondary, then the value is taken from the last decoded tooth (and therefore with reduced resolution).
Cannot be NULL.
Range: [0, 360) degrees
Resolution: at least 0.1 degrees for the primary crank wheel
Resolution: per tooth for secondary crank wheels

Return:

6.8.2.3.11. pan_get_crank_wheel_movement()
Definition:

PAN_RC_T pan_get_crank_wheel_movement(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_crank_movement);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to determine if the crankshaft wheel is moving or not.

The function retrieves whether the crankshaft wheel is moving or not. The ECU continually monitors the crankshaft wheel input signal looking for tooth edges. If the crankshaft signal decoding state machine has reached state Detect AB or higher, then the ECU declares the wheel as moving. See the earlier section "Crank decoding" for a description of the crank decoding state machine.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_movement

Pointer to the boolean result of whether the crank is moving.
Cannot be NULL.

Return:

6.8.2.3.12. pan_get_crank_speed_per_rev()
Definition:

PAN_RC_T pan_get_crank_speed_per_rev(
   PIO_CRANK_WHEEL_T   panf_wheel,
   F32                *panf_crank_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to determine the speed of the crankshaft wheel on a per revolution basis.

The function calculates the speed of the crankshaft wheel from the time taken to complete one revolution. The revolution starts at crank zero degrees and lasts 360 degrees, until crank zero degrees occurs again.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_speed

Pointer to where the current crank speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.13. pan_get_crank_speed_per_tooth()
Definition:

PAN_RC_T pan_get_crank_speed_per_tooth(
   PIO_CRANK_WHEEL_T   panf_wheel,
   F32                *panf_crank_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to determine the speed of the crank wheel on a per tooth basis.

The function calculates the speed of the crankshaft wheel on the time taken between the last two detected crank teeth. When calculating a speed across the a missing tooth sync point, the block adjusts the speed as if there were physical teeth present. Extra sync point teeth are ignored.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_speed

Pointer to where the current crank speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.14. pan_get_crank_wheel_sync()
Definition:

PAN_RC_T pan_get_crank_wheel_sync(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_crank_sync);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the synchronisation state for a crankshaft wheel.

The function retrieves whether the ECU has synchronised to the crankshaft wheel or not. The ECU continually monitors the crankshaft wheel input signal looking for tooth edges. If the crankshaft signal decoding state machine has reached state Count teeth or higher, then the ECU has synchronisation to the wheel. See the earlier section "Crank decoding" for a description of the crank decoding state machine.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_sync

Pointer to the boolean result of whether the crank is synced.
Cannot be NULL.

Return:

6.8.2.3.15. pan_get_crank_wheel_tooth_region()
Definition:

PAN_RC_T pan_get_crank_wheel_tooth_region(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_valid,
   U16                *panf_crank_tooth);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current crankshaft region tooth identifier.

The function retrieves the current region tooth identifier of the crankshaft wheel. See the earlier section "Crank tooth identification" for a description of crank tooth identifiers.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_crank_tooth is valid. Written to FALSE when the ECU cannot provide a crank tooth (for instance, the ECU has not synchronised to the crankshaft wheel), written to TRUE when parameter panf_crank_tooth is valid.
Cannot be NULL.

Arg (data out): panf_crank_tooth

Pointer to where the current tooth will be written. The written identifying tooth number of the last detected tooth of the crankshaft wheel. The reported identifier is adjusted by the tooth offset supplied to the pan_declare_engine_sync() function.
Cannot be NULL.
Range: [1, PIO_CRANK_TEETH_MAX] teeth

Return:

6.8.2.3.16. pan_get_crank_wheel_tooth()
Definition:

PAN_RC_T pan_get_crank_wheel_tooth(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_valid,
   U16                *panf_crank_tooth);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current crankshaft revolution tooth identifier.

The function retrieves the current revolution tooth identifier of the crankshaft wheel. See the earlier section "Crank tooth identification" for a description of crank tooth identifiers.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_crank_tooth is valid. Written to FALSE when the ECU cannot provide a crank tooth (for instance, the ECU has not synchronised to the crankshaft wheel), written to TRUE when parameter panf_crank_tooth is valid.
Cannot be NULL.

Arg (data out): panf_crank_tooth

Pointer to where the current tooth will be written. The written identifying tooth number of the last detected tooth of the crankshaft wheel. The reported identifier is adjusted by the tooth offset supplied to the pan_declare_engine_sync() function.
Cannot be NULL.
Range: [1, PIO_CRANK_TEETH_MAX] teeth

Return:

6.8.2.3.17. pan_get_crank_wheel_decoding_state()
Definition:

PAN_RC_T pan_get_crank_wheel_decoding_state(
   PIO_CRANK_WHEEL_T         panf_wheel,
   PIO_CRANK_WHEEL_STATE_T  *panf_state,
   U32                      *panf_error_bitmap);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the last error detected and current state of decoding a crankshaft wheel input.

The function retrieves the current state of decoding the crankshaft sensor signal. A detailed description of the decoding state machine can be found in the earlier section "Crank decoding". For reference, the decoding state values are:

The function retrieves the last detected error when processing the crank signal, indicating for example, that crank region synchronisation was lost due to a timeout between teeth arrival times (stall) or that crank region synchronisation was lost due to the wrong number of counted teeth between sync points.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_state

Pointer to where the current decoded state of the crank wheel will be written.
Cannot be NULL.

Arg (data out): panf_error_bitmap

Pointer to where an error bitmap about decoding the crank wheel will be written. When this function is called, the bitmap is cleared to zero. The bitmap is the summation of the values given below. For instance, the error value 40 means the decoding state machine lost synchronisation with the crank signal just before a sync point.
Cannot be NULL.

Value Description
0 No error detected whilst decoding.
1 An error internal to decoding state machine occurred. Please contact
2 An error internal to decoding state machine occurred. Please contact
4 An error internal to decoding state machine occurred. Please contact
8 The crankshaft has stalled (the time between consecutive teeth is sufficiently low that the ECU cannot tell if the crankshaft is moving or not). See the earlier section
16 The crankshaft has stalled whilst waiting for a tooth not immediately before, during, or immediately after the sync point.
32 The crankshaft has stalled whilst waiting for the tooth immediately before the sync point.
64 The crankshaft has stalled whilst waiting for the tooth immediately after the sync point.
128 The decoding state machine has lost region synchronisation because of a tooth found in a
256 The decoding state machine has lost region synchronisation because the extra tooth of a sync point was not found. This error condition can occur if the wrong sync point type has been selected when calling
512 The decoding state machine has lost region synchronisation because the application requested loss of sync by calling

Return:

6.8.2.3.18. pan_get_crank_wheel_sync_point_data()
Definition:

PAN_RC_T pan_get_crank_wheel_sync_point_data(
   PIO_CRANK_WHEEL_T   panf_wheel,
   U16                *panf_region_tooth_count,
   U32                *panf_period_before,
   U32                *panf_period_sync_point,
   U32                *panf_period_after);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve information about the last successfully decoded crankshaft wheel sync point.

The <blk:ref_this /> block retrieves information about the last successfully decoded crankshaft wheel sync point. This includes the number of counted teeth for that region, and the A, B and a sync point timing. A description of what constitutes a crank region, a sync point and sync point timing, can be found in the earlier sections "Crank wheel sync points" and "Sync point detection".

The function can be used by the application to determine which region of the crankshaft wheel has been successfully decoded. For crankshaft wheels with more than one sync point, the application must provide details about the next crank region by calling the pan_set_crank_wheel_sync_point_data() function from the corresponding crank wheel crank-sync-point task. More details are provided in the earlier section "Maintaining crank synchronisation".

Note that for crankshaft wheels that have one sync point, the ECU will maintain synchronisation to the crank wheel using the decoding state machine without the need for the application to declare a crank-sync-point task or call the pan_get_crank_wheel_sync_point_data() or pan_set_crank_wheel_sync_point_data() functions.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_region_tooth_count

Pointer to where the number of teeth detected since the last sync point will be written.
Cannot be NULL.
Range: [3, PIO_CRANK_TEETH_MAX]

Arg (data out): panf_period_before

Pointer to where the A sync point duration is written.
Cannot be NULL.
Range: [1, 2000000] microseconds

Arg (data out): panf_period_sync_point

Pointer to where the B sync point duration is written.
Cannot be NULL.
Range: [1, 2000000] microseconds

Arg (data out): panf_period_after

Pointer to where the a sync point duration is written.
Cannot be NULL.
Range: [1, 2000000] microseconds

Return:

6.8.2.3.19. pan_set_crank_wheel_sync_point_data()
Definition:

PAN_RC_T pan_set_crank_wheel_sync_point_data(
   PIO_CRANK_WHEEL_T   panf_wheel,
   U16                 panf_teeth_to_sync_point,
   S16                 panf_teeth_in_sync_point);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to provide information about the next crank region to the ECU.

The function provides information about the next crank region to the ECU. This includes the number of expected teeth for that region (ignoring any extra teeth), and the number of teeth that represent the sync point. A description of what constitutes a crank region can be found in the earlier sections "Crank wheel sync points" and "Sync point detection".

The function is used maintain synchronisation to a crankshaft wheel when the wheel has more than one sync point. The application must read information about the previous crank region and sync point by calling the pan_get_crank_wheel_sync_point_data() function from the corresponding crank wheel crank-sync-point task. More details are provided in the earlier section "Maintaining crank synchronisation".

Note that for crankshaft wheels that have one sync point, the ECU will maintain synchronisation to the crank wheel using the decoding state machine without the need for the application to declare a crank-sync-point task or call the pan_get_crank_wheel_sync_point_data() or pan_set_crank_wheel_sync_point_data() functions.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_teeth_to_sync_point

The number of teeth for the next crank region.
Cannot be NULL.
Range: [3, PIO_CRANK_TEETH_MAX]

Arg (data out): panf_teeth_in_sync_point

The number of teeth involved in the sync point at the end of the next crank region. Negative integers indicate missing teeth, positive integers represent extra teeth.
Cannot be NULL.
Range: [PIO_CRANK_EXTRA_MIN, PIO_CRANK_EXTRA_MAX] extra teeth
Range: [PIO_CRANK_MISSING_MIN, PIO_CRANK_MISSING_MAX] missing teeth

Return:

6.8.2.3.20. pan_get_crank_secondary_phase()
Definition:

PAN_RC_T pan_get_crank_secondary_phase(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_valid,
   F32                *panf_phase);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to retrieve the phase angle of a secondary crankshaft wheel relative to the primary wheel.

The function provides the current phase angle of the specified secondary crankshaft wheel relative to the primary crankshaft wheel that generates the angle clock. The crankshaft trigger wheel pattern need not be the same for the primary and secondary inputs.

The ECU continuously monitors the primary and secondary crankshaft wheel signals. The ECU measures the phase on each tooth of a secondary crankshaft wheel, as the difference between the angle clock of the primary crankshaft wheel and the angle of the secondary crankshaft wheel tooth.

The phase angle is always a value between 0 degrees and 360 degrees and represents the secondary wheel angle minus the primary wheel angle, so that if the secondary wheel is 10 degrees in advance of the primary, it will return a value of 10, and if the primary wheel is 10 degrees in advance of the secondary it will return a value of 350.

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL_SECONDARY_[NAME].

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_phase is valid.
Cannot be NULL.

Arg (data out): panf_phase

Pointer to where the current phase angle, between the primary crank wheel and the wheel selected in the panf_wheel parameter, is written.
Cannot be NULL.
Range: [0, 360) degrees
Resolution: at least 0.1 degrees

Return:

6.8.2.3.21. pan_get_crank_pin_state()
Definition:

PAN_RC_T pan_get_crank_pin_state(
   PIO_CRANK_WHEEL_T   panf_wheel,
   BOOL               *panf_pin_state);

Supported targets:

M220-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read the immediate digital state of a crankshaft wheel input pin.

The function provides the instantaneous digital voltage level (high or low) seen at a crankshaft wheel input pin. Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).

Arg (data in): panf_wheel

The configured crank wheel to read.
Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_pin_state

The state of the crank pin is written through this pointer. Set to zero if the voltage level on the crankshaft wheel pin is low, set to one if the voltage level on the crank pin is high. Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).
Cannot be NULL.
Range: 0 or 1

Return:

6.8.2.3.22. pan_config_cam_wheel()
Definition:

PAN_RC_T pan_config_cam_wheel(
   PDX_LCHAN_T          panf_lchan,
   PIO_CAM_WHEEL_T      panf_wheel,
   U8                   panf_num_teeth,
   PIO_CAM_CAP_EDGE_T   panf_tooth_edge_capture);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure a camshaft trigger wheel input channel.

The application must call this function for each input channel to be attached to a camshaft trigger wheel during application initialisation. The function must be called for other camshaft related blocks to operate.

The function parameters identify the teeth arrangement for one camshaft sensor input, including the maximum expected number of teeth and which teeth edges to record. When the angle clock is running, the application can retrieve the cam wheel tooth record by calling the pan_get_cam_wheel_teeth_angles() function with a matching camshaft wheel input channel selection.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): panf_lchan

The channel number of the digital input channel to be used for the cam input.
Use the macros included by the pio.h file, of the form PIO_DIN[NAME].

Arg (data in): panf_wheel

The wheel to configure for the cam input channel.
Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data in): panf_num_teeth

The number of physical teeth on the cam wheel.
Range: [PIO_CAM_TEETH_MIN, PIO_CAM_TEETH_MAX] teeth

Arg (data in): panf_tooth_edge_capture

The processed tooth edges to capture, either rising, falling or both. Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).
Use the enum included by the pio.h file, of the form PIO_CAM_CAP_EDGE_T.

Return:

6.8.2.3.23. pan_get_cam_wheel_movement()
Definition:

PAN_RC_T pan_get_cam_wheel_movement(
   PIO_CAM_WHEEL_T   panf_wheel,
   BOOL             *panf_cam_movement);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to determine whether a camshaft wheel is moving or not.

The function retrieves whether the camshaft wheel is moving or not. The ECU continually monitors the camshaft wheel input signal looking for tooth edges. If a tooth edge (as defined by the documentation for function pan_config_cam_wheel())is detected within a timeout period (approximately 2 seconds), then the ECU declares the wheel as moving. Otherwise, the ECU assumes the wheel is stationary and not moving.

Arg (data in): panf_wheel

The configured cam wheel to read.
Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_cam_movement

Pointer to the boolean result of whether the cam is moving.
Written FALSE if the camshaft wheel input appears to have stopped (i.e., is below the frequency measurement threshold of approximately 0.5 Hz), and written TRUE if the camshaft wheel input appears to be moving.
Cannot be NULL.

Return:

6.8.2.3.24. pan_get_cam_wheel_teeth_angles()
Definition:

PAN_RC_T pan_get_cam_wheel_teeth_angles(
   PIO_CAM_WHEEL_T   panf_wheel,
   F32              *panf_angles,
   U8               *panf_edges_type,
   U32              *panf_edges_last_cycle,
   U32              *panf_edges_this_cycle,
   BOOL             *panf_timeout,
   U32              *panf_count_timeout,
   U32              *panf_count_empty,
   U32              *panf_count_extra);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the measured angles of camshaft wheel teeth (rising edges, falling edges or both).

The function retrieves information about the processed camshaft wheel signal. The ECU continually monitors the camshaft wheel input, measures the angle of tooth edges and performs a number of operations:

  • Angle and edge measurement of teeth
    The ECU measures and records the angles and edges of processed cam teeth, relative to crank zero degrees of the primary crankshaft wheel input (see the earlier section "Crank zero degrees").
    Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).

  • Timeout check
    The ECU measures the duration between cam teeth edges and declares a timeout if no edge is seen for approximately 2 seconds (roughly 30 RPM for a single tooth cam trigger wheel). The ECU accumulates the count of time out events (modulo 16777216), and provides an outport to indicate if the signal is timed out when the block iterates.

  • No measurement (empty) indication
    The ECU counts the number of engine revolutions where there have been no camshaft wheel teeth detected (modulo 1677216).

  • Extra edge error indication
    The ECU counts the number of extra edge events seen (modulo 16777216). An extra edge event occurs when more edges than expected are detected in one cam wheel revolution. The number of expected teeth is specified by the application by calling pan_config_cam_wheel().

    For example, if there is persistent noise on the camshaft wheel sensor signal then the extra edge count will be incremented at the end of each camshaft revolution. If the pan_config_cam_wheel() function was called to configure two teeth but the wheel has three teeth, then the extra edge count will be incremented at the end of each camshaft revolution.

Arg (data in): panf_wheel

The configured cam wheel to read.
Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_angles

A pointer to an array the size of the number of edges configured by calling pan_config_cam_wheel(). The function writes the measured angle or angles of the processed camshaft wheel teeth edges. The angles are relative to zero degrees of the primary crankshaft wheel input, as the earlier section "Crank zero degrees", adjusted by the application declared engine angle offset, when the application calls pan_declare_engine_sync().
For example, if a tooth edge is detected 15 degrees after crank zero degrees, and the application has not declared engine sync, then the block will report the angle as 15. If the application subsequently declares engine sync with an angle offset of 360 crank degrees, then the function will report the angle as 375.
When the ECU loses synchronisation with the primary crankshaft then angles are reset to zero.
Cannot be NULL.
Range: [0, 720) degrees
Resolution: at least 0.1 degrees

Arg (data out): panf_edges_type

A pointer to an array the size of the number of edges configured by calling pan_config_cam_wheel(). The function writes the corresponding measurement of the tooth edge for each tooth angle, either falling (0), rising (1) or not yet sampled (2).
Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).
When the ECU loses synchronisation with the primary crankshaft then edges are reset to not yet sampled.
Cannot be NULL.
Range: [0, 720) degrees

Arg (data out): panf_edges_last_cycle

A pointer to a store written with the number of cam teeth edges captured in the previous engine cycle.
Cannot be NULL.
Range: [0, PIO_CAM_TEETH_MAX * 2] teeth

Arg (data out): panf_edges_this_cycle

A pointer to a store written with the number of cam teeth edges captured in the current engine cycle.
Cannot be NULL.
Range: [0, PIO_CAM_TEETH_MAX * 2] teeth

Arg (data out): panf_timeout

A pointer to a store written with a boolean representing whether the input signal from the cam trigger wheel has timed out (TRUE) or not (FALSE). A timeout is declared if there is no cam trigger wheel edge for approximately 2 seconds (roughly 30 RPM for a single tooth cam trigger wheel).
Cannot be NULL.

Arg (data out): panf_count_timeout

A pointer to a store written with the number of timeout events. A timeout is declared if there is no cam trigger wheel edge for approximately 2 seconds (roughly 30 RPM for a single tooth cam trigger wheel). The count accumulates events modulo 16777216 (i.e., the counter will wrap).
Cannot be NULL.
Range: [0, 16777216) events

Arg (data out): panf_count_empty

A pointer to a store written with the engine revolutions where no camshaft teeth edges are detected, wrapped modulo 16777216. An engine revolution starts at crank zero degrees and ends one or two crank revolutions later. The number of crank revolutions depends on the engine type selected when the pan_config_engine() function is called.
Cannot be NULL.
Range: [0, 16777216) events

Arg (data out): panf_count_extra

A pointer to a store written with the number of extra edge events wrapped modulo 16777216. An extra edge event occurs when more than the expected number of edges are detected per camshaft revolution. An engine revolution starts at crank zero degrees and ends one or two crank revolutions later. The number of crank revolutions depends on the engine type selected when the pan_config_engine() function is called.
Cannot be NULL.
Range: [0, 16777216) events

Return:

6.8.2.3.25. pan_get_cam_pin_state()
Definition:

PAN_RC_T pan_get_cam_pin_state(
   PIO_CAM_WHEEL_T   panf_wheel,
   BOOL             *panf_pin_state);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to reads the immediate digital state of a camshaft wheel input pin.

The function provides the instantaneous digital voltage level (high or low) seen at a camshaft wheel input pin. Note that the target ECU circuitry may invert the signal (see the ECU's Technical Specification for details about signal inversions).

Arg (data in): panf_wheel

The configured cam wheel to read.
Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_pin_state

The state of the cam pin is written through this pointer.
Cannot be NULL.
Range: 0 or 1

Return:

6.8.2.3.26. pan_config_engine()
Definition:

PAN_RC_T pan_config_engine(
   PIO_ENGINE_TYPE_T         panf_engine_type,
   PIO_ENGINE_CYCLE_TYPE_T   panf_engine_cycle_type,
   U8                        panf_num_cyl,
   volatile const F32       *panf_cyl_tdc_firing_angle,
   F32                       panf_cyl_tdc_calc_angle);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to specify information about the engine configuration.

The function specifies the engine cycle type (two-stroke or four-stroke), the TDC-firing angles for each cylinder and the relative angle to TDC-firing at which to trigger the TDC-calculation event. See the earlier section "Cylinder TDC-firing angles" for details on how the TDC-firing angle is derived from crank zero degrees, and see the earlier section "Cylinder TDC-calculation application events" for details on the TDC-calculation event.

As an example, take a symmetrical four stroke four cylinder engine with a 12-1 patterned crankshaft trigger wheel.

Relative to crank zero degrees, the TDC-firing angles for the cylinders in firing order are 46 degrees (cylinder 1), 226 degrees (cylinder 3), 406 degrees (cylinder 2) and 586 degrees (cylinder 4). The application will perform some calculations for each cylinder and 90 degrees prior to TDC-firing is deemed sufficient time to perform those calculations at the highest engine speed plus some margin. Then the parameters to this function would be:

  • panf_engine_type = PIO_ENGINE_CYCLE_TYPE_FOUR_STROKE

  • panf_num_cyl = 4

  • panf_cyl_tdc_firing_angle = { 46.0F, 406.0F, 226.0F, 586.0F }

  • panf_cyl_tdc_calc_angle = -90.0F

In response, the ECU activates the corresponding X task at angles 676 degrees (cylinder 1), 136 degrees (cylinder 3), 316 degrees (cylinder 2) and 496 degrees (cylinder 4).

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any engine related functions.

Arg (data in): panf_engine_type

The expected type of engine to configure for the application.
Use the enum included by the pio.h file, of the form PIO_ENGINE_TYPE[NAME].
Note that this parameter is no longer actively used by the ECU and will be removed in a future version of OpenECU.

Arg (data in): panf_engine_cycle_type

The cycle type of the engine, i.e. two-stroke or four-stroke.
Use the enum included by the pio.h file, of the form PIO_ENGINE_CYCLE_TYPE_[NAME].

Arg (data in): panf_num_cyl

The number of elements in panf_cyl_tdc_firing_angle
Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinders

Arg (data in): panf_cyl_tdc_firing_angle

An array of values defining the angle of each cylinder's TDC-firing relative to crank zero degrees. See the earlier section "Crank zero degrees" for more. The array is specified in cylinder order (and hence the firing order can be derived).
Cannot be NULL.
Range: [0, 360) degrees, for two stroke
Range: [0, 720) degrees, for four stroke

Arg (data in): panf_cyl_tdc_calc_angle

The angle in degrees relative to TDC-firing when the angular task for each cylinder is activated (a positive value denotes an angle after TDC-firing). It is a single value and applies to all cylinders.
Range: [-360, 360) degrees, for two stroke
Range: [-720, 720) degrees, for four stroke

Return:

6.8.2.3.27. pan_get_engine_cyl()
Definition:

PAN_RC_T pan_get_engine_cyl(
   BOOL  *panf_valid,
   U8    *panf_cyl);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current cylinder identifier.

The function retrieves the current cylinder identifier of the engine from the ECU. The cylinder identifier is updated whenever a new TDC-calculation angle is reached. See the earlier section "Engine TDC-firing events" for a definition of TDC-calculation. The application specifies the TDC-calculation angle by calling the pan_config_engine() function during application initialisation.

Note that if *panf_valid is set to zero, the value of the cylinder outport may change, but may not represent the actual engine position. Call the pan_get_engine_angle() function to determine crank position if the cylinder index is not valid.

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_cyl is valid. This will be set to a nonzero value if the engine is synchronized sufficiently to positively identify the cylinder (e.g., in crank, half or full engine synchronisation mode).
Cannot be NULL.

Arg (data out): panf_cyl

Pointer to where the current cylinder will be written.
Cannot be NULL.
Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinder

Return:

6.8.2.3.28. pan_get_engine_angle()
Definition:

PAN_RC_T pan_get_engine_angle(
   BOOL  *panf_valid,
   F32   *panf_engine_angle);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current engine angle.

The function retrieves the current angle of the crankshaft trigger wheel, relative to crank zero degrees (see the earlier section "Crank zero degrees". The retrieved value is taken from the angle clock, which is an estimate of crank decoding and position identification process (see the earlier section "Angle clock").

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_engine_angle is valid.
Written FALSE when the software cannot provide an engine angle (for instance, the ECU has not synchronised to the crankshaft wheel), written TRUE when the panf_engine_angle is valid.
Cannot be NULL.

Arg (data out): panf_engine_angle

Pointer to where the current engine angle will be written.
Cannot be NULL.
Range: [0, 360) degrees, for two-stroke
Range: [0, 720) degrees, for four-stroke
Resolution: at least 0.1 degrees

Return:

6.8.2.3.29. pan_get_engine_tooth()
Definition:

PAN_RC_T pan_get_engine_tooth(
   BOOL  *panf_valid,
   U16   *panf_engine_tooth);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current engine tooth identifier from the primary crankshaft position.

The function retrieves the current engine tooth identifier from the primary crankshaft wheel. See the earlier section "Engine tooth identification" for a description of engine tooth identifiers. Engine tooth identifiers are used when calling the pan_get_engine_speed_tr_abs() and pan_get_engine_speed_tr_rel() functions.

Arg (data out): panf_valid

Pointer to the boolean result of whether the value returned in panf_tooth is valid. Written FALSE when the ECU cannot provide an engine tooth identifier (for instance, the ECU has not synchronised to the crankshaft trigger wheel), written to TRUE when panf_engine_tooth is valid.
Cannot be NULL.

Arg (data out): panf_engine_tooth

Pointer to where the current engine tooth will be written.
Cannot be NULL.
Range: [1, PIO_CRANK_TEETH_MAX] teeth, for two-stroke
Range: [1, PIO_CRANK_TEETH_MAX * 2] teeth, for four-stroke

Return:

6.8.2.3.30. pan_get_engine_speed_per_cyl()
Definition:

PAN_RC_T pan_get_engine_speed_per_cyl(
   F32  *panf_engine_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to calculate the rotational speed of the engine measured between two adjacent cylinder TDC-calculation events.

Arg (data out): panf_engine_speed

Pointer to where the current engine speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.31. pan_get_engine_speed_per_rev()
Definition:

PAN_RC_T pan_get_engine_speed_per_rev(
   F32  *panf_engine_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to calculate the rotational speed of the engine measured over the last two primary crankshaft revolutions.

If the ECU has recorded one crank revolution but not yet two, then the speed is averaged over one revolution. This allows the application to retrieve a per-engine-revolution value as quickly as possible but without having to know how many crankshaft revolutions have so far occurred.

Arg (data out): panf_engine_speed

Pointer to where the current engine speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.32. pan_get_engine_speed_per_tooth()
Definition:

PAN_RC_T pan_get_engine_speed_per_tooth(
   F32  *panf_engine_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to calculate the rotational speed of the engine measured over the last two primary crankshaft teeth.

When calculating a speed across a crankshaft sync point, the block adjusts the speed as if there were physical teeth present in the case of missing teeth, or as if there was no physical teeth present in the case of an extra tooth.

Arg (data out): panf_engine_speed

Pointer to where the current engine speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.33. pan_get_engine_speed_tr_abs()
Definition:

PAN_RC_T pan_get_engine_speed_tr_abs(
   S16   panf_tooth,
   S16   panf_tooth_num,
   F32  *panf_engine_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to calculate the rotational speed of the engine measured between crank teeth relative to the first primary crank tooth (for the engine cycle).

The teeth are interpreted as relative to crank zero degrees, see the earlier section "Engine tooth identification".

For crankshaft wheels with missing teeth sync points, the time that the missing teeth would have occurred is not estimated and is treated the same as the last physical tooth prior to the missing region sync point. If requesting the engine speed based on missing teeth only, the function outputs zero.

For crankshaft wheels with extra teeth sync points, the time of any extra teeth is not recorded and is treated the same as the last physical tooth prior to the extra tooth sync point. If requesting the engine speed based on extra teeth only, the function outputs zero.

Arg (data in): panf_tooth

The first crank tooth to be used in the engine speed calculation. If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated.
Range: [1, n], for two-stroke
Range: [1, n*2], for four-stroke
where n is the number of physical crank teeth as specified when calling pan_engine_config().

Arg (data in): panf_tooth_num

The number of crank teeth after panf_tooth to be included as part of the engine speed calculation. The engine speed calculation is based on the time difference between the detection of these teeth.
If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated.
Range: [1, n), for two-stroke
Range: [1, n*2), for four-stroke
where n is the number of physical crank teeth as specified when calling pan_engine_config().

Arg (data out): panf_engine_speed

Pointer to where the current engine speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.34. pan_get_engine_speed_tr_rel()
Definition:

PAN_RC_T pan_get_engine_speed_tr_rel(
   U8    panf_cyl,
   S16   panf_tooth,
   S16   panf_tooth_num,
   F32  *panf_engine_speed);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to calculate the rotational speed of the engine measured between crank teeth relative to a cylinder's TDC-firing angle.

For crankshaft wheels with missing teeth sync points, the time that the missing teeth would have occurred is not estimated and is treated the same as the last physical tooth prior to the missing region sync point. If requesting the engine speed based on missing teeth only, the function outputs zero.

For crankshaft wheels with extra teeth sync points, the time of any extra teeth is not recorded and is treated the same as the last physical tooth prior to the extra tooth sync point. If requesting the engine speed based on extra teeth only, the function outputs zero.

Arg (data in): panf_cyl

The cylinder number to use to read engine speed.
Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinder

Arg (data in): panf_tooth

A crank tooth relative to the cylinder's TDC-firing angle (tooth), where 0 is the closest TDC-firing tooth, -1 the proceeding tooth, and so on. Extra teeth in sync points are ignored. If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated.
Range: (-n, 0], for two-stroke
Range: (-n*2, 0], for four-stroke
where n is the number of physical crank teeth as specified when calling pan_engine_config().

Arg (data in): panf_tooth_num

The number of crank teeth after panf_tooth to be included as part of the engine speed calculation. The engine speed calculation is based on the time difference between the detection of these teeth.
If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated.
Range: [1, n), for two-stroke
Range: [1, n*2), for four-stroke
where n is the number of physical crank teeth as specified when calling pan_engine_config().

Arg (data out): panf_engine_speed

Pointer to where the current engine speed will be written.
Cannot be NULL.
Range: [0, 10000] RPM

Return:

6.8.2.3.35. pan_get_engine_sync()
Definition:

PAN_RC_T pan_get_engine_sync(
   PIO_ENGINE_SYNC_MODE_T  *panf_engine_sync,
   F32                     *panf_engine_angle_offset,
   S16                     *panf_engine_tooth_offset);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve the current engine synchronisation mode.

The function retrieves the current engine synchronisation mode. The engine synchronisation mode can be changed by the application by calling the pan_declare_engine_sync() function. A detailed description of the engine synchronisation modes can be found in the earlier section "Engine synchronisation modes". For reference, the decoding state values are:

Arg (data out): panf_engine_sync

Pointer to where the current engine synchronisation mode will be written.
Cannot be NULL.

Arg (data out): panf_engine_angle_offset

Pointer to where the current engine angle offset will be written.
Cannot be NULL.

Arg (data out): panf_engine_tooth_offset

Pointer to where the current engine tooth offset will be written.
Cannot be NULL.

Return:

6.8.2.3.36. pan_declare_engine_sync()
Definition:

PAN_RC_T pan_declare_engine_sync(
   PIO_DECLARE_ENGINE_SYNC_MODE_T   panf_sync_mode,
   F32                              panf_engine_angle_offset,
   S16                              panf_engine_tooth_offset);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to declare synchronisation with the overall engine position.

The function instructs the ECU to switch to a particular engine synchronisation mode. The process is described in the earlier section "Engine synchronisation modes".

In short, the ECU will track the crankshaft wheel to achieve crank region synchronisation. The application must then determine the overall engine position, using crank, cam or other indicators, and move to either half or full engine synchronisation (it is not possible to select crank region synchronisation). At any point, the application can force loss of engine synchronisation to deactivate output drivers.

Each of the engine synchronisation modes enables different sets of angular functionality. When a function is disabled, input processing ceases and output drivers are turned off.

Function None Moving Region Half Full
Crank signal processing Y Y Y Y Y
Cam signal processing - - Y Y Y
Angle clock - - Y Y Y
Crank sync point triggers - - Y Y Y
Cylinder TDC triggers - - Y Y Y
A/D sampling - - Y Y Y
Knock sampling - - - Y Y
Port injection - Y - Y Y
Direct injection - - - Y Y
Digital outputs - - - Y Y

Arg (data in): panf_sync_mode

The engine synchronisation mode to move to. Set to one of no sync, half sync, or full sync. Changing to crank region sync is not supported. If panf_sync_mode matches the current engine synchronisation mode, then the ECU ignores the request to change mode.

Arg (data in): panf_engine_angle_offset

The offset to add to crank zero degrees first assigned when crank region synchronisation was found. For example, if the application requests 180 degrees offset after crank synchronisation is found, then the overall engine angle offset is 180 degrees. Subsequently, if the application requests 360 degrees offset, without loss of engine synchronisation, then the overall engine angle offset is 360 degrees (not 180 + 360 degrees).

When loss of engine synchronisation is detected, the ECU clears the engine angle offset to zero. Range: [-360, 360] degrees
Resolution: at least 0.1 degrees

Arg (data in): panf_engine_tooth_offset

The offset to add to the engine tooth identifier one, first assigned when crank region synchronisation was found. Like the panf_engine_angle_offset parameter, the value is an absolute offset, not an additive offset. Rather than the ECU determine the closest engine tooth to the engine angle offset the application can choose the closest. The ECU expects the tooth offset to match the angle offset and will not operate as expected if the application supplied tooth offset is more than +- 1 tooth from the actual tooth offset.

When loss of engine synchronisation is detected, the ECU clears the engine tooth offset to zero.
Range: [-n, n), for two-stroke
Range: [-n*2, n*2), for four-stroke
where n is the number of teeth on the primary crankshaft wheel.

Return:

6.8.2.3.37. pan_lose_engine_sync()
Definition:

PAN_RC_T pan_lose_engine_sync(void);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to force loss of engine synchronisation.

The function instructs the ECU to lose synchronisation with the primary crankshaft trigger wheel. The crank synchronisation process is described in the earlier section "Engine synchronisation modes".

Calling this function results in the ECU reverting to the No crank synchronisation mode, disabling most angular functionality. When functionality is disabled, input processing ceases and output drivers are turned off.

Function None Moving Region Half Full
Crank signal processing Y Y Y Y Y
Cam signal processing - - Y Y Y
Angle clock - - Y Y Y
Crank sync point triggers - - Y Y Y
Cylinder TDC triggers - - Y Y Y
A/D sampling - - Y Y Y
Knock sampling - - - Y Y
Port injection - Y - Y Y
Direct injection - - - Y Y
Digital outputs - - - Y Y

Return:

6.8.2.3.38. pan_config_injectors()
Definition:

PAN_RC_T pan_config_injectors(
   volatile const PDX_LCHAN_T  *panf_lchans,
   U32                          panf_chans,
   PIO_INJECTOR_DRIVE_T         panf_drive,
   BOOL                         panf_invert);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure injector channels and drive type.

This function is used to configure outputs for use as injector channels. All injectors will be configured for the type of engine specified by the call to pan_config_engine().

Note

If both this function and pan_config_injector() are call by the application, the most recent call will take precedence.

This function must be called by the application's initialisation function.

Arg (data in): panf_lchans

This is an array of output channels that will be configured as injector outputs. The first element will be applied to cylinder 1, the second to cylinder 2 and so on.
Must not be NULL
Use the macros included by the pio.h file, of the form PIO_INJOT_[NAME].

Arg (data in): panf_chans

The number of injector channels to configure, i.e, the number of elements in panf_lchans. This must be the same as the number of cylinders in the engine.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_drive

The injector drive type, i.e., saturating or peak-hold.
Use the macros included by the pio.h file, of the form PIO_INJECTOR_DRIVE_[NAME].

Arg (data in): panf_invert

This parameter is used to invert the polarity of the injector output signal, (for saturing injector drive types). Set false for active low (default), true for active high.

Return:

6.8.2.3.39. pan_config_injector()
Definition:

PAN_RC_T pan_config_injector(
   U32                         panf_inj_id,
   PDX_LCHAN_T                 panf_lchan,
   U32                         panf_cyl,
   PIO_INJECTOR_DRIVE_T        panf_drive_type,
   PIO_INJECTOR_PULSE_TYPE_T   panf_pulse_type,
   BOOL                        panf_invert);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure a single injector.

This function is used to configure an injector output channel to have a specific output drive and pulse type, and associate it with a specific cylinder.

Note

If both this function and pan_config_injectors() are called by the application, the most recent call will take precedence. The first call of this function after a call to pan_config_injectors() will reset the injector configuration for all injectors.

This function must be called by the application's initialisation function.

Arg (data in): panf_inj_id

This is the injector identifier to configure. This is a value in the range [1, PIO_ANG_MAX_INJECTORS] and identifies a logical injector.

Arg (data in): panf_lchan

This the output channels to associate with the specified injector ID. Use the macros included by the pio.h file, of the form PIO_INJOT_[NAME]. This channel associates the logical injector with a specific hardware channel.

Arg (data in): panf_cyl

The cylinder with which to associate this injector. This is the cylinder relative to which the injector events will be scheduled. Note that more than one injector can be associated with the same cylinder.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_pulse_type

The pulse type for the injector defined in pio.h: port-injection style or direct-injection style. Of the form PIO_INJECTOR_PULSE_TYPE_[NAME]

Arg (data in): panf_drive_type

The injector drive type, i.e., saturating or peak-hold.
Use the macros included by the pio.h file, of the form PIO_INJECTOR_DRIVE_[NAME].

Arg (data in): panf_invert

This parameter is used to invert the polarity of the injector output signal, (for saturing injector drive types). Set false for active low (default), true for active high.

Return:

6.8.2.3.40. pan_injection_config_successful()
Definition:

BOOL pan_injection_config_successful(
   PAN_RC_T  *panf_config_result);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to discover if injection configuration was successful.

Some aspects of the injection configuration have to occur after the initialisation functions are called. This is because the ordering of calls to the various initialisation functions cannot be guaranteed. This function reports whether or not injection configuration post-initialisation was successful.

Arg (data in): panf_config_result

If non-NULL, a return code will be written here to allow a higher level of detail in the case of an error occuring during configuration. If configuration has yet to take place, a value of PAN_RC_INVALID will be written here.
Range: [NULL or valid address]

Return:
  • TRUE - configuration was successful

  • FALSE - configuration failed

6.8.2.3.41. pan_config_injectors_comp_di()
Definition:

PAN_RC_T pan_config_injectors_comp_di(
   PAX_LCHAN_T          panf_frp_chan,
   volatile const F32  *panf_injcomp_map_x,
   U8                   panf_injcomp_map_x_sz,
   volatile const F32  *panf_injcomp_map_y,
   U8                   panf_injcomp_map_y_sz,
   volatile const F32  *panf_injcomp_map_z,
   volatile const F32  *panf_frp_tf_x_volts,
   volatile const F32  *panf_frp_tf_z_MPa,
   S32                  panf_frp_tf_sz,
   F32                  panf_frp_tf_max_volts);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure the volume conversion for direct injection.

The function configures the maps and channels used for direct-injection fuel injector conversion from volume to time.

When a direct injection schedule supplied by the application is specified using volume mode (PIO_INJDI_DURATION_MODE_VOLUME) then before each injection pulse is made, the fuel rail pressure (FRP) is sampled so that the appropriate injection duration can be accurately determined to deliver the requested fuel volume.

The injection duration is looked up in the map panf_injcomp_map_z, using requested pulse volume and the FRP as inputs. The FRP is sampled at the pulse on angle.

Note

This function must be called before scheduling any injections requiring volume-based injections.

Arg (data in): panf_frp_chan

The analogue input channel that the fuel rail pressure input is to be read from.
Use the macros included by the pio.h file, of the form PIO_AIN_INJ_FBK_[NAME].

Arg (data in): panf_injcomp_map_x

This is the x axis of the fuel rail pressure compensation map and contains pulse volume values.
The axis values must be strictly increasing. Out-of-range values result in error and leave the characteristic map unconfigured.
Cannot be NULL.
Range: [0, 512) mm3

Arg (data in): panf_injcomp_map_x_sz

The number of elements in panf_injcomp_map_x.
Size: [2, 10] elements for M220, M221 and M250 targets
Size: [2, 15] elements for M670 targets

Arg (data in): panf_injcomp_map_y

This is the y axis of the fuel rail pressure compensation map and contains fuel rail pressure values.
The axis values must be strictly increasing. Out-of-range values result in error and leave the characteristic map unconfigured.
Cannot be NULL.
Range: [0, 500] MPa

Arg (data in): panf_injcomp_map_y_sz

The number of elements in panf_injcomp_map_y.
Range: [2, 10] elements for M220, M221 and M250 targets
Range: [2, 15] elements for M670 targets

Arg (data in): panf_injcomp_map_z

This is the z axis (data) of the fuel rail pressure compensation map and contains injection pulse duration values. This data must be stored in column major order.
The values in this map will be clipped to the range [0, 1000] milliseconds.
Cannot be NULL.
Size: [2, 10] by [2, 10] elements, for M220, M221 and M250 targets
Size: [2, 15] by [2, 15] elements, for M670 targets
Range: [0, 1000] milliseconds
Resolution: (floor(max_duration/16.38375ms)+1)*0.2500us for M220, M221 and M250 targets
Resolution: (floor(max_duration/15.88727ms)+1)*0.2424us for M670 target
where max_duration is the maximum duration in the entire map.

Arg (data in): panf_frp_tf_x_volts

This is the x axis of the transfer function that converts a voltage (i.e., of a fuel-rail pressure sensor in voltage) into a fuel rail pressure quantity in engineering units.
Cannot be NULL.
Range: [2, 10] elements for M220, M221 and M250 targets
Range: [2, 15] elements for M670 targets
Range: [0, panf_frp_tf_max_volts] volts

Arg (data in): panf_frp_tf_z_MPa

This is the z axis of the transfer function that converts a voltage (i.e., of a fuel-rail pressure sensor in voltage) into a fuel rail pressure quantity in engineering units.
Cannot be NULL.
Size: 1 by [2, 10] elements, for M220, M221 and M250 targets
Size: 1 by [2, 15] elements, for M670 targets
Range: [0, 500] MPa

Arg (data in): panf_frp_tf_sz

The number of elements in panf_frp_tf_x_volts and panf_frp_tf_z_MPa.
Range: [2, 10] elements for M220, M221 and M250 targets
Range: [2, 15] elements for M670 targets

Arg (data in): panf_frp_tf_max_volts

The upper voltage limit of panf_frp_chan. I.e., on a 0-5v input, this would be 5v.
Range: [0, 24] volts

Return:

6.8.2.3.42. pan_set_injection_comp_frp_di()
Definition:

PAN_RC_T pan_set_injection_comp_frp_di(
   BOOL   panf_override,
   F32    panf_frp);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to override the fuel rail pressure input.

The function is used to override the fuel rail pressure input used for direct injection with an arbitrary value (for instance, when the application detects that the fuel rail pressure sensor has failed). When overridden, the ECU will this value in the injection duration calculations.

See the earlier section "Direct injection" for an overview of direct injection functionality. The application calls the pan_config_injectors_comp_di() function to select the desired fuel rail pressure input channel and to specify the volume to duration conversion table.

Arg (data in): panf_override

Set to true to override the fuel rail pressure input, false otherwise.

Arg (data in): panf_frp

The value to override the fuel rail pressure with.
Range: [0, 500] MPa

Return:

6.8.2.3.43. pan_config_injections_di()
Definition:

PAN_RC_T pan_config_injections_di(
   F32   panf_min_inj_time,
   F32   panf_min_off_time,
   F32   panf_drop_dead_angle);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure constraints for direct injection.

This function configures various parameters that the injection functionality uses when scheduling injections.

Arg (data in): panf_min_inj_time

This parameter can be used to apply a minimum duration to all pulses. Set to zero if a minimum pulse duration is not required. If a requested pulse duration is greater than zero but smaller than this minimum time, the ECU will generate a pulse equal to this minimum time. The actual delivered pulse may be shorter than this, however, if clipped by the drop dead angle.
Range: [0, 2097] milliseconds

Arg (data in): panf_min_off_time

The minimum time between pulses for a single injector, applied to all injectors. This parameter ensures a minimum time between pulses for an injector and will override the starting angle of a subsequent pulse if necessary.
Range: [0, 5] milliseconds

Arg (data in): panf_drop_dead_angle

The drop dead angle, applied to all cylinders, relative to TDC-firing. The ECU will stop injections at this point on a given cylinder.
Range: [0, 720] degrees

Return:

6.8.2.3.44. pan_set_injection_di()
Definition:

PAN_RC_T pan_set_injection_di(
   U8                          panf_inj,
   U8                          panf_pulses,
   volatile const F32         *panf_rel_on_angle,
   volatile const F32         *panf_fuel_amount,
   F32                         panf_duration_offset,
   PIO_INJDI_DURATION_MODE_T   panf_duration_mode);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to request injections for a given injector.

The function updates the direct injection schedule for an injector channel. See the earlier section "Direct injection" for an overview of direct injection. In short, the ECU monitors the angle clock and starts injection pulses based on the schedule defined by the function parameters (in particular, panf_rel_on_angle). The schedule of pulses can be specified in units of volume or time at run-time, based on the panf_duration_mode parameter.

  • If panf_duration_mode is set to volume mode, the ECU converts a requested volume of fuel from the panf_fuel_amount parameter into a pulse duration. The ECU samples fuel rail pressure shortly before the injection on angle and uses a map lookup to derive the required injection duration. This is to compensate for very rapid fluctuations in fuel rail pressure that cannot be compensated for in the application, as the correction must be made as late as near to the injection start as possible.

    The desired analogue input for fuel rail pressure and related map data and axes are configured when the application calls function pan_config_injectors_comp_di() during application initialisation.

  • If panf_duration_mode is set to time mode, the ECU uses the panf_fuel_amount parameter directly for pulse duration. The ECU will not compensate for fuel rail pressure in this mode.

The injection schedule update takes effect depending on whether the injection schedule has been started for this cycle or not:

  • If the application has not previously requested an injection schedule for this injector channel, then the update is applied immediately and the first pulse scheduled. If the angle clock has passed the first pulse's on angle for this cylinder cycle, then the first pulse will be postponed until the next cylinder cycle.

  • Otherwise, if the first injection pulse from the schedule prior to this update has not yet been generated for this cylinder cycle, then the update is applied immediately and the first pulse rescheduled. If first pulse is in the past compared to the current angle clock, then the first pulse will be postponed until the next cylinder cycle.

  • Otherwise, if the first injection pulse from the schedule prior to this update has been generated, then the request is buffered and applied at the start of the next cylinder cycle.

  • Otherwise, if the application makes no further requests to update the injection schedule, then the ECU will repeat the schedule at most 4 times. Once the repeats are completed, the ECU clears the schedule and no further injection pulses are generated until the application requests a new injection schedule.

The ECU supports the generation of up to six injection pulses per cylinder cycle. The on angles are relative to the each cylinder's TDC-firing angle (positive angles after TDC-firing).

Injection pulses are performed on each cylinder according to the requested pulse schedule. If two pulses overlap, the latter pulse will be delayed. (Note that its duration will not be modified.) If this delay then means that the next two pulses overlap, then the next pulse will be delayed too, and so on for the remaining pulses. In effect, the pulses will be shuffled along in time.

The application calls the pan_config_injections_di() function to define constrains that apply to all injectors.

  • The minimum injection duration that is applied to all pulses can be defined.

  • The minimum inter-injection delay applied to the durations between all pulses can be defined.

  • The drop-dead angle for each cylinder is an angle relative to TDC-firing and acts as a final injection cut-off point for a cylinder. That is, any injection in progress at this angle will be terminated and any subsequent injections for the cylinder cycle will not be scheduled.

    The drop-dead angle is set when the application calls the pan_config_injections_di() function during application initialisation. See the description for function pan_set_injection_di_dd() for how to adjust the drop dead angle during application run-time.

The direct injection functionality is active in full engine synchronisation mode only (see the earlier section "Engine synchronisation modes" for a description of modes). In any other mode, the ECU forces all injectors off. When the ECU detects loss of engine synchronisation, the injection schedule is cleared and the application must request a new schedule for injections to occur once full engine synchronisation is gained.

Arg (data in): panf_inj

The identifier of the injector output channel to update. If pan_config_injectors() was used to configure injector channels, the injector identifier corresponds to the cylinder with which the injector is associated. If pan_config_injector() was used, then the application defined the injector identifiers.
Range: [1, PIO_ANG_MAX_INJECTORS]

Arg (data in): panf_pulses

The number of elements in parameters panf_rel_on_angle and panf_fuel_amount.
Range: [0, PIO_ANG_INJECTOR_MAX_PULSES]

Arg (data in): panf_rel_on_angle

An array of starting angles for each pulse, relative to TDC-firing. A positive value indicates a pulse after TDC-firing. On angles for which the corresponding panf_fuel_amount is non-zero must be strictly increasing.
Cannot be NULL.
Size: [1, PIO_ANG_INJECTOR_MAX_PULSES]
Range: [-720, 720] degrees

Arg (data in): panf_fuel_amount

An array of amounts for each pulse, ordered to match panf_rel_on_angle.
If this value is zero, no pulse will be generated at the corresponding angle.
Fuel amounts will be clipped to the range limits.
Cannot be NULL.
Size: [1, PIO_ANG_INJECTOR_MAX_PULSES]
Range: [0, 512) mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME.
Range: [0, 1000] milliseconds if panf_duration_mode is PIO_INJDI_DURATION_MODE_TIME.

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data in): panf_duration_offset

An offset applied to this injector's injection durations, used to compensate for slight differences in injectors. This offset will be applied to the automatically computed pulse duration for both volume and duration modes.
Range: [-8.191, 8.192] milliseconds (1/4096)

Arg (data in): panf_duration_mode

Specifies if the fuel amount is specified in units of volume or time.
If the fuel amount is specified in volume, the ECU will compute the pulse duration at the start angle based on the characteristics provided by pan_config_injectors_comp_di.
Range: PIO_INJDI_DURATION_MODE_[NAME]

Return:

6.8.2.3.45. pan_set_injection_di_dd()
Definition:

PAN_RC_T pan_set_injection_di_dd(
   U8                          panf_inj,
   U8                          panf_pulses,
   volatile const F32         *panf_rel_on_angle,
   volatile const F32         *panf_fuel_amount,
   volatile const F32          panf_rel_dd_angle,
   F32                         panf_duration_offset,
   PIO_INJDI_DURATION_MODE_T   panf_duration_mode);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to request injections for a given injector.

The function performs the same functionality as pan_set_injection_di() and additionally allows the injection drop dead angle to be changed.

Arg (data in): panf_inj

The identifier of the injector output channel to update. If pan_config_injectors() was used to configure injector channels, the injector identifier corresponds to the cylinder with which the injector is associated. If pan_config_injector() was used, then the application defined the injector identifiers.
Range: [1, PIO_ANG_MAX_INJECTORS]

Arg (data in): panf_pulses

The number of elements in parameters panf_rel_on_angle and panf_fuel_amount.
Range: [0, PIO_ANG_INJECTOR_MAX_PULSES]

Arg (data in): panf_rel_on_angle

An array of starting angles for each pulse, relative to TDC-firing. A positive value indicates a pulse after TDC-firing. On angles for which the corresponding panf_fuel_amount is non-zero must be strictly increasing.
Cannot be NULL.
Size: [1, PIO_ANG_INJECTOR_MAX_PULSES]
Range: [-720, 720] degrees

Arg (data in): panf_fuel_amount

An array of amounts for each pulse, ordered to match panf_rel_on_angle.
If this value is zero, no pulse will be generated at the corresponding angle.
Fuel amounts will be clipped to the range limits.
Cannot be NULL.
Size: [1, PIO_ANG_INJECTOR_MAX_PULSES]
Range: [0, 512) mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME.
Range: [0, 1000] milliseconds if panf_duration_mode is PIO_INJDI_DURATION_MODE_TIME.

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data in): panf_rel_dd_angle

The drop dead angle applied to this injector, relative to TDC-firing. The ECU will stop injections at this point on a given cylinder.
Range: [0, 720] degrees

Arg (data in): panf_duration_offset

An offset applied to this injector's injection durations, used to compensate for slight differences in injectors. This offset will be applied to the automatically computed pulse duration for both volume and duration modes.
Range: [-8.191, 8.192] milliseconds (1/4096)

Arg (data in): panf_duration_mode

Specifies if the fuel amount is specified in units of volume or time.
If the fuel amount is specified in volume, the ECU will compute the pulse duration at the start angle based on the characteristics provided by pan_config_injectors_comp_di.
Range: PIO_INJDI_DURATION_MODE_[NAME]

Return:

6.8.2.3.46. pan_get_injection_di_setpoint()
Definition:

PAN_RC_T pan_get_injection_di_setpoint(
   U8                          panf_inj,
   U8                         *panf_pulses,
   F32                        *panf_rel_on_angle,
   F32                        *panf_fuel_amount,
   F32                        *panf_duration_offset,
   F32                        *panf_drop_dead_angle,
   PIO_INJDI_DURATION_MODE_T  *panf_duration_mode);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to read back direct injection parameters for a given injector.

This function is used to read the direct injection schedule for a given injector. This function can be used to verify that the data stored in eTPU memory match that which the application intended to write, allowing for checks of eTPU memory faults.

If this function is called while the eTPU is updating internal schedule parameters, it will wait until the eTPU is complete guaranteeing that all the parameters read are from a single schedule.

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_inj

The identifier of the injector output channel to read back. If pan_config_injectors() was used to configure injector channels, the injector identifier corresponds to the cylinder with which the injector is associated. If pan_config_injector() was used, then the application defined the injector identifiers.
Range: [1, PIO_ANG_MAX_INJECTORS]

Arg (data out): panf_pulses

The number of elements in the arrays containing the pulse durations and on angles.
Range: [0, PIO_ANG_INJECTOR_MAX_PULSES]

Arg (data out): panf_rel_on_angle

An array of PIO_ANG_INJECTOR_MAX_PULSES pulse on angles, relative to TDC to match the values passed passed to pan_set_injection_di().
Range: [-720, 720] degrees

Note

The value passed to the ECU is transformed to be kept with in a valid angle range. This transform cannot be reversed, so the angle is reported with the following transform applied:
on_angle = ((on_angle + 1080) mod 720) - 360

Arg (data out): panf_fuel_amount

An array of PIO_ANG_INJECTOR_MAX_PULSES pulse amounts to match the values passed to pan_set_injection_di().
Range: [0, 512) mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME.
Range: [0, 1000] milliseconds if panf_duration_mode is PIO_INJDI_DURATION_MODE_TIME.

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data out): panf_duration_offset

An offset applied to this injector's injection durations to match the value passed to pan_set_injection_di().
Range: [-8.191, 8.192] milliseconds (1/4096)

Arg (data out): panf_drop_dead_angle

The drop-dead angle configured for this injector to match the value passed to pan_config_injections_di().

Arg (data out): panf_duration_mode

Specifies if the fuel amount is specified in volume or time to match the value passed to pan_set_injection_di().
Range: PIO_INJDI_DURATION_MODE_[NAME]

Return:

6.8.2.3.47. pan_get_injection_di_feedback()
Definition:

PAN_RC_T pan_get_injection_di_feedback(
   U8    panf_inj,
   F32  *panf_rel_on_angles,
   F32  *panf_rel_off_angles,
   F32  *panf_durations,
   U32  *panf_pulse_count,
   F32  *panf_fuel_accum_time,
   F32  *panf_fuel_accum_vol);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve direct injection feedback information for a given injector.

At the end of each direct injection pulse, the ECU increments a counter of requested pulses, captures information about the pulse, and accumulates the injection duration (as time and, optionally, volume).

Whenever the ECU attempts to generate an injection pulse, the feedback information is updated. If the ECU cannot generate a pulse due to an electrical fault, or if the ECU partially generates a pulse due to the pulse schedule being cut short during the dead-time portion, the pulse feedback information is updated regardless.

The captured starting angle matches the application requested on angle. The captured ending angle is calculated shortly after each pulse ends, based on the latest crank tooth speed. The captured ending angle is an approximation only.

The accumulated flow time is incremented by the application request (either in time, or converted from volume to time just before the pulse starts), include the injector duration offset (used to account for mechanical and electrical differences between injectors), and takes into account a pulse that is cut short due to the drop-dead angle.

The accumulated volume is incremented only when the application requests are made in volume (requests made in units of time do not contribute to the accumulated volume variable). Regardless of whether a pulse is adjusted or not (for example, adjusted due to the minimum on time, or due to the drop-dead angle), the volume added to the accumulator is that supplied by the application.

The pulse count and accumulated feedback information is incremented using modulo arithmetic. The application must call this function frequently enough to avoid inaccurate results due to the modulo operation.

Arg (data in): panf_inj

The identifier of the injector output channel to retrieve feedback information. If pan_config_injectors() was used to configure injector channels, the injector identifier corresponds to the cylinder with which the injector is associated. If pan_config_injector() was used, then the application defined the injector identifiers.
Range: [1, PIO_ANG_MAX_INJECTORS]

Arg (data out): panf_rel_on_angles

An array of injection pulse starting angles, relative to TDC-firing. Indexed by pulse sequence.
Size: PIO_ANG_INJECTOR_MAX_PULSES
Range: [-720, 720] degrees

Note

The value passed to the ECU is transformed to be kept within a valid angle range. This transform cannot be reversed, so the angle is reported with the following transform applied:
on_angle = ((on_angle + 1080) mod 720) - 360

Arg (data out): panf_rel_off_angles

An array of injection pulse off angles, relative to TDC-firing. Indexed by pulse sequence. The off angle is inferred from the last crank tooth speed shortly after the end of the pulse. As such, the ending angle is an approximation only. Size: PIO_ANG_INJECTOR_MAX_PULSES
Range: [-720, 720] degrees

Note

The angle is reported with the following transform applied:
off_angle = ((off_angle + 1080) mod 720) - 360

Arg (data out): panf_durations

An array of injection pulse durations, indexed by pulse sequence.
Size: PIO_ANG_INJECTOR_MAX_PULSES
Range: [0, 1000] milliseconds

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data in): panf_pulse_count

The number of injection events that have occurred for this injector since the ECU was reset.
Range: [0, inf] modulo 8388608 pulses

Arg (data out): panf_fuel_accum_time

The accumulated injection durations in time for this injector since the ECU was reset.
Range: [0, inf] modulo 1041204 milliseconds

Arg (data out): panf_fuel_accum_vol

The accumulated fuel flow amounts (in volume) for this injector since the ECU was reset. If a pulse request is given in time then this parameter is no incremented for the request. If a pulse request is given in volume then this parameter is incremented at the end of each pulse.
Range: [0, inf] modulo 2097151 mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME.

Return:

6.8.2.3.48. pan_set_initial_injection_pi()
Definition:

PAN_RC_T pan_set_initial_injection_pi(
   F32   panf_flow_time,
   F32   panf_dead_time);

Supported targets:

M220-000, M221-000 and M670-000

Required license:

None (Main library).

Description:

Function to specify the duration of the initial injection (the priming fuel pulse).

An initial, or priming, fuel pulse is generated when the engine starts to turn. The purpose of the initial fuel pulse is to ensure there is sufficient fuel in the engine cylinders when the first sparks occur to match the environmental conditions and engine size, making the engine more likely to start.

The duration of the initial fuel pulse is calculated as MIN(panf_dead_time + panf_flow_time, 500) milliseconds and is unaffected by the end of intake angle specified by calling pan_set_injection_pi().

Due to the relative timing between sensing the engine starting to turn and the ECU synchronising with the crank trigger wheel which in turn causes scheduled spark events to occur, unburnt fuel can pass through a cylinder into the exhaust. Because unburnt fuel can pass into the exhaust, the initial fuel pulse method is not generally used for emissions related programmes. The initial fuel pulse can be turned off by not calling this function, or calling this function with a total injection time of zero milliseconds.

Call during application initialisation or during application run.

Note

Function pan_config_engine() must be called prior to calling this function.

Arg (data in): panf_flow_time

The length of the initial fuel pulse in milliseconds.
Range: [0, 500.0] milliseconds

Arg (data in): panf_dead_time

The duration of injection dead time.
Range: [0, 500.0] milliseconds
When the dead time is updated for injector 'n', it is updated for all injectors, as it is a shared parameter.

6.8.2.3.49. pan_set_injection_pi()
Definition:

PAN_RC_T pan_set_injection_pi(
   U8    panf_cyl,
   F32   panf_rel_on_angle,
   F32   panf_flow_time,
   F32   panf_dead_time,
   F32   panf_end_of_intake_angle,
   F32   panf_split_fuel_factor);

Supported targets:

M220-000, M221-000 and M670-000

Required license:

None (Main library).

Description:

Function to set the injector pulse schedule for a cylinder (angle-duration).

This function updates the port injection schedule for an injector channel. See the earlier section "Port injection" for an overview of port injection functionality. In short, the ECU monitors the angle clock and starts the main injection pulse based on the schedule given by parameter panf_rel_on_angle. The injection lasts for the requested duration.

The total injection drive signal lasts for panf_flow_time + panf_dead_time. These parameters are clipped to their respective ranges. The dead time represents the time it takes the injector needle to lift and allow fuel to flow. The flow time represents the time the injector allows fuel to pass the injector tip.

If the duration of the injection event extends beyond the parameter panf_end_of_intake_angle then the injection pulse is stopped. Usually panf_end_of_intake_angle is configured to occur before the inlet valve closes so that fuel is not left to pool behind the intake valve to be ingested in the next cylinder cycle.

The port injection functionality is active in half and full engine synchronisation mode (see the earlier section "Engine synchronisation modes" for a for a description of modes).

  • In half engine synchronisation mode for a four-stroke engine, injection pulses are generated every 360 degrees, and the panf_rel_on_angle and panf_end_of_intake_angle parameter values are interpreted modulo 360 degrees.

    The parameter panf_split_fuel_factor determines what fraction of the full flow time to apply. This allows wall-wetting effects to be included more easily when calculating the pulse durations. In this case, the pulse duration is given by:

    panf_dead_time + (panf_flow_time * panf_split_fuel_factor)

    In half engine synchronisation mode for a two-stroke engine, then injection pulses are generated as if the ECU were in full engine synchronisation mode.

  • In full engine synchronisation mode for a two or four-stroke engine, injection pulses are generated in full every engine cycle.

When neither half or full engine synchronisation is active, the ECU forces all injectors off (the exception to this rule is the initial fuel pulse which may occur if movement in the primary crank wheel has been detected but crank region synchronisation has not yet been achieved).

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_cyl

The cylinder that is being set up.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_rel_on_angle

The angle at which to start injection pulse from TDC-firing of cylinder.
Range: [-360, 360] degrees, for a two-stroke engine
Range: [-720, 720] degrees, for a four-stroke engine

Arg (data in): panf_flow_time

The duration of injection flow time.
Range: [0, 349.5] milliseconds

Arg (data in): panf_dead_time

The duration of injection dead time, (added to the flow time to make pulse).
Range: [0, 349.5] milliseconds

Arg (data in): panf_end_of_intake_angle

The angle at which to turn injector off. Must be no more than +- 720 degrees from the start of injection angle (panf_rel_on_angle).
Range: [-720, 720] degrees, for a two-stroke engine
Range: [-1440, 1440] degrees, for a four-stroke engine

Arg (data in): panf_split_fuel_factor

The fraction of the flow time used when in split-fuel mode, i.e. when injections are scheduled modulo 360 degrees before cam sync has been attained. For example, if this is set to 0.6, and the flow-time and dead-time are 1 ms and 0.2 ms respectively, and the on-angle is set to 40 degrees, then after crank sync has been achieved and before cam sync has been achieved, there will be two injections per engine cycle, scheduled at 40 and 400 degrees respectively (after that cylinder's TDC), each of duration:

0.6 x 1 ms + 0.2 ms = 0.8 ms.

Range: [0, 1) absolute

6.8.2.3.50. pan_update_injection_pi()
Definition:

PAN_RC_T pan_update_injection_pi(
   U8    panf_enable,
   U8    panf_enable_post_pulses,
   U8    panf_cyl,
   F32   panf_rel_on_angle,
   F32   panf_flow_time,
   F32   panf_dead_time,
   F32   panf_split_fuel_factor);

Supported targets:

M220-000, M221-000 and M670-000

Required license:

None (Main library).

Description:

Function to update a cylinder's injector pulse schedule (angle-duration).

This function schedules an update to the main pulse for the specified cylinder. If the main pulse has not started, the start angle may be adjusted. In all cases, the pulse duration is adjusted. This may result in: - the pulse stopping immediately; - the pulse contracting; - the pulse expanding; - the generation of a post pulse.

Call after calling pan_set_injector() to update the injection schedule.

Any pulse that is in progress at the end of intake angle specified by parameter panf_end_of_intake_angle when calling pan_set_injection_pi() is terminated immediately.

Otherwise, a main pulse lasts for the duration panf_dead_time + panf_flow_time. A post pulse lasts for the duration panf_dead_time

  • remaining flow-time, where the remaining flow-time is the flow-time passed by the panf_flow_time parameter, minus the flow-time already accumulated on this cycle. A post-pulse is only generated if this function is called with the panf_enable_post_pulses flag set to TRUE. Otherwise, if this function is called after a pulse has completed on the current cycle, then the newly updated data will be held over and used on the next cycle.

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_enable
  • TRUE if an update should occur;

  • FALSE otherwise.

Arg (data in): panf_enable_post_pulses
  • TRUE if a post pulse should occur;

  • FALSE otherwise.

Arg (data in): panf_cyl

The cylinder whose schedule is being updated.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_rel_on_angle

The angle at which to start injection pulse from TDC-firing of cylinder.
Range: [-360, 360] degrees, for a two-stroke engine
Range: [-720, 720] degrees, for a four-stroke engine

Arg (data in): panf_flow_time

The duration of injection flow time.
Range: [0, 349.5] milliseconds

Arg (data in): panf_dead_time

The duration of injection dead time.
Range: [0, 349.5] milliseconds
When the dead time is updated for injector 'n', it is updated for all injectors, as it is a shared parameter.

Arg (data in): panf_split_fuel_factor

The fraction of the flow time used when in split-fuel mode. See the corresponding parameter in pan_set_injection_pi() for details.
Range [0, 1) absolute

6.8.2.3.51. pan_get_injection_pi_setpoint()
Definition:

PAN_RC_T pan_get_injection_pi_setpoint(
   U8    panf_cyl,
   U8   *panf_enable_post_pulses,
   F32  *panf_rel_on_angle,
   F32  *panf_flow_time,
   F32  *panf_dead_time,
   F32  *panf_end_of_intake_angle,
   F32  *panf_split_fuel_factor);

Supported targets:

M220-000, M221-000 and M670-000

Required license:

None (Main library).

Description:

Function to read back port injection parameters for a given injector.

This function is used to read the port injection schedule for a given injector. This function can be used to verify that the data stored in eTPU memory match that which the application intended to write, allowing for checks of eTPU memory faults.

If this function is called while the eTPU is updating internal schedule parameters, it will wait until the eTPU is complete guaranteeing that all the parameters read are from a single schedule.

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_cyl

The cylinder that is being read back up.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data out): panf_enable_post_pulses

TRUE if a post pulse should occur or FALSE otherwise to match the value passed to pan_set_injection_pi().

Arg (data out): panf_rel_on_angle

The angle at which to start injection pulse from TDC-firing of cylinder to match the value passed to pan_set_injection_pi().
Range: [-360, 360] degrees, for a two-stroke engine
Range: [-720, 720] degrees, for a four-stroke engine

Arg (data out): panf_flow_time

The duration of injection flow time to match the value passed to pan_set_injection_pi().
Range: [0, 349.5] milliseconds

Arg (data out): panf_dead_time

The duration of injection dead time to match the value passed to pan_set_injection_pi().
Range: [0, 349.5] milliseconds

Arg (data out): panf_end_of_intake_angle

The angle at which to turn injector off to match the value passed to pan_set_injection_pi().
Range: [-720, 720] degrees, for a two-stroke engine
Range: [-1440, 1440] degrees, for a four-stroke engine

Arg (data out): panf_split_fuel_factor

The fraction of the flow time used when in split-fuel mode to match the value passed to pan_set_injection_pi().
Range [0, 1) absolute

Return:

6.8.2.3.52. pan_get_injection_pi_feedback()
Definition:

PAN_RC_T pan_get_injection_pi_feedback(
   U8    panf_cyl,
   U32  *panf_pulse_count,
   F32  *panf_flow_time_accum);

Supported targets:

M220-000, M221-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve port injection feedback information for a given injector/cylinder.

At the end of each port injection pulse, the ECU increments a counter of requested pulses and increments an accumulator of total injection flow time.

Whenever the ECU attempts to generate a pulse, the feedback information is updated. If the ECU cannot generate a pulse due to an electrical fault, or if the ECU partially generates a pulse due to the pulse schedule being cut short during the dead-time portion, the pulse count is incremented regardless.

The accumulated flow time does not include any of the dead-time portions, but does include priming/initial, main or post pulses, and correctly accounts for a pulse that is cut short due to the drop-dead angle.

The feedback information is incremented using modulo arithmetic. The application must call this function frequently enough to avoid inaccurate results due to the modulo operation.

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_cyl

The cylinder of the associated injector output channel to retrieve feedback information.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_pulse_count

The number of injection events that have occurred for cylinder/injector panf_cyl.
Range: [0, inf] modulo 8388608 pulses

Arg (data in): panf_flow_time_accum

The accumulated injection flow time for cylinder/injector panf_cyl.
Range: [0, inf] modulo 1041204 milliseconds

Return:

6.8.2.3.53. pan_config_knock()
Definition:

PAN_RC_T pan_config_knock(
   PAN_DEVICE_KNOCK_T   panf_knock_device,
   F32                  panf_region_start_angle);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to configure the parameters used to sample a knock sensor.

This function configures the knock processing functionality and sets the earliest starting angle of any knock detection window relative to each cylinder's TDC-firing angle.

Note

The angle sense differs from most other angular blocks. A positive value denotes an angle before TDC-firing, and a negative value denotes an angle after TDC-firing. See the earlier section "Relative angles to TDC-firing" for more.

See the earlier section "Knock sensor processing" for an overview of knock sensor processing. In short, the application schedules a sample window in which to process a knock sensor signal by calling the pan_set_knock_window() function. The parameters that can be adjusted for knock processing are set by the application by calling the an_set_knock_filter_hip901x() function . Shortly after the end of each sample window, the ECU completes knock signal processing and buffers the result which can be retrieved by the application by calling the pan_get_knock_feedback() function.

Arg (data in): panf_knock_device

The HIP901x device, as identified by the input pins associated with it. Use the macros included by the pio.h file, of the form PIO_KDEV_[4_PINS]_KNOCK.

Arg (data in): panf_region_start_angle

The earliest starting angle of any knock detection window relative to any cylinder's TDC-firing angle (positive angles before TDC).
Range: [-360, 360] deg

Return:

6.8.2.3.54. pan_get_knock_feedback()
Definition:

PAN_RC_T pan_get_knock_feedback(
   U8                   panf_cyl,
   PAN_LCHAN_KNOCK_T    panf_lchan,
   PIO_KNOCK_WINDOW_T   panf_knock_window,
   S16                 *panf_adc,
   BOOL                *panf_valid);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to retrieve the result of the last processed knock signal for a cylinder.

This function retrieves the result of the last processed knock signal for a cylinder. When the knock sensor signal was processed, and the parameters used in processing, are set by the application calling the pan_set_knock_window() and pan_set_knock_filter_hip901x() functions.

Knock signal processing is active in full engine synchronisation mode and disabled in other modes. When the ECU is not in full engine synchronisation mode, the knock processing result is forced to zero.

Arg (data in): panf_cyl

The cylinder to retrieve the processed knock result.
Range: [1, n]
where n is the number of cylinders specified when the application calls the pan_engine_config() function.

Arg (data in): panf_lchan

The knock channel to use as the knock input.
Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME].
Note that this parameter is currently unused, and is only provided for future expandability. The knock window channel is selected when the pan_set_knock_filter_hip901x() function is called.

Arg (data in): panf_knock_window

The knock window type to use. Must be set to:

  • PIO_KNOCK_WINDOW_ACTIVE - Use active knock window. Note that this parameter is unused, and is only provided for future expandability.

Arg (data out): panf_adc

Pointer to the conversion result for the last processed knock signal.
Range: [0, 4096] A/D counts

Arg (data out): panf_valid

Pointer to Boolean giving the validity of panf_adc. This parameter can be false if: lack of engine sync, knock is not configured in the application, the requested cylinder is outside of the number of cylinders configured for the engine, or if the requested knock start window is too close to the knock window region for the knock configuration (where "too close" is within 223 microseconds at the current engine speed).
Range: [0, 1] Boolean

Return:

6.8.2.3.55. pan_set_knock_window()
Definition:

PAN_RC_T pan_set_knock_window(
   U8                   panf_cyl,
   PAN_LCHAN_KNOCK_T    panf_lchan,
   PIO_KNOCK_WINDOW_T   panf_knock_window,
   F32                  panf_rel_on_angle,
   F32                  panf_rel_off_angle);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to schedule the angular region used to process a knock sensor signal for a cylinder.

This function schedules sampling and filtering of a knock transducer sensor signal in regions relative to each cylinder's TDC-firing event.

Note

The angle sense differs from most other angular blocks. A positive value denotes an angle before TDC-firing, and a negative value denotes an angle after TDC-firing. See the earlier section "Relative angles to TDC-firing" for more.

The filter characteristics are specific to the knock signal processing device. For the HIP901x family of knock signal processors, the pan_set_knock_filter_hip901x() function is used to configure these settings. The result of the sampling and filtering is provided by the pan_get_knock_feedback() function.

The above diagram shows a knock window relative to a cylinder's TDC-firing angle, where the knock transducer sensor signal is sampled and filtered. The knock window is chosen to centre on a cylinder's knocking event and is used to exclude other engine noise such as ignition and valve closing events.

For each cylinder, there is a region around the cylinder's TDC-firing angle within which a knock window can be generated.

If the start angle of the knock window lies outside the cylinder's region, or if the end angle occurs before start angle or if the window is too small to be generated reliably, no knock window is generated for that cylinder.

If the end angle extends into the next cylinder's region, the end angle is clipped so that it does not cause the knock window to extend into the next cylinder's region.

The result of the knock filtering is made available shortly after the end of the knock window via the pan_get_knock_feedback() function.

Knock signal processing is active in full engine synchronisation mode and disabled in other modes.

Arg (data in): panf_cyl

The cylinder for setting the knock window.
Range: [1, n]
where n is the number of cylinders specified when the application calls the pan_engine_config() function.

Arg (data in): panf_lchan

The knock channel to use as the knock input.
Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME].
Note that this parameter is currently unused, and is only provided for future expandability. The knock window channel is selected when the pan_set_knock_filter_hip901x() function is called.

Arg (data in): panf_knock_window

The knock window type to use. Must be set to:

  • PIO_KNOCK_WINDOW_ACTIVE - Use active knock window
    Note that this parameter is unused, and is only provided for future expandability.

Arg (data in): panf_rel_on_angle

Start angle of the knock detection window relative to the cylinder's TDC-firing angle (positive angles before TDC).
This function folds the angle into the range [0, 720) deg.

Arg (data in): panf_rel_off_angle

End angle of the knock detection window relative to the cylinder's TDC-firing angle (positive angles before TDC).
This function folds the angle into the range [0, 720) deg.

Return:

6.8.2.3.56. pan_set_knock_filter_hip901x()
Definition:

PAN_RC_T pan_set_knock_filter_hip901x(
   U8                          panf_cyl,
   PAN_LCHAN_KNOCK_T           panf_lchan,
   PIO_KNOCK_WINDOW_T          panf_knock_window,
   PIO_KNOCK_GAIN_T            panf_gain,
   PIO_KNOCK_BANDPASS_FREQ_T   panf_bandpass,
   PIO_KNOCK_TIME_CONST_T      panf_int_time_const);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Function to update the scheduled knock signal filtering parameters for a cylinder for the HIP901x family of engine knock signal processors.

This function sets the HIP901x device signal processing parameters to be applied to the knock transducer signal when it is sampled. The sensor sampling region is set by the application by calling the pan_set_knock_window() function. The result of the filtering is provided by the pan_get_knock_feedback() function.

A simplified view of the knock signal processing stages is given in the following block diagram:

  • The knock signal to process is first selected from two differential inputs, as selected by the application by calling the pan_config_knock() function. The device responsible for detecting knock can process just one sensor at a time.

  • The knock signal is then passed through a 3rd order anti-aliasing filter. This filter is required to have no more than 1dB attenuation at 20kHz (highest frequency of interest) and a minimum attenuation of 10dB at 180kHz.

  • The knock signal is then passed through a gain stage to compensate knock energies if needed.

  • The knock signal is then passed through a band-pass filter to detect the frequencies of interest. The filter frequency is established by the characteristics of the particular engine and transducer.

  • The knock signal is then passed through a full wave rectifier before being passed into an integrator stage, the output of which can be monitored for knock. Integration is towards the positive supply when a knock signal is present.

Knock signal processing is active in full engine synchronisation mode and disabled in other modes. When the ECU is not in full engine synchronisation mode, the knock processing result is forced to zero.

Arg (data in): panf_cyl

The cylinder for setting the knock window.
Range: [1, n]
where n is the number of cylinders specified when the application calls the pan_engine_config() function.

Arg (data in): panf_lchan

The knock channel to use as the knock input.
Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME].

Arg (data in): panf_knock_window

The knock window type to use. Must be set to:

  • PIO_KNOCK_WINDOW_ACTIVE - Use active knock window
    Note that this parameter is unused, and is only provided for future expandability.

Arg (data in): panf_gain

Gain applied to the knock transducer signal for the selected cylinder.
Use the macros included by the pio.h file, of the form PIO_KNOCK_GAIN_[GAIN].

Arg (data in): panf_bandpass

Bandpass centre frequency applied to the knock transducer signal for the selected cylinder.
Use the macros included by the pio.h file, of the form PIO_KNOCK_BANDPASS_FREQ_[FREQ]_KHZ.

Arg (data in): panf_int_time_const

Integration time constant applied to the knock transducer signal for the selected cylinder. See the HIP901x data sheet for further details.
Use the macros included by the pio.h file, of the form PIO_KNOCK_TIME_CONST_[TIMECONST]_US.

Return:

6.8.2.3.57. pan_convert_knock_filter_hip901x_values()
Definition:

PAN_RC_T pan_convert_knock_filter_hip901x_values(
   F32                         panf_gain_real,
   F32                         panf_bandpass_real,
   F32                         panf_int_time_const_real,
   PIO_KNOCK_GAIN_T           *panf_gain_enum,
   PIO_KNOCK_BANDPASS_FREQ_T  *panf_bandpass_enum,
   PIO_KNOCK_TIME_CONST_T     *panf_int_time_const_enum);

Supported targets:

M670-000

Required license:

None (Main library).

Description:

Convert real values for HIP901x filter values into enumeration values.

Arg (data in): panf_gain_real

Gain applied to the knock transducer signal.
Range: [0.111, 2] unitless

Arg (data in): panf_bandpass_real

Bandpass centre frequency applied to the knock transducer signal.
Range: [1.22, 19.98] kHz

Arg (data in): panf_int_time_const_real

Integration time constant applied to the knock transducer signal. See the HIP901x data sheet for further details.
Range: [40, 600] microseconds

Arg (data out): panf_gain_enum

Enum for gain closest to panf_gain_real.
selected cylinder.

Arg (data out): panf_bandpass_enum

Enum for bandpass closest to panf_bandpass_real.

Arg (data out): panf_int_time_const_enum

Enum for integration time constant closest to panf_int_time_const_real.

Return:

6.8.2.3.58. pan_config_sparks()
Definition:

PAN_RC_T pan_config_sparks(
   volatile const PDX_LCHAN_T  *panf_lchans,
   U32                          panf_chans,
   PIO_SPARK_TYPE_T             panf_spark_type,
   BOOL                         panf_invert,
   BOOL                         panf_do_presync_360);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to configure a set of spark channels for running an engine.

This function configures a set of spark output channels and the drive method (coil-on-plug or wasted spark). The drive method results in different spark pulse sequences depending on the engine synchronisation mode (see the earlier section "Engine synchronisation modes" for

  • Coil-on-plug - associates one spark output pin with one spark coil. In full engine synchronisation mode, the ECU generates one spark pulse. In half engine synchronisation mode, the ECU will either generate no spark pulses, or generate two spark pulses per engine cycle, depending on the panf_do_presync_360 parameter.

    Generating two spark pulses per engine cycle helps start the engine when the application does not know which half of the engine cycle is active. This mode of spark generation is similar to wasted spark, and indeed half of the sparks are wasted on average, but unlike the wasted spark mode, there must be one coil for each cylinder.

  • Wasted spark - associates one spark output pin with two spark coils. Each spark coil corresponds to one engine cylinder. The wasted spark option can be used to run a four-stroke engine that have evenly spaced TDC-firing angles with half as many spark output pins.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): panf_lchans

This is an array of output channels that will be configured as spark outputs. The first element will be applied to cylinder 1, the second to cylinder 2 and so on.
Must not be NULL.
Use the macros included by the pio.h file, of the form PIO_IGNOT_[NAME].

Arg (data in): panf_chans

The number of spark channels to configure, i.e, the number of elements in panf_lchans. This must be the same as the number of cylinders in the engine.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_spark_type

The spark type required, coil-on-plug or wasted spark. i.e., one of the PIO_SPARK_TYPE_[NAME] macros included by the pio.h file.

Arg (data in): panf_invert

Set to true to invert the polarity of the output, false otherwise.

Arg (data in): panf_do_presync_360

Set true to emit sparks every 360 degrees until full engine synchronisation has been obtained, false otherwise. Emitting sparks every 360 degrees can aid quicker engine starting for inline engines, but may be unsuitable for "V" engines if shared-coil wasted spark is also in use.

Return:

6.8.2.3.59. pan_set_spark()
Definition:

PAN_RC_T pan_set_spark(
   U8    panf_cyl,
   F32   panf_rel_on_angle,
   F32   panf_rel_off_angle);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to update the requested schedule of spark pulses for one spark channel.

This function schedules a spark pulse for a cylinder. See the earlier section "Scheduling coil outputs" for an overview of driving coils. In short, the ECU monitors the angle clock and generates a spark pulse based on the schedule's panf_rel_on_angle and panf_rel_off_angle, relative to a cylinder's TDC-firing angle.

Note

The angle sense differs from most other angular blocks. A positive value denotes an angle before TDC-firing, and a negative value denotes an angle after TDC-firing. See the earlier section "Relative angles to TDC-firing" for more.

The generation of one or more spark pulses is based on the current engine synchronisation mode and the configuration applied by the application. See the earlier section "Engine synchronisation modes" for an overview of synchronisation modes.

  • In full engine synchronisation mode with the wasted spark option disabled, the ECU generates one pulse per engine cycle per spark output pin.

  • In full engine synchronisation mode with the wasted spark option enabled, the ECU generates two pulses per engine cycle per spark output pin. The wasted spark option can be used to run a four-stroke engine that have evenly spaced TDC-firing angles with half as many spark output pins.

  • In half engine synchronisation mode with the 360 degree spark option disabled, the ECU will generate no spark pulses.

  • In half engine synchronisation mode with the 360 degree spark option enabled and the wasted spark option disabled, the ECU will generate two pulses per engine cycle per spark output pin. The spark schedule is repeated every 360 degrees.

  • In half engine synchronisation mode with the 360 degree spark option enabled and the wasted spark option enabled, the ECU will generate two pulses per engine cycle per spark output pin. The spark schedule with the later angle is chosen to be repeated every 360 degrees.

    Note

    On an evenly spaced TDC-firing angle engine, there is unlikely to be much of a difference between the two cylinder spark schedule requests. But for an unevenly spaced TDC-firing angle engine, it isn't possible to know which of two cylinder schedules to use for a single spark output pin. So the ECU chooses the last of the two schedules as being too late in one cylinder will give poor-torque firing but being too early in other cylinder may result in backwards firing.

    For this reason, neither wasted spark nor 360 degree spark options are recommended for an asymmetrical engine.

    In all cases, if the application requests a change to the spark schedule using this function, then the ECU takes one of two actions. If a spark pulse is being generated when the application makes the new schedule request, then the new request is buffered for the next cycle, but if a spark pulse is not being generated then the new request is used immediately. In the case where the new schedule is used immediately, this will result in a second spark pulse for the engine cycle if the new schedule starting angle is in the future.

If the application makes no further requests to update the spark schedule, then the ECU will repeat the schedule at most 4 times. Once the repeats are completed, the ECU clears the schedule and no further spark pulses are generated until the application requests a new spark schedule.

The spark functionality is active in half and full engine synchronisation mode only. In any other mode, the ECU forces all spark outputs off.

Note

Unlike other angular functionality, when an application updates the spark schedule, the ECU will wait for the existing spark pulse to complete (if one is active) and then immediately schedule the update. If the update can be scheduled in the same cylinder cycle, then it will be, otherwise the update will be scheduled for the next cylinder cycle. For this reason, it may be preferable to update the spark schedule using the TDC-calculation task, rather than using a periodic task.

If the ECU has electrical monitoring and protection features, that can automatically turn off a spark output in the event of over-current (for example), then leaving the spark output on for too long may lead to advanced spark timing when the ECU turns the spark output off before the end angle has been reached to protect the electronics.

Arg (data in): panf_cyl

This is the cylinder to update.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_rel_on_angle

This is angle on which to begin the spark pulse, relative to TDC for this cylinder. Note that a positive value indicates an angle before TDC-firing.
Range: [-360, 360] for two-stroke
Range: [-720, 720] for four-stroke

Arg (data in): panf_rel_off_angle

This is angle on which to end the spark pulse, relative to TDC for this cylinder. Note that a positive value indicates an angle before TDC-firing.
Range: [-360, 360] for two-stroke
Range: [-720, 720] for four-stroke

Return:

6.8.2.3.60. pan_spark_config_successful()
Definition:

BOOL pan_spark_config_successful(
   PAN_RC_T  *panf_config_result);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to discover if spark configuration was successful.

Some aspects of the spark configuration have to occur after the initialisation functions are called. This is because the ordering of calls to the various initialisation functions cannot be guaranteed. This function reports whether or not spark configuration post-initialisation was successful.

Arg (data in): panf_config_result

If non-NULL, a return code will be written here to allow a higher level of detail in the case of an error occurring during configuration. If configuration has yet to take place, a value of PAN_RC_INVALID will be written here.
Range: [NULL or valid address]

Return:
  • TRUE - configuration was successful

  • FALSE - configuration failed

6.8.2.3.61. pan_get_spark_feedback()
Definition:

PAN_RC_T pan_get_spark_feedback(
   U8    panf_cyl,
   F32  *panf_last_off_angle,
   U32  *panf_pulse_count);

Supported targets:

M220-000, M221-000, M250-000 and M670-000

Required license:

None (Main library).

Description:

Function to retrieve spark feedback information for a given cylinder.

At the end of each spark pulse, the ECU increments a counter of requested pulses and captures the requested off angle of the pulse.

When the ECU attempts to generate a pulse, the feedback information is updated. If the ECU cannot generate a pulse due to an electrical fault, the pulse count and off angle is updated regardless.

When capturing the last pulse off angle, the function does not make a distinction between the main pulse (requested) and either a secondary pulse for wasted spark on the same output channel, or a secondary pulse for starting an engine in half engine synchronisation mode. It is up to the application to make the distinction if that is required.

The feedback pulse count is incremented using modulo arithmetic. The application must call this function frequently enough to avoid inaccurate results due to the modulo operation.

Arg (data in): panf_cyl

The cylinder of the associated spark output channel to retrieve feedback information.
Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_last_off_angle

This is the angle which the last spark pulse ended, relative to TDC-firing for this cylinder. A positive value indicates an angle before TDC-firing.
Range: [-180, 180] for two-stroke
Range: [-360, 360] for four-stroke

Arg (data in): panf_pulse_count

The number of spark events that have occurred for this cylinder since the ECU was reset.
Range: [0, inf] modulo 8388608

Return:

6.9. Waveform properties feature (PROP)

6.9.1. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and prop.h
Enumerations
 PROP_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PROP) functions.

 PROP_ERROR_CODE_T

Error values for debugging when an error is found when calling the waveform properties feature (PROP), the API calls a function with an enumeration from this type.

 PROP_WAVEFORM_T

This enumeration gives the selectable waveform to configure.

 PROP_PHASE_NUM_T

This enumeration gives the selectable phase to set waveform properties for.

Data types
 PROP_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets.

Functions
PROP_RC_Tprop_set_phase_for_waveform_33816

Define the properties of a particular phase of a desired waveform.

PROP_RC_Tprop_set_waveform_for_output

Associate an output channel with a waveform.

PROP_RC_Tprop_configure_boost

Configure the boost supply.

6.9.2. Interface detail

6.9.2.1.  Enumerations

6.9.2.1.1. PROP_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some digital input feature (PROP) functions.

Enumerations:
PROP_RC_OK

Return code if everything progressed as expected.

PROP_RC_UNCONFIGURABLE_PHASE_OR_WAVEFORM

Return code if trying to configure more than the maximum number of phases or waveforms.

PROP_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PROP_RC_VBOOST_TOO_LOW

Return code if the boost supply voltage is configured too low.

PROP_RC_VBOOST_TOO_HIGH

Return code if the boost supply voltage is configured too high.

PROP_RC_DURATION_TOO_LOW

Return code if the phase duration is configured too low.

PROP_RC_DURATION_TOO_HIGH

Return code if the phase duration is configured too high.

PROP_RC_CURRENT_TOO_LOW

Return code if the phase current is configured too low.

PROP_RC_CURRENT_TOO_HIGH

Return code if the phase duration is configured too high.

PROP_RC_BOOST_NOT_ALLOWED

Return code if the phase is configured to drive boost, but is not allowed in that phase high.

6.9.2.1.2. PROP_ERROR_CODE_T
Summary:

Error values for debugging when an error is found when calling the waveform properties feature (PROP), the API calls a function with an enumeration from this type.

Enumerations:
PROP_CHANNEL_INVALID

Error raised if the channel 'n' is invalid.

'n' is (error_code - PROP_CHANNEL_INVALID).

PROP_DEVICE_INVALID

Error raised if the device 'n' is invalid.

'n' is (error_code - PROP_DEVICE_INVALID).

PROP_WAVEFORM_INVALID

Error raised if the waveform number 'n' is invalid.

'n' is (error_code - PROP_WAVEFORM_INVALID).

PROP_PHASE_INVALID

Error raised if the waveform number 'n' is invalid.

'n' is (error_code - PROP_PHASE_INVALID).

PROP_PHASE_1_3_NOT_CONFIGURED

Error raised if the waveform number 'n' phases 1 and 3 are not configred.

'n' is (error_code - PROP_PHASE_1_3_NOT_CONFIGURED).

PROP_PHASE_3_NOT_CONFIGURED

Error raised if the waveform number 'n' phase 3 is not configred.

'n' is (error_code - PROP_PHASE_3_NOT_CONFIGURED).

PROP_NO_PHASES_CONFIGURED

Error raised if the waveform number 'n' phase 1, 2, and 3 are not configred.

'n' is (error_code - PROP_NO_PHASES_CONFIGURED).

PROP_BOOST_NOT_CONFIGURED

Error raised if any phase attempts to configure a phase as boosted, but the boost supply has not been configured.

6.9.2.1.3. PROP_WAVEFORM_T
Summary:

This enumeration gives the selectable waveform to configure.

Enumerations:
PROP_WAVEFORM_1

Waveform type 1.

PROP_WAVEFORM_2

Waveform type 2.

PROP_WAVEFORM_3

Waveform type 3.

PROP_WAVEFORM_4

Waveform type 4.

PROP_WAVEFORM_MAX
6.9.2.1.4. PROP_PHASE_NUM_T
Summary:

This enumeration gives the selectable phase to set waveform properties for.

Enumerations:
PROP_PHASE_1

Phase 1 properties.

PROP_PHASE_2

Phase 2 properties.

PROP_PHASE_3

Phase 3 properties.

PROP_PHASE_MAX

6.9.2.2.  Data types

6.9.2.2.1. PROP_LCHAN_T
Definition:

typedef U16 PROP_LCHAN_T

Description:

This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target.

6.9.2.3.  Functions

6.9.2.3.1. prop_set_phase_for_waveform_33816()
Definition:

PROP_RC_T prop_set_phase_for_waveform_33816(
   PIO_WAVEFORM_T   propf_waveform,
   PIO_PHASE_T      propf_phase,
   F32              propf_t_drive_on,
   F32              propf_t_drive_off,
   F32              propf_t_dither_off,
   F32              propf_c_max,
   BOOL             propf_vboost,
   BOOL             propf_switch_at_c);

Required license:

None (Main library).

Description:

Define the properties of a particular phase of a desired waveform.

Define the properties for a phase of a waveform.

Can raise the following errors:
PROP_WAVEFORM_INVALID + propf_waveform

Arg (data in): propf_waveform

The waveform to configure. Use values of the enum PIO_WAVEFORM_T included by the pio.h file.

Arg (data in): propf_phase

The phase of the waveform to configure. Use values of the enum PIO_PHASE_T included by the pio.h file.

Arg (data in): propf_t_drive_on

The total duration of the phase to configure, in microseconds.
Range: [0, 3000] us if phase is boosted or
[0, 10922.5] us if non-boosted.

Arg (data in): propf_t_drive_off

The total duration of the switch time. This is the time when the waveform switches from one phase to the next.
Range: [0, 10922.5] us.

Arg (data in): propf_t_dither_off

The off time for the hysteresis during the current control.
Range: [10, 10922.5] us.

Arg (data in): propf_c_max

The current threshold value to trip for current control.
Range: [0, 25] A if phase is boosted or
[0, 16] A if non-boosted.

Arg (data in): propf_vboost

Whether or not this phase uses the boost supply for current control. This property is ignored if the boost supply has not been configured.
Range: 0 if this phase uses battery,
1 if this phase is boosted.

Arg (data in): propf_switch_at_c

Whether or not this phase immediately switches to the next phase when the current threshold is reached. Range: 0 if this phase continues for a duration after it reaches maximum current,
1 if it switches immediately to the next phase.

Return:

6.9.2.3.2. prop_set_waveform_for_output()
Definition:

PROP_RC_T prop_set_waveform_for_output(
   PIO_WAVEFORM_T   propf_waveform,
   PROP_LCHAN_T     propf_lchan);

Required license:

None (Main library).

Description:

Associate an output channel with a waveform.

Sets one of the output channels to a particular configured waveform.

Can raise the following errors:
PROP_CHANNEL_INVALID + propf_lchan

Arg (data in): propf_waveform

The waveform to associate with an output. Use macros from PIO_WAVEFORM_T enum. The waveform must be properly configured before platform post initialisation.

Arg (data in): propf_lchan

The channel to use for the output. Use the macros included by the pio.h file, of the form PIO_PHOT_[NAME] or PIO_BPHOT_[NAME].

Return:

6.9.2.3.3. prop_configure_boost()
Definition:

PROP_RC_T prop_configure_boost(
   F32   propf_boost_voltage);

Required license:

None (Main library).

Description:

Configure the boost supply.

Configure the boost supply of the ECU.

Arg (data in): propf_boost_voltage

The desired boost voltage to set.
Range: [40, 65] V.

Return:

Chapter 7. Extended Diagnostics Functions

This section gives details on the Extended Diagnostics Functions which are an optional addition to the OpenECU platform.

7.1. Introduction to Diagnostics

The legislated requirements for the infrastructure to manage on-board diagnostics data has grown steadily over the years. This section describes the OpenECU approach to providing that support in a flexible way. This allows the users of OpenECU and related systems to concentrate on the system they are developing and at the same time meet the legislated requirements for emissions related control systems.

The diagnostic infrastructure support has been designed to meet both CARB and EURO diagnostics requirements and communicate with scan tools according to both heavy duty (J1939) and passenger car (ISO15765) protocols. It is aimed at vehicles which have to comply with 2010 and beyond legislation (eg EURO6).

It is important that the user understands general OBD terminology and the interactions between the various SAE/ISO standards and emissions/OBD legislated requirements. The standards are generally very good at describing their own terms and acronyms; therefore they have not been repeated here. There is no substitute for reading the relevant standard. A quick browse is absolutely essential, so that you will know where to look when the time comes for more detailed information.

The term diagnostics can be taken to mean many different tasks on different levels. The following diagram shows some of these. Details of how the user's application has to interact with the OpenECU platform are described below.

Figure 7.1. Functional Levels within a Diagnostics System

Functional Levels within a Diagnostics System

7.2. Diagnostic Legislation

The OpenECU diagnostics infrastructure has been tailored to meet the following legislation. In many cases, the exact description for a particular behaviour has to be extracted from more than one document.

For European OBD documents, most of the emissions related legislation is held within Directive 70/220/EEC, which has been amended many times over the years. OBD requirements are held within Annex XI, which itself was created and subsequently modified by directives:

  • 1998/69/EC

  • 1999/102/EC

  • 2002/80/EC

  • 2003/76/EC

For heavy-duty diesel vehicles the Commission brought in Directive 2003/522. Subsequently, Directive 2005/55/EC introduced additional requirements for Euro-V emissions compliant diagnostic systems from 2008 or 2009 onwards. This was in turn amended by:

  • 2005/78/EC

  • 2006/51/EC

  • 2008/74/EC

For Euro-VI heavy duty diesel vehicles, the previous regulations were revoked and a new Commission Directive 582/2011 was put in place.

The Californian (CARB) diagnostics requirements are captured within Title 13 California Code of Regulations in either section 1962.8 for passenger cars, light and medium duty vehicles or section 1971.1 for heavy duty vehicles.

Scan tool communications fall into two main categories: heavy duty using J1939 and light duty using ISO15765 based protocols. The second (light duty) category also includes the original J1979 diagnostic service requirements (also described in ISO15031-5) as well as the higher numbered KWP2000 and UDS services.

The J1939 requirements are based on the SAE standards:

  • J1939-03 On Board Diagnostics Implementation Guide

  • J1939-73 Application Layer - Diagnostics

  • J1939-21 Network Layer (Transport Protocol)

The ISO related requirements are based on:

  • ISO15031, parts 5,6 and 7

  • ISO15765, parts 2,3 and 4

The implementation within the OpenECU platform attempts to steer a course through these various diagnostics requirements. At times they conflict and in such cases, the implementation allows the user to select one alternative or another. There are also cases where a user may want to deliberately over-ride some aspect of the protocol or diagnostic requirements (e.g. during manufacturing). In these cases, the platform provides the user application with the ability to make those changes. Therefore it is essential that the application works together with the platform to provide a coherent and legally compliant diagnostic system. It cannot be left to just one side or the other.

One of the more confusing areas is the overlap between J1939-73 and ISO15031-5 (J1979) services for the generic, mandatory services. Both protocols have the ability to transmit more or less the same information, but in wildly different ways. The following table is loosly derived from one in J1939-73 and attempts to translate between the two.

Table 7.1. Diagnostic Service Comparisons

ISO/J1979 ServiceISO DescriptionJ1939 DMJ1939 Description
0x01 PID 00Request Powertrain Data - index of supported PIDsDM24Use DM24 to declare emissions related support for powertrain data and DM25 freeze frame
0x01 PID 01Number of DTCs, MIL status, supported monitors and their status (readiness)DM5OBD compliance, previously active and active DTC count monitors supported and their status (readiness)
0x01 PIDs 03-1BActual current powertrain parameter dataVariousNormally provided PGs will be used to retrieve the parameter data
0x01 PID 1COBD legislation supportedDM5Which OBD legislation is supported
0x01 PID 21, 4D, 31, 4EDistance and time while MIL on, Distance and time since DTCs clearedDM21Diagnostic Readiness 2 reports this data
0x01 PID 41, 1F, 30Continuously monitored systems status, time since engine start, number of warm ups since DTCs clearedDM26Diagnostic Readiness 3 reports status of monitors on this data
0x02Freeze frame data - byte00 says which PIDs supported, byte02 says which DTC caused each freeze frame, bytes 04-FF have the dataDM4, DM24/DM25DM 4 contains basic freeze frames - note the PG tells what DTC caused it and the PG contains standard parameter data. DM25 provides more parameter support than DM4. DM24 says which SPNs are supported.
0x03Emission-related powertrain DTCsDM1 or DM12, DM23Emissions related active(MIL on) DTCs and lamp status regular message on DM1 or when required on DM12. DM23 can report DTCs which are confirmed but the MIL is off.
0x04Clear all emissions related OBD dataDM3 or DM11DM3 clears previously active DTCs and DM11 clears all DTCs
0x05Oxygen sensor test data (use service 0x06 instead)Not usedNo planned support for specific oxygen sensor data
0x06Test results for non-continuously monitored systemsDM10, DM7, DM8, DM30DM10 gives the test IDs supported, DM7 invokes the test and DM8 or DM30 are used to report the test results
0x07Emissions-related Pending DTCsDM6, DM27DM6 has emissions related Pending DTCs and DM27 has all Pending DTCs
0x08Request control of onboard system, test or componentDM7, DM8DM7 commands the test and DM8 reports the results
0x09 Infotype 00Infotype 00 declares which other infotypes are supportedVariousIndividual DMs used for specific infotype data
0x09 Infotype 01 / 02Vehicle's VIN numberData StreamReported on Data Stream (J1939-71), using PGN 65260
0x09 Infotype 03 / 04Vehicle information - Calibration IDDM19Bytes 5-20 contain calibration information
0x09 Infotype 05 / 06Vehicle information - Calibration verification number (CVN)DM19Bytes 1-4 contain CVN
0x09 Infotype 07 / 08In use performance ratios for diagnostic monitorsDM20Indicates how often monitors complete compared to vehicle operation
0x09 Infotype 09 / 0AECU acronym and name  
0x0APermanent DTCs (emissions related)DM28Permanent DTCs (emissions related)

7.3. Approach

The approach to implementing the diagnostics functions is a balance between providing flexibility and requiring minimal intervention. The user needs the ability to configure their data and choose which services to support. In some cases, the scan tool interactions do not require additional user code as the data is well structured and can be reported simply by the OpenECU platform.

The user needs to define the diagnostic data through the C-API tool. This will then allow functions to be called relating to DTCs, freeze-frames, PIDs, monitors etc.

The diagnostics system works closely with the NVM file system. Again, the user has some flexibility in terms of allocating certain amounts of memory or choosing when data is written, but for the most part, this interface is seamless. Diagnostic data can be stored when desired (e.g. when the ignition key is turned off) and is retrieved safely with minimal input from the user.

Communications with the scan tool behave slightly differently for J1939 compared to ISO15765 and related protocols. For J1939, the user's application is required to check for scan tool requests and emit replies as required. However, for most of the ISO15765 standard services, the data is retrieved by the platform and sent back to the scan tool with minimal intervention from the user's application. However, the application must keep the required data up to date.

Figure 7.2. Scan tool link via Platform

Scan tool link via Platform

7.4. Diagnostic Trouble Codes and Freeze-Frames

Diagnostic Trouble Codes (a.k.a. DTCs or fault codes) are the basic building blocks of the diagnostic infrastructure. There are multiple standards for the fault information to follow as well as choices for its life-cycle depending on whether it is emissions-related or permanent and the legislation being followed. These details are selected as part of the function call for each DTC thereby allowing the user to configure the system for various aspects of diagnostic legislation.

DTCs may be grouped into tables to help the user manipulate them. They can then be cleared (by table name) if required.

DTCs will also have an associated freeze-frame that is stored when the fault occurs. The user may specify several different types of freeze-frame for use with different DTCs. The various freeze-frame definitions may include more or less data to be captured when a fault occurs. Note that the legislation requires some specific pieces of data to be captured for emissions related faults.

For a specific piece of data to be captured in a freeze-frame, the application needs to provide it to the platform. This is one of the uses of the ppid_update_pid() function (also used for J1939 SPN data). The platform can grab the latest data the application supplied when required. The same update mechanism allows the OpenECU platform to provide real-time data from within the user's application to a scan tool (e.g. for J1979 service $01 or J1939 DM24).

There are user configurations related to freeze-frames, which determine the total number to capture and the maximum amount of RAM and NV memory to allocate for freeze-frames. This allows the user to limit the allocation of memory (e.g. in the event of repeated faults) while at the same time making maximum use of the resources available in the ECU. This flexibility means that the system can be tailored to be more useful during development phases (when extra memory may be available) and then scaled back for the production version without changes to the application structure. See also Section 8.1.4.25, “Compound statement: ff-data”.

There are various interface file options (see Section 8.1.4.28, “Compound statement: dtc-data”) describing how the faults should behave. In particular, note the distinctions between CARB permanent and Euro non-eraseable DTCs. In each case the conditions required to clear the DTC are fully specified in the relevant legislation.

7.5. Diagnostic Monitors, Tests and Performance Ratios

A complete emissions related diagnostic system will have a have a set of diagnostic monitors to check the performance of each of the various components on a vehicle. These diagnostic monitors are in turn made of a series of diagnostic tests. The individual tests may be performed continuously, for example checking the range of an analogue input or the state of an output signal. Alternatively the tests may be classed as non-continuous which means that they can only be performed when the vehicle is in a certain operating state for example checking the performance of a catalyst or the EGR sub-system.

The OpenECU platform allows the user to define the monitors and related tests in the system using interface file statements. See Section 8.1.4.34, “Compound statement: dme-data” and Section 8.1.4.32, “Compound statement: dte-data”.

The user's application can use the functions ppr_update_dme_in_use_status() and ppr_update_dte_in_use_status() to indicate whether a DME or DTE is in-use in the current application build. This is useful in allowing the run-time configuration of an application for a system if required.

The user's application must use the functions ppr_update_dme_data(), ppr_update_dte_data() and ppr_update_dte_test_value() in conjunction with their individual diagnosis algorithms and provide data from each time an individual test is performed. The data is used in two ways by the platform:

  • Firstly, each time a test is run, this allows the platform to update the numerator and denominator to be used in calculating the In-Use-Performance-Ratio for that particular diagnostic.

  • Secondly the most recent test results (and limits) must be available for communication to a scan tool. The platform will store this data in NVM (to keep it in the event of a power down) for future communication to a scan tool.

Note that the legislation has some specific values (MonitorID) that must be used for specific sub-system emissions monitors.

7.6. Worked Example - building a diagnostic system

In this example, we will build a hypothetical flow monitor which is to be part of an emissions compliant system and therefore needs to meet legal diagnostic requirements. We shall build it to meet Californian OBD regulations and the scan tool will use ISO 15765 to communicate with the ECU.

7.6.1. Step 1 — Test Conditions at the Monitor level

The flow monitor is made up of two individual flow tests, each of which can only be performed under certain conditions. The application needs to select the conditions to trigger each of the actual tests. In legal terms, this is a non-continuous monitor and therefore needs to inform the system when it can run for use in determining the In Use Performance Ratio (numerator / denominator).

The application code below shows a set of conditions for each of the tests being used to control whether two functions are run. Each of those functions will contain an individual flow test and associated interfaces. A Diagnostic Test Entity is updated for each test, maintaining a performance ratio for each.

static BOOL low_flow_complete  = FALSE;
static BOOL high_flow_complete = FALSE;

BOOL both_tests_run;

BOOL normal_state   = (Operational_state    == mftc_normal_operation_state );
BOOL at_temperature = (Measured_temperature >  mftc_temperature_thresh_high);
BOOL flow_low       = (Flow_parameter       <  Another_flow_parameter      );
BOOL pressure_high  = (Measured_pressure    >= mftc_pressure_thresh_high   );
BOOL pressure_low   = (Measured_pressure    <= mftc_pressure_thresh_low    );

BOOL run_low_flow_test  = (normal_state && at_temperature && pressure_high &&  flow_low);
BOOL run_high_flow_test = (normal_state && at_temperature && pressure_low  && !flow_low);

BOOL monitor_enabled = (run_low_flow_test || run_high_flow_test);



if (run_low_flow_test)
{
    Low_Flow_Test(&low_test_value, &low_test_limit, &low_flow_complete);
}

if (run_high_flow_test)
{
    High_Flow_Test(&low_test_value, &high_test_limit, &high_flow_complete);
}

ppr_update_dte_data(LOW_FLOW_DTE_ID,           /* U8 pprf_dte_id */
                    run_low_flow_test,         /* BOOL pprf_sp_den_update_enable */
                    low_flow_complete);        /* BOOL pprf_sp_num_update_enable */
                    
ppr_update_dte_test_value(LOW_FLOW_DTE_ID,     /* U8 pprf_dte_id */
                          low_test_value,      /* U16 pprf_test_value */
                          low_test_limit,      /* U16 pprf_test_limit_min */
                          mftc_low_max_fixed,  /* U16 pprf_test_limit_max */
                          run_low_flow_test,   /* BOOL pprf_test_run */
                          FALSE);              /* BOOL pprf_reset_dte */
                                  
/* Similarly for HIGH_FLOW_DTE, omitted here for brevity */

The overall diagnostic monitor entity (DME) is updated depending on whether all of the possible DTEs in the group have been run. It is possible to force the DME state update for development purposes, but these parameters have been left FALSE.

both_tests_run = (low_flow_complete && high_flow_complete);

ppr_update_dme_data(FLOW_DME_ID,               /* U8 pprf_dme_id */
                    both_tests_run,            /* BOOL pprf_monitor_run */
                    FALSE,                     /* BOOL pprf_force_complete */
                    FALSE,                     /* BOOL pprf_force_not_complete */
                    monitor_enabled);          /* BOOL pprf_monitor_enabled */

For an ISO based scan tool, the data is accessed by a Service $06 command. Passing the data to the scan tool is handled directly by the platform.

7.6.2. Step 2 — Individual Flow Tests

We’ve invented two individual tests which make up our flow monitor. The principle is the same for each, so will only consider one here.

The example code below shows how an individual pass/fail result is used to set and clear DTCs. In practice a more complex debouncing strategy might be used (e.g. using put_leaky_bucket_f32()).

static void High_Flow_Test(U16* test_value, U16* test_limit, BOOL* test_complete)
{
    F32 test_limit_float;
    
    put_cal_map_2d_f32(Flow_data.pressure, Flow_data.temperature, 
                       MFTM_HIGH_FLOW_NX, MFTM_HIGH_FLOW_NY S32 putf_nx,
                       mftm_high_flow_lim_x, mftm_high_flow_lim_y, mftm_high_flow_lim_z,
                       &test_limit_float);
    *test_limit = (U16) test_limit_float;
    
    *test_value = Flow_test_algorithm(Flow_data.parameter1, Flow_data.parameter2);
    
    millisec_since_last = ptm_ms_time_diff_update(&time_last_ran);
    sec_since_power_on  = ptm_s_time_diff(startup_time);
    
    if (*test_value <= *test_limit)
    {
        out_of_range_time_ms += millisec_since_last;
    }
    
    test_failed = (out_of_range_time_ms > Hi_flow_time);
    
    if (sec_since_power_on > Hi_flow_test_duration)
    {
        *test_complete = TRUE;
    }
    
    pdtc_update_plat_obd_dtc(&HighFlowDtc,    /* const PDTC_DTC_T *const pdtcf_const_dtc */
                             test_failed,     /* BOOL pdtcf_test_failed */
                             *test_complete); /* BOOL pdtcf_test_completed */
}

We’ve made up some imaginary table which provides a test limit. The flow test algorithm computes a value which is compared against this limit. If the value is greater than the limit, then an integrator adds up the time for which it is over the limit. Once suitable time has passed, the test is considered to have failed and a fault code will be stored by calling the DTC update function.

The duration timer allows for sufficient time to pass and if the test value was not above the limit, the test will be completed and passed.

Recall that the test limits and test value are passed out to the DTE for use in the event of a scan tool service $06 request. The platform is asked to store the new results after a short delay. This is required, as the service $06 request needs to be given the most recent test results, even if those results are days or even weeks old.

When a DTC is triggered (via the test_failed flag as shown above) an emissions related system must capture a freeze frame. This mechanism uses the PID and freeze-frame facilities; see also Section 8.1.4.30, “Compound statement: pid-data” and Section 8.1.4.25, “Compound statement: ff-data”.

7.6.3. J1979/ISO 15031 Scan tool request/response

Once a model has been built with the diagnostics integrated, there is very little left for the application to do to respond correctly to J1939/ISO 15031 scan tool requests. The platform keeps track of any DTCs and whether they are classed as “pending” or “active” etc. The data entered into each DTC block will define this. As drive-cycles and warm-up cycles go by, fault data and freeze-frame data will be erased if they don’t recur. Similarly as individual tests happen, the test result data is stored, together with the numerator/denominator counts for each of the defined monitors.

If a scan tool now follows the J1979/ISO 15031 standard to request emissions data, the OpenECU system will respond with the correctly formatted data for each request. The full list of emissions related diagnostic services are detailed below.

The build process will automatically create a calibration variable named pdgc_emissions_report_min_sev with a default value of "sev-c". This calibration is used to determine the emissions severity level at or above which the platform will include a DTC when transmitting DM32 data.

The build process will create entries for this value in the A2L file for sev-a (highest), sev-b1, sev-b2, sev-c, or sev-none (lowest). To emit all DTCs regardless of their emissions severity level, use sev-none.

In order to change the default value, use the emissions-report-min-severity statement in the configuration file.

Table 7.2. PDG supported services

IDServiceNotes
0x01Request Current Powertrain Diagnostic Data (J1979)Used to read PID values that have a J1979 8-bit identifier defined
0x02Request Powertrain Freeze Frame Data (J1979)Used to read PID values that have been captured when a DTC occurred
0x03ReadEmissionDTCs (J1979)Reports only DTCs defined as emission-related
0x04ClearEmissionDTCs (J1979)Clears only DTCs defined as emission-related
0x06RequestOBDTestResults (J1979)Reports test results for ISO test IDs
0x07ReadEmissionDTCsPending (J1979)Reports only DTCs defined as emission-related that are pending
0x09RequestVehicleInformation (J1979)Used to read Vehicle Information data stored as InfoTypes
0x0AReadEmissionDTCsPermanent (J1979)Reports only DTCs defined as emission-related that are permanent
0x10StartDiagnosticSession (KW2000-3) or DiagnosticSessionControl (UDS)Used to request a change between diagnostic sessions. (Default, Extended and Programming)
0x11ECUReset (KW2000-3, UDS)Used to reset the ECU. Only supported by Bootloader to exit reprogramming mode
0x14ClearDiagInfo (KW2000-3, UDS)Clears all or subgroup of ISO DTCs (not J1939-only DTCs)
0x17ReadStatusOfDTC (KW2000-3)Reports the status of the specified DTC
0x18ReadDTCByStatus (KW2000-3)All DTCs, regardless of emissions severity
0x19ReadDTCInfo (UDS)16-bit DTCs currently output, lower byte zero; many subfunctions
0x21ReadDataByLocalIdentifier (KW2000-3)Used to read PID values using an 8-bit identifier
0x22ReadDataByCommonID (KW2000-3, UDS)Used to read PID values using an 16-bit identifier
0x23ReadMemoryByAddress (KW2000-3, UDS)Used to read raw memory contents (subject to security restrictions)
0x24ReadScalingDataByIdentifier (UDS)Used to read scaling data for a PID
0x27SecurityAccess (KW2000-3, UDS)Used to grant security access in boot loader mode
0x28CommunicationControl (UDS)Used to switch on/off the transmission and or the reception of certain messages
0x28DisableNormalMessageTransmission (J2190)Used to switch off the transmission of non-diagnostic and non-network management messages
0x29EnableNormalMessageTransmission (J2190)Used to switch on the transmission for all messages
0x2AReadDataByPeriodicIdentifier (UDS)Used to request automatic periodic transmission of selected PIDs
0x2CDynamicallyDefineDataIdentifier (UDS)Used to specify a new PID composed of other PIDs or memory reads
0x2EWriteDataByLocalIdentifier (KW2000-3, UDS)Used to write PIDs specified by 16-bit identifier (eg NV PID data)
0x2FIOControlByCommonID (KW2000-3, UDS)Used to override PID values using a 16-bit identifier
0x30IOControlByLocalID (KW2000-3, UDS)Used to override PID values (identified by KW2000 8-bit local identifier)
0x31RoutineControl (UDS)Used to initiate a specified process in boot loader mode, e.g. erase memory
0x34RequestDownload (KW2000-3, UDS)Used to initiate a downloading of a block of memory in boot loader mode (only the downloading of unencrypted, uncompressed data is currently supported)
0x36TransferData (KW2000-3, UDS)Used to download data in boot loader mode (only the downloading to flash is currently supported)
0x37RequestTransferExit (KW2000-3, UDS)Used to terminate data transfer between the tester and the ECU in boot loader mode
0x3ETesterPresentPing” to maintain communications
0x85ControlDTCSettingUsed to Stop or Start the setting of DTCs

Note

Services $14, $17 and $18 use the ISO 15031-6 values for groupOfDTC groups in KW2000-3 style (powertrain 0x0000, chassis 0x4000, body 0x8000, network/other 0xC000, all 0xFF00). For $14, the equivalent 24-bit UDS values may alternatively be used (0x000000, 0x400000, ... and 0xFFFFFF for 'all').

Note

Please contact Pi Innovo for support with flash reprogramming. The EraseMemory routine ($FF00) typically specified by OEMs is supported in two formats:

  • Numeric range: If a length is supplied, the address value is interpreted as an actual device address and the specified range is erased.

  • Logical index: If no length is supplied, the address value is interpreted as the zero-based index of the eraseable flash block, which is device-dependent. For example, the MPC5534 M0 block (0x40000 - 0x5FFFF) has index 6. This follows the HIS group reprogramming specification.

7.7. Extended Diagnostic Functions

7.7.1. J1939 Extended Diagnostics feature (PJ1939)

7.7.1.1. Overview

This section covers the extended diagnostics functions available in addition to the basic J1939 functions (see Section 5.17, “J1939 (SAE) messaging feature (PJ1939)”):

SAE J1939/73

Defines the application layer diagnostics, which includes (amongst other things) support for Diagnostic Trouble Codes (DTC).

The library supports the following diagnostic messages (to deal with Diagnostic Trouble Codes):

DM1

All active Diagnostic Trouble Codes

DM2

All previously active Diagnostic Trouble Codes

DM3

Clear all previously active Diagnostic Trouble Codes

DM6

Pending emissions-related Diagnostic Trouble Codes

DM11

Clear all Diagnostic Trouble Codes

DM12

Active emissions-related Diagnostic Trouble Codes

DM23

Previously active emissions-related Diagnostic Trouble Codes

DM27

All pending Diagnostic Trouble Codes

DM28

Permanent Diagnostic Trouble Codes

DM35

Transient Diagnostic Trouble Codes

DM40

Harmonized B1 Diagnostic Trouble Codes

The library supports the following diagnostic messages, to deal with freeze frame data:

DM4

Freeze Frame Parameters

DM24

SPN Support

DM25

Expanded Freeze Frame

The library supports the following diagnostic messages, to deal with diagnostic readiness data:

DM5

Diagnostic Readiness 1 Data.

DM20

Monitor Performance Ratio.

DM21

Diagnostic Readiness 2 Data.

DM26

Diagnostic Readiness 3 Data.

The library supports the following diagnostic messages, deal with World Wide Harmonization and Global Technical Regulation:

DM36

Harmonized Vehicle Roadworthiness.

DM37

Harmonized System Roadworthiness.

DM38

Harmonized Global Technical Regulation Description.

DM39

System Cumulative Continuous MI.

It is assumed throughout this document, that the reader is familiar with the SAE J1939 specifications.

7.7.1.2. Extended Diagnostic messages

The extended diagnostics library provides functions to help deal with diagnostic messaging in addition to the basic DM1 and DM1 functions in the core library, specifically DM3, DM4, DM5, DM6, DM7, DM8, DM10, DM11, DM12, DM20, DM21, DM23, DM24, DM25, DM26, DM27, DM28, DM29, DM30, DM31, DM35, DM36, DM37, DM38, DM39, DM40, DM41, DM42, DM43, DM44, DM45, DM46, DM47, DM48, DM49, DM50, DM51, and DM52 messages through the functions pj1939_dm4_transmit(), pj1939_dm5_transmit(), pj1939_get_dm7_commanded_test(), pj1939_dm8_transmit(), pj1939_dm10_transmit(), pj1939_dm20_transmit(), pj1939_dm21_transmit(), pj1939_dm24_transmit(), pj1939_dm25_transmit(), pj1939_dm26_transmit(), pj1939_dm30_transmit(), pj1939_dm35_transmit(), pj1939_dm36_transmit(), pj1939_dm37_transmit(), pj1939_dm38_transmit(), pj1939_dm39_transmit(), pj1939_dm40_transmit(),

The extended library provides functions to help deal with additional diagnostic messaging, specifically DM32, DM33 and DM34 messages, through the functions pj1939_dm32_transmit(), pj1939_dm33_transmit() and pj1939_dm34_transmit().

In accordance to the J1939/73 specification, section 5.7, these messages are transmitted on request.

The library provides a function to set the status of engine operating in the NTE control areas for pollutants NOx and PM pj1939_set_control_area_status().

The library provides functions to set the engine hour timers for AECDs pj1939_update_aecd_eng_timer1() and pj1939_update_aecd_eng_timer2().

7.7.1.3. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pj1939.h
Macros
 PJ1939_RX_DATA

Indicates that a fresh message has been received since last polled.

 PJ1939_RX_OVERRUN

Indicates that more than one message has been received since last polled.

 PJ1939_RX_ERROR

Indicates that a receive error occurred associated with a message.

 PJ1939_SAE_RESERVED_1

SAE reserved.

 PJ1939_OBD_II

OBD II (CARB).

 PJ1939_OBD

OBD (Federal, EPA).

 PJ1939_OBD_OBD_II

OBD and OBD II.

 PJ1939_OBD_I

OBD I.

 PJ1939_NO_OBD_II

Not intended to meet OBD II requirements.

 PJ1939_EOBD

EOBD.

 PJ1939_EOBD_OBD_II

EOBD and OBD II.

 PJ1939_EOBD_OBD

EOBD and OBD.

 PJ1939_JOBD

JOBD.

 PJ1939_JOBD_OBD_II

JOBD and OBD II.

 PJ1939_JOBD_EOBD_OBD_II

JOBD, EOBD and OBD II.

 PJ1939_HDV_B1

Heavy Duty Vehicles (EURO 1V) B1.

 PJ1939_HDV_B2

Heavy Duty Vehicles (EURO V) B2.

 PJ1939_HDV_C

Heavy Duty Vehicles (EURO EEC) C (gas engines).

 PJ1939_EMD

Engine Manufacturer Diagnostics.

 PJ1939_EMD_PLUS

Engine Manufacturer Diagnostics Enhanced (EMD+).

 PJ1939_HDV_OBD

Heavy Duty/OBD.

 PJ1939_WWH_OBD

World Wide Harmonized OBD.

 PJ1939_OBD_II_REV

OBD II (CARB) Revised.

 PJ1939_HD_EOBD_REV

Heavy Duty Vehicles (EURO IV and V) Revised.

 PJ1939_SAE_RESERVED_2

SAE reserved.

 PJ1939_OBD_M_SI_SD_I

OBD-M Compliance for Spark_Ignition Sterndrive and Inboard Engines.

 PJ1939_EURO_VI

Heavy Duty Vehicles EURO VI (revisions specified in 2010-2011).

 PJ1939_OBD_OBD_II_HD_OBD

OBD, OBD II, and Heavy Duty/On-Board Diagnostics (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 20].

 PJ1939_OBD_OBD_II_HD_OBD_P

OBD, OBD II, and Heavy Duty/On-Board Diagnostics Partial (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 19].

Enumerations
 PJ1939_ACK_AND_CONTROL_BYTE_T

The type of PGN response required A J1939 acknowledgement message can be of type Positive Acknowledgedment(ACK), Negative Acknowledgement(NACK), Access Denied(ACCESS_DENIED) or Cannot Respond(BUSY).

 PJ1939_NTE_CNTRL_AREA_STATUS_T

The NTE control area status.

 PJ1939_NTE_CNTRL_AREA_T

The NTE control areas.

 PJ1939_EXT_DTC_TX_T_

The DM formats supported by the pj1939_ext_dtc_transmit function.

Data types
 PJ1939_DM7_BUFFER_T

This is a structure to store details of requested tests received in DM7 message.

 PJ1939_AECD_T

This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data.

 PJ1939_SEED_KEY_CONFIG_T

Structure configuring security J1939.

 PJ1939_SEED_REQUEST_CALLBACK_T

Typedef for the callback function used to generate a seed for a J1939 seed-key exchange.

 PJ1939_KEY_VALIDATION_CALLBACK_T

Typedef for the callback function used to validate a key for a J1939 seed-key exchange.

 PJ1939_EXT_DTC_TX_T

The DM formats supported by the pj1939_ext_dtc_transmit function.

Variables
const U8pj1939_dm7_request_buf_size

This is the number of DM7 test requests that are to be buffered.

PJ1939_DM7_BUFFER_Tpj1939_req_test_list

This is the stored buffer of DM7 requests which have been received but have not yet been processed.

NS_J1939_CHANNEL_T *pj1939_req_test_channel

This is a buffer indicating with which channel a DM7 request is associated.

const U8pj1939_num_aecd

The total number of EI-AECDs that are declared.

PJ1939_AECD_T *constpj1939_aecd_table

The list of AECDs that the library will maintain.

Functions
BOOLpj1939_pgn_send_ack

This function attempts to send an acknowledgement in response to a J1939 request.

voidpj1939_dm5_transmit

This function attempts to transmit a J1939 DM5 response message.

voidpj1939_dm20_transmit

This function attempts to transmit a J1939 DM20 response message.

voidpj1939_dm21_transmit

This function attempts to transmit a J1939 DM21 response message.

voidpj1939_dm26_transmit

This function attempts to transmit a J1939 DM26 response message.

BOOLpj1939_check_dm7_commanded_test

Determine the requested test(s) to be run - as commanded by the DM7 message.

BOOLpj1939_get_dm7_commanded_test

Get a DM7 request for running a test or for test results, if received.

voidpj1939_dm8_transmit

This function attempts to transmit a J1939 DM8 response message.

voidpj1939_dm30_transmit

This function attempts to transmit a J1939 DM30 response message.

voidpj1939_dm10_transmit

This function attempts to transmit a J1939 DM10 response message.

voidpj1939_ext_dtc_transmit

This function attempts to transmit a J1939 DTC message.

voidpj1939_dm35_transmit

This function attempts to transmit a J1939 DM35 message.

voidpj1939_dm40_transmit

This function attempts to transmit a J1939 DM40 message.

voidpj1939_dm32_transmit

This function attempts to transmit a J1939 DM32 response message.

BOOLpj1939_set_control_area_status

This function sets the NTE control area status.

voidpj1939_dm34_transmit

This function attempts to transmit a J1939 DM34 response message.

voidpj1939_update_aecd_eng_timer1

This function updates the EI-AECD engine hours timer1 for the specified AECD.

voidpj1939_update_aecd_eng_timer2

This function updates the EI-AECD engine hours timer2 for the specified AECD.

voidpj1939_dm33_transmit

This function attempts to transmit a J1939 DM33 response message.

voidpj1939_dm4_transmit

Call a function to transmit a J1939 DM4 message.

voidpj1939_dm25_transmit

Call a function to transmit a J1939 DM25 message.

voidpj1939_dm24_transmit

This function attempts to transmit a J1939 DM24.

voidpj1939_dm36_transmit

This function attempts to transmit a J1939 DM36 message.

voidpj1939_dm37_transmit

This function attempts to transmit a J1939 DM37 message.

voidpj1939_dm38_transmit

This function attempts to transmit a J1939 DM38 message.

voidpj1939_dm39_transmit

This function attempts to transmit a J1939 DM39 message.

7.7.1.4. Interface detail

7.7.1.4.1.  Macros
7.7.1.4.1.1. PJ1939_RX_DATA
Definition:

#define PJ1939_RX_DATA 1

Description:

Indicates that a fresh message has been received since last polled.

7.7.1.4.1.2. PJ1939_RX_OVERRUN
Definition:

#define PJ1939_RX_OVERRUN 2

Description:

Indicates that more than one message has been received since last polled.

7.7.1.4.1.3. PJ1939_RX_ERROR
Definition:

#define PJ1939_RX_ERROR 4

Description:

Indicates that a receive error occurred associated with a message.

7.7.1.4.1.4. PJ1939_SAE_RESERVED_1
Definition:

#define PJ1939_SAE_RESERVED_1 ((U8)0)

Description:

SAE reserved.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.5. PJ1939_OBD_II
Definition:

#define PJ1939_OBD_II ((U8)1)

Description:

OBD II (CARB).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.6. PJ1939_OBD
Definition:

#define PJ1939_OBD ((U8)2)

Description:

OBD (Federal, EPA).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.7. PJ1939_OBD_OBD_II
Definition:

#define PJ1939_OBD_OBD_II ((U8)3)

Description:

OBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.8. PJ1939_OBD_I
Definition:

#define PJ1939_OBD_I ((U8)4)

Description:

OBD I.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.9. PJ1939_NO_OBD_II
Definition:

#define PJ1939_NO_OBD_II ((U8)5)

Description:

Not intended to meet OBD II requirements.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.10. PJ1939_EOBD
Definition:

#define PJ1939_EOBD ((U8)6)

Description:

EOBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.11. PJ1939_EOBD_OBD_II
Definition:

#define PJ1939_EOBD_OBD_II ((U8)7)

Description:

EOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.12. PJ1939_EOBD_OBD
Definition:

#define PJ1939_EOBD_OBD ((U8)8)

Description:

EOBD and OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.13. PJ1939_JOBD
Definition:

#define PJ1939_JOBD ((U8)10)

Description:

JOBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.14. PJ1939_JOBD_OBD_II
Definition:

#define PJ1939_JOBD_OBD_II ((U8)11)

Description:

JOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.15. PJ1939_JOBD_EOBD_OBD_II
Definition:

#define PJ1939_JOBD_EOBD_OBD_II ((U8)13)

Description:

JOBD, EOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.16. PJ1939_HDV_B1
Definition:

#define PJ1939_HDV_B1 ((U8)14)

Description:

Heavy Duty Vehicles (EURO 1V) B1.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.17. PJ1939_HDV_B2
Definition:

#define PJ1939_HDV_B2 ((U8)15)

Description:

Heavy Duty Vehicles (EURO V) B2.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.18. PJ1939_HDV_C
Definition:

#define PJ1939_HDV_C ((U8)16)

Description:

Heavy Duty Vehicles (EURO EEC) C (gas engines).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.19. PJ1939_EMD
Definition:

#define PJ1939_EMD ((U8)17)

Description:

Engine Manufacturer Diagnostics.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.20. PJ1939_EMD_PLUS
Definition:

#define PJ1939_EMD_PLUS ((U8)18)

Description:

Engine Manufacturer Diagnostics Enhanced (EMD+).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.21. PJ1939_HDV_OBD
Definition:

#define PJ1939_HDV_OBD ((U8)20)

Description:

Heavy Duty/OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.22. PJ1939_WWH_OBD
Definition:

#define PJ1939_WWH_OBD ((U8)21)

Description:

World Wide Harmonized OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.23. PJ1939_OBD_II_REV
Definition:

#define PJ1939_OBD_II_REV ((U8)22)

Description:

OBD II (CARB) Revised.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.24. PJ1939_HD_EOBD_REV
Definition:

#define PJ1939_HD_EOBD_REV ((U8)23)

Description:

Heavy Duty Vehicles (EURO IV and V) Revised.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.25. PJ1939_SAE_RESERVED_2
Definition:

#define PJ1939_SAE_RESERVED_2 ((U8)24)

Description:

SAE reserved.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.26. PJ1939_OBD_M_SI_SD_I
Definition:

#define PJ1939_OBD_M_SI_SD_I ((U8)25)

Description:

OBD-M Compliance for Spark_Ignition Sterndrive and Inboard Engines.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.27. PJ1939_EURO_VI
Definition:

#define PJ1939_EURO_VI ((U8)26)

Description:

Heavy Duty Vehicles EURO VI (revisions specified in 2010-2011).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.28. PJ1939_OBD_OBD_II_HD_OBD
Definition:

#define PJ1939_OBD_OBD_II_HD_OBD ((U8)34)

Description:

OBD, OBD II, and Heavy Duty/On-Board Diagnostics (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 20].

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.1.29. PJ1939_OBD_OBD_II_HD_OBD_P
Definition:

#define PJ1939_OBD_OBD_II_HD_OBD_P ((U8)35)

Description:

OBD, OBD II, and Heavy Duty/On-Board Diagnostics Partial (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 19].

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

7.7.1.4.2.  Enumerations
7.7.1.4.2.1. PJ1939_ACK_AND_CONTROL_BYTE_T
Summary:

The type of PGN response required A J1939 acknowledgement message can be of type Positive Acknowledgedment(ACK), Negative Acknowledgement(NACK), Access Denied(ACCESS_DENIED) or Cannot Respond(BUSY).

Enumerations:
ACK
NACK
ACCESS_DENIED
BUSY
7.7.1.4.2.2. PJ1939_NTE_CNTRL_AREA_STATUS_T
Summary:

The NTE control area status.

Enumerations:
PJ1939_NTE_OUTSIDE_CNTRL_AREA
PJ1939_NTE_INSIDE_CNTRL_AREA
PJ1939_NTE_RESERVED
PJ1939_NTE_AREA_NOT_AVAILABLE
7.7.1.4.2.3. PJ1939_NTE_CNTRL_AREA_T
Summary:

The NTE control areas.

Enumerations:
PJ1939_NOX_NTE_AREA
PJ1939_NOX_NTE_CARVE_OUT_AREA
PJ1939_NOX_NTE_DEFICIENCY_AREA
PJ1939_PM_NTE_AREA
PJ1939_PM_NTE_CARVE_OUT_AREA
PJ1939_PM_NTE_DEFICIENCY_AREA
7.7.1.4.2.4. PJ1939_EXT_DTC_TX_T_
Summary:

The DM formats supported by the pj1939_ext_dtc_transmit function.

Enumerations:
PJ1939_EXT_DTC_DM6

Obtain DTCs for DM6.

PJ1939_EXT_DTC_DM12

Obtain DTCs for DM12.

PJ1939_EXT_DTC_DM23

Obtain DTCs for DM23.

PJ1939_EXT_DTC_DM27

Obtain DTCs for DM27.

PJ1939_EXT_DTC_DM28

Obtain DTCs for DM28.

PJ1939_EXT_DTC_DM29

Obtain DTCs for DM29.

PJ1939_EXT_DTC_DM31

Obtain DTCs for DM31.

PJ1939_EXT_DTC_DM41

Obtain DTCs for DM41.

PJ1939_EXT_DTC_DM42

Obtain DTCs for DM42.

PJ1939_EXT_DTC_DM43

Obtain DTCs for DM43.

PJ1939_EXT_DTC_DM44

Obtain DTCs for DM44.

PJ1939_EXT_DTC_DM45

Obtain DTCs for DM45.

PJ1939_EXT_DTC_DM46

Obtain DTCs for DM46.

PJ1939_EXT_DTC_DM47

Obtain DTCs for DM47.

PJ1939_EXT_DTC_DM48

Obtain DTCs for DM48.

PJ1939_EXT_DTC_DM49

Obtain DTCs for DM49.

PJ1939_EXT_DTC_DM50

Obtain DTCs for DM50.

PJ1939_EXT_DTC_DM51

Obtain DTCs for DM51.

PJ1939_EXT_DTC_DM52

Obtain DTCs for DM52.

PJ1939_EXT_DTC_COUNT
7.7.1.4.3.  Data types
7.7.1.4.3.1. PJ1939_DM7_BUFFER_T
Summary:

This is a structure to store details of requested tests received in DM7 message.

Members:
U32 PJ1939_DM7_BUFFER_T::spn

This is the suspect parameter number (SPN) of the received J1939 DM7 message.

Range: [0, 524287]

U8 PJ1939_DM7_BUFFER_T::tid

This is the test identifier (TID) of the received J1939 DM7 message.

Range: [0, 255]

U8 PJ1939_DM7_BUFFER_T::fmi

This is the failure mode indicator (FMI) of the received J1939 DM7 message.

Range: [0, 31]

U8 PJ1939_DM7_BUFFER_T::tool_addr

This is the source address of the received J1939 DM7 message or destination for a corresponding DM30 message.

Range: [0, 255]

U8 PJ1939_DM7_BUFFER_T::ecu_addr

This is the destination address of the received J1939 DM7 message or source for the corresponding DM30 message.

Range: [0, 255]

Description:

This is a structure to store details of requested tests received in DM7 message.

Note that source and destination address must be stored because DM30 requires a destination address; and the application may also want to permit/refuse requests from specific sources.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

7.7.1.4.3.2. PJ1939_AECD_T
Summary:

This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data.

Members:
U8 PJ1939_AECD_T::aecd_number

This is the EI-AECD number.

U32 PJ1939_AECD_T::engine_hours_timer1

This is the EI-AECD Engine Hours Timer 1.

Will indicate total active time when commanding up to, but not including, 75% reduction of the maximum emissions control effectiveness.

U32 PJ1939_AECD_T::engine_hours_timer2

This is the (optional) EI-AECD Engine Hours Timer 2.

Will indicate total active time when 75% or more reduction of the maximum emissions control effectiveness.

Description:

This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

7.7.1.4.3.3. PJ1939_SEED_KEY_CONFIG_T
Summary:

Structure configuring security J1939.

Members:
BOOL PJ1939_SEED_KEY_CONFIG_T::security_required

If security_required is set FALSE, no seed-key exchange is required.

The callback structure elements are ignored.

If security_required is set TRUE, the callbacks provided are used to unlock the security.

If security_required is set TRUE but either callback is NULL, it will not be possible to unlock security and the calibration tool will be permanently prohibited from invoking reprogramming activities.

PJ1939_SEED_REQUEST_CALLBACK_T PJ1939_SEED_KEY_CONFIG_T::seed_request_callback

Pointer to callback function which is called to request a seed value when the calibration tool attempts to jump to bootloader.

Set this value to NULL if security is not required.

PJ1939_KEY_VALIDATION_CALLBACK_T PJ1939_SEED_KEY_CONFIG_T::key_validation_callback

Pointer to callback function which is called to validate a key value returned by the calibration tool against a previously generated seed.

Set this value to NULL if security is not required.

7.7.1.4.3.4. PJ1939_SEED_REQUEST_CALLBACK_T
Definition:

typedef U16(* PJ1939_SEED_REQUEST_CALLBACK_T)(void)

Description:

Typedef for the callback function used to generate a seed for a J1939 seed-key exchange.

This function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

In future software, the callback function will be copied to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Return:

The function must return a 16-bit seed value. Typically this will be generated through a random or pseudo-random process.

7.7.1.4.3.5. PJ1939_KEY_VALIDATION_CALLBACK_T
Definition:

typedef BOOL(* PJ1939_KEY_VALIDATION_CALLBACK_T)(U16 key, U16 seed)

Description:

Typedef for the callback function used to validate a key for a J1939 seed-key exchange.

The function must validate if the passed seed and key values match.

This function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

In future software, the callback function will be copied to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg: key

The key is a 16-bit value returned by the calibration tool.

Arg: seed

This is the 16-bit seed value.

Return:

The function must return TRUE if the key is correct, or FALSE if not.

7.7.1.4.3.6. PJ1939_EXT_DTC_TX_T
Definition:

typedef enum PJ1939_EXT_DTC_TX_T_ PJ1939_EXT_DTC_TX_T

Description:

The DM formats supported by the pj1939_ext_dtc_transmit function.

7.7.1.4.4.  Variables
7.7.1.4.4.1. pj1939_dm7_request_buf_size
Definition:

const U8 pj1939_dm7_request_buf_size

Description:

This is the number of DM7 test requests that are to be buffered.

Range: [1, 255] buffers.

7.7.1.4.4.2. pj1939_req_test_list
Definition:

PJ1939_DM7_BUFFER_T pj1939_req_test_list[]

Description:

This is the stored buffer of DM7 requests which have been received but have not yet been processed.

The array is sized by pj1939_dm7_request_buf_size.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time.

7.7.1.4.4.3. pj1939_req_test_channel
Definition:

NS_J1939_CHANNEL_T* pj1939_req_test_channel[]

Description:

This is a buffer indicating with which channel a DM7 request is associated.

The array must have pj1939_dm7_request_buf_size elements.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized a build time.

7.7.1.4.4.4. pj1939_num_aecd
Definition:

const U8 pj1939_num_aecd

Description:

The total number of EI-AECDs that are declared.

7.7.1.4.4.5. pj1939_aecd_table
Definition:

PJ1939_AECD_T* const pj1939_aecd_table[]

Description:

The list of AECDs that the library will maintain.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_aecd. The array is not to be accessed by application code.

7.7.1.4.5.  Functions
7.7.1.4.5.1. pj1939_pgn_send_ack()
Definition:

BOOL pj1939_pgn_send_ack(
   const U32                             pj1939f_pgn_to_ack,
   const PJ1939_ACK_AND_CONTROL_BYTE_T   pj1939f_required_response,
   const U8                              pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to send an acknowledgement in response to a J1939 request.

Arg (data in): pj1939f_pgn_to_ack

The PGN request that is being acknowledged.

Arg (data in): pj1939f_required_response

The required response - ACK/NACK/ACCESS_DENIED/BUSY.

Arg (data in): pj1939f_channel_id

The J1939 Channel ID over which to transmit the message Range: [0,pj1939_num_channels)

Return:
  • TRUE - if transmission succeeds

  • FALSE - if transmission fails

7.7.1.4.5.2. pj1939_dm5_transmit()
Definition:

void pj1939_dm5_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_priority,
   U8                          pj1939f_obd_compliance,
   U8                         *pj1939f_error_flag,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM5 response message.

Can raise the following errors:
PJ1939_DM5_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM5 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_obd_compliance

The OBD compliance to be reported in DM5 byte 3.
Range: [0, 255]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.3. pj1939_dm20_transmit()
Definition:

void pj1939_dm20_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM20 response message.

Can raise the following errors:
PJ1939_DM20_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.4. pj1939_dm21_transmit()
Definition:

void pj1939_dm21_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   U16        pj1939f_time_while_mil_on,
   U16        pj1939f_distance_while_mil_on,
   U16        pj1939f_time_since_dtc_clear,
   U16        pj1939f_distance_since_dtc_clear,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM21 response message.

Can raise the following errors:
PJ1939_DM21_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data in): pj1939f_time_while_mil_on

The accumulated count (in minutes) run by the engine while the MIL is activated. Refer to J1939-73 Feb2010 section 5.7.21.3 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 64255] minutes

Arg (data in): pj1939f_distance_while_mil_on

The distance travelled (in kilometres) while the MIL is activated. Refer to J1939-73 Feb2010 section 5.7.21.1 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 64255] kilometres

Arg (data in): pj1939f_time_since_dtc_clear

The engine running time (in minutes) accumulated since emission related DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.21.4 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 64255] minutes

Arg (data in): pj1939f_distance_since_dtc_clear

The distance accumulated (in kilometres) since emission related DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.21.2 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 64255] kilometres

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.5. pj1939_dm26_transmit()
Definition:

void pj1939_dm26_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   BOOL       pj1939f_use_dest_addr,
   U16        pj1939_eng_time_since_ign_start,
   U8         pj1939_warmup_count_since_dtc_clear,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM26 response message.

Can raise the following errors:
PJ1939_DM26_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data in): pj1939_eng_time_since_ign_start

The time (in seconds), since key-on, that the engine has been running. Refer to J1939-73 Feb2010 section 5.7.26.1 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 64255] seconds

Arg (data in): pj1939_warmup_count_since_dtc_clear

The number of warm-up cycles since all DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.26.2 for details. The platform will limit the transmitted value to the range specified below.
Range: [0, 250]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.6. pj1939_check_dm7_commanded_test()
Definition:

BOOL pj1939_check_dm7_commanded_test(
   U8         pj1939f_tid,
   U32        pj1939f_spn,
   U8         pj1939f_fmi,
   U8        *pj1939f_source_addr,
   U8        *pj1939f_dest_addr,
   U8 const   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Determine the requested test(s) to be run - as commanded by the DM7 message.

Arg (data in): pj1939f_tid

The J1939 'test identifier' value to match.
Range: [0, 255]

Arg (data in): pj1939f_spn

The 'suspect parameter number' value to match (when a DM30 response is required).
Range: [0, 524287]

Arg (data in): pj1939f_fmi

The 'failure mode indicator' value to match (when a DM30 response is required).
Range: [0, 31]

Arg (data out): pj1939f_source_addr

The source address for the DM7 request message requesting this test. May be NULL.

Arg (data out): pj1939f_dest_addr

The destination address for the DM7 request message requesting this test. May be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

Return:

TRUE - if the requested test is to be run. FALSE - if no request was received for the specified test.

7.7.1.4.5.7. pj1939_get_dm7_commanded_test()
Definition:

BOOL pj1939_get_dm7_commanded_test(
   PJ1939_DM7_BUFFER_T  *pj1939f_test,
   const U8              pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Get a DM7 request for running a test or for test results, if received.

Arg (data out): pj1939f_test

Pointer to structure which will be populated with details of the test requested, if a DM7 request has been received.
Must not be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

Return:

TRUE - if a DM7 request has been received. FALSE - if no DM7 request requires processing.

Note

If multiple DM7 requests are received between calls to this function, the DM7 requests are not guaranteed to be reported in the order in which they are received. To ensure this does not cause a problem, it is recommended that the function is called repeatedly and each DM7 request returned is serviced, until the function returns FALSE indicating that there are no more DM7 requests.

7.7.1.4.5.8. pj1939_dm8_transmit()
Definition:

void pj1939_dm8_transmit(
   U8           pj1939f_tid,
   const U8     pj1939f_priority,
   const U8     pj1939f_dest_addr,
   const BOOL   pj1939f_use_dest_addr,
   U8          *pj1939f_error_flag,
   U8          *pj1939f_transport_error,
   const U8     pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM8 response message.

Can raise the following errors:
PJ1939_DM8_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_tid

The test identifier for which the results are to be transmitted.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request).
Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.9. pj1939_dm30_transmit()
Definition:

void pj1939_dm30_transmit(
   const PJ1939_DM7_BUFFER_T  *pj1939f_req_test,
   const U8                    pj1939f_priority,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM30 response message.

Can raise the following errors:
PJ1939_DM30_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_req_test

The structure containing the details of the requested test.
This may be obtained directly from pj1939_get_dm7_commanded_test. The response will be sent to the tool_addr unless the ecu_addr is 255 (i.e. the request was sent to the global address).

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.10. pj1939_dm10_transmit()
Definition:

void pj1939_dm10_transmit(
   const U8   pj1939f_priority,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM10 response message.

Supported by targets: M250, M460, M461.

Can raise the following errors:
PJ1939_DM10_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.11. pj1939_ext_dtc_transmit()
Definition:

void pj1939_ext_dtc_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_transmit,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   BOOL                        pj1939f_use_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id,
   PJ1939_EXT_DTC_TX_T         pj1939f_dm_type);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DTC message.

Request that a J1939 DTC message is constructed from the contents of a diagnostic trouble code table and transmitted.

The DM message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM messages are transmitted on request.

Can raise the following errors:
PJ1939_DM6_TRANSMIT_INVALID_ARG. PJ1939_DM12_TRANSMIT_INVALID_ARG. PJ1939_DM23_TRANSMIT_INVALID_ARG. PJ1939_DM27_TRANSMIT_INVALID_ARG. PJ1939_DM28_TRANSMIT_INVALID_ARG. PJ1939_DM29_TRANSMIT_INVALID_ARG. PJ1939_DM31_TRANSMIT_INVALID_ARG. PJ1939_DM41_TRANSMIT_INVALID_ARG. PJ1939_DM42_TRANSMIT_INVALID_ARG. PJ1939_DM43_TRANSMIT_INVALID_ARG. PJ1939_DM44_TRANSMIT_INVALID_ARG. PJ1939_DM45_TRANSMIT_INVALID_ARG. PJ1939_DM46_TRANSMIT_INVALID_ARG. PJ1939_DM47_TRANSMIT_INVALID_ARG. PJ1939_DM48_TRANSMIT_INVALID_ARG. PJ1939_DM49_TRANSMIT_INVALID_ARG. PJ1939_DM50_TRANSMIT_INVALID_ARG. PJ1939_DM51_TRANSMIT_INVALID_ARG. PJ1939_DM52_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM12 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_transmit

Set true if the DM12 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority

The priority of the DM12 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

Arg (data in): pj1939f_dm_type

Specifies the desired DM format to transmit. Supported values: PJ1939_EXT_DTC_DM6 PJ1939_EXT_DTC_DM12 PJ1939_EXT_DTC_DM23 PJ1939_EXT_DTC_DM27 PJ1939_EXT_DTC_DM28 PJ1939_EXT_DTC_DM29 PJ1939_EXT_DTC_DM31 PJ1939_EXT_DTC_DM41 PJ1939_EXT_DTC_DM42 PJ1939_EXT_DTC_DM43 PJ1939_EXT_DTC_DM44 PJ1939_EXT_DTC_DM45 PJ1939_EXT_DTC_DM46 PJ1939_EXT_DTC_DM47 PJ1939_EXT_DTC_DM48 PJ1939_EXT_DTC_DM49 PJ1939_EXT_DTC_DM50 PJ1939_EXT_DTC_DM51 PJ1939_EXT_DTC_DM52

7.7.1.4.5.12. pj1939_dm35_transmit()
Definition:

void pj1939_dm35_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_force_transmission,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM35 message.

Request that a J1939 DM35 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM35 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

The transmission of a DM35 message can involve many CAN packets and to avoid overloading the CAN bus, the J1939 specification provides some guidance for transmission rates. This can be overridden if necessary.

  • forced transmission - causes the function to attempt to transmit a DM35 message regardless of any change in transient fault status of any DTC.

  • unforced transmission - causes the function to attempt to transmit a DM35 message. This will occur if there is at least one DTC with a change in transient fault status from the last time that DTC was transmitted AND the minimum allowed interval has elapsed since that last transmission.

Can raise the following errors:
PJ1939_DM35_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM35 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_force_transmission

Set true if the DM35 message should be transmitted regardless of DTC transient fault changes.

Arg (data in): pj1939f_priority

The priority of the DM35 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM35 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.13. pj1939_dm40_transmit()
Definition:

void pj1939_dm40_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   BOOL                        pj1939f_use_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM40 message.

Request that a J1939 DM40 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM40 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM40 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM40_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM40 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Cannot be NULL.

Arg (data in): pj1939f_priority

The priority of the DM40 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM40 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.14. pj1939_dm32_transmit()
Definition:

void pj1939_dm32_transmit(
   const PDTC_TABLE_T *const   pj1939f_table,
   const U8                    pj1939f_priority,
   const U8                    pj1939f_dest_addr,
   U8                         *pj1939f_error_flag,
   U8                         *pj1939f_transport_error,
   const U8                    pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM32 response message.

Can raise the following errors:
PJ1939_DM32_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table

A pointer to a diagnostic trouble code table. The contents of the DM32 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).
Only DTCs with emissions severities greater than the calibrated pdgc_emissions_report_min_sev are reported. See the documentation for the CAPI interface tool regarding the emissions-severity statement for more information.
Cannot be NULL.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.15. pj1939_set_control_area_status()
Definition:

BOOL pj1939_set_control_area_status(
   PJ1939_NTE_CNTRL_AREA_T          pj1939f_cntrl_area,
   PJ1939_NTE_CNTRL_AREA_STATUS_T   pj1939f_cntrl_area_status);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function sets the NTE control area status.

Arg (data in): pj1939f_cntrl_area

The NTE control area for which the status has to be set.

Arg (data in): pj1939f_cntrl_area_status

The status for the selected NTE control area.

Return:
  • TRUE - if the status was updated successfully

  • FALSE - if the status was not updated due to invalid arguments

7.7.1.4.5.16. pj1939_dm34_transmit()
Definition:

void pj1939_dm34_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM34 response message.

Supported by targets: M250, M460, M461.

Can raise the following errors:
PJ1939_DM34_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.17. pj1939_update_aecd_eng_timer1()
Definition:

void pj1939_update_aecd_eng_timer1(
   const U8    pj1939f_aecd_number,
   const U32   pj1939f_engine_hours);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function updates the EI-AECD engine hours timer1 for the specified AECD.

Arg (data in): pj1939f_aecd_number

The AECD number for which the timer is to be updated.

Arg (data in): pj1939f_engine_hours

The engine hours value in minutes to be set. J1939 spec refers to this as 'engine hours', however the actual value is in minutes

7.7.1.4.5.18. pj1939_update_aecd_eng_timer2()
Definition:

void pj1939_update_aecd_eng_timer2(
   const U8    pj1939f_aecd_number,
   const U32   pj1939f_engine_hours);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function updates the EI-AECD engine hours timer2 for the specified AECD.

Arg (data in): pj1939f_aecd_number

The AECD number for which the timer is to be updated.

Arg (data in): pj1939f_engine_hours

The engine hours value in minutes to be set. J1939 spec refers to this as 'engine hours', however the actual value is in minutes.

7.7.1.4.5.19. pj1939_dm33_transmit()
Definition:

void pj1939_dm33_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM33 response message.

Can raise the following errors:
PJ1939_DM33_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined.
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.20. pj1939_dm4_transmit()
Definition:

void pj1939_dm4_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   BOOL       pj1939f_use_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Call a function to transmit a J1939 DM4 message.

Request that a J1939 DM4 (standard freeze frame) message is transmitted.

DM4 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM4_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the DM4 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM4 message for transmission,written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.21. pj1939_dm25_transmit()
Definition:

void pj1939_dm25_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   BOOL       pj1939f_use_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Call a function to transmit a J1939 DM25 message.

Request that a J1939 DM25 (expanded freeze frame) message is transmitted.

DM25 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM25_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the DM25 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM25 message for transmission,written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.22. pj1939_dm24_transmit()
Definition:

void pj1939_dm24_transmit(
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   BOOL       pj1939f_use_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM24.

The DM24 messages is constructed from the lists of SPNs defining:

  • the expanded freeze frame (J1939, DM25)

  • support for Data Stream messages

  • support for Scaled Test Results (J1939, DM30)

  • SPN data lengths

The supported expanded freeze frame SPNs are those defined via the calibration vector identified by the j1939-dm25-ff-name assignment statement in the CAPI file. The Data Stream SPNs comprise those PIDS defined in the CAPI file that have SPN IDs. Whilst SPNs supporting Scaled Test Results are those associated with DTEs (Diagnostic Test Entities) in the CAPI file.

DM24 messages are transmitted on request.

Note: it is up to the user to package the datastream SPNs into a PGN and transmit them on request using the pj1939_pg_transmit() function.

Can raise the following errors:
PJ1939_DM24_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the DM24 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM24 message for transmission,written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.23. pj1939_dm36_transmit()
Definition:

void pj1939_dm36_transmit(
   const U8   pj1939f_priority,
   U8         pj1939f_vnrw_component_count,
   U8         pj1939f_continuous_mil,
   U8         pj1939f_mil_display_strategy,
   U8         pj1939f_mil_activation_mode,
   U16        pj1939f_incomplete_monitor_count,
   U16        pj1939f_mil_accumulated_time,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM36 message.

The DM36 message contents are constructed from the supplied parameters and platform internal data (where necessary).

DM36 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM36_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the DM36 message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_vnrw_component_count

The sum of the system or component non-roadworthiness counts. Refer to J1939-73 Feb2010 section 5.7.36.1 for details. The platform will limit the value to the range specified below.
Range: [0, 250]

Arg (data in): pj1939f_continuous_mil

A code indicating whether one or more systems or components requires that the MIL be steady (continuous) burning. Refer to J1939-73 Feb2010 section 5.7.36.2 for details. The platform will limit the value to the range specified below.
Range: [0, 3]

Arg (data in): pj1939f_mil_display_strategy

A code indicating whether any system is configured to employ a discriminatory MIL display. Refer to J1939-73 Feb2010 section 5.7.36.3 for details. The platform will limit the value to the range specified below.
Range: [0, 3]

Arg (data in): pj1939f_mil_activation_mode

A code indicating the most severe form of MIL display required by the failure status of any system or component. Refer to J1939-73 Feb2010 section 5.7.36.4 for details. The platform will limit the value to the range specified below.
Range: [0, 15]

Arg (data in): pj1939f_incomplete_monitor_count

The number of incomplete diagnostic monitors for a given sub-system or component. Refer to J1939-73 Feb2010 section 5.7.36.5 for details. The platform will limit the value to the range specified below.
Range: [0, 64255]

Arg (data in): pj1939f_mil_accumulated_time

The accumulated count, in minutes, that the MIL is activated for the current MIL activation. Refer to J1939-73 Feb2010 section 5.7.36.6 for details. The platform will limit the value to the range specified below. This range is chosen to match that of the accumulated time sent on DM21 message.
Range: [0, 64255] minutes

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM36 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.24. pj1939_dm37_transmit()
Definition:

void pj1939_dm37_transmit(
   const BOOL   pj1939f_force_transmission,
   const U8     pj1939f_priority,
   U8           pj1939f_snrw_component_count,
   U8           pj1939f_continuous_mil,
   U8           pj1939f_mil_display_strategy,
   U8           pj1939f_mil_activation_mode,
   U16          pj1939f_incomplete_monitor_count,
   U8          *pj1939f_error_flag,
   const U8     pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM37 message.

The DM37 message contents are constructed from the supplied parameters and platform internal data (where necessary).

DM37 messages are transmitted in accordance with the transmission rates defined in J1939-73 Feb2010 section 5.7.37 This function must be scheduled at a 0.1Hz or faster rate in order to fulfil those requirements.

Can raise the following errors:
PJ1939_DM37_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_force_transmission

Set to TRUE if the DM37 message should be transmitted in addition to the periodic transmission and regardless of any change in input data. Refer to J1939-73 Feb2010 section 5.7.37 for details of transmission rates.

Arg (data in): pj1939f_priority

The priority of the DM37 message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_snrw_component_count

The number of components that the system has determined to be non-roadworthy. Refer to J1939-73 Feb2010 section 5.7.37.1 for details. The platform will limit the value to the range specified below.
Range: [0, 250]

Arg (data in): pj1939f_continuous_mil

A code indicating whether the system requires that the MIL be steady (continuous) burning. Refer to J1939-73 Feb2010 section 5.7.37.2 for details. The platform will limit the value to the range specified below.
Range: [0, 3]

Arg (data in): pj1939f_mil_display_strategy

A code indicating whether the system is configured to employ a discriminatory MIL display. Refer to J1939-73 Feb2010 section 5.7.37.3 for details. The platform will limit the value to the range specified below.
Range: [0, 3]

Arg (data in): pj1939f_mil_activation_mode

A code indicating the most severe form of MIL display required by the failure status the system or component. Refer to J1939-73 Feb2010 section 5.7.37.4 for details. The platform will limit the value to the range specified below.
Range: [0, 15]

Arg (data in): pj1939f_incomplete_monitor_count

The number of incomplete diagnostic monitors for a given sub-system or component. Refer to J1939-73 Feb2010 section 5.7.37.5 for details. The platform will limit the value to the range specified below. This range is chosen to match that of the 'Vehicle Incomplete Monitor Count' sent on DM36 message.
Range: [0, 64255]

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM37 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.25. pj1939_dm38_transmit()
Definition:

void pj1939_dm38_transmit(
   const U8  *pj1939f_gtr_description,
   U8         pj1939f_string_length,
   const U8   pj1939f_priority,
   const U8   pj1939f_dest_addr,
   BOOL       pj1939f_use_dest_addr,
   U8        *pj1939f_error_flag,
   U8        *pj1939f_transport_error,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM38 message.

The DM38 message contents are constructed from the supplied parameter.

DM38 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM38_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_gtr_description

A description of the UN/ECE WWH OBD Global Technical Regulation (GTR) to which the sub-system or component complies. See J1939-73 Feb2010 section 5.7.38.1 for details. The platform will limit the individual character ASCII value to the range specified below. Should a character fall outside, it is rejected and no further characters are processed. Range: [0, 127]

Arg (data in): pj1939f_string_length

The length of the UN/ECE WWH OBD Global Technical Regulation (GTR) string. See J1939-73 Feb2010 section 5.7.38.1 for details. The platform will limit the length to the range specified below. Range: [0, 200] characters

Arg (data in): pj1939f_priority

The priority of the DM38 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions).
Range: [0, 7]

Arg (data in): pj1939f_dest_addr

Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 255]

Arg (data in): pj1939f_use_dest_addr

Setting this parameter to FALSE will cause the message to ignore the destination address parameter and send the message to the global address.
Range: [0, 1] Boolean

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM38 message for transmission, Written false otherwise.
Cannot be NULL.

Arg (data out): pj1939f_transport_error

A pointer to the location to write the saturated count of transport errors encountered.
Cannot be NULL.
Range: [0, 255] errors

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.1.4.5.26. pj1939_dm39_transmit()
Definition:

void pj1939_dm39_transmit(
   const U8   pj1939f_priority,
   U32        pj1939f_sys_cumulative_mil_time,
   U16        pj1939f_total_b1_time,
   U8        *pj1939f_error_flag,
   const U8   pj1939f_channel_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function attempts to transmit a J1939 DM39 message.

The DM39 message contents are constructed from the supplied parameters.

DM39 messages are transmitted on request.

Can raise the following errors:
PJ1939_DM39_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority

The priority of the DM39 message to be transmitted. The lower the priority value, the higher the message priority.
Range: [0, 7]

Arg (data in): pj1939f_sys_cumulative_mil_time

The total amount of time that the MIL has been demanded to be illuminated during the life of the system or component. Refer to J1939-73 Feb2010 section 5.7.39.1 for details. The platform will limit the value to the range specified below.
Range: [0, 4204501215] scaled at 0.05 hr/bit

Arg (data in): pj1939f_total_b1_time

The total amount of time that one or more DTCs with emission severity B1 have been active. Refer to J1939-73 Feb2010 section 5.7.39.2 for details. The platform will limit the value to the range specified below.
Range: [0, 64255] scaled at 0.1 hr/bit

Arg (data out): pj1939f_error_flag

A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM39 message for transmission, written false otherwise.
Cannot be NULL.

Arg (data in): pj1939f_channel_id

The J1939 channel on which to transmit the message.

7.7.2. Diagnostics (ISO-15765 and KWP2000) feature (PDG)

7.7.2.1. Overview

The library's diagnostic feature handles communications with an external test tool using ISO 15765-2 based protocols (J1979, Keyword Protocol 2000-3, and ISO 14229-1 UDS).

This feature provides few callable functions. To use it, configure the required communication settings in the interface file (see Section 8.1.4.18, “Compound statement: iso-diagnostics”). Also specify the diagnostic trouble codes (Section 8.1.4.28, “Compound statement: dtc-data”), parameter identifiers (Section 8.1.4.30, “Compound statement: pid-data”), and routines (Section 8.1.4.37, “Compound statement: routine-data”).

The application software should then use the functionality described in Section 5.18, “Diagnostic Trouble Code (DTC) feature (PDTC)”, Section 7.7.5, “Parameter Identifier feature (PPID)” Section 7.7.6, “In-Use Performance Ratio feature (PPR)”, and Section 7.7.2.3, “Routine Control - service 0x31”.

7.7.2.2. Supported Diagnostic Services

The diagnostic services supported are drawn from three standards: SAE J1979 (ISO 15031-5, "OBD2"), Keyword Protocol 2000-3 (ISO 14230-3) and Unified Diagnostic Services (UDS, ISO 14229-1). They all work in the same way, with the first byte of each request message indicating the required service. Some services are the same (or compatible) in KW2000-3 and UDS.

Table 7.3. PDG supported services

IDServiceNotes
0x01Request Current Powertrain Diagnostic Data (J1979)Used to read PID values that have a J1979 8-bit identifier defined
0x02Request Powertrain Freeze Frame Data (J1979)Used to read PID values that have been captured when a DTC occurred
0x03ReadEmissionDTCs (J1979)Reports only DTCs defined as emission-related
0x04ClearEmissionDTCs (J1979)Clears only DTCs defined as emission-related
0x06RequestOBDTestResults (J1979)Reports test results for ISO test IDs
0x07ReadEmissionDTCsPending (J1979)Reports only DTCs defined as emission-related that are pending
0x09RequestVehicleInformation (J1979)Used to read Vehicle Information data stored as InfoTypes
0x0AReadEmissionDTCsPermanent (J1979)Reports only DTCs defined as emission-related that are permanent
0x10StartDiagnosticSession (KW2000-3) or DiagnosticSessionControl (UDS)Used to request a change between diagnostic sessions. (Default, Extended and Programming)
0x11ECUReset (KW2000-3, UDS)Used to reset the ECU. Only supported by Bootloader to exit reprogramming mode
0x14ClearDiagInfo (KW2000-3, UDS)Clears all or subgroup of ISO DTCs (not J1939-only DTCs)
0x17ReadStatusOfDTC (KW2000-3)Reports the status of the specified DTC
0x18ReadDTCByStatus (KW2000-3)All DTCs, regardless of emissions severity
0x19ReadDTCInfo (UDS)16-bit DTCs currently output, lower byte zero; many subfunctions
0x21ReadDataByLocalIdentifier (KW2000-3)Used to read PID values using an 8-bit identifier
0x22ReadDataByCommonID (KW2000-3, UDS)Used to read PID values using an 16-bit identifier
0x23ReadMemoryByAddress (KW2000-3, UDS)Used to read raw memory contents (subject to security restrictions)
0x24ReadScalingDataByIdentifier (UDS)Used to read scaling data for a PID
0x27SecurityAccess (KW2000-3, UDS)Used to grant security access in boot loader mode
0x28CommunicationControl (UDS)Used to switch on/off the transmission and or the reception of certain messages
0x28DisableNormalMessageTransmission (J2190)Used to switch off the transmission of non-diagnostic and non-network management messages
0x29EnableNormalMessageTransmission (J2190)Used to switch on the transmission for all messages
0x2AReadDataByPeriodicIdentifier (UDS)Used to request automatic periodic transmission of selected PIDs
0x2CDynamicallyDefineDataIdentifier (UDS)Used to specify a new PID composed of other PIDs or memory reads
0x2EWriteDataByLocalIdentifier (KW2000-3, UDS)Used to write PIDs specified by 16-bit identifier (eg NV PID data)
0x2FIOControlByCommonID (KW2000-3, UDS)Used to override PID values using a 16-bit identifier
0x30IOControlByLocalID (KW2000-3, UDS)Used to override PID values (identified by KW2000 8-bit local identifier)
0x31RoutineControl (UDS)Used to initiate a specified process in boot loader mode, e.g. erase memory
0x34RequestDownload (KW2000-3, UDS)Used to initiate a downloading of a block of memory in boot loader mode (only the downloading of unencrypted, uncompressed data is currently supported)
0x36TransferData (KW2000-3, UDS)Used to download data in boot loader mode (only the downloading to flash is currently supported)
0x37RequestTransferExit (KW2000-3, UDS)Used to terminate data transfer between the tester and the ECU in boot loader mode
0x3ETesterPresentPing” to maintain communications
0x85ControlDTCSettingUsed to Stop or Start the setting of DTCs

Note

Services $14, $17 and $18 use the ISO 15031-6 values for groupOfDTC groups in KW2000-3 style (powertrain 0x0000, chassis 0x4000, body 0x8000, network/other 0xC000, all 0xFF00). For $14, the equivalent 24-bit UDS values may alternatively be used (0x000000, 0x400000, ... and 0xFFFFFF for 'all').

Note

Please contact Pi Innovo for support with flash reprogramming. The EraseMemory routine ($FF00) typically specified by OEMs is supported in two formats:

  • Numeric range: If a length is supplied, the address value is interpreted as an actual device address and the specified range is erased.

  • Logical index: If no length is supplied, the address value is interpreted as the zero-based index of the eraseable flash block, which is device-dependent. For example, the MPC5534 M0 block (0x40000 - 0x5FFFF) has index 6. This follows the HIS group reprogramming specification.

7.7.2.3. Routine Control - service 0x31

The library's Routine Control feature provides support for diagnostic routines accessed by numeric identifier using the ISO 14229-1 (UDS) protocol.

Routines can be used to allow a diagnostic tool to perform a custom function within the ECU. For example, a function of the ECU can be started and stopped from the diagnostic tool, or a set of values can be written to or read from ECU memory. The actual routine is defined by the application software.

7.7.2.3.1. Use of Routines

Routines are declared in the interface file (see Section 8.1.4.37, “Compound statement: routine-data”). The C-API tool generates a C identifier for each routine based on the name specified in the interface file, which can be passed to the functions pdg_update_routine_ctrl_data() and pdg_get_routine_rqst().

Routine requests from the diagnostic tool must be retrieved by the application by calling pdg_get_routine_rqst(). pdg_get_routine_rqst() will inform the application if the routine ID has been requested, which sub-function is requested, and any optional routineControlOptionRecord bytes. Note: the requestRoutineResults subfunction is handled internally by the library based on the data passed to the library by the pdg_update_routine_ctrl_data() function.

The application must keep the library informed of the status of all routines by calling pdg_update_routine_ctrl_data(). pdg_update_routine_ctrl_data() is used to inform the library of the following information:

  • If the routine is capable of running. If the routine is not capable of running, the library will respond to a startRoutine request with a conditionsNotCorrect negative response.

  • If the routine is currently running.

  • If the routine has valid results available. If valid results are not available, the library will respond to a requestResults request with a requestSequenceError negative response.

  • The routine results bytes.

  • The routine statusRecord bytes.

Routines can be configured to be timed or untimed. See ISO 14229-1 section 13 for the description of "Method A" (untimed) and "Method B" (timed) routines.

If the routine is configured as an untimed routine, the diagnostic tool must send a startRoutine request, and the library will pass this request to the application once the application calls pdg_get_routine_rqst(). The application is then responsible for starting the routine and informing the library that the routine has started by calling pdg_update_routine_ctrl_data(). To stop the routine after it has been started, the diagnostic tool must send a stopRoutine request, and the library will pass this request to the application once the application calls pdg_get_routine_rqst(). The application is responsible for stopping the routine and informing the library that the routine is no longer running by calling pdg_update_routine_ctrl_data().

If the routine is configured as a timed routine, the application is responsible for stopping the routine after it has completed. However, the application shall allow for the routine to stop if a stopRoutine request is received from the diagnostic tool. In all cases, the applciation is responsible for informing the platform that the routine is either running or not running by calling pdg_update_routine_ctrl_data().

The following flow chart summarizes how to use the service $31 routine control interface functions in a typical application.

Figure 7.3. Routine control usage flowchart

Routine control usage flowchart

7.7.2.3.2. Platform Routines

Some routines are handled by the platform without any input from the application. These routines have routine IDs that may not be used by the application. The reserved routine IDs are: 0x0202, 0x0203, 0xFF00, and 0xFF01.

7.7.2.4. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pdg.h
Macros
 PDG_SECURITY_FN_MAX_SIZE

The maximum supported size of UDS security callback function (see PDG_SECURITY_CALLBACK_FN_T).

 PDG_MAX_SEED_SIZE

The maximum supported size of UDS security seed (see PDG_SECURITY_CALLBACK_FN_T).

 PDG_SESSION_UDS_DEFAULT

Default session entered automatically at startup, by tool request or by timeout of another session type.

 PDG_SESSION_UDS_PROGRAMMING

Programming session entered by tool request (will not be seen in application running mode)

 PDG_SESSION_UDS_EXTENDED

Extended session entered by tool request.

 PDG_NUM_SEC_LEVELS_PER_SERVICE

Limit on number of specific security levels that can be assigned to a service.

Enumerations
 PDG_RC_T

Diagnostic feature return codes.

 PDG_ROUTINE_RC_T

An enumerated type which contains success and failure codes returned by some routine control functions.

 PDG_CALLBACK_OUTCOME_T

Return codes by the application to indicate how it would like the PDG feature to continue handling the message just received.

 PDG_CC_COMM_TYPE_T

Communication type parameter for the communication control diagnostic service.

 PDG_CC_CTRL_TYPE_T

The subfunction parameter controlType for the communication control diagnostic service.

 PDG_SECURITY_OPTION_T

Controls whether certain services are allowed to run, and if so whether they require any or specific security levels to have been unlocked.

Data types
 PDG_GENERAL_CALLBACK_FN_T

Callback function pointer type for general callback.

 PDG_ID_REQUEST_CALLBACK_FN_T

Callback function pointer type for the ID request callback.

 PDG_SECURITY_CALLBACK_FN_T

Callback function pointer type for the security callback.

 PDG_SECURITY_END_FN_T

Function pointer type to mark the end of the security callback.

Variables
const volatile PIO_EMISSION_SEV_TYPE_Tpdgc_emissions_report_min_sev

Calibration to determine the minimum emissions severity of DTCs to be reported.

Functions
U8pdg_get_active_session_type

Retrieves type of currently active diagnostic session.

voidpdg_set_active_session_type

Sets the type of currently active diagnostic session.

PDG_RC_Tpdg_set_infotype

Function to set the InfoType data.

PDG_CC_CTRL_TYPE_Tpdg_get_comm_ctrl_state

Function to retrieve status of communication control diagnostic service.

PDG_RC_Tpdg_comm_ctrl_cond_not_correct

Function to indicate the conditions for communications control (service $28) are not correct.

PDG_ROUTINE_RC_Tpdg_update_routine_ctrl_data

Update platform-cached values for this routine with fresh application values.

PDG_ROUTINE_RC_Tpdg_get_routine_rqst

Retrieve routine requests from the diagnostic tool.

7.7.2.5. Interface detail

7.7.2.5.1.  Macros
7.7.2.5.1.1. PDG_SECURITY_FN_MAX_SIZE
Definition:

#define PDG_SECURITY_FN_MAX_SIZE 2048

Description:

The maximum supported size of UDS security callback function (see PDG_SECURITY_CALLBACK_FN_T).

7.7.2.5.1.2. PDG_MAX_SEED_SIZE
Definition:

#define PDG_MAX_SEED_SIZE ((U8) 8u)

Description:

The maximum supported size of UDS security seed (see PDG_SECURITY_CALLBACK_FN_T).

7.7.2.5.1.3. PDG_SESSION_UDS_DEFAULT
Definition:

#define PDG_SESSION_UDS_DEFAULT ((U8) 0x01)

Description:

Default session entered automatically at startup, by tool request or by timeout of another session type.

7.7.2.5.1.4. PDG_SESSION_UDS_PROGRAMMING
Definition:

#define PDG_SESSION_UDS_PROGRAMMING ((U8) 0x02)

Description:

Programming session entered by tool request (will not be seen in application running mode)

7.7.2.5.1.5. PDG_SESSION_UDS_EXTENDED
Definition:

#define PDG_SESSION_UDS_EXTENDED ((U8) 0x03)

Description:

Extended session entered by tool request.

7.7.2.5.1.6. PDG_NUM_SEC_LEVELS_PER_SERVICE
Definition:

#define PDG_NUM_SEC_LEVELS_PER_SERVICE 3 /* If altered, NVM file format must change! */

Description:

Limit on number of specific security levels that can be assigned to a service.

7.7.2.5.2.  Enumerations
7.7.2.5.2.1. PDG_RC_T
Summary:

Diagnostic feature return codes.

Enumerations:
PDG_RC_OK

Everything okay.

PDG_RC_BAD_INFOTYPE

The requested infotype is not recognised.

PDG_RC_BAD_ARGS

A null pointer was passed as an argument or an incorrect string length was given or unable to find the given subnet.

PDG_RC_PLATFORM_INFOTYPE

The requested infotype is handled by the platform.

PDG_RC_BAD_LICENSE

User is not licensed for this feature.

7.7.2.5.2.2. PDG_ROUTINE_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some routine control functions.

Enumerations:
PDG_ROUTINE_RC_OK

Return code if everything progressed as expected.

PDG_ROUTINE_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PDG_ROUTINE_RC_BAD_CONFIG_DATA

Return code if the routine configuration data was invalid for requested operation.

PDG_ROUTINE_RC_NOT_FOUND

No such routine ID found.

PDG_ROUTINE_RC_ERROR

Unspecified error.

7.7.2.5.2.3. PDG_CALLBACK_OUTCOME_T
Summary:

Return codes by the application to indicate how it would like the PDG feature to continue handling the message just received.

Enumerations:
PDG_STANDARD_PLATFORM_REPLY

Construct reply according to normal platform behaviour.

PDG_STAY_SILENT

Do not send any response to this message at all.

PDG_SEND_WHOLE_APP_MSG

Cease normal processing of this message, and transmit the data loaded into the transmit buffer by the application callback routine instead.

PDG_SEND_WITH_APP_ID_DATA

For a PID request, use the ID value bytes placed in the transmit buffer by the application callback routine and continue processing the rest of the message as normal.

PDG_SEND_OMITTING_THIS_ID

For a PID request, omit the ID echo and value bytes for this PID, but continue processing the rest of the request (which may include requests for other PIDs) as usual.

7.7.2.5.2.4. PDG_CC_COMM_TYPE_T
Summary:

Communication type parameter for the communication control diagnostic service.

Enumerations:
PDG_NORMAL_MSGS

All application-related communication (inter-application signal exchange between multiple in-vehicle servers).

PDG_NETWORK_MSGS

All network-management-related communication.

PDG_NORMAL_AND_NETWORK_MSGS

All network management and application-related communication.

Description:

Communication type parameter for the communication control diagnostic service.

Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E).

7.7.2.5.2.5. PDG_CC_CTRL_TYPE_T
Summary:

The subfunction parameter controlType for the communication control diagnostic service.

Enumerations:
PDG_MSG_CTRL_INCONSISTENT

Indicates inconsistent control types for network and normal messages where the application requested communication type is both network and normal messages.

PDG_ENABLE_RX_AND_TX

Indicates the reception and transmission of messages are enabled for the specified communication type.

PDG_ENABLE_RX_AND_DISABLE_TX

For the specified communication type indicates the reception of messages are enabled and the transmission of messages are disabled.

PDG_DISABLE_RX_AND_ENABLE_TX

For the specified communication type indicates the reception of messages are disable and the transmission of messages are enabled.

PDG_DISABLE_RX_AND_TX

Indicates the reception and transmission of messages are disabled for the specified communication type.

Description:

The subfunction parameter controlType for the communication control diagnostic service.

Encoded as per table 53 of IS0 14229-1:2006(E).

7.7.2.5.2.6. PDG_SECURITY_OPTION_T
Summary:

Controls whether certain services are allowed to run, and if so whether they require any or specific security levels to have been unlocked.

Enumerations:
PDG_SECURITY_WORKS_WITHOUT

Always allowed regardless of security status.

PDG_SECURITY_ANY_LEVEL

Allowed so long as some security level has been unlocked.

PDG_SECURITY_SPECIFIED_LEVELS

Allowed only if a security level has been unlocked that is in the specific list required for this service to be enabled.

PDG_SECURITY_NEVER_ALLOWED

Service is never allowed regardless of security.

7.7.2.5.3.  Data types
7.7.2.5.3.1. PDG_GENERAL_CALLBACK_FN_T
Definition:

typedef PDG_CALLBACK_OUTCOME_T(* PDG_GENERAL_CALLBACK_FN_T)(const U8 *pdgf_rx_msg_buff, S16 pdgf_rx_msg_len, U8 *pdgf_tx_msg_buff, S16 *pdgf_tx_msg_len, S16 pdgf_max_tx_msg_len, BOOL pdgf_physically_addressed)

Description:

Callback function pointer type for general callback.

Every time PDG receives a request, if a callback function of this type is supplied, it will be called. This gives the application code the opportunity to perform any specific processing that overrides the normal platform behaviour.

Arg (data in): pdgf_rx_msg_buff

The start of the ISO16765-2 receive buffer containing the request message bytes (e.g. element 0 will be the service ID).

Arg (data in): pdgf_rx_msg_len

The length of the ISO16765-2 request received.

Arg (data in,out): pdgf_tx_msg_buff

A pointer to the start of the transmit buffer in which any response message should be constructed.

Arg (data out): pdgf_tx_msg_len

The size of the message (if any) which has been constructed by the application in the transmit buffer is returned through this pointer.

Arg (data in): pdgf_max_tx_msg_len

The available space in the ISO16765-2 transmit buffer. The application must not attempt to construct a message longer than this.

Arg (data in): pdgf_physically_addressed

Whether the request message was received using the physical address for this ECU rather than the functional address used to interrogate all ECUs.

Return:

See PDG_CALLBACK_OUTCOME_T.

7.7.2.5.3.2. PDG_ID_REQUEST_CALLBACK_FN_T
Definition:

typedef PDG_CALLBACK_OUTCOME_T(* PDG_ID_REQUEST_CALLBACK_FN_T)(const struct PPID_PID_CONST_T *pdgf_id_requested,const U8 *pdgf_rx_msg_buff, S16 pdgf_rx_msg_len, S16 pdgf_rx_id_offset, U8 *pdgf_tx_msg_buff, S16 *pdgf_tx_msg_len, S16 pdgf_max_tx_len, S16 pdgf_tx_id_data_offset, S16 *pdgf_tx_id_data_len, S16 pdgf_max_id_data_len, BOOL pdgf_physically_addressed)

Description:

Callback function pointer type for the ID request callback.

Every time PDG receives a request for an ID value, if a callback function of this type is supplied, it will be called. This gives the application code the opportunity to inject custom values computed at the time of the request for the corresponding PID. Alternatively, the application may opt to override the entire message response.

Arg (data in): pdgf_id_requested

A pointer to the PID structure for the ID that has been requested, if it is defined; otherwise NULL for an unknown PID (which the application may still choose to provide a value for).

Arg (data in): pdgf_rx_msg_buff

The start of the ISO16765-2 receive buffer containing the request message bytes (e.g. element 0 will be the service ID).

Arg (data in): pdgf_rx_msg_len

The length of the ISO16765-2 request received.

Arg (data in): pdgf_rx_id_offset

The index into the receive message buffer at which the first byte of the ID being requested exists. This will be a single byte for KW2000-3 LocalIdentifier or J1979 $01 requests, but two bytes for KW20003 CommonIdentifier or UDS Identifier requests.

Arg (data in,out): pdgf_tx_msg_buff

A pointer to the start of the transmit buffer in which any complete response message should be constructed.

Arg (data out): pdgf_tx_msg_len

The size of the complete response message (if any) which has been constructed by the application in the transmit buffer is returned through this pointer.

Arg (data in): pdgf_max_tx_msg_len

The available space in the ISO16765-2 transmit buffer. The application must not attempt to construct a message longer than this.

Arg (data in): pdgf_tx_id_data_offset

The index into the transmit message buffer at which the first byte of the ID value should be placed by the application, if it does so.

Arg (data out): pdgf_tx_id_data_len

The size of the value (if any) which has been placed in the transmit buffer for this ID by the application is returned through this pointer.

Arg (data in): pdgf_max_id_data_len

The maximum size allowed for the value bytes for this ID to avoid transmit buffer overrun. The application must not attempt to write more bytes for this ID than this size.

Arg (data in): pdgf_physically_addressed

Whether the request message was received using the physical address for this ECU rather than the functional address used to interrogate all ECUs.

Return:

See PDG_CALLBACK_OUTCOME_T.

7.7.2.5.3.3. PDG_SECURITY_CALLBACK_FN_T
Definition:

typedef U8(* PDG_SECURITY_CALLBACK_FN_T)(const U8 *pdgf_request_message, U16 pdgf_request_message_len, U8 *pdgf_seed_buffer, U8 *pdgf_seed_len, U32 pdgf_random)

Description:

Callback function pointer type for the security callback.

Every time PDG receives a SecurityAccess ($27) request, it will call a function of this type if provided in your application. Using a callback in this way allows you to implement your own, confidential algorithm. You must provide a function of this type if the use-security-fn setting in the interface file is TRUE.

In order to work during flash reprogramming, this function is copied to non-volatile memory before the application code is erased. This means that the code must be relocatable.

Warning

If this function calls another function, including a compiler-generated arithmetic utility, it will fail to run correctly once relocated. This function must be written with great care.

Note

Your function must be immediately followed in memory by an end marker (see PDG_SECURITY_END_FN_T).

The second byte of the request message is the securityAccessType parameter (refer to the UDS/ISO 14229-1 specification). Which values you support to is your own choice. However, odd values must be used for requestSeed and even values for sendKey.

If the request is requestSeed, you are required to provide seed bytes which will then be sent back to the test tool in a positive response message.

If the request is sendKey, you should validate the key in the request message against the previously sent seed, and return a negative response code if you consider the key invalid or zero otherwise.

If the option to enable security during UDS flash reprogramming is enabled then the platform will only proceed if a valid key has been accepted. (See iso-diagnostics group .capi file options for details and an example security algorithm function.)

Arg (data in): pdgf_request_message

A pointer to the complete request message from the diagnostic test tool.

Arg (data in): pdgf_request_message_len

The complete byte length (including service ID) of the request message from the diagnostic test tool.

Arg (data in,out): pdgf_seed_buffer

The buffer in which this function should place the seed bytes to return to the diagnostic test tool; the same seed bytes are made available if the function is being called to validate a key. Fill the buffer from element zero first.

Arg (data out): pdgf_seed_len

The size in bytes of the seed value that this function is providing, if a seed is requested. Range: [1, PDG_MAX_SEED_SIZE].

Arg (data in): pdgf_random

A 32-bit pseudorandom number provided by the platform library that may be used as the basis of a seed value.

Note

This is not a random number of high cryptographic quality.

Return:

Zero if the platform should emit a positive response; otherwise, the negative response code that should be sent.

7.7.2.5.3.4. PDG_SECURITY_END_FN_T
Definition:

typedef void(* PDG_SECURITY_END_FN_T)(void)

Description:

Function pointer type to mark the end of the security callback.

See also PDG_SECURITY_CALLBACK_FN_T.

The function you provide of this type must immediately follow the security callback function you provide for UDS. It is used by the platform to compute the size of the security function so that it can be copied to non-volatile memory.

7.7.2.5.4.  Variables
7.7.2.5.4.1. pdgc_emissions_report_min_sev
Definition:

const volatile PIO_EMISSION_SEV_TYPE_T pdgc_emissions_report_min_sev

Description:

Calibration to determine the minimum emissions severity of DTCs to be reported.

7.7.2.5.5.  Functions
7.7.2.5.5.1. pdg_get_active_session_type()
Definition:

U8 pdg_get_active_session_type(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Retrieves type of currently active diagnostic session.

Return:

One of PDG_SESSION_UDS_DEFAULT, PDG_SESSION_UDS_EXTENDED or PDG_SESSION_UDS_PROGRAMMING. The UDS state value is returned even if the test tool used a KW2000-3 value to request entry to the session.

7.7.2.5.5.2. pdg_set_active_session_type()
Definition:

void pdg_set_active_session_type(
   U8   pdgf_session);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Sets the type of currently active diagnostic session.

Arg (data in): pdgf_session

One of PDG_SESSION_UDS_DEFAULT, PDG_SESSION_UDS_EXTENDED or PDG_SESSION_UDS_PROGRAMMING. The UDS state value is returned even if the test tool used a KW2000-3 value to request entry to the session.

7.7.2.5.5.3. pdg_set_infotype()
Definition:

PDG_RC_T pdg_set_infotype(
   PIO_INFOTYPE_T   pdgf_infotype_id,
   const U8        *pdgf_infotype_data,
   U8               pdgf_infotype_length,
   BOOL             pdgf_pending);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Function to set the InfoType data.

Call this function from initialisation and when the application is running if necessary to set or update the J1979 Infotype data.

Arg (data in): pdgf_infotype_id

An enumerated constant that matches the INFOTYPE id.

Arg (data in): pdgf_infotype_data

Pointer to the array containing the data to be written.

Arg (data in): pdgf_infotype_length

Length of the array containing the data to be written.

Arg (data in): pdgf_pending

Indicates the availability of the application data. False indicates the data is available. When true, a J1979 request for the data will result in the negative response code $78 (requestCorrectlyReceived-ResponsePending) followed by a negative response code $78 message at 4.5s intervals until pdgf_pending transistions to false where upon the supplied infotype data is sent. Only applicable to the CVN infotype.

Return:
  • PDG_RC_OK - everything ok

  • PDG_RC_BAD_LICENSE - not licensed to execute this function

  • PDG_RC_BAD_INFOTYPE - infotype not supported by platform

  • PDG_RC_BAD_ARGS - null pointer or undefined infotype

  • PDG_RC_PLATFORM_INFOTYPE - infotype handled exclusively by platform

7.7.2.5.5.4. pdg_get_comm_ctrl_state()
Definition:

PDG_CC_CTRL_TYPE_T pdg_get_comm_ctrl_state(
   PDG_CC_COMM_TYPE_T   pdgf_communication_type,
   U8                   pdgf_subnet_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Function to retrieve status of communication control diagnostic service.

Service $28 switches on/off the transmission and or the reception of certain CAN messages. The onus is on the application to dictate which messages to switch on/off, as such the status of communication control service is provided to the application via this function.

Arg (data in): pdgf_communication_type

Communication type parameter. Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E)

Arg (data in): pdgf_subnet_id

The subnet identifier. Only 4 subnets supported 0x0, 0x1, 0x2 and 0xF. Subnet encoded as per table B.1 in Annex B of IS0 14229-1:2006(E). ID 0x0 receiving node and all connected networks. ID 0x1 and 0x2 specific network identity. ID 0xF Network which the request is recieved on.

Return:
  • PDG_MSG_CTRL_INCONSISTENT - inconsistent control types for network and normal messages where the application requested communication type is both network and normal messages

  • PDG_ENABLE_RX_AND_TX - reception and transmission of messages are enabled

  • PDG_ENABLE_RX_AND_DISABLE_TX - reception of messages are enabled and the transmission of messages are disabled

  • PDG_DISABLE_RX_AND_ENABLE_TX - reception of messages are disable and the transmission of messages are enabled

  • PDG_DISABLE_RX_AND_TX - reception and transmission of messages are disabled

7.7.2.5.5.5. pdg_comm_ctrl_cond_not_correct()
Definition:

PDG_RC_T pdg_comm_ctrl_cond_not_correct(
   BOOL                 pdgf_conditions_not_correct,
   U8                   pdgf_subnet_id,
   PDG_CC_COMM_TYPE_T   pdgf_comm_type);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Function to indicate the conditions for communications control (service $28) are not correct.

Where the conditions are not correct a negative response code of conditionsNotCorrect (NRC $22) is sent in reply to a service $28 request. NRC $22 indicates the server (ECU) is in a critical normal mode activity and therefore cannot disable/enable the requested communication type.

Call this function from initialisation and/or periodically.

Arg (data in): pdgf_conditions_not_correct

True if conditions are not correct to disable/enable the requested communication type otherwise false if conditions are ok.

Arg (data in): pdgf_subnet_id

The subnet identifier. Only 5 subnets supported 0x0, 0x1, 0x2, 0x3 and 0xF. Subnet encoded as per table B.1 in Annex B of IS0 14229-1:2006(E). ID 0x0 receiving node and all connected networks. ID 0x1, 0x2 and 0x3 specific network identity. ID 0xF Network which the request is recieved on.

Arg (data in): pdgf_comm_type

Communication type parameter. Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E)

Return:
  • PDG_RC_OK - everything okay

  • PDG_RC_BAD_LICENSE - not licensed to execute this function

  • PDG_RC_BAD_ARGS - unable to find the subnet

7.7.2.5.5.6. pdg_update_routine_ctrl_data()
Definition:

PDG_ROUTINE_RC_T pdg_update_routine_ctrl_data(
   struct PDG_ROUTINE_T *const   pdgf_routine_data,
   BOOL                          pdgf_routine_ready,
   BOOL                          pdgf_routine_running,
   const U8                     *pdgf_routine_status_record,
   BOOL                          pdgf_routine_results_valid,
   const U8                     *pdgf_routine_results);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update platform-cached values for this routine with fresh application values.

Arg (data in,out): pdgf_routine_data

Pointer to the routine control data structure to be updated

Arg (data in): pdgf_routine_ready

Flag from the application to signal that the routine is able to run if requested.

Arg (data in): pdgf_routine_running

Flag from the application to signal that the routine is currently running.

Arg (data in): pdgf_routine_status_record

Pointer to the routine status record bytes to be transmitted in the response message.

Arg (data in): pdgf_routine_results_valid

Flag from the application to signal that valid routine results are available.

Arg (data in): pdgf_routine_results

Pointer to the routine results bytes.

Return:

7.7.2.5.5.7. pdg_get_routine_rqst()
Definition:

PDG_ROUTINE_RC_T pdg_get_routine_rqst(
   struct PDG_ROUTINE_T *const   pdgf_routine_data,
   PDG_ROUTINE_CTRL_T *const     pdgf_routine_rqst,
   U8 *const                     pdgf_routine_ctrl_option_record);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Retrieve routine requests from the diagnostic tool.

Arg (data in): pdgf_routine_data

Pointer to the routine control data structure.
Cannot be NULL.

Arg (data out): pdgf_routine_rqst

Pointer to an enumeration which will hold the routine control request.
Cannot be NULL.

Arg (data out): pdgf_routine_ctrl_option_record

Pointer to a buffer to hold the routine control option record bytes. Can be NULL if routine control options are not used for this routine.

Return:

7.7.3. Diagnostic Trouble Code Extended (DTC) feature (PDTC)

7.7.3.1. Overview

This section covers the extended diagnostics functions available in addition to the basic diagnostic trouble code (DTC) functionality (see Section 5.18, “Diagnostic Trouble Code (DTC) feature (PDTC)”):

Library controlled OBD state handling

The library supports platform controlled On-Board Diagnostics and DTC state handling as per CARB OBD standards, including freeze frame capture.

DTC ageing

The library ages DTCs based on drive cycles and warm-up cycles.

ISO DTC type

The library adds an ISO DTC type in addition to the J1939 DTC type provided as standard.

7.7.3.2. Platform On-Board Diagnostic support

The library supports platform controlled On-Board Diagnostics and DTC state handling as per CARB OBD standards. This functionality, available at extra cost, can be used by calling the pdtc_update_plat_obd_dtc() C-API function.

An OBD DTC can have up to three freeze frames associated with it: an ISO freeze frame, a J1939 DM4 freeze frame, and/or a J1939 DM25 expanded freeze frame. See section Section 7.7.4, “Freeze Frame feature (PFF)” for details.

The application declares the PDTC_DTC_T data structure per DTC of interest during build time which contains the configuration for that DTC: J1939 SPN/FMI/CM, ISO-15765 DTC ID, lamps to light when DTC is active, and so on. The PDTC_DTC_T data structure then references two further data structures, PDTC_DTC_NV_T and PDTC_DTC_VAR_T, which store the DTC's non-volatile variables (stored in flash between power cycles) and volatile variables (held in RAM and lost on power-off) respectively.

Each DTC can be in one of four states. Its state is Clear if its fault conditions have never been present, or if a previously active fault has healed itself (its fault conditions have not been present for a sufficient amount of time). Its state is Pending if its fault conditions are present, but have not been present for long enough to confirm the fault. Its state becomes Active if a Pending DTC's fault conditions persist long enough for it to be confirmed, or if a Previously Active DTC's fault conditions return. Its state becomes Previously Active if an Active DTC's fault conditions have been not been present for a sufficient amount of time.

The library will transition through the different states, Clear, Pending, Active and Previously Active based upon the inputs from the application, pdtcf_test_failed and pdtcf_test_completed as well as information regarding current drive cycle and warm up cycle count.

State transitions are also affected by whether transitions between Previously Active and Pending states are permitted when a previously active fault recurs. Behaviour in this situation is not specified by CARB (and therefore not by other OBD specifications deriving from CARB), so behaviour is manufacturer-specific and has therefore been made configurable. Calibration pdtc_transition_prev_act_to_pend specifies whether this transition is enabled or not (set to TRUE to enable). In the C-API configuration file, this is controlled by the setting transition-previously-active-to-pending (see Section 8.1.4.28, “Compound statement: dtc-data”).

If transitions between Previously Active and Pending states are disabled, the following diagram describes the DTC state transitions.

Figure 7.4. Platform OBD state machine — no transitions between Previously Active and Pending

Platform OBD state machine — no transitions between Previously Active and Pending

If transitions between Previously Active and Pending states are enabled, the following diagram describes the DTC state transitions.

Figure 7.5. Platform OBD state machine — transitions between Previously Active and Pending

Platform OBD state machine — transitions between Previously Active and Pending

The library keeps track of a new drive cycle or warm-up cycle based on inputs from the application, pdtcf_start_of_dc and pdtcf_start_of_wup respectively, to the following functions:

7.7.3.2.1. DTC ageing in Previously Active state

Detection of warm-up and DTC ageing in the Previously Active state is not as straightforward as it might at first appear. OBD regulations (in particular CARB and European regulations) define drive cycles unambiguously, but are less clear on the definition of a warm-up cycle. It has therefore been necessary to adopt an interpretation which is believed to be the most stringent possible interpretation, so that regulatory compliance can be assured.

The OpenECU interpretation of a warm-up cycle is “an ignition cycle in which a warm-up (as reported by the customer) occurs”. The test causing a DTC to be raised must also run and pass during the same ignition cycle in which the warm-up occurs, in order for the DTC to be aged by one warm-up count. The following diagram describes scenarios which illustrate how this will work in an application.

At points A and B a test has not been run and passed in the same warm-up cycle, so the warm-up count is not incremented.

At point C the warm-up has not yet occurred when the test is run and passed, so the warm-up count is not incremented. At point D the warm-up occurs, and as a result of the test having been previously run and passed, the warm-up count is incremented. Further instances of the test running and passing during this ignition cycle (E) do not affect the warm-up count, because this is required to count warm-ups and not test executions.

At point F the test is run and passed when the warm-up has already occurred, so the warm-up count is incremented immediately. Further instances of the test running and passing during this ignition cycle (G) again do not affect the warm-up count.

Due to power-hold relays, capacitors or other system behaviour, the ECU may not lose power when the ignition is cycled. Points H and J illustrate that tests carried out on subsequent ignition cycles with warm-ups will increment the warm-up count, even if the ECU has not been powered off. Point K illustrates that the requirement for test run and warm-up remains.

Tests may also be required to take place during the power-hold period. Point L illustrates that the warm-up count will be incremented during the power-hold period if a warm-up cycle has previously taken place this ignition cycle. Point M illustrates that the requirement for warm-up still exists during the power-hold period.

Note that this diagram does not mention drive cycles, as these are calculated independently and do not affect warm-up (except insofar as they are based on conditions arising in the same vehicle). Note also that the diagram does not mention warm-ups reported with the ignition off, because the regulatory definition of a warm-up requires the engine to be on (and hence the ignition to be on).

7.7.3.3. Diagnostic trouble codes — J1939

The library maintains an internal state for a J1939 DTC as described by Section 5.18.3, “Diagnostic trouble codes — J1939”.

7.7.3.4. Diagnostic trouble codes — ISO

The library maintains an internal state for an ISO DTC based on the pdtcf_state_in parameter to the function pdtc_update_iso_dtc(). State transitions depend on whether transitions from Inactive state to Pending state are enabled, as shown by the following state diagrams. This is enabled or disabled by the calibration pdtc_transition_prev_act_to_pend. This calibrations's value is controlled in the C-API configuration file by the setting transition-previously-active-to-pending (see Section 8.1.4.28, “Compound statement: dtc-data”).

If transitions from Inactive state to Pending state are disabled, the following diagram describes the DTC state transitions.

Figure 7.6.  ISO DTC state machine — no transitions from Inactive to Pending

ISO DTC state machine — no transitions from Inactive to Pending

If transitions from Inactive state to Pending state are enabled, the following diagram describes the DTC state transitions.

Figure 7.7.  ISO DTC state machine — transitions from Inactive to Pending

ISO DTC state machine — transitions from Inactive to Pending

Not shown in the above figures is that the DTC state can be forcefully set to clear through the use of the pdtc_clear_all(), pdtc_clear_all_if_active() or pdtc_clear_all_if_inactive() or pdtc_clear_dtcs() functions.

7.7.3.5. Storage of data across power cycles

As described in Section 5.18.4, “Storage of data across power cycles”, if the DTC information stored across power cycles cannot be recalled correctly then DTCs are reset to default start-up conditions:

Table 7.4. DTC initialisation values

DTC informationInitial value
StateClear
Test Never Completed Since OBD Reset (reported by ISO-15765)Yes
Number of Times Set Active Count (reported by J1939)0
Lamp States (Section 7.7.3.4, “Diagnostic trouble codes — ISO” and Section 5.18.3, “Diagnostic trouble codes — J1939” only)All off
Drive Cycle Count (Section 7.7.3.2, “Platform On-Board Diagnostic support” only)0
Warm-up Cycle Count (Section 7.7.3.2, “Platform On-Board Diagnostic support” only)0
Test Run/Passed/Failed This Drive Cycle (Section 7.7.3.2, “Platform On-Board Diagnostic support” only)Test not run
Total time in "Active" state0
Total time in "Previously Active" state0
Time remaining until torque derate (relevant only for DTCs which have torque derate)Maximum (62.5 hours)

7.7.3.6. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and pdtc.h
Macros
 PDTC_LAMPS_OFF

Value for all lamps OFF.

 PDTC_OBD_CLEAR_EMISSIONS_RELATED

Bit 0 set for reporting ISO-15765 emissions-related DTCs cleared via ISO-15765 service $04 OBD request.

 PDTC_OBD_CLEAR_ALL

Bit 1 set for reporting all ISO-15765 DTCs cleared via ISO-15765 service $14 OBD request (regardless of groupOfDTC option).

 PDTC_OBD_CLEAR_PREV_ACTIVE

Bit 2 set for reporting J1939 DTCs in Previously Active state cleared via J1939 DM3 OBD request.

 PDTC_OBD_CLEAR_ACTIVE

Bit 3 set for reporting J1939 DTCs in Active state cleared via J1939 DM11 OBD request.

 PDTC_DISABLE_COUNTER_TRANSITION

Value used to disable DTC transitions based on counters of drive cycles or warm-up cycles.

 PDTC_DISABLE_ENGINE_RUNNING_TRANSITION

Value used for DTC time_to_deactive and time_to_clear settings to disable the DTC transitions from "Active" to "Previously Active" or from from "Previously Active" to "Clear" based on time with engine running and fault not present.

Enumerations
 PDTC_LAMP_T

This enumeration declares the different lamps which may be controlled by DTC states, where certain types of lamp require special reporting by on-board diagnostics.

 PDTC_COMBINED_LAMP_STATE_T

This enumeration declares all possible states for a lamp.

 PDTC_MI_MODE_T

This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no.

 PDTC_IT_TYPE_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's state.

 PDTC_IT_ESEV_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's emissions severity.

 PDTC_IT_STATE_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's state.

Data types
 PDTC_DTC_NV_T

This structure declares the run-time data to be stored with each DTC.

 PDTC_DTC_VAR_T

This structure declares the variable data to be stored in RAM with each DTC type.

 PDTC_DTC_T

This structure declares the constant data to be stored with each DTC type.

 PDTC_TABLE_VAR_T

This structure declares all per-DTC-table variable data.

Variables
const BOOLpdtc_lamp_flashing_is_priority

This calibration selects the lamp priority system used to select the desired state for a lamp when multiple DTCs are active and request different states.

const BOOLpdtc_transition_prev_act_to_pend

This calibration selects the DTC state behaviour when a fault recurs whilst the DTC is in the "previously active" state.

const PDTC_TABLE_Tpdtc_table_all

This is a table of all DTCs defined in the system.

Functions
PDTC_MI_MODE_Tpdtc_get_mi_activation_mode

Supplies the current MI activation mode.

U32pdtc_get_b1_cumulative_counter

Supplies the cumulative time in seconds for which any B1 fault has been active.

U32pdtc_get_b1_continuous_counter

Supplies the time in seconds for which any B1 fault has been active continuously.

U32pdtc_get_mil_cumulative_counter

Supplies the cumulative time in seconds for which the MI has been demanded to be illuminated.

PDTC_ERROR_CODE_Tpdtc_clear_all_tables

Clear the state of each DTC of matching type in all the DTC tables.

PDTC_ERROR_CODE_Tpdtc_clear_all_by_severity

Clear the state of each DTC of matching type emission severity level in a DTC table.

voidpdtc_clear_dtcs

Clear DTCs, within a DTC table, which match the supplied criteria.

PIO_DTC_LAMP_STATES_Tpdtc_get_lamp_state

This function returns the current state of a lamp, based on DTCs set in the selected table.

PIO_DTC_LAMP_STATES_Tpdtc_get_MIL_status

Indicates whether the MIL has to be ON due to DTCs (CARB), based on all DTC tables in the system.

PIO_DTC_LAMP_STATES_Tpdtc_get_RSL_status

Indicates whether the Red lamp has to be ON due to DTCs (CARB).

PIO_DTC_LAMP_STATES_Tpdtc_get_AWL_status

Indicates whether the Amber lamp has to be ON due to DTCs (CARB).

PIO_DTC_LAMP_STATES_Tpdtc_get_Protect_lamp_status

Indicates whether the Protect lamp has to be ON due to DTCs (CARB).

BOOLpdtc_match_exists

Determine the existence and count of DTCs, within a DTC table, which match the supplied criteria.

U32pdtc_check_table_cleared

Reports whether DTCs have been cleared by OBD request.

PDTC_ERROR_CODE_Tpdtc_get_dtc_status

Retrieve the status data of a DTC.

voidpdtc_plat_obd_update_clr_perm_ok

Keeps track of whether conditions have been met for clearing CARB permanent DTCs after an OBD clear request.

voidpdtc_plat_obd_update_engine_running

Keeps track of engine running state for DTCs.

voidpdtc_plat_obd_update_ign_cyc

Keeps track of new ignition cycle.

voidpdtc_plat_obd_update_dc_count

Keeps track of new drive cycle for DTCs.

voidpdtc_plat_obd_update_wup_count

Keeps track of new warmup cycle for DTCs.

PDTC_ERROR_CODE_Tpdtc_update_iso_dtc

Function to update the state and data of an ISO DTC.

PDTC_ERROR_CODE_Tpdtc_update_plat_obd_dtc

Function to update the state and data of the DTC when controlled by platform.


TypeIdentifier
Include file
 openecu.h and pio.h
Enumerations
 @7

This enumeration declares the different types of DTC lamp state available.

Data types
 PIO_DTC_LAMP_STATES_T

This enumeration declares the different types of DTC lamp state available.

7.7.3.7. Interface detail

7.7.3.7.1.  Macros
7.7.3.7.1.1. PDTC_LAMPS_OFF
Definition:

#define PDTC_LAMPS_OFF ((U8)0xFF)

Description:

Value for all lamps OFF.

7.7.3.7.1.2. PDTC_OBD_CLEAR_EMISSIONS_RELATED
Definition:

#define PDTC_OBD_CLEAR_EMISSIONS_RELATED ((U32)0x01)

Description:

Bit 0 set for reporting ISO-15765 emissions-related DTCs cleared via ISO-15765 service $04 OBD request.

Reported by function pdtc_check_table_cleared.

7.7.3.7.1.3. PDTC_OBD_CLEAR_ALL
Definition:

#define PDTC_OBD_CLEAR_ALL ((U32)0x02)

Description:

Bit 1 set for reporting all ISO-15765 DTCs cleared via ISO-15765 service $14 OBD request (regardless of groupOfDTC option).

Reported by function pdtc_check_table_cleared.

7.7.3.7.1.4. PDTC_OBD_CLEAR_PREV_ACTIVE
Definition:

#define PDTC_OBD_CLEAR_PREV_ACTIVE ((U32)0x04)

Description:

Bit 2 set for reporting J1939 DTCs in Previously Active state cleared via J1939 DM3 OBD request.

Reported by function pdtc_check_table_cleared.

7.7.3.7.1.5. PDTC_OBD_CLEAR_ACTIVE
Definition:

#define PDTC_OBD_CLEAR_ACTIVE ((U32)0x08)

Description:

Bit 3 set for reporting J1939 DTCs in Active state cleared via J1939 DM11 OBD request.

Reported by function pdtc_check_table_cleared.

7.7.3.7.1.6. PDTC_DISABLE_COUNTER_TRANSITION
Definition:

#define PDTC_DISABLE_COUNTER_TRANSITION ((U8)0xFF)

Description:

Value used to disable DTC transitions based on counters of drive cycles or warm-up cycles.

7.7.3.7.1.7. PDTC_DISABLE_ENGINE_RUNNING_TRANSITION
Definition:

#define PDTC_DISABLE_ENGINE_RUNNING_TRANSITION ((U32)0xFFFFFFFF)

Description:

Value used for DTC time_to_deactive and time_to_clear settings to disable the DTC transitions from "Active" to "Previously Active" or from from "Previously Active" to "Clear" based on time with engine running and fault not present.

7.7.3.7.2.  Enumerations
7.7.3.7.2.1. PDTC_LAMP_T
Summary:

This enumeration declares the different lamps which may be controlled by DTC states, where certain types of lamp require special reporting by on-board diagnostics.

Enumerations:
PDTC_LAMP_PROTECT

This is the Protect lamp.

PDTC_LAMP_AMBER_WARNING

This is the Amber Warning lamp.

PDTC_LAMP_RED_STOP

This is the Red Stop lamp.

PDTC_LAMP_MIL

This is the MIL.

PDTC_NUM_LAMPS

Count number of lamp types supported.

7.7.3.7.2.2. PDTC_COMBINED_LAMP_STATE_T
Summary:

This enumeration declares all possible states for a lamp.

Enumerations:
PDTC_COMBINED_SLOW_FLASH

Slow flash (1Hz, 50% duty cycle)

PDTC_COMBINED_FAST_FLASH

Fast flash (2Hz or faster, 50% duty cycle)

PDTC_COMBINED_ON

Lamp on continuous.

PDTC_COMBINED_SHORT_MIL_ACTV_ON

MIL only - lamp on, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) active and lamp required to be on.

PDTC_COMBINED_SHORT_MIL_ACTV_OFF

MIL only - lamp off, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) active and lamp required to be off.

PDTC_COMBINED_SHORT_MIL_INACTIVE

MIL only - lamp off, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) present but Short MIL sequence inactive.

PDTC_COMBINED_CLASS_C_ACTIVE_ON

MIL only - lamp on, due to WWH OBD Class C DTC(s) set and lamp required to be on for reporting.

PDTC_COMBINED_CLASS_C_ACTIVE_OFF

MIL only - lamp off, due to WWH OBD Class C DTC(s) set and lamp required to be off for reporting.

PDTC_COMBINED_CLASS_C_INACTIVE

MIL only - lamp off, due to WWH OBD Class C DTC(s) set and reporting not in progress.

PDTC_COMBINED_SELF_TEST_ON

MIL only - lamp on, due to self-test in progress.

PDTC_COMBINED_SELF_TEST_OFF

MIL only - lamp off, due to self-test in progress.

PDTC_COMBINED_OFF

Lamp off, no relevant DTCs set.

7.7.3.7.2.3. PDTC_MI_MODE_T
Summary:

This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no.

Enumerations:
PDTC_MODE_MI_OFF

Off = No malfunction.

PDTC_MODE_ON_DEMAND_MI

On Demand MI = Class C malfunction.

PDTC_MODE_SHORT_MI

Short MI = Class B malfunction and B1 counter < 200 hours.

PDTC_MODE_CONTINUOUS_MI

Continuous MI = Class A malfunction or B1 counter > 200 hours.

Description:

This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no.

49, Addendum 48.

7.7.3.7.2.4. PDTC_IT_TYPE_COMPARATOR_T
Summary:

This enumeration declares the comparison tests for a DTC's state.

Enumerations:
PDTC_IT_TYPE_DC

Don't care.

PDTC_IT_TYPE_CT

Contains.

7.7.3.7.2.5. PDTC_IT_ESEV_COMPARATOR_T
Summary:

This enumeration declares the comparison tests for a DTC's emissions severity.

Enumerations:
PDTC_IT_ESEV_DC

Don't care.

PDTC_IT_ESEV_EQ

Equals.

PDTC_IT_ESEV_NE

Not equal.

PDTC_IT_ESEV_LT

Less than.

PDTC_IT_ESEV_LTE

Less than or equal.

PDTC_IT_ESEV_GT

Greater than.

PDTC_IT_ESEV_GTE

Greater than or equal.

7.7.3.7.2.6. PDTC_IT_STATE_COMPARATOR_T
Summary:

This enumeration declares the comparison tests for a DTC's state.

Enumerations:
PDTC_IT_STATE_DC

Don't care.

PDTC_IT_STATE_EQ

Equals.

PDTC_IT_STATE_NE

Not equal.

7.7.3.7.3.  Data types
7.7.3.7.3.1. PDTC_DTC_NV_T
Summary:

This structure declares the run-time data to be stored with each DTC.

Members:
U8 PDTC_DTC_NV_T::dtc_dc_count

This keeps track of the number of drive cycles, and is used for different purposes depending on the DTC state.


On entry to "Pending" state, this is reset to zero. On each subsequent drive cycle where the test for this DTC is run and fails, the counter is incremented until the limit is reached for transition to "Active" state.\n On entry to "Active" state, this is reset to zero. If the test for this DTC runs and fails, the counter is reset to zero. On each subsequent drive cycle where the test for this DTC is run and passed, and the test did not run and fail during the same drive cycle, the counter is incremented until the limit is reached for transition to "Previously Active" state.

U8 PDTC_DTC_NV_T::dtc_wup_count

This keeps track of the number of warm-up cycles.

This will be reset each time a DTC state transitions to Previously active state. It will be incremented each subsequent warm up cycle that the fault is not present.

U8 PDTC_DTC_NV_T::test_status_flags

This keeps track of test status flags that are required to be stored over power cycles, using individual bits to store/report each flag.


Bit 0: Test run this drive cycle. Set to 1 if the test for the DTC has been run in the current drive cycle. Set to 0 on starting a new drive cycle.\n Bit 1: Test failed this drive cycle. Set to 1 if the test for the DTC has failed in the current drive cycle. Set to 0 on starting a new drive cycle.\n Bit 2: Test not completed. Set to 0 if the test for the DTC has been run since the last ClearDiagnostics request has been performed.\n Set to 1 when ClearDiagnostics request is serviced. Bit 3: DTC previously active. Set to 1 if a DTC transitions from the "Previously Active" state to the "Pending" state as a result of a test failure occurring whilst the DTC is in the "Previously Active" state. Set to 0 if a DTC transitions from the "Clear" state to the "Pending" state as a result of a test failure occurring whilst the DTC is in the "Clear" state.\n Bit 4: Permanent DTC OBD clear requested. Set to 0 on entry to "Active" state. Set to 1 if a DTC is permanent, the DTC is in the "Active" state, an OBD request to clear the DTC has been received, and test has not failed this drive cycle. Set to 0 if test runs and fails, or on the DTC leaving the "Active" state.\n Bit 5: Permanent DTC ageing conditions met. Set to 0 on entry to "Active" state. Set to 1 if "Permanent DTC OBD clear requested" is set and vehicle/operating conditions to clear permanent DTC are met (by function pdtc_plat_obd_update_clr_perm_ok()). Set to 0 if test runs and fails.

U16 PDTC_DTC_NV_T::time_until_derate

This keeps track of the time left until derate will occur.

This parameter will only be applicable when the DTC attribute 'has_torque_derate' is TRUE and DTC is in state ACTIVE. In all other cases, this will be set to the maximum value of 62.5 hours, as required for J1939 DM32. Scaled as 1 bit = 1 minute.

U16 PDTC_DTC_NV_T::total_prev_active_time

This keeps track of the total time that the DTC is in state PREVIOUSLY_ACTIVE.

Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements. This also meets J1939 DM32 resolution requirement.

U16 PDTC_DTC_NV_T::total_active_time

This keeps track of the total time that the DTC is in state ACTIVE.

Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements. This also meets J1939 DM32 resolution requirement.

U16 PDTC_DTC_NV_T::engine_running_time

This keeps track of the time that the engine is running when the DTC is in states ACTIVE and PREVIOUSLY_ACTIVE and the DTC's fault is not present.

This is used for the time-based ageing/clearing of DTCs as per Euro regulations (directive 2005-78-EC Annex IV section 3.9). Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements.

Description:

This structure declares the run-time data to be stored with each DTC.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.3.7.3.2. PDTC_DTC_VAR_T
Summary:

This structure declares the variable data to be stored in RAM with each DTC type.

Members:
U8 PDTC_DTC_VAR_T::test_status_flags

This keeps track of test status flags that are not required to be stored over power cycles, using individual bits to store/report each flag.

Bit 3: Engine running timer is currently measuring time spent in "Active" state with engine running and DTC fault not present. Set to 1 when timer is running. Set to 0 when timer is not running.
Bit 4: Engine running timer is currently measuring time spent in "Previously Active" state with engine running and DTC fault not present. Set to 1 when timer is running. Set to 0 when timer is not running.
Bit 5: Test passed this ignition cycle. Set to 1 when test has been run and passed in the current ignition cycle. Set to 0 on starting a new ignition cycle. Only set when DTC is in "Previously Active" state.
Bit 6: DTC active this ignition cycle. Set to 1 when DTC state is "Active" in the current ignition cycle. Set to 0 on starting a new ignition cycle with DTC not in "Active" state.
Bit 7: Transient fault. Set to 1 when test is run and passed. Set to 0 when test is run and failed.

U8 PDTC_DTC_VAR_T::minutes_this_hour

This increments every minute up to 60, when it resets back to zero, using previous_time_stamp to track the time interval.

This timer allows updating of time in "Active" or "Previously Active" states and time to derate at appropriate intervals, without requiring storage of more data in NV.

U32 PDTC_DTC_VAR_T::previous_time_stamp

This is the time stamp for computing time in states "Active" or "Previously Active".

  • valid only when platform decides DTC states. The time stamp can be used for both, because the resolution used for timing in these states is such that any time "lost" on a change between "Active" and "Previously Active" is not significant.

U32 PDTC_DTC_VAR_T::engine_running_time_stamp

This is the time stamp for measuring the time spent in states "Active" or "Previously Active" with the engine running and the DTC not set.

Description:

This structure declares the variable data to be stored in RAM with each DTC type.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.3.7.3.3. PDTC_DTC_T
Summary:

This structure declares the constant data to be stored with each DTC type.

Members:
PIO_EMISSION_SEV_TYPE_T PDTC_DTC_T::severity

This is the emission severity associated with a DTC.


Range: [0, 4]

PIO_DTC_UDS_SEV_T PDTC_DTC_T::uds_severity

This is the UDS $19 service severity field associated with a DTC.


Range: [0, 255]

U16 PDTC_DTC_T::iso_16bit_id

This is the KW2000-3/ISO15031-6 ID to use for CAN OBD diagnostics.


Range: [0, 65535]

PDTC_LAMPS_SET_FOR_DTC_T PDTC_DTC_T::lamps_set

This is a structure controlling the status of each lamp when this DTC is set.

If a lamp is unused in an application, its status should always be set to "off", to avoid confusion if a non-existent lamp is reported as being "on".

BOOL PDTC_DTC_T::permanent_storage

This indicates whether the DTC is to be treated as permanent when it is "Active", according to CARB regulations.

BOOL PDTC_DTC_T::requires_conditions_to_clear

This indicates that a permanent DTC requires vehicle/operating conditions to be met as specified by CARB (19711 section (d)(2.3.1)(C)(ii)b.) before the DTC may be cleared.

To meet CARB requirements, this should always be set for permanent DTCs reporting faults for monitors that are not subject to minimum ratio requirements as specified by CARB (19711 section (d)(3.2)). Optionally, permanent DTCs reporting faults for monitors that are subject to minimum ratio requirements may also require these conditions to be met.

U8 PDTC_DTC_T::dc_count_limit

This is the number of drive cycles required for a DTC in state 'Pending' to progress to state 'Active'.

This is valid only for DTCs whose state is controlled by the platform. It is not used for DTCs whose state is set directly by the legacy J1939/ISO-15765 interface.

If set to zero, the DTC does not remain in state 'Pending' but immediately transitions to state 'Active'.

U8 PDTC_DTC_T::error_free_dc_count_limit

This is the number of drive cycles required for a DTC in state 'Active' to progress to state 'Previously Active'.

This is valid only for DTCs whose state is controlled by the platform. It is not used for DTCs whose state is set directly by the legacy J1939/ISO-15765 interface.

If set to zero, the DTC immediately transitions to state 'Previously Active' when the test runs and passes.

If set to 255, the DTC will not transition to state 'Previously Active' based on drive cycles with the test passed. This is not required by any current OBD legislation, but may be necessary for manufacturer-specific DTCs.

If set to any other value, the DTC will transition from 'Active' to 'Previously Active' either when the engine running time is reached OR when sufficient drive cycles without faults are reached, whichever happens first. See Directive 2005-78-EC Annex IV section 3.8.1.

U8 PDTC_DTC_T::self_heal_wup_count_limit

This is the number of warm-up cycles required for a DTC in state 'Previously Active' to progress to state 'Clear'.


If set to zero, the DTC does not remain in state 'Previously Active' but immediately transitions to state 'Clear'.\n If set to 255, the DTC will not transition to state 'Clear' based on warm-up cycles. This is required for permanent DTCs under Euro regulations, as per Directive 2005-78-EC Annex IV section 3.9.2.\n If set to any other value, the DTC will transition from 'Previously Active' to 'Clear' either when the engine running time is reached OR when sufficient warm-up cycles without faults are reached, whichever happens first. See Directive 2005-78-EC Annex IV section 3.9.1.

U8 PDTC_DTC_T::fault_symptom

This is a 4-bit code for the DTC's fault symptom.

0x0 = NONE
0x1 = ABOVE_MAX
0x2 = BELOW_MIN
0x4 = NO_SIGNAL
0x8 = INVALID_SIGNAL

The symptom for other values up to 0xF can be defined by the application

BOOL PDTC_DTC_T::non_erasable

This indicates whether the DTC is a 'non-erasable' DTC, as defined by Euro regulations.

BOOL PDTC_DTC_T::reg_exh_emission_lvl_exceedance

This indicates whether the DTC is a 'regulated exhaust level exceedance' DTC, as required for constructing the J1939 DM32 message.

BOOL PDTC_DTC_T::has_torque_derate

This indicates whether this DTC is required by the applicable OBD regulation to have a torque derate.

U32 PDTC_DTC_T::time_to_derate

The number of hours (specified in seconds) the malfunction can be active until the OBD required derate will occur.

This parameter will only be applicable when parameter 'has_torque_derate' is TRUE.
Range [0, 62.5] hours i.e. [0, 225000] seconds

U32 PDTC_DTC_T::time_to_deactivate

The number of hours (specified in seconds) with engine running and the fault not present, in order for the DTC to transition from "Active" to "Previously Active".

If set to 0xFFFFFFFF, this condition will never be checked. Note that the internal timer cannot store times greater than 0x02D00000 seconds, so any value greater than this effectively amounts to disabling the condition. If enabled, typically this time will be set to 24 hours, as per Directive 2005-78-EC Annex IV section 3.8.1.

If this condition is enabled, the DTC will transition from "Active" to "Previously Active" either when this engine running time is reached OR when sufficient drive cycles without faults are reached, whichever happens first. (See Directive 2005-78-EC Annex IV section 3.8.1.)

U32 PDTC_DTC_T::time_to_clear

The number of hours (specified in seconds) with engine running and the fault not present, in order for the DTC to transition from "Previously Active" to "Clear".

If set to 0xFFFFFFFF, this condition will never be checked. Note that the internal timer cannot store times greater than 0x02D00000 seconds, so any value greater than this effectively amounts to disabling the condition. If enabled, typically this time will be set to 100 hours for non-permanent DTCs or 9600 hours for permanent DTCs, as per Directive 2005-78-EC Annex IV sections 3.9.1 and 3.9.2.

If this condition is enabled and the condition on warm-ups is enabled, the DTC will transition from "Previously Active" to "Clear" either when this engine running time is reached OR when sufficient warm-up cycles without faults are reached, whichever happens first. (See Directive 2005-78-EC Annex IV section 3.9.1.)

const PFF_FF_CONST_T* PDTC_DTC_T::freeze_frame

This points to a freeze frame structure if this DTC has any associated freeze frames.

May be NULL if no freeze frames associated with this DTC. Though this shall be defaulted to freeze frame ID 1.

Description:

This structure declares the constant data to be stored with each DTC type.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.3.7.3.4. PDTC_TABLE_VAR_T
Summary:

This structure declares all per-DTC-table variable data.

Members:
BOOL PDTC_TABLE_VAR_T::emissions_related_dtcs_cleared

This stores whether emissions-related DTCs in the table have recently been cleared using ISO service $04.

BOOL PDTC_TABLE_VAR_T::all_dtcs_cleared

This stores whether all DTCs in the table have recently been cleared using ISO service $14.

BOOL PDTC_TABLE_VAR_T::prev_active_dtcs_cleared

This stores whether previously active DTCs in the table have recently been cleared using J1939 DM3 (by call to function pdtc_clear_all_if_inactive).

BOOL PDTC_TABLE_VAR_T::active_dtcs_cleared

This stores whether previously active DTCs in the table have recently been cleared using J1939 DM11 (by call to function pdtc_clear_all_if_active).

Description:

This structure declares all per-DTC-table variable data.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.3.7.4.  Variables
7.7.3.7.4.1. pdtc_lamp_flashing_is_priority
Definition:

const BOOL pdtc_lamp_flashing_is_priority

Description:

This calibration selects the lamp priority system used to select the desired state for a lamp when multiple DTCs are active and request different states.

If TRUE, flashing states take priority, giving the order (highest to lowest) of: fast flash, slow flash, continuous on, off. If FALSE, continuous on takes priority over flashing states, giving the order (highest to lowest) of: continuous on, fast flash, slow flash, off.

Care must be taken to ensure that DTC lamp states, in combination with the priority system selected and the effects of the fault which caused the DTC, meet any relevant OBD regulations. For instance, CARB requires emissions-related faults to set the MIL continuous-on during a drive cycle, and do not permit the MIL to flash during a drive cycle if emissions-related faults are active.

7.7.3.7.4.2. pdtc_transition_prev_act_to_pend
Definition:

const BOOL pdtc_transition_prev_act_to_pend

Description:

This calibration selects the DTC state behaviour when a fault recurs whilst the DTC is in the "previously active" state.

This behaviour is not specified by CARB (and hence is also unspecified in CARB-derived OBD schemes), so the desired behaviour will be manufacturer-specific.

If this calibration is TRUE, the DTC will transition from the "previously active" state to the "pending" state when a fault recurs. If the fault remains set, the DTC will transition to "active" as normal. If the fault does not recur, the DTC will transition back to the "previously active" state, and will clear all aging counters so that aging is restarted.

If this calibration is FALSE, the DTC will transition directly from the "previously active" state to the "active" state when a fault recurs.

7.7.3.7.4.3. pdtc_table_all
Definition:

const PDTC_TABLE_T pdtc_table_all

Description:

This is a table of all DTCs defined in the system.

It is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

This table is intended to group all const/NV data for all DTCs, so that operations on all DTCs can be carried out without the risk of carrying out these operations multiple times on DTCs that are referenced by multiple tables.

This table is not intended to be used for carrying out lamp state checks or other per-table operations. Since this is the case, no per-table data exists for this table.

7.7.3.7.5.  Functions
7.7.3.7.5.1. pdtc_get_mi_activation_mode()
Definition:

PDTC_MI_MODE_T pdtc_get_mi_activation_mode(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Supplies the current MI activation mode.

Return:

PDTC_MI_MODE_T as per the Euro VI - UN ECE Regulation No. 49, Addendum 48 definitions

7.7.3.7.5.2. pdtc_get_b1_cumulative_counter()
Definition:

U32 pdtc_get_b1_cumulative_counter(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Supplies the cumulative time in seconds for which any B1 fault has been active.

Return:

Cumulative continuous-B1 counter as required by DM39 in the J1939-73 specification

  • in seconds

Note

The limits required by DM messages are not applied here, the application will have to scale and apply limits as required when used.

7.7.3.7.5.3. pdtc_get_b1_continuous_counter()
Definition:

U32 pdtc_get_b1_continuous_counter(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Supplies the time in seconds for which any B1 fault has been active continuously.

Return:

Single-B1 counter as required to define the MI activation mode as per the UN-ECE Regulation No.49, Addendum 48

  • in seconds

7.7.3.7.5.4. pdtc_get_mil_cumulative_counter()
Definition:

U32 pdtc_get_mil_cumulative_counter(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Supplies the cumulative time in seconds for which the MI has been demanded to be illuminated.

Return:

Cumulative MI time as required by DM39 in the J1939-73 specification

  • in seconds

Note

The limits required by DM messages are not applied here, the application will have to scale and apply limits as required when used.

7.7.3.7.5.5. pdtc_clear_all_tables()
Definition:

PDTC_ERROR_CODE_T pdtc_clear_all_tables(
   const PIO_DTC_TYPE_T   pdtcf_type);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Clear the state of each DTC of matching type in all the DTC tables.

For each DTC table the function to clear all DTCs in the table is called.

Freeze frame data associated with the cleared DTCs is also cleared. Monitor (DME and DTE) data is also cleared other than persistent data which is never cleared (e.g. numerators and denominators).

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Return:

7.7.3.7.5.6. pdtc_clear_all_by_severity()
Definition:

PDTC_ERROR_CODE_T pdtc_clear_all_by_severity(
   const PDTC_TABLE_T *const       pdtcf_table,
   const PIO_DTC_TYPE_T            pdtcf_type,
   const PIO_EMISSION_SEV_TYPE_T   pdtcf_emissions_min_sev);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Clear the state of each DTC of matching type emission severity level in a DTC table.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type and severity is equal to or higher than pdtcf_emissions_min_sev then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Can raise the following errors: PDTC_CLEAR_ALL_INVALID_ARG

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Arg (data in): pdtcf_emissions_min_sev

Emission level of the DTC to match against

Return:

7.7.3.7.5.7. pdtc_clear_dtcs()
Definition:

void pdtc_clear_dtcs(
   const PDTC_TABLE_T *const          pdtcf_table,
   const PIO_DTC_TYPE_T               pdtcf_type,
   const PDTC_IT_TYPE_COMPARATOR_T    pdtcf_type_comparator,
   const PIO_EMISSION_SEV_TYPE_T      pdtcf_esev,
   const PDTC_IT_ESEV_COMPARATOR_T    pdtcf_esev_comparator,
   const PDTC_STATE_T                 pdtcf_state,
   const PDTC_IT_STATE_COMPARATOR_T   pdtcf_state_comparator,
   const BOOL                         pdtcf_clear_unconditionally);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Clear DTCs, within a DTC table, which match the supplied criteria.

Can raise the following errors:
PDTC_CLEAR_DTCS_INVALID_ARG

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to clear. See the PIO header files for more details.

Arg (data in): pdtcf_type_comparator

The comparison to apply to the type of DTCs to clear e.g. PDTC_IT_TYPE_DC

Arg (data in): pdtcf_esev

Emissions severity of DTC to clear. See the PIO header files for more details.

Arg (data in): pdtcf_esev_comparator

The comparison to apply to the emissions severity of DTCs to clear e.g. PDTC_IT_ESEV_LT

Arg (data in): pdtcf_state

State of DTCs to clear (e.g., PDTC_STATE_ACTIVE).

Arg (data in): pdtcf_state_comparator

The comparison to apply to the state of DTCs to clear e.g. PDTC_IT_STATE_NE

Arg (data in): pdtcf_clear_unconditionally

If set TRUE, all DTCs meeting the terms of the comparator(s) will be cleared immediately, regardless of whether they are CARB permanent DTCs or Euro non-erasable DTCs. If set FALSE, any CARB permanent DTCs will be cleared under the conditions of the CARB regulations, and Euro non-erasable DTCs will never be cleared.
Typically this would be set FALSE for clearing DTCs via OBD scan tool request, and would be set TRUE for a full reset of DTCs during production or in other situations where OBD regulations on clearing DTCs are not relevant (e.g. moving the ECU to a different vehicle).

7.7.3.7.5.8. pdtc_get_lamp_state()
Definition:

PIO_DTC_LAMP_STATES_T pdtc_get_lamp_state(
   const PDTC_TABLE_T *const   pdtcf_dtc_table,
   const PDTC_LAMP_T           pdtcf_lamp);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function returns the current state of a lamp, based on DTCs set in the selected table.

Arg (data in): pdtcf_dtc_table

Table of DTCs for which lamp status is to be reported

Arg (data in): pdtcf_lamp

Lamp for which status is to be reported

Return:

7.7.3.7.5.9. pdtc_get_MIL_status()
Definition:

PIO_DTC_LAMP_STATES_T pdtc_get_MIL_status(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Indicates whether the MIL has to be ON due to DTCs (CARB), based on all DTC tables in the system.

Return:

7.7.3.7.5.10. pdtc_get_RSL_status()
Definition:

PIO_DTC_LAMP_STATES_T pdtc_get_RSL_status(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Indicates whether the Red lamp has to be ON due to DTCs (CARB).

Return:

7.7.3.7.5.11. pdtc_get_AWL_status()
Definition:

PIO_DTC_LAMP_STATES_T pdtc_get_AWL_status(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Indicates whether the Amber lamp has to be ON due to DTCs (CARB).

Return:

7.7.3.7.5.12. pdtc_get_Protect_lamp_status()
Definition:

PIO_DTC_LAMP_STATES_T pdtc_get_Protect_lamp_status(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Indicates whether the Protect lamp has to be ON due to DTCs (CARB).

Return:

7.7.3.7.5.13. pdtc_match_exists()
Definition:

BOOL pdtc_match_exists(
   const PDTC_TABLE_T *const       pdtcf_table,
   const PIO_DTC_TYPE_T            pdtcf_type,
   const PIO_EMISSION_SEV_TYPE_T   pdtcf_esev,
   BOOL                            pdtcf_esev_gte_test,
   const PDTC_STATE_T              pdtcf_state,
   U16                            *pdtcf_count);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Determine the existence and count of DTCs, within a DTC table, which match the supplied criteria.

Can raise the following errors:
PDTC_MATCH_EXISTS_INVALID_ARG

Arg (data in): pdtcf_table

Pointer to table of DTCs.
Cannot be NULL.

Arg (data in): pdtcf_type

Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Arg (data in): pdtcf_esev

Emissions severity of DTC to match against. See the PIO header files for more details.

Arg (data in): pdtcf_esev_gte_test

Set to TRUE if the function is to match against DTCs with an emissions severity greater than or equal to that supplied in parameter pdtcf_esev. Set to FALSE if the function is to match against DTCs with an emissions severity equal to that supplied in parameter pdtcf_esev.

Arg (data in): pdtcf_state

State of DTC to match against (e.g., PDTC_STATE_ACTIVE).

Arg (data out): pdtcf_count

Count of the number of matching DTCs.

Return:

TRUE - At least one matching DTC exists. FALSE - Otherwise.

7.7.3.7.5.14. pdtc_check_table_cleared()
Definition:

U32 pdtc_check_table_cleared(
   const PDTC_TABLE_T *const   pdtcf_table_to_check);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Reports whether DTCs have been cleared by OBD request.

If, since the last call to this function, one or more OBD requests have been received that caused DTCs in this DTC table to be cleared, these OBD request(s) are reported to the application.

Arg (data in): pdtcf_table_to_check

DTC table for which OBD clear request(s) will be reported.

Return:

Bitmask indicating OBD clear request(s) since last call to this function:

7.7.3.7.5.15. pdtc_get_dtc_status()
Definition:

PDTC_ERROR_CODE_T pdtc_get_dtc_status(
   const PDTC_DTC_T *const   pdtcf_dtc,
   U8                       *pdtcf_lamp_bitmap,
   PDTC_STATE_T             *pdtcf_state,
   U8                       *pdtcf_count);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Retrieve the status data of a DTC.

Arg (data in): pdtcf_dtc

Pointer to DTC to retrieve values from. Cannot be NULL.

Arg (data out): pdtcf_lamp_bitmap

Pointer to location to accept bitmap of lamp information (relevant to J1939 DTCs only). This location will be set to the value of the pdtcf_lamp_bitmap_in parameter used in the most recent call to pdtc_update_j1939_dtc.
May be NULL, in which case no output is written for this value.
Note that this is only used by the legacy (deprecated) interface for J1939 DTCs, to allow backwards compatibility for existing applications, and may be removed in a future version of the API. Instead of this parameter, use one of pdtc_get_lamp_state(), pdtc_get_MIL_status(), pdtc_get_RSL_status(), pdtc_get_AWL_status(), pdtc_get_Protect_lamp_status(), or pdtc_get_j1939_current_lamps().

Arg (data out): pdtcf_state

Pointer to where the current DTC state will be written. One of PDTC_STATE_CLEAR, PDTC_STATE_ACTIVE, PDTC_STATE_INACTIVE or PDTC_STATE_PENDING will be written.
May be NULL, in which case no output is written for this value.

Arg (data out): pdtcf_count

Pointer to where the current J1939-style DTC activation count will be written.
May be NULL in which case no output is written for this value.
Range: [0, 127] counts

Return:

7.7.3.7.5.16. pdtc_plat_obd_update_clr_perm_ok()
Definition:

void pdtc_plat_obd_update_clr_perm_ok(
   BOOL   pdtcf_ok_to_clear_perm);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Keeps track of whether conditions have been met for clearing CARB permanent DTCs after an OBD clear request.

When an OBD clear request is received, permanent DTCs for some monitors may be cleared as soon as the test is complete. Permanent DTCs for other monitors require certain vehicle/operating conditions to be met, according to CARB 19711 section (d)(2.3.1)(C)(ii)b..

Arg (data in): pdtcf_ok_to_clear_perm

If TRUE, indicates that vehicle/operating conditions are met according to CARB 19711 section (d)(2.3.1)(C)(ii)b..

7.7.3.7.5.17. pdtc_plat_obd_update_engine_running()
Definition:

void pdtc_plat_obd_update_engine_running(
   BOOL   pdtcf_engine_is_running);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Keeps track of engine running state for DTCs.

Arg (data in): pdtcf_engine_is_running

If TRUE, indicates that engine is running

7.7.3.7.5.18. pdtc_plat_obd_update_ign_cyc()
Definition:

void pdtc_plat_obd_update_ign_cyc(
   BOOL   pdtcf_start_of_ignc);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Keeps track of new ignition cycle.

Arg (data in): pdtcf_start_of_ignc

Indicates whether it is the start of an ignition cycle or otherwise.
Application should call pdtc_plat_obd_update_ign_cyc with pdtcf_start_of_ignc set to TRUE when transitioning into a new ignition cycle.

7.7.3.7.5.19. pdtc_plat_obd_update_dc_count()
Definition:

void pdtc_plat_obd_update_dc_count(
   BOOL   pdtcf_start_of_dc);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Keeps track of new drive cycle for DTCs.

Arg (data in): pdtcf_start_of_dc

Indicates whether it is the start of drive cycle or otherwise.
Application should call pdtc_plat_obd_update_dc_count(TRUE) while transitioning into a new drive cycle.

7.7.3.7.5.20. pdtc_plat_obd_update_wup_count()
Definition:

void pdtc_plat_obd_update_wup_count(
   BOOL   pdtcf_start_of_wup);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Keeps track of new warmup cycle for DTCs.

Arg (data in): pdtcf_start_of_wup

Indicates whether it is the start of warmup cycle or otherwise.
Application should call pdtc_plat_obd_update_wup_count(TRUE) while transitioning into a new warm-up cycle.

7.7.3.7.5.21. pdtc_update_iso_dtc()
Definition:

PDTC_ERROR_CODE_T pdtc_update_iso_dtc(
   const PDTC_DTC_T *const   pdtcf_dtc,
   PDTC_STATE_T              pdtcf_state_in);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Function to update the state and data of an ISO DTC.

Can raise the following errors:
PDTC_UPDATE_INVALID_ARG.

Arg (data in,out): pdtcf_dtc

Pointer to DTC to update. Cannot be NULL.

Arg (data in): pdtcf_state_in

The state to change to (or remain at).

Return:

7.7.3.7.5.22. pdtc_update_plat_obd_dtc()
Definition:

PDTC_ERROR_CODE_T pdtc_update_plat_obd_dtc(
   const PDTC_DTC_T *const   pdtcf_const_dtc,
   BOOL                      pdtcf_test_failed,
   BOOL                      pdtcf_test_completed);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Function to update the state and data of the DTC when controlled by platform.

Can raise the following errors:
PDTC_UPDATE_INVALID_ARG.

Arg (data in): pdtcf_const_dtc

Pointer to DTC to update.
Cannot be NULL.

Arg (data in): pdtcf_test_failed
  • TRUE = Test failed for this DTC in current run

  • FALSE = Test passed for this DTC in current run

Arg (data in): pdtcf_test_completed
  • TRUE = Test for this DTC has been run before current call

  • FALSE = Test for this DTC has not been run before current call

Return:

7.7.3.8. Interface detail - PIO

Some enumerations and variables for the DTC feature are included in pio.h

7.7.3.8.1.  Enumerations
7.7.3.8.1.1. @7
Summary:

This enumeration declares the different types of DTC lamp state available.

Enumerations:
PIO_DTC_LAMP_SLOW_FLASH

Slow Flash.

PIO_DTC_LAMP_FAST_FLASH

Fast Flash.

PIO_DTC_LAMP_ON

Continuously On.

PIO_DTC_LAMP_OFF

No Effect.

PIO_DTC_LAMP_STATES_LAST
7.7.3.8.2.  Data types
7.7.3.8.2.1. PIO_DTC_LAMP_STATES_T
Definition:

typedef PSY_PACK_ENUM enum @7 PIO_DTC_LAMP_STATES_T

Description:

This enumeration declares the different types of DTC lamp state available.

7.7.4. Freeze Frame feature (PFF)

7.7.4.1. Overview

The freeze frame feature is a diagnostic feature used to capture a snapshot of PID or SPN data at the point a Diagnostic Trouble Code is activated. This data snapshot is stored in NVM using the PFS feature. Access to this data is then provided over the J1979 / J1939 / UDS diagnostic protocols.

A freeze frame may be one of four types:

  • ISO freeze frame: available over J1979 service $02.

  • J1939 Freeze Frame Parameters (DM4).

  • J1939 Expanded Freeze Frames (DM25).

  • UDS Snapshot: available over ISO 14229-1 (UDS) service $19.

A given DTC may be associated with (up to) one freeze frame of each type. However, for non-emissions DTCs, ISO J1979 service $02 freeze frames will not be captured.

There is no direct interface to the PFF feature, as actions causing freeze frame instances to be captured or deleted are triggered by the PDTC feature.

If a DTC has one or more associated freeze frames, an instance of each of these freeze frames is captured each time a DTC undergoes one of the following state transitions:

  • Clear to Active

  • Clear to Pending

  • Previously Active to Pending

  • Previously Active to Active

Note in particular that a DTC can acquire multiple instances of freeze frames if it transitions from Previously Active to Pending or Active repeatedly. The number of freeze frame instances of a given freeze frame type is capped at 126. All freeze frame instances associated with a particular DTC are deleted when that DTC transitions to the Clear state. Additionally the last freeze frame instance captured for a particular DTC is deleted when the DTC transitions from state Pending to state Previously Active for all freeze frame types other than UDS snapshots.

Snapshot storage gives preference to the first and the most recent occurrence of a particular DTC. The snapshot captured as a result of the first occurrence of a DTC is assigned DTCSnapshotRecordNumber 0. The snapshot captured as a result of the next occurrence of a DTC is assigned DTCSnapshotRecordNumber 1 and is replaced upon subsequent occurrences of the DTC.

Stored freeze frame data may be accessed over the ISO 15765-2 J1979, ISO 14229-1 UDS, or the J1939 (SAE) communication protocols using the following features, respectively:

  • PDG - Service $02 (J1979).

  • PDG - Service $19 (UDS).

  • PJ1939 - DM4, DM24 and DM25.

Note: non-volatile PIDs are not supported in freeze frames. If a freeze frame is defined by the application to contain a non-volatile PID, this PID is ignored by the PFF feature when capturing or accessing the freeze frame data.

7.7.4.2. ISO J1979 Freeze frame

A stored ISO J1979 freeze frame contains the following data:

Note: if the following PIDs are included in a freeze frame definition, they shall be ignored by the platform code: the service PIDs (i.e. $00, $20, $40, etc.); unsupported PIDs; PID $02. PID $02 is always captured alongside the freeze frame, but not separately as one of the listed PIDs in the freeze frame definition.

7.7.4.3. UDS Snapshot

A stored ISO 14229-1 UDS snapshot contains the following data:

7.7.4.4. J1939 Freeze Frame Parameters (DM4)

A stored DM4 freeze frame contains the following data, as specified in J1939-73 FEB2010:

  • Freeze Frame Length (1 byte)

  • SPN of the setting DTC (19 bits)

  • FMI of the setting DTC (5 bits)

  • SPN Conversion Method (1 bit)

  • DTC Occurrence Count (7 bits)

  • Mandatory SPN data values (8 bytes)

  • Manufacturer Specific SPN data (0 to 1772 bytes)

Note: similar to J1939-73 FEB2010 the SPN, FMI, conversion method and DTC occurrence count are packed into 4 bytes in NVM. The DTC occurrence count in the freeze frame may be out of sync when DTC becomes Active.

Any unsupported Mandatory SPNs shall have each date byte stored as 0xFF. Any unsupported Manufacturer SPNs specified are ignored by the platform code. The vector defining the Manufacturer SPNs is calibratable.

7.7.4.5. J1939 Expanded Freeze Frame (DM25)

A stored DM25 freeze frame contains the following data, as specified in J1939-73 FEB2010:

  • Expanded Freeze Frame Length (1 byte)

  • SPN of the setting DTC (19 bits)

  • FMI of the setting DTC (5 bits)

  • SPN Conversion Method (1 bit)

  • DTC Occurrence Count (7 bits)

  • SPN data (0 to 1780 bytes)

Note: similar to J1939-73 FEB2010 the SPN, FMI, conversion method and DTC occurrence count are packed into 4 bytes in NVM. The DTC occurrence count in the freeze frame may be out of sync when DTC becomes Active.

A calibratable vector is used to identify the SPNs that are captured in the DM25 freeze frame. Only supported SPN data may be captured. Unsupported SPNs are ignored by the platform code.

7.7.4.6. Freeze Frame Calibrations

As noted above, with the exception of the J1939 DM4 Mandatory freeze frame SPNs, the SPNs and PIDs defining each freeze frame are calibratable. The vector calibration simply consists of a list of PID or SPN identifiers. If one of these calibrations is changed, any existing freeze frames will no longer match their corresponding freeze frame definition. As a result, if 'old' freeze frame data is read, the data received will not be in the expected format or match the expected PID or SPN. It is therefore strongly recommended that the calibrations defining the freeze frames are not changed on-the-fly, and that all DTCs are cleared following any changes to the freeze frame calibrations.

7.7.5. Parameter Identifier feature (PPID)

7.7.5.1. Overview

The library's PID feature provides support for parameters accessed by numeric identifier (hence PID) using the ISO 15765-2 based protocols SAE J1979, Keyword Protocol 2000-3 or ISO 14229-1 (UDS). The PID feature also allows parameters to be defined as Suspect Parameter Numbers (SPNs), which will eventually enable them to be accessed using the SAE J1939 protocol. At the present time, however, these SPNs are only able to be used to capture freeze frames for J1939 Diagnostic Trouble Codes.

A PID can be used to make internal values (e.g. sensor values or identification strings) visible on an external service test tool.

Additionally, PIDs can be configured to allow override, so that the application-calculated value of the PID is temporarily replaced with a value specified by the external tool. This can be used to test actuators (by overriding a value used to command an output position) or simulate the effect of particular sensor input values, for example.

7.7.5.2. Use of PIDs

PIDs are declared in the interface file (see Section 8.1.4.30, “Compound statement: pid-data”). The C-API tool generates a C identifier for each PID, based on the name specified in the interface file, which can be passed to the functions ppid_update_pid() and ppid_get_pid().

PID values must be set by the application by calling ppid_update_pid(). For constant values, this need be done only once. For varying values (e.g. sensor readings), the application should repeatedly do this to keep the PID value up to date, because the external tool may read the PID value at any time without the application's prior knowledge.

PIDs can be configured to allow override by the external test tool, and for the PID value to be automatically replaced by the test tool value. For this to work, the application cannot assume that the current PID value is the same as the value it most recently set using ppid_update_pid(). Instead, the application should read the latest value using ppid_get_pid() before use. Usually the application-set value will be returned, but if the external test tool requests an override of the value using an inputOutputControlByIdentifier service, then a different value may be returned.

Alternatively, a PID can be configured to allow the receipt of inputOutputControl data from the test tool, but not have the received data replace the normal reported value (resend-input-as-output = false). In this case the ppid_get_override_data() function can be used to retrieve the data sent by the test tool, and that data need not be the same size as the reported PID data.

Some applications may need to dynamically compute or fetch PID values at the time they are requested, or perform some other application-specific processing or response. For this purpose the PDG feature callback functions can be used. In particular see the PDG_ID_REQUEST_CALLBACK_FN_T type of callback.

7.7.5.3. Platform PIDs

Some PIDs are handled by the platform without any input from the application. In the J1979 standard, PID 0x02 is defined to hold the DTC that caused a freeze frame to be stored. For service $02, the freeze frame in question is identified by the request message, but for service $01 it is just the first freeze frame that has been stored. To satisfy this context-dependent definition, PID 0x02 is handled directly by the platform. The application should not define such a PID and any such PID that is defined will be ignored in the case of a standard platform reply. (This behaviour can still be overridden through the use of PDG_ID_REQUEST_CALLBACK_FN_T type callbacks).

Similar remarks apply to PIDs 0x00, 0x20, 0x40, etc. which are defined in the J1979 standard as bitfields that identify which other PIDs are supported in various contexts.

7.7.5.4. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and ppid.h
Macros
 PPID_MAX_PID_BYTE_LEN

This is the maximum length of PID data currently supported.

 PPID_ECU_CONTROLLED

Indicates that ControlParameter from InputOutputControl request from test tool was "return control to ECU", or this PID is not currently subject to IOControl.

 PPID_CURRENT_STATE_FROZEN

Indicates that ControlParameter from InputOutputControl request from test tool was "freeze current state", indicating that this PID is currently subject to override by the tool.

 PPID_SHORT_TERM_ADJUSTMENT

Indicates that ControlParameter from InputOutputControl request from test tool was "short term adjustment", indicating that this PID is currently subject to override by the tool.

 PPID_J1939_SPN_PID

Flag masks used for attributes of PIDs; low values are used where they may be used in a bitfield to save space when stored as non-volatile PIDs.

 PPID_KWP_8BIT_PID

Bitmask for a KWP2000 8-bit based PID.

 PPID_ISO_16BIT_PID

Bitmask for a KWP2000 16-bit based PID.

 PPID_VAR_LENGTH

Bitmask for a variable length based PID.

 PPID_J1979_8BIT_PID

Bitmask for a J1979 8-bit based PID.

 PPID_RESEND_IN_OUT

Bitmask for a PID that can pass its overridden data to the application.

 PPID_NON_VOLATILE

Bitmask for a PID stored across power-cycles in non-volatile memory.

 PPID_ALPHANUMERIC

Bitmask for a ASCII string based PID.

Enumerations
 PPID_RC_T

An enumerated type which contains success and failure codes returned by some ISO diagnostic parameter ID (PPID) functions.

Data types
 PPID_PID_CONST_T

This structure collates the data associated with each PID.

Variables
struct PPID_PID_CONST_Tppid_table

This is a list of the ISO 16-bit PIDs the library will maintain.

const U16ppid_num_pids

This is the total number of ISO 16-bit PIDs the library will maintain.

struct PPID_8BIT_ID_LOOKUP_Tppid_j1979_8bit_map

This is a list of the J1979 8-bit PIDs that the library will maintain.

const U16ppid_num_j1979_ids

This is the total number of J1979 8-bit PIDs the library will maintain.

struct PPID_8BIT_ID_LOOKUP_Tppid_kwp_8bit_map

This is a list of the KW2000 8-bit PIDs that the library will maintain.

const U16ppid_num_kwp_ids

This is the total number of KW2000 8-bit PIDs the library will maintain.

struct PPID_J1939_SPN_LOOKUP_Tppid_j1939_spn_map

This is a list of the J1939 SPNs that the library will maintain.

const U16ppid_num_j1939_spns

This is the total number of J1939 SPNs the library will maintain.

Functions
PPID_RC_Tppid_update_pid

Update platform-cached values for this PID with fresh application values.

PPID_RC_Tppid_get_pid

Retrieve current value of PID, which may be an override value.

PPID_RC_Tppid_get_override_data

Retrieve a range of data representing the value of a PID, which may be an overridden value.

PPID_RC_Tppid_set_nv_pid

This function sets a new value for the nonvolatile PID specified.

PPID_RC_Tppid_get_nv_commit_status

Use this function to determine whether nonvolatile PID data is saved.

PPID_RC_Tppid_get_nv_pid

This function can be used to determine whether a nonvolatile PID exists (with a value set), what size it is, and to retrieve the content.

PPID_RC_Tppid_delete_nv_pid

This function deletes a nonvolatile PID.

PPID_RC_Tppid_delete_all_nv_pids

This function deletes all nonvolatile PIDs.

7.7.5.5. Interface detail

7.7.5.5.1.  Macros
7.7.5.5.1.1. PPID_MAX_PID_BYTE_LEN
Definition:

#define PPID_MAX_PID_BYTE_LEN 512

Description:

This is the maximum length of PID data currently supported.

7.7.5.5.1.2. PPID_ECU_CONTROLLED
Definition:

#define PPID_ECU_CONTROLLED 0x00

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "return control to ECU", or this PID is not currently subject to IOControl.

7.7.5.5.1.3. PPID_CURRENT_STATE_FROZEN
Definition:

#define PPID_CURRENT_STATE_FROZEN 0x05

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "freeze current state", indicating that this PID is currently subject to override by the tool.

7.7.5.5.1.4. PPID_SHORT_TERM_ADJUSTMENT
Definition:

#define PPID_SHORT_TERM_ADJUSTMENT 0x07

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "short term adjustment", indicating that this PID is currently subject to override by the tool.

7.7.5.5.1.5. PPID_J1939_SPN_PID
Definition:

#define PPID_J1939_SPN_PID 0x01

Description:

Flag masks used for attributes of PIDs; low values are used where they may be used in a bitfield to save space when stored as non-volatile PIDs.

Bitmask for a J1939 SPN based PID.

7.7.5.5.1.6. PPID_KWP_8BIT_PID
Definition:

#define PPID_KWP_8BIT_PID 0x02

Description:

Bitmask for a KWP2000 8-bit based PID.

7.7.5.5.1.7. PPID_ISO_16BIT_PID
Definition:

#define PPID_ISO_16BIT_PID 0x04

Description:

Bitmask for a KWP2000 16-bit based PID.

7.7.5.5.1.8. PPID_VAR_LENGTH
Definition:

#define PPID_VAR_LENGTH 0x08

Description:

Bitmask for a variable length based PID.

7.7.5.5.1.9. PPID_J1979_8BIT_PID
Definition:

#define PPID_J1979_8BIT_PID 0x10

Description:

Bitmask for a J1979 8-bit based PID.

7.7.5.5.1.10. PPID_RESEND_IN_OUT
Definition:

#define PPID_RESEND_IN_OUT 0x20

Description:

Bitmask for a PID that can pass its overridden data to the application.

7.7.5.5.1.11. PPID_NON_VOLATILE
Definition:

#define PPID_NON_VOLATILE 0x40

Description:

Bitmask for a PID stored across power-cycles in non-volatile memory.

7.7.5.5.1.12. PPID_ALPHANUMERIC
Definition:

#define PPID_ALPHANUMERIC 0x80

Description:

Bitmask for a ASCII string based PID.

7.7.5.5.2.  Enumerations
7.7.5.5.2.1. PPID_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some ISO diagnostic parameter ID (PPID) functions.

Enumerations:
PPID_RC_OK

Return code if everything progressed as expected.

PPID_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PPID_RC_BAD_CONFIG_DATA

Return code if the PID configuration data was invalid for requested operation.

PPID_RC_NOT_FOUND

No such PID found.

PPID_RC_ALREADY_SET

PID value already set so it does not require any initialisation write.

PPID_NV_SAVE_PENDING

Saving of PIDs to nonvolatile memory is in progress.

PPID_RC_ERROR

Unspecified error.

7.7.5.5.3.  Data types
7.7.5.5.3.1. PPID_PID_CONST_T
Summary:

This structure collates the data associated with each PID.

Members:
U16 PPID_PID_CONST_T::pid_id

The 16-bit ID of the PID, used by the test tool to address it.

This is a "CommonIdentifier" in KW2000-3 or just "Identifier" in UDS. The PID may or may not support this type of ID. This may instead be used for RoutineControl services if appropriate for this ID.

U16 PPID_PID_CONST_T::byte_len

The number of bytes of data this PID consists of.

U8* PPID_PID_CONST_T::app_supplied_data

This points to the current (application-supplied) values.

Initialised to zero by the platform Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when requested by an external diagnostic test tool.

U8* PPID_PID_CONST_T::override_data

This points to override values set temporarily by the external test tool.

May be NULL if no overrides allowed for this PID. Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

U8* PPID_PID_CONST_T::override_state

This points to the value which records how this PID is currently being overridden by the external test tool via IOControl messages.

Zero means no override. Do not access the data this points to in user code. If modified the platform will be unable to correctly process data overrides.

U8* PPID_PID_CONST_T::control_enable_mask_data

This points to controlEnableMask values last requested by the external during a freeze or short-term adjustment.

May be NULL if no overrides are allowed for this PID. Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

const U8* PPID_PID_CONST_T::scaling_data

This points to the scaling data bytes, which are constants determined at build time.

U32 PPID_PID_CONST_T::j1939_spn_id

The ID used to identify if this PID represents a J1939 SPN.

U8 PPID_PID_CONST_T::j1979_8bit_id

The 8-bit ID used if this PID should be sent in response to a J1979 service $01 request.

U8 PPID_PID_CONST_T::kwp_8bit_lid

The 8-bit LocalIdentifier used if this PID should be sent in response to a KW2000-3 service $21 request, or modified via a $30 InputOutputControlByLocalID request.

U8 PPID_PID_CONST_T::control_enable_mask_size

This defines the maximum number of controlEnableMask byte values allowed for this PID.

U8 PPID_PID_CONST_T::scaling_byte_len

The number of byte in the scaling data for this PID.

Description:

This structure collates the data associated with each PID.

Note

The application may use the ID and size elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

7.7.5.5.4.  Variables
7.7.5.5.4.1. ppid_table
Definition:

struct PPID_PID_CONST_T ppid_table[]

Description:

This is a list of the ISO 16-bit PIDs the library will maintain.

7.7.5.5.4.2. ppid_num_pids
Definition:

const U16 ppid_num_pids

Description:

This is the total number of ISO 16-bit PIDs the library will maintain.

7.7.5.5.4.3. ppid_j1979_8bit_map
Definition:

struct PPID_8BIT_ID_LOOKUP_T ppid_j1979_8bit_map[]

Description:

This is a list of the J1979 8-bit PIDs that the library will maintain.

7.7.5.5.4.4. ppid_num_j1979_ids
Definition:

const U16 ppid_num_j1979_ids

Description:

This is the total number of J1979 8-bit PIDs the library will maintain.

7.7.5.5.4.5. ppid_kwp_8bit_map
Definition:

struct PPID_8BIT_ID_LOOKUP_T ppid_kwp_8bit_map[]

Description:

This is a list of the KW2000 8-bit PIDs that the library will maintain.

7.7.5.5.4.6. ppid_num_kwp_ids
Definition:

const U16 ppid_num_kwp_ids

Description:

This is the total number of KW2000 8-bit PIDs the library will maintain.

7.7.5.5.4.7. ppid_j1939_spn_map
Definition:

struct PPID_J1939_SPN_LOOKUP_T ppid_j1939_spn_map[]

Description:

This is a list of the J1939 SPNs that the library will maintain.

7.7.5.5.4.8. ppid_num_j1939_spns
Definition:

const U16 ppid_num_j1939_spns

Description:

This is the total number of J1939 SPNs the library will maintain.

7.7.5.5.5.  Functions
7.7.5.5.5.1. ppid_update_pid()
Definition:

PPID_RC_T ppid_update_pid(
   const struct PPID_PID_CONST_T *const   ppidf_pid_const_data,
   const U8                              *ppidf_app_supplied_data);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update platform-cached values for this PID with fresh application values.

Arg (data in,out): ppidf_pid_const_data

Pointer to the PID data structure to be updated

Arg (data in): ppidf_app_supplied_data

Application supplied data to be used for the update

Return:

Note: ppidf_app_supplied_data is initialised to zero by the platform

7.7.5.5.5.2. ppid_get_pid()
Definition:

PPID_RC_T ppid_get_pid(
   const struct PPID_PID_CONST_T  *ppidf_pid_const_data,
   U8                             *ppidf_pid_data,
   U8                             *ppidf_override_state);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Retrieve current value of PID, which may be an override value.

Arg (data in): ppidf_pid_const_data

Pointer to the PID data structure.
Cannot be NULL.

Arg (data out): ppidf_pid_data

Pointer to the buffer (address of array) provided by the application to receive the PID data.
Cannot be NULL.

Arg (data out): ppidf_override_state

Pointer to variable set to nonzero code if the PID is overridden, zero otherwise. The code value will be one of:

Return:

7.7.5.5.5.3. ppid_get_override_data()
Definition:

PPID_RC_T ppid_get_override_data(
   const struct PPID_PID_CONST_T  *ppidf_pid_const_data,
   U8                             *ppidf_override_data,
   U8                             *ppidf_override_state,
   U8                             *ppidf_control_enable_mask_data,
   U8                             *ppidf_num_cem_bytes);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Retrieve a range of data representing the value of a PID, which may be an overridden value.

Retrieve current value of PID bytes as last sent by diagnostic tool as IOControl states.

Arg (data in): ppidf_pid_const_data

Pointer to the PID data structure.
Cannot be NULL.

Arg (data out): ppidf_override_data

Pointer to the buffer (address of array) provided by the application to receive the PID data. This must be at least large enough for the input byte length declared for this PID (or the output length if that was not explicitly specified, and so assumed equal).
Can be NULL if the actual data is not required.

Arg (data out): ppidf_override_state

Pointer to variable set to nonzero code if the PID is overridden, zero otherwise. The code is the IOControl parameter from the request message.
Can be NULL if overridden status is not required.

Arg (data out): ppidf_control_enable_mask_data

Pointer to the buffer (address of array) provided by the application to receive the controlEnableMask data (if the PID is configured to accept it).
Both this and ppidf_num_cem_bytes must be non-NULL if the data is required.

Arg (data out): ppidf_num_cem_bytes

Pointer to variable set to the number of controlEnableMask bytes last received for this PID when an IOControl override was requested.
Both this and ppidf_control_enable_mask_data must be non-NULL if the data is required.

Return:

7.7.5.5.5.4. ppid_set_nv_pid()
Definition:

PPID_RC_T ppid_set_nv_pid(
   U8         ppidf_type_flags,
   U8         ppidf_kwp_8bit_id,
   U16        ppidf_pid_id,
   U32        ppidf_j1939_spn_id,
   const U8  *ppidf_new_data_ptr,
   U8         ppidf_new_size,
   BOOL       ppidf_only_if_uninit);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function sets a new value for the nonvolatile PID specified.

In a running application, only the PIDs that are predefined for that application will be accepted by this function.

Note

This function is also available in boot loader mode, when any PID is acceptable. However, any PIDs set in boot mode that are not defined by an application will be discarded when that application starts.

Arg (data in): ppidf_type_flags

One or more of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID ORd together to indicate which type(s) of ID this PID shall be identified by.

Arg (data in): ppidf_kwp_8bit_id

If relevant, the KW2000 LID for this PID. Otherwise unused.

Arg (data in): ppidf_pid_id

If relevant, the KW2000/UDS 16-bit ID for this PID. Otherwise unused.

Arg (data in): ppidf_j1939_spn_id

If relevant, the J1939 SPN for this PID. Otherwise unused.

Arg (data in): ppidf_new_data_ptr

Pointer to the byte data from which the new value of this PID will be copied. Cannot be NULL if any data is to be written, but other error status values can still be obtained if it is NULL.

Arg (data in): ppidf_new_size

New size for the value of this PID. Must be within the specific range set for this PID.

Arg (data in): ppidf_only_if_uninit

If TRUE, the PID value is set only if no prior value existed for this PID (intended for initialisation to a default in a newly-flashed application). Otherwise, the new value is always set.

Return:
  • PPID_RC_ALREADY_SET - if ppidf_only_if_uninit=TRUE and a value was already set for this PID

  • PPID_RC_ERROR - if the new value could not be written (e.g. if not defined for this application)

  • PPID_RC_OK - if operation is successful

7.7.5.5.5.5. ppid_get_nv_commit_status()
Definition:

PPID_RC_T ppid_get_nv_commit_status(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Use this function to determine whether nonvolatile PID data is saved.

Saving is performed asynchronously in a background task while application execution continues.

Return:

7.7.5.5.5.6. ppid_get_nv_pid()
Definition:

PPID_RC_T ppid_get_nv_pid(
   U8    ppidf_type_flag,
   U32   ppidf_id,
   U8   *ppidf_data_ptr,
   U16   ppidf_min_size,
   U16   ppidf_max_size,
   U16  *ppidf_current_size);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function can be used to determine whether a nonvolatile PID exists (with a value set), what size it is, and to retrieve the content.

Arg (data in): ppidf_type_flag

One of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID indicating which type of ID is being provided to identify the PID.

Arg (data in): ppidf_id

Identifies this PID. The value passed will be interpreted as a KW2000 LID, KW2000/UDS 16-bit ID or J1939 SPN depending on ppidf_type_flag.

Arg (data out): ppidf_data_ptr

If a value is set for this PID, the data content will be written to this location unless it is set to NULL. The caller must ensure that this points to a buffer of sufficient size to accept the data. Set to NULL if the actual data is not required.

Arg (data in): ppidf_min_size

If the stored data length is less than this value, PPID_RC_ERROR will be returned and no data will be written through ppidf_data_ptr, but the actual size will still be returned through ppidf_current_size.

Arg (data in): ppidf_max_size

Similar to ppidf_min_size, but the maximum size allowable.

Arg (data out): ppidf_current_size

Unless this is NULL, the current data size of the PID will be written through this pointer if a value currently exists.

Return:
  • PPID_RC_ERROR - if the PID does not currently have a value set or the size was out of range

  • PPID_RC_OK - if operation is successful

7.7.5.5.5.7. ppid_delete_nv_pid()
Definition:

PPID_RC_T ppid_delete_nv_pid(
   U8    ppidf_type_flag,
   U32   ppidf_id);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function deletes a nonvolatile PID.

Arg (data in): ppidf_type_flag

One of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID indicating which type of ID is being provided to identify the PID.

Arg (data in): ppidf_id

Identifies this PID. The value passed will be interpreted as a KW2000 LID, KW2000/UDS 16-bit ID or J1939 SPN depending on ppidf_type_flag.

Return:
  • PPID_RC_ERROR - if the PID did not currently have a value set (nothing to delete)

  • PPID_RC_OK - if operation is successful

7.7.5.5.5.8. ppid_delete_all_nv_pids()
Definition:

PPID_RC_T ppid_delete_all_nv_pids(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

This function deletes all nonvolatile PIDs.

Return:
  • PPID_RC_OK - currently no error conditions so always succeeds

7.7.6. In-Use Performance Ratio feature (PPR)

7.7.6.1. Overview

The library's In-Use Performance Ratio feature provides a mechanism to declare Diagnostic test entities (DTEs), belonging to particular Diagnostic monitor entities(DMEs), and track their individual as well as overall performance ratio.

The library groups DTEs and DMEs into separate tables. These tables allow the application to act on a group of DTEs or DMEs as one action.

DTEs and DMEs and their corresponding data may be reported over ISO 15765-2 based protocols, or J1939, or both.

7.7.6.2. Diagnostic Test Entities (DTE)

The application declares the DTEs of interest during build time by defining the feature variables ppr_num_dte and ppr_dte_table Individual DTEs are declared in the interface file (see Section 8.1.4.32, “Compound statement: dte-data”).

The library calculates the current numerator and denominator count of a DTE based on the inputs from application, pprf_dte_id, pprf_sp_den_update_enable and pprf_sp_num_update_enable to the platform function ppr_update_dte_data()

The library also maintains the current test value and limits of a DTE based on inputs from the application, pprf_dte_id, pprf_test_value and pprf_test_valid to the platform function ppr_update_dte_test_value()

The information for a DTE is recalled from non-volatile store after application initialisation occurs. If DTEs cannot be recalled from non-volatile store, then the DTEs are reset to a default value.

On receipt of J1939 DM3 or DM11 messages, the application can call the platform function ppr_update_dte_test_value() with argument pprf_reset_dte set to TRUE for each DTE defined, in order to clear the monitor test results.

7.7.6.3. Diagnostic Monitor Entities (DME)

The application declares the DMEs of interest during build time by defining the feature variables ppr_num_dme and ppr_dme_table Individual DMEs are declared in the interface file (see Section 8.1.4.34, “Compound statement: dme-data”).

The library calculates information related to a DME based on inputs from the application, pprf_dme_id, pprf_monitor_run, pprf_force_complete, pprf_force_not_complete and pprf_monitor_enabled parameters to the platform function ppr_update_dme_data()

The information for a DME is recalled from non-volatile store after application initialisation occurs. If DMEs cannot be recalled from non-volatile store, then the DMEs are reset to a default value.

7.7.6.4. Storage of data across power cycles

On start-up, the library attempts to retrieve the DTE and DME table data prior to running the application. While the application is running, the time at which these tables are stored back to non-volatile memory is determined by the application itself.

The DTE and DME table data is check-summed using a 16-bit CRC. Failure to match the check-sum against the table data during library initialisation means that the data cannot be recovered. In this case, the table data is reverted to the default start-up conditions for each type of DTE or DME respectively.

Similar to the case of DTCs, the two types of non-volatile memory dedicated to DTEs and DMEs are:

Battery backed RAM and
Flash

7.7.6.5. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

7.7.6.6. Interface index

An index of interface objects for this feature.

TypeIdentifier
Include file
 openecu.h and ppr.h
Macros
 PPR_STORE_IN_BBRAM

This macro defines the value for ppr_store when non-volatile data is to be stored in battery backed RAM across power cycles.

 PPR_STORE_IN_FLASH

This macro defines the value for ppr_store when non-volatile data is to be stored in Flash across power cycles.

 PPR_TEST_AND_MON_TYPE_ISO

The bit position for DTE type definition Bit 0 - to define whether DTE is relevant to ISO (J1979) protocol.

Enumerations
 PPR_RC_T

An enumerated type which contains success and failure codes returned by some In-Use Performance Ratio (PPR) functions.

 PPR_TEST_RUN_STATE_T

An enumerated type which contains the state of the test run.

Data types
 PPR_DTE_NV_T

This structure declares the run-time data to be stored with each DTE.

 PPR_DTE_CONST_T

This structure collates the data associated with each DTE.

 PPR_DME_NV_T

This structure declares the run-time data to be stored with each DME.

 PPR_DME_CONST_T

This structure collates the data associated with each Monitor ID.

 PPR_DME_DATA_T

This structure is for the data calculated for reporting the DME data.

Variables
const U8ppr_store

This defines which memory type will be used to store non-volatile PPR data.

const U16ppr_num_dte

The total number of DTEs that are declared.

const U16ppr_num_dme

The total number of DMEs that are declared.

const PPR_DTE_CONST_Tppr_dte_table

The table of DTEs.

const PPR_DME_CONST_Tppr_dme_table

The table of DMEs.

const U8ppr_j1939_test_mapping_list

This is a sorted list of bit mapping for J1939 Test Ids - used for DM10 message.

Functions
PPR_RC_Tppr_update_dte_data

Update the Numerator and Denominator values for this DTE depending on whether application says that it is ready to be updated.

PPR_RC_Tppr_update_dte_test_value

Update the test value for this DTE depending on whether application says that it is ready to be updated.

PPR_RC_Tppr_update_dte_in_use_status

The application can configure itself at run-time to include or remove the DTE from those considered for diagnostic reporting.

PPR_RC_Tppr_update_dme_data

Update the DME data depending on whether application says that it is ready to be updated.

PPR_RC_Tppr_update_dme_in_use_status

The application can configure itself at run-time to include or remove the DME from those considered for diagnostic reporting.

voidppr_update_gen_denominator

Update the General denominator depending on whether application says that it is ready to be updated.

voidppr_update_ign_cyc_counter

Update the Ignition cycle count depending on whether application says that it is ready to be updated.

PPR_RC_Tppr_get_dme_ratio

Obtain the In-Use performance ratio values for this DME.

PPR_RC_Tppr_get_monitor_group_data

Obtain the In-Use performance data values for this monitor group.

PPR_RC_Tppr_get_dme_status

Obtain the Monitor enable, readiness complete, completed status for the DME.

U16ppr_get_dme_incomplete_count

Obtain the total number of monitors (DMEs) that are enabled and not complete.

PPR_RC_Tppr_get_dte_status

Obtain the NV data for the DTE.

voidppr_handle_new_ign_cyc

Handles any data updates needed at start of new ignition cycle.

voidppr_handle_new_drive_cycle

Handles any data updates needed at start of new drive cycle.

U16ppr_get_ign_cycle_count

Obtain the ignition cycle count.

U16ppr_get_gen_denominator

Obtain the general denominator.

voidppr_commit_to_store

Commit RAM data to non-volatile store.

BOOLppr_is_store_intact

Test whether there are data changes not yet committed to NV store.

7.7.6.7. Interface detail

7.7.6.7.1.  Macros
7.7.6.7.1.1. PPR_STORE_IN_BBRAM
Definition:

#define PPR_STORE_IN_BBRAM 0

Description:

This macro defines the value for ppr_store when non-volatile data is to be stored in battery backed RAM across power cycles.

7.7.6.7.1.2. PPR_STORE_IN_FLASH
Definition:

#define PPR_STORE_IN_FLASH 1

Description:

This macro defines the value for ppr_store when non-volatile data is to be stored in Flash across power cycles.

7.7.6.7.1.3. PPR_TEST_AND_MON_TYPE_ISO
Definition:

#define PPR_TEST_AND_MON_TYPE_ISO 0x1

Description:

The bit position for DTE type definition Bit 0 - to define whether DTE is relevant to ISO (J1979) protocol.

Bit 1 - to define whether DTE is relevant to J1939 protocol.

7.7.6.7.2.  Enumerations
7.7.6.7.2.1. PPR_RC_T
Summary:

An enumerated type which contains success and failure codes returned by some In-Use Performance Ratio (PPR) functions.

Enumerations:
PPR_RC_OK

Return code if everything progressed as expected.

PPR_RC_BAD_ARGS

Return code if at least one of the arguments could not be used.

PPR_RC_BAD_CONFIG_DATA

Return code if the PPR configuration data was invalid for requested operation.

7.7.6.7.2.2. PPR_TEST_RUN_STATE_T
Summary:

An enumerated type which contains the state of the test run.

Enumerations:
PPR_TEST_NOT_RUN

Test has not been run (ever).

PPR_TEST_RUN_THIS_DC

Test has been run this drive cycle.

PPR_TEST_RUN

Test has been run, but not this drive cycle.

7.7.6.7.3.  Data types
7.7.6.7.3.1. PPR_DTE_NV_T
Summary:

This structure declares the run-time data to be stored with each DTE.

Members:
U16 PPR_DTE_NV_T::numerator

The Specific Numerator for the test.

U16 PPR_DTE_NV_T::denominator

The Specific Denominator for the test.

U16 PPR_DTE_NV_T::test_value

The Test value for the test.

U16 PPR_DTE_NV_T::test_lim_max

The maximum limit of the test value for the test Pass/Fail criteria.

U16 PPR_DTE_NV_T::test_lim_min

The minimum limit of the test value for the test Pass/Fail criteria.

BOOL PPR_DTE_NV_T::dte_in_use

Specifies if the DTE is in-use for current application.

BOOL PPR_DTE_NV_T::numerator_updated_this_cycle

This keeps track of whether the Numerator has been updated this drive cycle.

BOOL PPR_DTE_NV_T::denominator_updated_this_cycle

This keeps track of whether the Denominator has been updated this drive cycle.

PPR_TEST_RUN_STATE_T PPR_DTE_NV_T::test_run_status

This keeps track of whether the Test has been run this cycle / ever.

Description:

This structure declares the run-time data to be stored with each DTE.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.6.7.3.2. PPR_DTE_CONST_T
Summary:

This structure collates the data associated with each DTE.

Members:
U8 PPR_DTE_CONST_T::dte_id

The DTE identifier - calibratable by the application.

U8 PPR_DTE_CONST_T::dte_type

The DTE type - ISO or J1939 or BOTH Bit 0 = 1 implies ISO Bit 1 = 1 implies J1939.

U8 PPR_DTE_CONST_T::dme_id

The DME to which this DTE belongs - calibratable by the application.

U8 PPR_DTE_CONST_T::iso_tid

The ISO specified Test ID that requires ratio monitoring.

U8 PPR_DTE_CONST_T::j1939_tid

The J1939 specified Test ID that requires ratio monitoring.

U8 PPR_DTE_CONST_T::mon_id

The Monitor group ID to which the DTE belongs Applicable only for reporting over ISO.

U8 PPR_DTE_CONST_T::scaling_id

The identifier is used to reference the scaling and unit to be used by the external test equipment to calculate and display the test values/ results Applicable only for reporting over ISO.

U16 PPR_DTE_CONST_T::slot_id

The SLOT identifier for the DTE Applicable only for reporting over J1939.

U32 PPR_DTE_CONST_T::spn

The SPN associated with the DTE Applicable only for reporting over J1939.

U8 PPR_DTE_CONST_T::fmi

The FMI associated with the DTE Applicable only for reporting over J1939.

U8 PPR_DTE_CONST_T::component_id

The Component identifier for the DTE Applicable only for reporting over J1939.

PPR_DTE_NV_T* PPR_DTE_CONST_T::dte_data_nv

Pointer to the modifiable data part of the Test data.

Description:

This structure collates the data associated with each DTE.

Note

The application may use the ISO and J1939 Test IDs, Monitor group ID and Component ID elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

7.7.6.7.3.3. PPR_DME_NV_T
Summary:

This structure declares the run-time data to be stored with each DME.

Members:
U16 PPR_DME_NV_T::dme_run_count

The Run count used for setting Readiness 'complete' status for the DME.

BOOL PPR_DME_NV_T::dme_in_use

Specifies if the DME is in-use for current application.

BOOL PPR_DME_NV_T::dme_readiness_complete

The Readiness 'complete' status for the DME.

BOOL PPR_DME_NV_T::dme_enabled

Indicates whether the monitoring for the DME is enabled.

BOOL PPR_DME_NV_T::dme_completed

Indicates whether the monitoring conditions for the DME are met.

Description:

This structure declares the run-time data to be stored with each DME.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

7.7.6.7.3.4. PPR_DME_CONST_T
Summary:

This structure collates the data associated with each Monitor ID.

Members:
U8 PPR_DME_CONST_T::dme_id

The DME identifier - calibratable by the application.

U8 PPR_DME_CONST_T::dme_type

The DME type - ISO or J1939 or BOTH Bit 0 = 1 implies ISO Bit 1 = 1 implies J1939.

U8 PPR_DME_CONST_T::mon_id

The Monitor ID that requires ratio monitoring.

PIO_MONITOR_GROUP_T PPR_DME_CONST_T::mon_grp

The Monitor group which this DME belongs to.

U16 PPR_DME_CONST_T::readiness_count_lim

The readines count limit - the number of times monitor has to be run before declared as Readiness COMPLETE.

U32 PPR_DME_CONST_T::spn

The SPN for the DME Applicable only for reporting DM20 messages over J1939.

PPR_DME_NV_T* PPR_DME_CONST_T::dme_data_nv

Pointer to the modifiable data part of the Monitor data.

Description:

This structure collates the data associated with each Monitor ID.

Note

The application may use the Monitor ID and rediness count limit elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

7.7.6.7.3.5. PPR_DME_DATA_T
Summary:

This structure is for the data calculated for reporting the DME data.

Members:
U16 PPR_DME_DATA_T::dme_numerator

The Specific Numerator for the monitor group.

U16 PPR_DME_DATA_T::dme_denominator

The Specific Denominator for the monitor group.

F32 PPR_DME_DATA_T::dme_ratio

The Ratio for the monitor group.

7.7.6.7.4.  Variables
7.7.6.7.4.1. ppr_store
Definition:

const U8 ppr_store

Description:

This defines which memory type will be used to store non-volatile PPR data.

If set to PPR_STORE_IN_BBRAM then non-volatile data is stored in battery backed RAM, and if set to PPR_STORE_IN_FLASH then the non-volatile data is stored in Flash.

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

7.7.6.7.4.2. ppr_num_dte
Definition:

const U16 ppr_num_dte

Description:

The total number of DTEs that are declared.

7.7.6.7.4.3. ppr_num_dme
Definition:

const U16 ppr_num_dme

Description:

The total number of DMEs that are declared.

7.7.6.7.4.4. ppr_dte_table
Definition:

const PPR_DTE_CONST_T ppr_dte_table[]

Description:

The table of DTEs.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal ppr_num_dte (or one if there are DTEs). The array is not to be accessed by application code.

7.7.6.7.4.5. ppr_dme_table
Definition:

const PPR_DME_CONST_T ppr_dme_table[]

Description:

The table of DMEs.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal ppr_num_dme (or one if there are no DMEs). The array is not to be accessed by application code.

7.7.6.7.4.6. ppr_j1939_test_mapping_list
Definition:

const U8 ppr_j1939_test_mapping_list[64]

Description:

This is a sorted list of bit mapping for J1939 Test Ids - used for DM10 message.

7.7.6.7.5.  Functions
7.7.6.7.5.1. ppr_update_dte_data()
Definition:

PPR_RC_T ppr_update_dte_data(
   U8     pprf_dte_id,
   BOOL   pprf_sp_den_update_enable,
   BOOL   pprf_sp_num_update_enable);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update the Numerator and Denominator values for this DTE depending on whether application says that it is ready to be updated.

Arg (data in): pprf_dte_id

The DTE ID for which the N & R are to be updated

Arg (data in): pprf_sp_den_update_enable

Indicates whether the Denominator is ready to be updated

Arg (data in): pprf_sp_num_update_enable

Indicates whether the Numerator is ready to be updated

Return:

7.7.6.7.5.2. ppr_update_dte_test_value()
Definition:

PPR_RC_T ppr_update_dte_test_value(
   U8     pprf_dte_id,
   U16    pprf_test_value,
   U16    pprf_test_limit_min,
   U16    pprf_test_limit_max,
   BOOL   pprf_test_run,
   BOOL   pprf_reset_dte);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update the test value for this DTE depending on whether application says that it is ready to be updated.

For J1939 DTEs the guidelines for the use of test results is as detailed below as per J1939-73 spec dated Sept 2010. The application is expected to set the right combination of test results in order to convey the correct results over J1939 messages to the test tools:- Test_Value Test_Max Test_Min Interpretation 0x0000 to 0xFAFF 0xFFFF 0xFFFF Test Pass 0xFE00 0xFFFF 0xFFFF Test Fail with error 0xFB00 0xFFFF 0xFFFF Test Not Complete 0xFB01 0xFFFF 0xFFFF Test cannot be performed less than 0xFFFF any value 0xFFFF Test Fail (value less than min) any value 0xFFFF 0xFFFF Test fail without values

For ISO-15765 DTEs, all test values within the range specified by min and max will be interpreted as "Test Pass" including values equal to min or max.

Arg (data in): pprf_dte_id

The DTE ID for which the test value is to be updated

Arg (data in): pprf_test_value

The test value, supplied by the application

Arg (data in): pprf_test_limit_min

The minimum test limit for this test, supplied by the application

Arg (data in): pprf_test_limit_max

The maximum test limit for this test, supplied by the application

Arg (data in): pprf_test_run

Indicates whether the test has been run and new values are available. If set to TRUE, the stored test values will be set to the values passed. If set to FALSE, the stored values will be left unchanged.

Arg (data in): pprf_reset_dte

If set to TRUE, the stored test values will be reset. This will typically be used by the application when starting a new monitor cycle (see note). If set to FALSE, the stored values will be left unchanged. If both pprf_test_run and pprf_reset_dte are set TRUE, pprf_test_run takes precedence.

Return:

Note

After a monitor completes, the application must update all the Test ID that were used by the monitor with appropriate passing or failing results. If a test result was not utilised during the monitoring event, the Test values must be reset. Test results from previous completed monitoring events must not be mixed with test results from current event.

7.7.6.7.5.3. ppr_update_dte_in_use_status()
Definition:

PPR_RC_T ppr_update_dte_in_use_status(
   U8     pprf_dte_id,
   BOOL   pprf_in_use);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

The application can configure itself at run-time to include or remove the DTE from those considered for diagnostic reporting.

Arg (data in): pprf_dte_id

The DTE ID for which the status is to be updated

Arg (data in): pprf_in_use

Indicates whether the DTE is in-use

  • TRUE - indicates that the DTE is in use.

  • FALSE - indicates that the DTE is not in use.

Return:

Note

All DTEs are enabled by default

7.7.6.7.5.4. ppr_update_dme_data()
Definition:

PPR_RC_T ppr_update_dme_data(
   U8     pprf_dme_id,
   BOOL   pprf_monitor_run,
   BOOL   pprf_force_complete,
   BOOL   pprf_force_not_complete,
   BOOL   pprf_monitor_enabled);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update the DME data depending on whether application says that it is ready to be updated.

Arg (data in): pprf_dme_id

The DME identifier for which the data is to be updated

Arg (data in): pprf_monitor_run

Indicates whether the monitor has been run. When the application asks for forceful Readiness COMPLETE or NOT COMPLETE, the flag indicating whether the monitoring conditions for the DME are met (completed) is set depending on the value of this parameter.

Arg (data in): pprf_force_complete

Indicates whether the monitor has to be forced to COMPLETE readiness status

  • TRUE - indicates that the readiness status should be forced to COMPLETE independent of the number of times monitor has been run.

  • FALSE - indicates that the readiness status has to be set depending on the number of times the monitor has been run and if it is enabled.

Arg (data in): pprf_force_not_complete

Indicates whether the monitor has to be forced to NOT COMPLETE readiness status

  • TRUE - indicates that the readiness status should be forced to NOT COMPLETE independent of the number of times monitor has been run.

  • FALSE - indicates that the readiness status has to be set depending on the number of times the monitor has been run and if it is enabled. Both pprf_force_complete and pprf_force_not_complete should not be set to TRUE in the same time.

Arg (data in): pprf_monitor_enabled

Indicates whether the monitor is Enabled

  • TRUE - indicates that the monitor is enabled.

  • FALSE - indicates that the monitor is disabled for some reason.

    • Readiness complete count will not be computed if the monitor is DISabled

Return:

7.7.6.7.5.5. ppr_update_dme_in_use_status()
Definition:

PPR_RC_T ppr_update_dme_in_use_status(
   U8     pprf_dme_id,
   BOOL   pprf_in_use);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

The application can configure itself at run-time to include or remove the DME from those considered for diagnostic reporting.

Arg (data in): pprf_dme_id

The DME ID for which the status is to be updated

Arg (data in): pprf_in_use

Indicates whether the DME is in-use

  • TRUE - indicates that the DME is in use.

  • FALSE - indicates that the DME is not in use.

Return:

Note

All DMEs are enabled by default

7.7.6.7.5.6. ppr_update_gen_denominator()
Definition:

void ppr_update_gen_denominator(
   BOOL   pprf_gen_den_update_enable);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update the General denominator depending on whether application says that it is ready to be updated.

Arg (data in): pprf_gen_den_update_enable

Indicates whether the denominator has to be updated

7.7.6.7.5.7. ppr_update_ign_cyc_counter()
Definition:

void ppr_update_ign_cyc_counter(
   BOOL   pprf_ign_cyc_update_enable);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Update the Ignition cycle count depending on whether application says that it is ready to be updated.

Arg (data in): pprf_ign_cyc_update_enable

Indicates start of ignition cycle

7.7.6.7.5.8. ppr_get_dme_ratio()
Definition:

PPR_RC_T ppr_get_dme_ratio(
   U8               pprf_dme_id,
   PPR_DME_DATA_T  *pprf_dme_data);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the In-Use performance ratio values for this DME.

Arg (data in): pprf_dme_id

The DME for which the ratio, numerator and denominator data is needed

Arg (data in,out): pprf_dme_data

Pointer to the DME data - which will be updated Cannot be NULL

Return:

7.7.6.7.5.9. ppr_get_monitor_group_data()
Definition:

PPR_RC_T ppr_get_monitor_group_data(
   PIO_MONITOR_GROUP_T   pprf_mon_grp,
   PPR_DME_DATA_T       *pprf_dme_data);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the In-Use performance data values for this monitor group.

Arg (data in): pprf_mon_grp

The Monitor group for which the numerator and denominator data is needed

Arg (data out): pprf_dme_data

Pointer to the data - which will be updated Cannot be NULL

Return:

7.7.6.7.5.10. ppr_get_dme_status()
Definition:

PPR_RC_T ppr_get_dme_status(
   U8             pprf_dme_id,
   PPR_DME_NV_T  *pprf_dme_nv_data);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the Monitor enable, readiness complete, completed status for the DME.

Arg (data in): pprf_dme_id

The DME for which data is needed

Arg (data in,out): pprf_dme_nv_data

Pointer to the DME data - which will be updated Cannot be NULL

Return:

7.7.6.7.5.11. ppr_get_dme_incomplete_count()
Definition:

U16 ppr_get_dme_incomplete_count(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the total number of monitors (DMEs) that are enabled and not complete.

Return:

The number of enabled and incomplete monitors (DMEs)

7.7.6.7.5.12. ppr_get_dte_status()
Definition:

PPR_RC_T ppr_get_dte_status(
   U8             pprf_dte_id,
   PPR_DTE_NV_T  *pprf_dte_nv_data);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the NV data for the DTE.

Arg (data in): pprf_dte_id

The DTE for which data is needed

Arg (data in,out): pprf_dte_nv_data

Pointer to the DTE data - which will be updated Cannot be NULL

Return:

7.7.6.7.5.13. ppr_handle_new_ign_cyc()
Definition:

void ppr_handle_new_ign_cyc(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Handles any data updates needed at start of new ignition cycle.

Resets the ignition cycle count's "update status"

7.7.6.7.5.14. ppr_handle_new_drive_cycle()
Definition:

void ppr_handle_new_drive_cycle(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Handles any data updates needed at start of new drive cycle.

7.7.6.7.5.15. ppr_get_ign_cycle_count()
Definition:

U16 ppr_get_ign_cycle_count(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the ignition cycle count.

Return:

U16 - The ignition cycle count.

7.7.6.7.5.16. ppr_get_gen_denominator()
Definition:

U16 ppr_get_gen_denominator(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Obtain the general denominator.

Return:

The general denominator.

7.7.6.7.5.17. ppr_commit_to_store()
Definition:

void ppr_commit_to_store(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Commit RAM data to non-volatile store.

Update the validity status for the non-volatile data, and if the data is stored in Flash, then write the data to Flash.

Warning

This function suspends the scheduler for a period of time. The period of time depends on the size of data and the storage location. If storing information to Flash, the worst case Flash erase time given worst case environmental conditions, can be around 1.8 seconds.

7.7.6.7.5.18. ppr_is_store_intact()
Definition:

BOOL ppr_is_store_intact(void);

Supported targets:

All targets

Required license:

EXT_DIAG (Extended diagnostics library).

Description:

Test whether there are data changes not yet committed to NV store.

Return:

True if there are no data changes since the last commit to the non-volatile store (from calling ppr_commit_to_store()), false otherwise

Chapter 8. Support tools

8.1. Interface and DDE tool

The interface and DDE tool performs two main functions:

  1. The interface tool reads a specification of the interface between the application and library, and generates the interface code to link the application and library together. Although the interface code could be written by hand, some sections of the interface code are hard to maintain by hand. The interface tool will replace the hard to maintain code with a simple text based specification.

  2. The interface tool reads a specification of the data items in the application and generates an output file which can be used to inspect the application and library code when it is executing on the ECU. At the moment, only the ASAP2 output file format is supported, but other formats may be added in the future.

How the interface tool fits into the OpenECU system is explained in more detail in Section 4.6.1, “Building an application”.

8.1.1. Simple interface file example

Perhaps the best way to understand what the interface tool and interface specification is all about, is to describe a simple example. The following example of an interface file covers the target ECU, the application and basic CCP settings.

target-ecu  1
{
  hw-part-number   = "01T-068276";  2
  hw-issue-number  = 2;
  hw-option        = "000";
}

application  3
{
  major-version    = 1;  4
  minor-version    = 0;
  subminor-version = 0;

  name             = "Simple application";  5
  copyright        = "Copyright 2016, Pi Innovo";
  description      = "A simple application showing how to use OpenECU at a minimum.";

  os-native  6
  {
    stack-size     = 8192;  7

    task  8
    {
      name         = application_processing;
      function     = app_proc_task;
      priority     = 10;
      period       = 100;
    }
  }
}

ccp-messaging  9
{
  cro              = 1784;  10
  dto              = 1785;
  station-address  = 0;
  can-bus          = 0;

  enabled-during-application-mode = true;  11
}

1

All statements regarding the target ECU to be used are written here. The statements are included between the opening and closing brace ({}) and this is a common mechanism to group common statements together.

2

In this case, there are three statements that identify the ECU that the application is to be built and run on.

3

All statements about the application are written here. This includes identifying the application name, version and so on, as well as identifying the operating system and tasks to schedule.

4

This collection of statements identifies the version to be assigned to the application. The version number is available to the calibration tool.

5

This collection of statements provides information about the application, which is embedded into the binary image of the application during compilation. The information is available to the calibration tool.

6

Within the application statements, the operating system is identified and the application tasks defined.

7

The application and library require some memory to be dedicated to a stack and this statement does just that. More details about how OpenECU handles the stack can be found in Section 5.6.1.3, “Stack sharing”.

8

Each application task has a number of attributes, including a general name for reference within the interface file, the C identifier for the application function that implements the task, a task priority and a period in milliseconds. More details about how OpenECU treats tasks can be found in Section 5.6, “Task scheduling (PKN)”.

Although only one task is shown here, multiple application tasks can be declared.

9

The primary communication mechanism from the ECU to the reprogramming and calibration tools is with CCP (see Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)” and Appendix C, Supporting tools for more).

All statements regarding CCP communication are written here.

10

In this example, the default CCP settings have been chosen.

11

And in this example, CCP messaging is enabled during application mode so that the calibration tool can view the application variables as the application runs on the ECU.

As part of the build process at step 1, the interface tool is run against the interface file to generate the interface code:

Figure 8.1. Building the interface code

Building the interface code

which is then compiled at step 2, ready to be linked with the application and library in later steps.

The interface tool is a command line tool and naturally fits into software build environments (e.g., from within make). In this example, if the interface file were named sample.capi, then the command to generate the interface code files would look like this:

capi.py --interface-file sample.capi --output-code sample_capi

The result of running this command would be a set of files named sample_capi*.* which contains the data definitions and function definitions required to link the application with the library.

The following sections cover how to run the interface tool and what contents an interface tool should contain.

8.1.2. Running the interface tool

The interface tool has a command line interface. It is invoked by running the command:

capi.py arguments

The list of arguments can be specified in different forms:

argument

A string entered on the command line following the tool command. E.g., running the interface tool as if it accepts one file-name argument would be:

capi.py file-name.txt
option

An argument, used to provide specific information, starts with a hyphen. There are two types of options: with a single hyphen and with a double hyphen.

single — starts with a single hyphen and ends with a single character. E.g., the option to print the interface tool's arguments is:

-h

Single hyphen options can be merged. For instance, the options:

-f -W

can be represented as:

-fW

double — starts with a double hyphen and ends with a string. E.g., the option to specify the interface file is:

--interface-file sample.capi
option argument

An argument that follows an option that requires an argument. The following argument can be disjoint, or joint, to the option. For instance, the following options show the disjoint form:

-i file-name.txt

--interface-file file-name.txt

and the joint form is:

-offline.txt

--input=file-name.txt

8.1.2.1. Options (input)

-i FILE, --interface-file=FILE

Specify the file-name for the interface file.

This argument is optional. If this argument is not present then the tool will attempt to read the interface file from the console.

8.1.2.2. Options (target identification and configuration)

--cfg-flags

Obtain the -DCFG flags to pass to the compiler in order to correctly identify the hardware being used in the platform source code. It should be used in conjunction with the --interface-file option. The capi.py tool reads target-ecu information given in the interface file and maps that to the internal names used to identify that ECU within the software domain.

See the batch files in the C-API examples for an example of how to use this option

This argument is optional. However, it is recommended that it is used in batch files for compiling the C-API applications to remove any dependencies on the internal names used to identify the ECU within the software domain, which these names may change from time to time.

--target-path

Obtain the path to the platform code appropriate to the target ECU. This option should be used in conjunction with the --interface-file option. The capi.py tool reads target-ecu information given in the interface file and maps that to the internal names used to identify that ECU within the software domain.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

This argument is optional. However, it is recommended that it is used in batch files for compiling the C-API applications to remove any dependencies on the internal names used to identify the ECU within the software domain, since these names may change from time to time.

--output-linker-file=FILE

Generate the correct linker file depending on the target and memory configuration (for those targets that support this option) as specified in the interface file: see Section 8.1.4.7, “Compound statement: target-ecu” and Section 8.1.4.13, “ Compound statement: memory-config ” for details of how to specify these items.

This argument is optional. However, it is particularly useful for non-standard memory configurations where it will automatically create the correct linker file for that configuration.

When using this command line option, the base path to the OpenECU installation must also be specified using the --oe-base-path=PATH command line option. Furthermore, some targets support more than one compiler. For these targets the compiler should be specified using the --compiler-id=COMPILER command line option.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--ld-excerpt-file=FILE

Insert the specified linker file excerpt created with --diab-ldfile=FILE or --gcc-ldfile=FILE into the linker file.

This argument is optional. It particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

When using this command line option, the base path to the OpenECU installation must also be specified using the --oe-base-path=PATH command line option and the output linker file must be specified using the --output-linker-file=FILE command line option. Furthermore, some targets support more than one compiler. For these targets the compiler should be specified using the --compiler-id=COMPILER command line option.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--oe-base-path=PATH

Specify the path to the OpenECU installation. This is required when using the --output-linker-file=FILE command line option.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--compiler-id=COMPILER

Specify the compiler. This is (only) required when using the --output-linker-file=FILE command line option for those targets that support more than one compiler. The COMPILER must be one of:

  • diab_5_5_1_0

  • diab_5_8

  • diab_5_9

  • gcc_4_7_3

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

8.1.2.3. Options (code output)

--output-code=FILE

Specify the template file-name for code output. Interface code is written to more than one file. For instance, if the option

--output-code api

is given, then the tool will generate files api.h and api.c.

This argument is optional. If this argument is not specified then the interface tool will not generate any interface code files.

8.1.2.4. Options (ASAP2 output)

--asap2-naming=ASAP2_NAMING

Specify the ASAP2 naming scheme to be applied to DDEs taken from prefix-style data dictionary files included by the interface specification file (see options -i, --interface-file). Must be one of: prefix_name, prefix.name prefix.name_prefix, name, or name_prefix.

The scheme determines how the name for a prefix-style DDE is transformed into the name of the equivalent ASAP2 object. For instance, if the scheme prefix.name_prefix was selected

--asap2-naming prefix.name_prefix

then the DDE name mbe_engine_speed would be transformed into mbe.engine_speed_mbe when generating an ASAP2 description file.

This argument is optional. If the argument is not specified then the tool uses a default of prefix_name

-b TYPE, --bool-type=TYPE

Specify the implementation type for booleans. Must be one of: u8 (booleans are represented using the unsigned 8-bit integer type), or float (booleans are represented using the 32-bit IEEE floating point type).

This is an optional argument. If the argument is not specified then the tool uses a default of u8.

--diab-ddumpfile=FILE

Specify the file-name of the output from the Diab ddump command. The ddump command extracts information from the ELF file, including details about structures, enumerations and addresses of variables. This information is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The ddump command should be executed as follows:

ddump -Dht [file-name].elf > [file-name].ddump.tmp

resulting in a textual representation of the ELF information.

The option --diab-ddumpfile cannot be specified at the same time as any of the --diab-mapfile, --gcc-objfile, or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

--gcc-objfile=FILE

Specify the file-name of the output from the GNU objdump command. The objdump command extracts information from the ELF file, including details about structures, enumerations and addresses of variables. This information is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The objdump command should be executed as follows:

objdump -W -h -t [file-name].elf > [file-name].objdump.tmp

resulting in a textual representation of the ELF information.

The option --gcc-objfile cannot be specified at the same time as any of the --diab-mapfile, --diab-ddumpfile, or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

-m FILE, --diab-mapfile=FILE

Specify the file-name of the Diab linker MAP file. The MAP file is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The option --diab-mapfile cannot be specified at the same time as any of the --gcc-objfile, --diab-ddumpfile, or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

If generating an ASAP2 file, one of the above must be specified.

If generating a final application image, --diab-mapfile or --gcc-mapfile must be specified.

-m FILE, --gcc-mapfile=FILE

Specify the file-name of the Diab linker MAP file. The MAP file is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The option --diab-mapfile cannot be specified at the same time as any of the --gcc-objfile, --diab-ddumpfile, or --diab-mapfile options. If generating an ASAP2 file, one of the options must be specified.

If generating an ASAP2 file, one of the above must be specified.

If generating a final application image, --diab-mapfile or --gcc-mapfile must be specified.

--diab-ldfile=FILE

Specify the file-name of the Diab linker definition file excerpt produced to allow specific linkage of certain functions and symbols. This linker definition file excerpt must be inserted into the main linker definition file after the line containing the text "APP_CODE_FLASH_INSERT".

This particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

If this option is not specified, a linker definition file excerpt will not be produced. This may be acceptable if an application does not require it.

--gcc-ldfile=FILE

Specify the file-name of the GCC linker definition file excerpt produced to allow specific linkage of certain functions and symbols. This linker definition file excerpt must be inserted into the main linker definition file after the line containing the text "APP_CODE_FLASH_INSERT".

This particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

If this option is not specified, a linker definition file excerpt will not be produced. This may be acceptable if an application does not require it.

-n LENGTH, --name-length=LENGTH

Specify maximum length of identifier names in ASAP2 files. Names longer than the specified length will be modified to a unique name of the specifed length.

If LENGTH is given a value of 0, then there will be no limit on identifier lengths.

This is an optional argument. If the argument is not specified then the tool uses a default of 32.

--output-asap2-canape=FILE

Specify the file-name to write the Vector CANape specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to Vector CANape. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an Vector CANape ASAP2 file.

--output-asap2-generic=FILE

Specify the file-name to write the an ASAP2 description to. The ASAP2 contains a generic description, without elements for specific calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate a generic ASAP2 file.

--output-asap2-inca=FILE

Specify the file-name to write the ETAS INCA specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to ETAS INCA. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an ETAS INCA ASAP2 file.

--output-asap2-vision=FILE

Specifies the file-name to write the ATI Vision specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to ATI Vision. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an ATI Vision ASAP2 file.

--old-format

Specifies that the OpenECU build process will generate old-style ASAP2 map names. Old style ASAP2 map names contain _z at the end of the map name. This usage was used in releases older than version 1.9.0 and this option was introduced to allow for backwards compatibility of calibration files.

This argument is optional. If the argument is not specified then the interface tool will not generate old style ASAP2 map names.

8.1.2.5. Options (final application image generation)

--output-s-rec=FILE

Specifies the file in which to write the final application image in s-record format. The CCP settings, and checksum are populated in the applicaiton and calibration headers.

--img-app, --img-cal and --diab-mapfile must be specified.

If --crc or --ipv4-sum are specified, then the application or calibration headers will be poplated with the specified CRC or IPv4 checksum.

If this argument is not specified, then the interface tool will not generate a final application s-record.

-A FILE, --img-app=FILE

Specifies the file containing the application binary image generated by the compiler.

For the diab compiler, this file is generated as follows:

ddump -Rv -u -n .text_app,.data,.sdata [name].elf -o image_app_[name].bin.tmp

If generating a final application image, --img-app must be specified.

-C FILE, --img-cal=FILE

Specifies the file containing the calibration binary image generated by the compiler.

For the diab compiler, this file is generated as follows:

ddump -Rv -u -n .rodata,.sdata2,.cal_sec [name].elf -o image_cal_[name].bin.tmp

If generating a final application image, --img-cal must be specified.

-c VALUE, --crc=VALUE

If specified with --output-s-rec this option can be used to populate the headers with a CRC checksum, according to the specified value:

OptionFunction
--crc aCalculate crc for application header.
--crc cCalculate crc for calibration header.
--crc acCalculate crc for both.
--ipv4-sum=VALUE

If specified with --output-s-rec this option can be used to populate the headers with a IPv4 checksum, according to the specified value:

OptionFunction
--ipv4-sum aCalculate checksum for application header.
--ipv4-sum cCalculate checksum for calibration header.
--ipv4-sum acCalculate checksum for both.

8.1.2.6. Options (data dictionary output)

--output-elf-contents=FILE

Specifies the file-name to write a C-style data dictionary to. The data dictionary entries are those found in the application ELF information (see --diab-ddumpfile) and not already listed in a data dictionary file included from an interface specification (see -i, --interface-file). This option may help when incrementally building up new DD files from existing C code.

Unreferenced C objects do not contain enough information in the ELF file to generate an equivalent DD entry. For instance, if a data dictionary file were created from the following snippet:

U32 unreferenced_var;
U32 var;

void main(void)
{
    do_something(var);
}

an entry for var would be created but no entry for unreferenced_var would be created.

If this option is specified then the --diab-ddumpfile option must also be specified.

--include-platform-vars

The --output-elf-contents option will filter out most of the library variables. And in most circumstances this is the better option, presenting only variables which are relevant to the application. However, this filtering can be turned off by specifying this option if the filtering inadvertently removes application variables.

--warn-missing-ddes

Generate a warning if a DDE cannot be found in the MAP or ELF file, and continue to create the ASAP2 file (rather than raise an error and stop generating the ASAP2 file).

This argument is optional. If the argument is not specified then the interface tool will raise an error when a DDE cannot be found.

--check-dde-data-types

Generate a warning if the data type of a DDE does not match the equivalent variable data type from the ELF file.

This argument is optional. If the argument is not specified then the interface tool will not warn the user of data type mismatches.

8.1.2.7. Options (miscellaneous)

-h, --help

Show a summary of the command line arguments to the interface tool, then exit.

This argument is optional.

--version

Show the version of the interface tool, then exit.

This argument is optional.

--cleanup

Remove temporary files when an error is found (see the details on removing temporary files for more). This is the default behaviour of the tool.

This argument is optional. If the argument is not specified then the tool will default to removing temporary files when an error is found.

--dont-cleanup

Do not remove temporary files when an error is found (see the details on removing temporary files for more).

This argument is optional. If the argument is not specified then the tool will default to removing temporary files when an error is found.

--output-ast=FILE

Specify the file-name template that the tool writes a representation of its internal workings for technical support purposes. The files written to are: FILE_pre_default.ast and FILE_post_default.ast. To be used in conjunction with the see --dont-cleanup argument.

This argument is optional. If the argument is not specified then the interface tool will not generate the technical support files.

--output-mscript=FILE

Specifies the file-name to write a MATLAB script which executes to fill the MATLAB workspace with details on the prefix-style DDEs (C-style DDEs are not acted on as their naming style cannot always be expressed in MATLAB).

This argument is optional. If the argument is not specified then the interface tool will not generate an m-script file.

This option is provided for other OpenECU products and is not necessary to use the C-API OpenECU product.

8.1.3. Warning and error messages

The interface tool reports warnings and error messages is a consistent way. A typical error message might look like:

(capi.py): OpenECU interface tool (version <number>, built <date>)  1
(capi.py): (error 601) 2 line 9 of 'test.capi'  3 : unexpected input. 4
(capi.py):
(capi.py): hw-part-number-bad  5
(capi.py): ^  6

1

If a warning or error occurs, the interface tool always prints an identification line, detailing the tool version number and build date.

2

Each warning or error message has a unique code which can be referenced in Appendix B, OpenECU error and warning codes, where each message is explained in more detail.

3

If applicable, the location of the error in the form of either a file-name, or a file-name and line number, is given. Some warnings and errors occur after all input files have been processed, and as there is no specific file-name or line number to refer to, the message will contain a useful reference (e.g., the name of the DDE which caused the message).

4

The actual warning or error message itself. In this case, the keyword hw-part-number has been modified so that it is no longer a keyword, and the error message shows that the input text is unexpected.

5

If applicable, the line which caused the problem is shown.

6

If applicable, the point in the line which caused the error is shown. In this case, the keyword which caused the tool to raise the error is highlighted.

If an error occurs then the interface tool does two things:

  1. The tool returns with a code signalling failure. This code can be used to stop the build process, for instance, when using make. Stopping the build process ensures that the build of an application does not complete with an incorrect mix of files.

  2. The tool attempts to remove any files it created. By removing files, any subsequent process which relies on files from the interface tool will fail, thus ensuring that the build of an application does not complete with an incorrect mix of files.

8.1.4. Interface file contents

The interface file contains a set of statements, with whitespace and comments to aid readability. The format of these statements is explained in the following sections.

8.1.4.1. White space

The interface file can contain whitespace. Space characters, tab characters and so on can be used between and within comments and statements to aid readability.

8.1.4.2. Comments

The interface file may contain comments. A comment starts with /*, ends with */, and contains arbitrary text and new lines in between. For instance, the following:

  target-ecu
  {
      /* Specify the M250-000 issue 2 as the target ECU. */
      hw-part-number   = "01T-068276";
      hw-issue-number  = 2;
      hw-option        = "000";
  }

shows a valid comment on the third line. Comments cannot be nested. For instance, the following:

/* Here is a comment.
 *
 * /* Which contains a nested comment when it should not. */
 */

would cause the interface tool to raise a syntax error.

8.1.4.3. Numbers

The interface file may contain numbers. A number must range between 0 and 2147483647 inclusive, cannot be negative. The number can be represented as decimal or hexadecimal, as shown here (both major-version and minor-version are assigned 1010):

    major-version = 10;
    minor-version = 0xa;

Decimal numbers must only contain digits ('0' through '9'), hexadecimal numbers may contain digits, lower case 'a' through 'f' and upper case 'A' through 'F'.

8.1.4.4. Identifiers

The interface file may contain identifiers. Identifiers are unique names given to objects so that they can be identified by other parts of the interface file.

   name = identifier;

Identifiers must be 31 characters or less in length, can contain the '_' character, digit characters, 'a' through 'z' characters and 'A' through 'Z' characters, but cannot start with a digit.

When naming an object, all identifiers must be unique (an error message is reported if a duplicated identifier is found).

8.1.4.5. Strings

The interface tool may contain strings. Strings start and end with a double quote '"' character, and can contain any printable ASCII character from space (ASCII 32) through to tilde (ASCII 126).

   description = "string";

8.1.4.6. Statements

The interface file contains a set of statements which describe the interface between the application and library. There are two types of statement:

compound statement

These statements contain a group of related statements between an opening and closing brace ({}). For instance:

target-ecu
{
    /* Further assignment and compound statements go here */
}

is a compound statement. A compound statement typically contains at least one assignment or compound statement. Although the braces are shown on separate lines, there is no need to do so — in this case, placing the braces on separate lines aids readability.

assignment statement

These statements associate an attribute with a value or string, or a list of values or strings, and end with a semi-colon. For instance:

hw-part-number = "01T-068276";

is an assignment statement.

An interface file can contain the following compound statements:

target-ecu { ... } 1
application { ... } 2
memory-config { ... } 3
can-messaging { ... } 4
ccp-messaging { ... } 5
iso-diagnostics { ... }  6
j1939-messaging { ... } 7
ff-data { ... } 8
dtc-data { ... } 9
pid-data { ... } 10
dte-data { ... } 11
dme-data { ... } 12
adaptives { ... } 13
tunes { ... } 14
ddes { ... } 15
nonvolatile-filesystem { ... } 16
routine-data { ... } 17

1

The required target-ecu compound statement groups information about what target ECU the application must be built against. This compound statement is covered in Section 8.1.4.7, “Compound statement: target-ecu” in more detail.

2

The required application compound statement groups information about the application, its version, name, description, tasks, resources and choice of scheduler. This compound statement is covered in Section 8.1.4.8, “Compound statement: application” in more detail.

3

The optional memory-config compound statement groups information about memory configuration options. This compound statement is covered in Section 8.1.4.13, “ Compound statement: memory-config ” in more detail.

4

The optional can-messaging compound statement groups information about CAN messaging. This compound statement is covered in Section 8.1.4.14, “Compound statement: can-messaging” in more detail.

5

The optional ccp-messaging compound statement groups information about CCP messaging, including the CAN identifiers to be used for CRO and DTO messages, the station identifier, baud rate, and CAN bus. It also configures seed-key security for CCP. This compound statement is covered in Section 8.1.4.15, “Compound statement: ccp-messaging” in more detail.

6

The optional iso-diagnostics compound statement groups information about ISO 15765-2 based diagnostics over CAN (selected services from J1979 OBD, ISO 14229-1 Unified Diagnostic Services and Keyword Protocol 2000-3). This compound statement is covered in Section 8.1.4.18, “Compound statement: iso-diagnostics” in more detail.

7

The optional j1939-messaging compound statement groups information about J1939 messaging, including whether J1939 is enabled or not, the network name, preferred network addresses, PGNs to listen for, and so on. This compound statement is covered in Section 8.1.4.19, “Compound statement: j1939-messaging” in more detail.

8

The optional ff-data compound statement groups information about freeze frames. This compound statement is covered in Section 8.1.4.25, “Compound statement: ff-data” in more detail.

9

The optional dtc-data compound statement groups information about diagnostic trouble codes (DTCs), including DTC tables. This compound statement is covered in Section 8.1.4.28, “Compound statement: dtc-data” in more detail.

10

The optional pid-data compound statement groups information about parameters accessed by identifier (PIDs) via ISO diagnostic protocols. This compound statement is covered in Section 8.1.4.30, “Compound statement: pid-data” in more detail.

11

The optional dte-data compound statement groups information about parameters accessed by In-Use performance ratios via ISO diagnostic protocols. This compound statement is covered in Section 8.1.4.32, “Compound statement: dte-data” in more detail.

12

The optional dme-data compound statement groups information about parameters accessed by In-Use performance ratios via ISO diagnostic and J1939 protocols. This compound statement is covered in Section 8.1.4.34, “Compound statement: dme-data” in more detail.

13

The optional adaptives compound statement groups information about non-volatile memory data and how it is to be stored by the target ECU. This compound statement is covered in Section 8.1.4.36, “Compound statement: adaptives” in more detail.

14

The optional tunes compound statement groups information about Tunes, which are RAM based calibrations. Note that Tunes are supported on only a few target ECUs. This compound statement is covered in Section 8.1.4.39, “Compound statement: tunes” in more detail.

15

The optional ddes compound statement groups information about data dictionary elements (DDEs), including the units and DDE files to process, and whether to automatically generate library DDE (see Section 8.1.7, “Automatic ASAP2 entries”). This compound statement is covered in Section 8.1.4.40, “Compound statement: ddes” in more detail.

16

The optional nonvolatile-filesystem compound statement groups information related to the non-volatile file system, including maximum write queue size and maximum number of user and platform files. This compound statement is covered in Section 8.1.4.12, “Compound statement: nonvolatile-filesystem” in more detail.

17

The optional routine-data compound statement groups information about routines accessed by identifier via ISO diagnostic protocols. This compound statement is covered in Section 8.1.4.37, “Compound statement: routine-data” in more detail.

8.1.4.7. Compound statement: target-ecu

The required target-ecu compound statement can contain the following statements:

target-ecu
{
    hw-part-number  = string; 1
    hw-issue-number = integer; 2
    hw-option       = string; 3
}

In this case, there are three statements that identify the ECU that the application is to be built and run on. The ECU is identified by its hardware part-number, issue number and option. These items can be found on the label of the ECU. For example, an M250 Developer module might have the following information on its label:

Part No. 01T-068276-000 2m1

1

The required hw-part-number assignment statement should match the "01T-XXXXXX" part of the text, so here it would be set to 01T-068276.

The required hw-issue-number assignment statement is the number immediately before the "m", so in this example it would be set to 2. (The number after the "m" should always be ignored.) Note that for some modules the issue number is preceded by the letters "iss". These should be ignored: the hw-issue-number must always be a number.

The optional hw-option assignment statement corresponds to the final three characters attached by a hyphen to the hw-part-number text string. In the example this is simply "000". For some modules, these three trailing characters are not present on the label. In that case, the hw-option statement can be omitted.

8.1.4.8. Compound statement: application

The required application compound statement can contain the following statements:

application
{
    major-version    = integer; 1
    minor-version    = integer;
    subminor-version = integer;

    name        = string; 2
    description = string;
    copyright   = string;

    os-native { ... } 3
}

1

The required major-version, minor-version and subminor-version assignment statements identify the version of the application. The integer for each must be in the range [0, 65535].

2

The required name, description and copyright assignment statements identify information about the application which is embedded into the interface code and ASAP2 description files.

In the name statement can include tokens which are automatically converted during application build. Tokens are single words starting and ending in the “%” character. For instance, the string “Application for %target%” contains one token named target, which is converted to the target ECU name during a model build. The following table lists the available tokens:

TokenReplacement
%copyright%Replaced with the string from the copyright statement.
%target%Replaced with a string representing the ECU target and option.
%ver-major%Replaced with the string from the major-version statement.
%ver-minor%Replaced with the string from the minor-version statement.
%ver-subminor%Replaced with the string from the subminor-version statement.

3

The required os-native compound statement identifies that the library will use the OpenECU scheduler (see Section 5.6, “Task scheduling (PKN)” for more). The list of supported schedulers may be extended in the future. The compound statement is covered in Section 8.1.4.9, “Compound statement: os-native” in more detail.

8.1.4.9. Compound statement: os-native

The required os-native compound statement can contain the following statements:

os-native
{
    stack-size = integer; 1
    watchdog = library or application; 2
    mem-runtime-checks-enabled = true or false; 3

    task { ... }     4
    resource { ... } 5
}

1

The required stack-size assignment statements specify the size of the scheduler's shared stack (Section 5.6.1.3, “Stack sharing”). The integer must be in the range [1024, ..].

2

The optional watchdog assignment statement can be used to assign responsibility for kicking the watchdog (Section 5.3.1.7, “System watchdog handling”) to the platform or application. If this statement is omitted then responsibility is taken by the platform and the application should not call psc_kick_watchdog().

3

The optional mem-runtime-checks-enabled assignment statement can be used to disable background memory checks, which are otherwise enabled on most targets. Usually this option should be omitted to allow the memory checks to proceed.

4

The required task compound statement, which can be repeated, identifies an application task that the library must schedule together with the library's own tasks (see Section 4.6.4, “Application and library tasks”). The compound statement is covered in Section 8.1.4.10, “Compound statement: task” in more detail.

5

The optional resource compound statement, which can be repeated, identifies a resource and the group of tasks which access that resource (see Section 5.6.1.6, “Resource locking”). The compound statement is covered in Section 8.1.4.11, “Compound statement: resource” in more detail.

8.1.4.10. Compound statement: task

The required task compound statement, which can be repeated up to 12 times, can contain the following statements:

task
{
    name     = string; 1
    function = identifier; 2
    trigger  = string; 3

    priority = integer; 4
    period   = integer; 5
    offset   = integer; 6
}

1

The required name assignment statement identifies the name for this task. The task name is referred to in various places throughout the interface file.

The task name must not be repeated in another task compound statement.

2

The required function assignment statement identifies the C function name for this task. The library calls the function when the task becomes the highest priority task ready to run. The application must implement the C function, to match the prototype:

extern void identifier(void);

The interface tool will generate a warning if the task's function is repeated in another task compound statement. It is the responsibility of the application to ensure that the C function is re-entrant.

3

The optional trigger assignment statement identifies the cause for making the task ready to run. The trigger-type can be one of:

  • periodic — meaning the task is made ready to run some many milliseconds since the last time it was made ready to run.

  • tdc-firing — meaning the task is made ready to run per TDC-calculation cylinder event (see Section 6.2.3, “Cylinder TDC-calculation application events” for more).

  • crank-sync-point-n — meaning the task is made ready to run on each successfully decoded crankshaft trigger wheel sync point (see Section 6.1.2.2, “Crank wheel sync points” for more). The use of n denotes an integer, where 1 represents the primary crank wheel, and 2 through 5 represents the first to the fourth secondard crank wheel in sequential order.

If the task is specified as periodic, then the period assignment statement must also be specified.

4

The required priority assignment statement specifies the priority of this application task relative to other application tasks. The higher the value of the task's priority statement, the higher priority the task has relative to others.

The application tasks fit into a larger priority ordering as given in Section 4.6.4, “Application and library tasks”. The integer must positive.

The value of the task priority must not be repeated in another task compound statement.

5

The optional period assignment statement specifies the period of the task in milliseconds. The library will make the task ready to run every period millisecond.

If the task trigger is specified as tdc-firing or crank-sync-point-n, then the period statement must not be specified.

The integer must be in the range [1, 3600000] milliseconds.

6

The optional offset assignment statement specifies the offset to the task's period in milliseconds. The library will delay the first time the task is made ready to run by offset milliseconds.

The integer must be positive.

If the offset assignment statement isn't given then the interface tool sets the task's offset to zero milliseconds.

The interface tool will generate a warning message if the task's offset is more than twice the task's period in case the offset was mis-specified.

8.1.4.11. Compound statement: resource

The optional resource compound statement, which can be repeated, can contain the following statements:

resource
{
    name = identifier; 1
    used-by-task task-list; 2
}

1

The required name assignment statement gives a name to this resource, which can then be referenced by other parts of the interface file and in the application code.

The resource's name must not be repeated in another resource compound statement.

2

The required used-by-task assignment statement identifies the tasks which use this resource. The task-list must be the name of one task, or the names of multiple tasks separated by commas. The library will record a fault if any task which was not in the list tried to claim the resource.

8.1.4.12. Compound statement: nonvolatile-filesystem

The optional nonvolatile-filesystem compound statement can contain the following statements:

nonvolatile-filesystem
{
    write-queue-size          = integer; 1
    max-num-of-user-files     = integer; 2
    max-num-of-platform-files = integer; 3
}

1

The write-queue-size assignment statement identifies the maximum number of files allowed in the write queue.

2

The max-num-of-user-files assignment statement identifies the maximum number of user files that can to be stored.

3

The max-num-of-platform-files assignment statement identifies the maximum number of platform files that can to be stored.

The interface tool will set this value to a minimum value if the user specifies a number less than that. If the freeze frame feature is supported, this minimum value is 10 plus the sum of the maximum number of freeze frames that may be stored for each freeze frame type: ISO, J1939 DM4 and J1939 DM25. If the freeze frame feature is not supported, the minimum value is 10.

8.1.4.13.  Compound statement: memory-config

The optional memory-config compound statement can contain the following statement:

memory-config
{
    config-id  = identifier; 1
}

1

The required config-id assignment statement identifies the memory configuration to be used. The different memory configurations are designated by a letter, and should be written in the format config-a for configuration A, and so on. See Appendix D, Memory configurations for details of the memory configurations available for different targets.

Note

Different linker files are required for different memory configurations. See --output-linker-file=FILE for a command line option that generates the correct linker file automatically based on the config-id identifier and other information gleaned from the interface file.

8.1.4.14. Compound statement: can-messaging

The optional can-messaging compound statement can contain the following statements:

can-messaging
{
    number-of-receive-messages  = integer; 1
    number-of-transmit-messages = integer;
}

1

The optional number-of-receive-messages and number-of-transmit-messages assignment statements identify the number of receive and transmit messages the library will handle (see Section 5.15, “CAN messaging feature (PCX)” for more).

The interface tool will adjust the number of receive and transmit messages given here if CCP and J1939 messaging requires additional messages.

The integer for each statement must be in the range [0, 100].

If the number-of-receive-messages assignment statement is not given then the interface tool assumes zero receive messages. Similarly for the number of transmit messages.

8.1.4.15. Compound statement: ccp-messaging

The optional ccp-messaging compound statement can contain the following statements:

ccp-messaging
{
    enabled-during-application-mode = boolean; 1

    cro             = integer; 2
    cro-ext-id      = boolean;
    dto             = integer;
    dto-ext-id      = boolean;

    station-address = integer; 3

    can-bus         = integer; 4
    baud            = integer; 5

    raster { ... } 6

    security-dev-mode = boolean; 7

    security { ... } 8
}

1

The optional enabled-during-application-mode assignment statement identifies whether CCP communications is enabled during application mode or not (see Section 4.3, “System modes” for more on system modes and Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)” for more on CCP).

If the enabled-during-application-mode statement is not given then the interface tool assumes CCP is enabled during application mode.

2

The optional cro and dto assignment statements identify the CAN identifiers to be used for CCP communication with the PC based tool (see Section 5.16.1.1, “Messaging”).

The integer for each statement must be in the range [0, 2047] (or the range [0, 536870911] when in extended ID mode). The integers must not be equal.

If the cro assignment statement is not given then the interface tool assumes a CAN identifier of 1785. If the dto assignment statement is not given then the interface tool assumes a CAN identifier of 1784. The values match the default CCP settings (Table 4.2, “CCP defaults”).

The optional cro-ext-id and dto-ext-id assignment statements configure the cro and dto to use extened 29 bit identifiers, respectively. If either of these values are not provided, they will default to false.

3

The optional station-address assignment statement identifies the CCP station address of the ECU. Multiple ECUs can use the same CRO and DTO CAN identifiers so long as each has a unique station address.

The integer value of the statement must be in the range [0, 255].

If the station-address assignment statement is not given then the interface tool assumes a value of zero (matching the default CCP settings from Table 4.2, “CCP defaults”).

4

The optional can-bus assignment statement identifies the CAN bus to use for CCP messaging.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 8.1.4.7, “Compound statement: target-ecu”).

If the can-bus assignment statement is not given then the interface tool assumes the first CAN bus will be used.

5

The optional baud assignment statement identifies the baud rate in kBps of the CAN bus to use for CCP messaging during reprogramming mode. The baud rate of the CAN bus during application mode is controlled by the application code.

The integer for the statement must be one of: 1000, 500, 250, 125, 100, 83 (corresponding to 83.333 kBps), 62 (corresponding to 62.5 kBps), 50, 33 (corresponding to 33.333 kBps).

If the baud assignment statement is not given then the interface tool assumes a baud rate of 500 kBps.

6

The optional raster compound statement allows the application to vary the size and transmission rate of ECU DAQ rasters.

Note

If there are no raster statements then the following default configuration is applied.

M110, M220,
M221, M250,
M460, M461
M670
Rate (milliseconds)SizeSize
101530
1001530
2001530
10001530

7

The security-dev-mode statement specifies whether the reprogramming security function is in development. This statement is optional and defaults to false. If the statement is present and assigned a value of true, then all CCP security functions will be ignored by the firmware when the ECU is power cycled with the FEPS voltage applied.

This statement allows a security algorithm to be tested without the risk of putting the ECU in a state where it cannot be reprogrammed. Otherwise, an error in the security algorithm will necessitate returning the ECU to Pi for servicing.

8

The optional security compound statement specifies the security required to carry out CCP actions. Permission to carry out CCP actions is known in CCP terminology as privilege levels. Current CCP privilege levels are calibration, data acquisition and programming. This statement may appear more than once to configure security separately for each privilege level. If security is not explicitly specified for a privilege level, that privilege level defaults to requiring no security (and therefore if this statement is never used then no CCP actions will require security).

No checks are carried out to ensure that the same CCP privilege level is not specified in more than one security statement. If this occurs, the application will only use the details from the first security statement encountered which specifies the required privilege level. It will ignore any subsequent security statements.

8.1.4.16. Compound statement: raster

The optional raster compound statement can contain the following statements:

raster
{
    name        = string; 1
    description = string; 2
    size        = integer; 3
    rate        = integer; 4
}

1

The required name assignment statement is a unique name for the CCP DAQ raster. The name is written to the ASAP2 file and used by the calibration tool to identify the raster.

2

The required desc assignment statement is a description of the CCP DAQ raster's use.

3

The required size assignment statement gives the number of ODTs for the CCP DAQ raster. The total number of ODTs across raster statements must not exceed the range given below. For instance, on the M670, it is permissible to have two raster statements each with a size of 127. But adding a third raster statement with a size of 1 brings the total to 255, which exceeds the limit.

Range: [1, 254]

4

The required rate assignment statement is the suggested period between transmission of the CCP DAQ raster. Some calibration tools will use the suggested period (e.g., INCA) whilst other calibration tools will ignore the suggest period and allow the user to vary the transmission rate on the fly (e.g., Vision). One of 0.005, 0.010, 0.030, 0.050, 0.100, 0.200, 0.500, 1.000 seconds.

8.1.4.17. Compound statement: security

The optional security compound statement can contain the following statements:

security
{
    privilege-level              = identifiers; 1
    security-required            = boolean; 2
    ecu-seed-generation-function = string; 3
    ecu-key-validation-function  = string; 4
    asap-dll-file                = string; 5
    asap-key-generation-function = string; 6
}

1

The privilege-level statement specifies the privilege level(s) for which the following security specifiers are to be applied. This is a comma-separated list of one or more of the following:

Table 8.1. CCP privilege levels

Privilege levels
calibration
data_acquisition
programming


If a security statement exists, a privilege-level statement is compulsory within that security statement.

2

The security-required statement specifies whether security is required for the specified privilege level(s). This must be set to False if no security is required for a privilege level, or to True if security is required.

If a security statement exists, a security-required statement is compulsory within that security statement.

3

The ecu-seed-generation-function statement identifies the C function which will be called when a seed is requested for unlocking the specified privilege level. This is optional; if omitted, the platform will automatically generate a random 32-bit seed value.

If specified, the application must implement the C function, to match the prototype defined by PCP_SEED_GENERATOR_T. See Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for further details relating to how these functions must be implemented.

4

The ecu-key-validation-function statement identifies the C function which will be called when a key is passed to attempt to unlock the specified privilege level. If security-required has been set to True for this privilege level, a key validation function must be specified, otherwise an error will be reported.

If specified, the application must implement the C function, to match the prototype defined by PCP_KEY_VALIDATOR_T. See Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for further details relating to how these functions must be implemented.

5

The asap-dll-file statement identifies the ASAP1-standard DLL which will be used by the calibration tool to provide the key generation function for the specified privilege level. This is optional, and is used only when generating ASAP2 files for use by the calibration tool. If the user does not require ASAP2 files, or if the user will be configuring the calibration tool by hand to identify this DLL, it may be omitted.

6

The asap-key-generation-function statement identifies the C function within the above DLL which will be used by the calibration tool to provide key generation for the specified privilege level. This is optional. ASAP1 specifies that the function name must be ASAP1A_CCP_ComputeKeyFromSeed, and this function name will be used as the default if the statement is omitted.

The ability to specify this function name is currently only supported by the ATI Vision calibration tool. This option should therefore be used with caution in case support for other calibration tools is required.

8.1.4.18. Compound statement: iso-diagnostics

The optional iso-diagnostics compound statement can contain the following statements:

iso-diagnostics
{
    can-bus = integer; 1

    can-rx-id      = integer; 2
    can-func-rx-id = integer;
    can-tx-id      = integer;

    can-rx-id-extd = true or false; 3
    can-tx-id-extd = true or false;

    size-of-rx-buffer = integer; 4
    size-of-tx-buffer = integer;

    emissions-report-min-severity =  emissions-severity; 5

    general-callback =  true or false; 6
    id-request-callback = true or false; 7

    use-security-fn = true or false; 8

    flash-allowed = without-security, any-security-level, specified-security-levels or never; 9
    flash-security-levels = integer or comma-separated list of integers; 10

    mem-read-allowed = without-security, any-security-level, specified-security-levels or never; 11
    mem-read-security-levels = integer or comma-separated list of integers; 12

    max-num-of-uds-periodic-id = integer; 13
    uds-periodic-id-base-period-ms = integer; 14
    max-num-of-uds-dynamically-defined-id = integer; 15

    active-session-iso-16bit-id = integer; 16
    active-session-kwp-8bit-id = integer; 17

    mem-read-ok-def-session = true or false;  18
    mem-read-ok-extd-session = true or false;
    mem-read-ok-prog-session = true or false;

    service-03-dtcs = no-override | report-active-and-prev-active; 19
    service-07-dtcs = no-override | report-pending-and-active; 20
    service-0a-dtcs = no-override | report-active-and-prev-active; 21

    extd-data-dc-since-failed-rec-num = none | integer; 22
    extd-data-failed-dc-count-rec-num = none | integer;
    extd-data-occurrence-count-rec-num = none | integer;
    extd-data-time-active-rec-num = none | integer;
    extd-data-time-prev-active-rec-num = none | integer;
    extd-data-time-until-derate-rec-num = none | integer;
    extd-data-wu-since-failed-rec-num = none | integer;
    extd-data-time-engine-running-rec-num = none | integer;

}

1

The optional can-bus assignment statement identifies the CAN bus to use for ISO diagnostics.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 8.1.4.7, “Compound statement: target-ecu”). The baud rate of the CAN bus is specified by the application code.

If the can-bus assignment statement is not given then the interface tool assumes the first CAN bus will be used.

2

The required can-rx-id, can-func-rx-id and can-tx-id assignment statements identify the CAN identifiers to be used for ISO diagnostic communications with the external tool.

The integer for each statement must be in the range [0, 2047] for standard (11 bit) CAN identifiers or [0,536870911] for extended (29 bit) CAN identifiers. The integers must not be equal.

If these statements are not present, then ISO diagnostic support is disabled.

3

The optional can-rx-id-extd and can-tx-id-extd assignment statements specify whether extended (29 bit) format CAN identifiers are to be used instead of the default 11 bit format identifiers for ISO diagnostic communications. It is possible to transmit using an 11 bit identifier and receive using a 29 bit identifier and vice versa.

Allowed values are true or false.

4

The optional size-of-rx-buffer and size-of-tx-buffer assignment statements specify how large (in bytes) the space reserved for the longest diagnostic request message and response message respectively. If omitted, a default is used.

The integer for each statement must be in the range [1, 4095].

Applications which need to support the transmission of a long list of supported DTCs will need a large transmit buffer. Applications which need to accept a long series of inputOutputControlByIdentifier bytes to override a PID value will need a large receive buffer. Otherwise, smaller values can be used to save RAM.

5

The optional emissions-report-min-severity assignment statement specifies the severity level at (or above) which DTCs will be reported by J1939/DM32 and all J1979/ISO 15031 emissions-related services.

The value of emissions-severity must be one of sev-a (highest), sev-b1, sev-b2, sev-c, or sev-none (lowest). If omitted, sev-c is used by default. To emit all DTCs regardless of their emissions severity level, use sev-none.

6

The optional general-callback statement specifies whether the application is providing a callback function (which must be named psc_diag_general_callback) to handle custom processing of diagnostic message responses. For details see type PDG_GENERAL_CALLBACK_FN_T.

If omitted, a default of false is used.

7

The optional id-request-callback statement specifies whether the application is providing a callback function (which must be named psc_diag_id_request_callback) to handle custom generation of PID values on request. For details see type PDG_ID_REQUEST_CALLBACK_FN_T.

If omitted, a default of false is used.

8

The optional use-security-fn statement specifies whether the application is providing a custom security algorithm to handle seed generation and key validation via the SecurityAccess ($27) service. Whether security has passed can then be used to control access to sensitive services such as flash reprogramming or ReadMemoryByAddress.

If used the function must be named psc_diag_security_callback and be followed immediately by a function named psc_diag_security_end. See types PDG_SECURITY_CALLBACK_FN_T and PDG_SECURITY_END_FN_T for more details. Also, an example function is provided below in this section.

If omitted, a default of false is used.

9

The optional flash-allowed statement specifies the circumstances under which ISO 14229-1 (UDS) flash reprogramming is allowed by your application. This setting is stored in non-volatile memory and applies even after the current application is erased, until replaced by a new application with its own setting.

The options are as follows:

without-security

Always allowed, and no SecurityAccess exchange is required first.

any-security-level

Allowed if a SecurityAccess seed-key exchange has been passed successfully, but it does not matter which security level (LEV_SAT_RSD in the UDS standard) was negotiated.

specified-security-levels

Only allowed if a SecurityAccess seed-key exchange has been passed successfully, and the security level (LEV_SAT_RSD in the UDS standard) was negotiated is one specified in the list (flash-security-levels option).

never

Never allowed, regardless of SecurityAccess exchanges.

For selective run-time control of UDS reprogramming, see also pdg_inhibit_reprogramming().

If omitted, a default of never is normally used. However, if the deprecated allow-reflash = true option is used, use-security-fn = true implies any-security-level and use-security-fn = false implies without-security.

10

The optional flash-security-levels statement is only relevant if flash-allowed = specified-security-levels has been specified. Specify one or more values of the seed-key security level (LEV_SAT_RSD in the UDS standard) at which flash programming should be permitted. The levels must be odd values as used in the requestSeed request. (The corresponding level in the sendKey message is an even number equal to LEV_SAT_RSD + 1.)

Range: [1, 125]

11

The optional mem-read-allowed statement is very similar to the flash-allowed option described in detail above, but this time controls access to ECU memory via the ReadMemoryByAddress service ($23).

The deprecated option mem-read-needs-security is still supported for backwards compatibility; true implies any-security-level and false implies without-security.

Otherwise, if not specified, a default of never is assumed.

12

The optional mem-read-security-levels statement is very similar to the flash-security-levels statement described in detail above, but this time relevant to ReadMemoryByAddress.

The deprecated mem-read-needs-security option maps to without-security if set false or any-security-level if set true.

13

PIDs for automatic periodic sending must be in the 0xF2nn identifier range. Of those, the optional max-num-of-uds-periodic-id parameter is the maximum number that the platform will allow to be simultaneously requested by the test tool for automatic periodic transmission while the application is running via UDS service $2A.

If omitted, this defaults to zero.

The integer for this statement must be in the range [0, 254].

14

The optional uds-periodic-id-base-period-ms parameter is the "fast" target rate for PIDs requested for automatic transmission via UDS service $2A in milliseconds. The "medium" rate is 2x this period, and the "slow" rate is 4x this period. The platform will send PIDs more slowly than the target rate if this target cannot be met due to the PID size and transport protocol delays.

The integer for this statement must be in the range [20, 65530].

15

The optional max-num-of-uds-dynamically-defined-id parameter defines the number of internal buffer slots allocated for the construction of dynamically-defined PIDs via UDS service $2C. If necessary one large PID definition may straddle several internal buffers.

If omitted, this defaults to zero.

The integer for this statement must be in the range [0, 255].

16

The optional active-session-iso-16bit-id assignment statement, if used, defines a PID which will be emitted in response to a ReadDataBy[Common]Identifier (service $22) request in both application mode and during reprogramming (boot loader mode).

The value emitted identifies the active diagnostic session using the same values as the pdg_get_active_session_type() function.

The integer for this statement must be in the range [0, 65535].

17

The optional active-session-kwp-8bit-id assignment statement, if used, similarly defines a Keyword Protocol 2000-3 LocalIdentifier which will be emitted in response to a ReadDataByLocalIdentifier (service $21) request to indicate the current session type.

The integer for this statement must be in the range [0, 255].

18

The optional mem-read-ok-def-session, mem-read-ok-extd-session and mem-read-ok-prog-session assignment statements control whether the ReadMemoryByAddress (service $23) service is permitted in the default, extended and programming session respectively. As this service permits access to the code and calibration areas of memory, it is disabled in all session types by default.

19

The optional service-03-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Active DTCs (service $03) request. If omitted, no override of the standard J1979 service $03 response will be applied.

The value for this statement must be one of no-override (default) or report-active-and-prev-active (transmit Active and Previously Active DTCs).

20

The optional service-07-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Pending DTCs (service $07) request. If omitted, no override of the standard J1979 service $07 response will be applied.

The value for this statement must be one of no-override (default) or report-pending-and-active (transmit Pending and Active DTCs).

21

The optional service-0a-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Active DTCs with Permanent Status (service $0A) request. If omitted, no override of the standard J1979 service $0A response will be applied.

The value for this statement must be one of no-override (default) or report-active-and-prev-active (transmit Active and Previously Active DTCs).

22

The optional DTC extended data record assignment statements, if used, define the extended data record numbers to be applied to the response of a read DTC information (service $19) request to read DTC extended data (sub-function $06).

extd-data-dc-since-failed-rec-num

The specified record number reports the one byte record containing the number of drive cycles since the last test failure. The record is only available when the DTC is active.

extd-data-failed-dc-count-rec-num

The specified record number reports the one byte record containing the number of drive cycles in which the test has failed. The record is only available when the DTC is pending.

extd-data-occurrence-count-rec-num

The specified record number reports the one byte record containing the DTC occurrence count.

extd-data-time-active-rec-num

The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the DTC has been in the active state.

extd-data-time-engine-running-rec-num

The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the engine has been running while the DTC's fault has not been present and the DTC has been in the 'active' or 'previously active' state.

extd-data-time-prev-active-rec-num

The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the DTC has been in the previously active state.

extd-data-time-until-derate-rec-num

The specified record number reports the two byte record containing total time (resolution 1min/bit) left until derate will occur. The record is only available while the DTC is in the active state and the DTC attribute 'has-torque-derate' is true.

extd-data-wu-since-failed-rec-num

The specified record number reports the two byte record containing the number of warm-up cycles in which the fault is not present. It is reset upon the DTC state transition to previously active.

The values used for these statements must be none (default) or an integer in the range [1,239]

8.1.4.18.1. Notes on seed-key function

You must implement your own security function to use seed-key security; it is not supplied by Pi Innovo, because it will be specific and confidential to you. The function must be written such that it does not depend on any statically allocated variables and does not call any functions, including functions inserted by the compiler for math utilities for example. This is to ensure that it is fully relocatable, which is required for it to run as part of the boot loader in reprogramming mode, as well as in normal application mode.

Your algorithm may be implemented in C for compilation during your application build. It does not matter which source file it is in.

Alternatively, you can compile your C code to make an object (.o) file and link it with the other object files generated in your build. This is useful if you wish to be cautious with confidentiality by avoiding application-builders needing to have the C source code available.

The function name for the security algorithm and the second empty function that marks the end of it are fixed. If they are missing, a linker error will be reported. A complete example block of code is presented below, in which the "secret" algorithm is to reverse the order of the two seed bytes to form the correct key:

#include "openecu.h"


/*****************************************************************************
 *  Purpose: Called by the library when UDS/KW2000 diagnostic security access
 *           is required.
 *  Returns: Return code to send to tool on error, otherwise zero if OK.
 *  Notes:   Code is copied to nonvolatile memory and must be relocatable. It
 *           must not call any functions (including compiler arithmetic
 *           utilities).
 *****************************************************************************
 */
U8 psc_diag_security_callback
(
    const U8*  pdgf_request_message,      /* The received unpacked request message */
    U16        pdgf_request_message_len,  /* Total byte length of request message  */
    U8*        pdgf_seed_buffer,          /* Place seed here, or access it when computing correct key */
    U8*        pdgf_seed_len,             /* Specify your seed length (in bytes) here (max 8 bytes) */
    U32        pdgf_random                /* Pseudorandom number you may use to generate seed */
)
{

    if (pdgf_request_message_len < 2)
    {
        return 0x13; /* invalid length */
    }

    switch (pdgf_request_message[1])
    {
    case 0x03: /* a requestSeed value we choose to support */
        /* Set up the seed bytes, here using the provided random number */
        pdgf_seed_buffer[0] = (U8) pdgf_random & 0xff;
        pdgf_seed_buffer[1] = (U8) (pdgf_random >> 8);
        *pdgf_seed_len = 2;
        return 0;
        break;
    case 0x04: /* corresponding sendKey value */
        if ((pdgf_request_message_len == 4) &&
            (pdgf_request_message[2] == pdgf_seed_buffer[1]) &&
            (pdgf_request_message[3] == pdgf_seed_buffer[0])   )
        {
            /* security passed -- bytes reversed! */
            return 0;
        }
        else
        {
            return 0x35; /* invalid key */
        }
        break;
    default:
        return 0x12; /* unsupported parameters */
        break;
    }
}

/*****************************************************************************
 *  Purpose: Marks the end of the security function above.
 *  Returns: None.
 *  Notes:   Must be placed immediately after the security function. The
 *           platform uses this to calculate the size of the security function
 *           when relocating it to non-volatile memory for use in
 *           reprogramming mode.
 *****************************************************************************
 */
void psc_diag_security_end
(
    void
)
{
}

8.1.4.19. Compound statement: j1939-messaging

The optional j1939-messaging compound statement can contain the following statements:

j1939-messaging
{
    enabled = true or false; 1    

    size-of-message-buffer = integer; 2
    num-simultaneous-tx    = integer; 3
    num-simultaneous-rx    = integer;
    num-rx-tx              = integer; 4

    dm7-req-buf-size       = integer; 5
    multiframe-priority    = integer; 6
    
    channel { ... } 7
    pgn-receive { ... } 8
    pgn-requested { ... } 9
    aecd-data { ... } 10
}

1

The optional enabled assignment statement identifies whether J1939 communications is enabled during application mode or not (see Section 4.3, “System modes” for more on system modes and Section 5.17, “J1939 (SAE) messaging feature (PJ1939)” for more on J1939).

If the enabled statement is not given then the interface tool assumes J1939 is disabled during application mode.

2

The optional size-of-message-buffer assignment statement identifies the maximum size of any J1939 message the library will need to receive or transmit for the application. It's provided to help adjust the memory footprint of the library if necessary.

The integer for the statement must be in the range [8, 1785] bytes.

If the size-of-message-buffer assignment statement is not given then the interface tool assumes a buffer size of 1785 bytes.

3

The optional num-simultaneous-tx and num-simultaneous-rx assignment statements identify the number of simultaneous transmit and receive buffers the library will process. They statements are provided to help adjust the memory footprint of the library if necessary.

The integer for each statement must be in the range [1, 20] buffers.

If the num-simultaneous-tx statement is not given then the interface tool assumes there is one transmit buffer. Similarly for the num-simultaneous-rx statement.

4

The optional num-rx-tx assignment statement identifies the number of message buffers assigned for J1939 reception and transmission. The statement is provided to help adjust the memory footprint of the library if necessary.

The integer for the statement must be in the range [1, 100] buffers.

If the num-rx-tx assignment statement is not given then the interface tool assumes one buffer.

5

The optional dm7-req-buf-size assignment statement identifies the number of Test or SPN requests recieved via DM7 that are to be buffered/ queued.

The integer for the statement must be in the range [1, 10].

If the num-rx-tx assignment statement is not given then the interface tool assumes one test will be queued.

6

The optional multiframe-priority assignment statement allows the priority for all multi-frame J1939 diagnostic messages (DMs) to be overridden with the value provided. If this statement is absent, the priority for single-frame and multi-frame messages alike is set by the argument passed in the C-API function for that DM. (See Section 5.17.8, “Core Diagnostic messages” for information on these functions.) If this statement is present, however, that function argument only defines the priority for single-frame messages. Note that the generic PG transmit function pj1939_pdu_transmit() is unaffected by this, since it transmits only fixed length messages anyway.

The integer for the statement must be in the range [0, 7].

7

One or more channel compound statements define define a J1939 channel associated with a CAN bus. The channel statement defines the channel and its node name and address. See Section 8.1.4.20, “Compound statement: channel” for more detail.

8

The optional pgn-receive compound statement, which can be repeated, identifies a PGN that the library must receive and present to the application code. The compound statement is covered in Section 8.1.4.21, “Compound statement: pgn_receive” in more detail.

9

The optional pgn-requested compound statement, which can be repeated, identifies a PGN that another J1939 node may request from the ECU. The library buffers the request information for these PGNs and presents the information to the application. The compound statement is covered in Section 8.1.4.22, “Compound statement: pgn_requested” in more detail.

10

The optional aecd-data compound statement, identifies the set of EI-AECDs that the application supports. The compound statement is covered in Section 8.1.4.23, “Compound statement: aecd-data” in more detail.

8.1.4.20. Compound statement: channel

The required channel compound statements contain the following statements:

channel
{
    channel-id              = integer; 1
    
    can-bus                 = integer; 2
    
    address                 = integer; 3

    industry-group          = integer; 4
    vehicle-system-instance = integer;
    vehicle-system          = integer;
    function                = integer;
    function-instance       = integer;
    ecu-instance            = integer;
    manufacturer-code       = integer;
    identity-number         = integer;

    listen-for-dm1-message address-list; 5
    listen-for-dm2-message address-list;
}

1

The required channel-id assignment statement assigns an index to this channel definition.

Each integer must be unique across all channel compound statements, must start at 0, and be continuously increasing integers.

2

The required can-bus assignment statement identifies the CAN bus to use for J1939 messaging.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 8.1.4.7, “Compound statement: target-ecu”). The baud rate of the CAN bus is specified by the application code.

The integer for the statement cannot be repeated in multiple channel compound statements.

3

The required address assignment statement identifies the preferred network address for the ECU. The library will attempt to claim this address according to SAE J1939/81.

The automatically generated calibration parameter for this is pj1939c_node_addr_0[n]. where n is the channel-id for this channel.

The integer for the statement must be in the range [0, 253].

4

The required industry-group, vehicle-system-instance, vehicle-system, function, function-instance, ecu-instance, manufacturer-code and identity-number assignment statements identify the unique 64-bit name for the ECU on the J1939 network for this channel.

The acceptable value range of each statement is given in Table 8.2, “Value ranges for J1939 name statements”.

Table 8.2. Value ranges for J1939 name statements

StatementRange
industry-group[0, 7]
vehicle-system-instance[0, 15]
vehicle-system[0, 127]
function[0, 255]
function-instance[0, 31]
ecu-instance[0, 7]
manufacturer-code[0, 2047]
identity-number[0, 2097151]

5

The optional listen-for-dm1-message and listen-for-dm2-message assignment statements identify the addresses of J1939 nodes which transmit DM1 and DM2 messages that the library must receive for the application on this channel. In each statement, the address-list must be a single address, or set of addresses separated by a comma.

The address-list values for the statement must be in the range [0, 253].

If the listen-for-dm1-message statement is not given then the interface tool assumes an empty list of addresses. Similarly for the listen-for-dm2-message statement.

8.1.4.21. Compound statement: pgn_receive

The optional pgn_receive compound statement, which can be repeated, can contain the following statements:

pgn_receive
{
    pdu-datapage = integer; 1
    pdu-format   = integer;
    pdu-specific = integer;

    size         = integer; 2
}

1

The required pdu-datapage, pdu-format and pdu-specific assignment statements identify the 17-bit parameter group number for the J1939 message the library will receive and buffer for the application.

The acceptable value range of each statement is given in Table 8.3, “Value ranges for J1939 PDUs”.

Table 8.3. Value ranges for J1939 PDUs

StatementRange
pdu-datapage[0, 1]
pdu-format[0, 255]
pdu-specific[0, 255]

The PDU of the message must not be repeated in another pgn-receive compound statement.

The pdu-specific value must be zero if the pdu-format value is less than 240.

2

The required size assignment statement identifies the expected length of the PG message.

The integer for the statement must be in the range [0, size-of-message-buffer], where size-of-message-buffer is specified in the j1939-messaging compound statement (see Section 8.1.4.19, “Compound statement: j1939-messaging”).

8.1.4.22. Compound statement: pgn_requested

The optional pgn_requested compound statement, which can be repeated, can contain the following statements:

pgn_requested
{
    pdu-datapage = integer; 1
    pdu-format   = integer;
    pdu-specific = integer;
}

1

The required pdu-datapage, pdu-format and pdu-specific assignment statements identify the 17-bit parameter group number for the J1939 message the library will note as being requested for the application.

The acceptable value range of each statement is given in Table 8.3, “Value ranges for J1939 PDUs”.

The PDU of the message must not be repeated in another pgn-requested compound statement.

The pdu-specific value must be zero if the pdu-format value is less than 240.

8.1.4.23. Compound statement: aecd-data

The optional aecd-data compound statement can contain the following statements:

aecd-data
{
    aecd { ... } 1
    aecd { ... }
}

1

Each aecd compound statement identifies an Emission Increasing Auxiliary Emission Control Device (EI-AECD). The compound statement is covered in Section 8.1.4.24, “Compound statement: aecd” in more detail.

8.1.4.24. Compound statement: aecd

The aecd compound statement, which can be repeated, can contain the following statements:

aecd
{
    name = identifier; 1
    aecd-number = integer; 2
}

1

The required name assignment statement identifies the AECD uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the AECD.

An error is raised if a duplicate AECD name is found.

2

The required aecd-number assignment statement identifies the AECD number uniquely.

An error is raised if a duplicate AECD number is found.

8.1.4.25. Compound statement: ff-data

The optional ff-data compound statement can contain the following statements:

ff-data
{
    nvm-allocation-bytes = integer; 1
    ram-allocation-bytes = integer; 2
    max-num-of-j1979-ff = integer; 3
    max-num-of-j1939-dm4-ff = integer; 4
    max-num-of-j1939-dm25-ff = integer; 5
    max-num-of-uds-snapshot-ff = integer; 6
    num-of-j1939-dm25-ff-spns = integer; 7
    j1939-dm25-ff-name = identifier; 8
    ff-store-by-dtc-severity = true or false; 9

    freeze-frame { ... } 10
    freeze-frame { ... }
}

1

The required nvm-allocation-bytes assignment statement specifies the total number of bytes allocated to freeze frame storage in non-volatile memory.

Each freeze frame is stored in a separate file using the PFS file system. In addition to the stored freeze frame data, there is a maximum of 27 bytes of overhead associated with each stored file. This overhead contributes to the freeze frame allocation in NVM.

An appropriate NVM limit should be selected to meet the needs of the application taking into consideration freeze frame file sizes and the number of freeze frames that may be stored. A description of the data stored for each freeze frame type is provided in Section 7.7.4, “Freeze Frame feature (PFF)”.

The integer for the statement must be in the range [0, 65535] bytes.

2

The required ram-allocation-bytes assignment statement specifies the size (in bytes) of a RAM buffer used to hold snapshots of freeze frames prior to writing to non-volatile memory.

In addition to the freeze frame data, for each freeze frame held in this buffer an additional 4 bytes of information is also held for the purpose of file storage. Thus, when setting the size of the freeze frame RAM buffer, it must at least be equal to the size of the largest freeze frame's data (in bytes) plus 4 bytes. If multiple freeze frames are to be captured on activation of the same DTC then the buffer must be large enough to hold the freeze frame data of all the DTC's associated freeze frames, plus storage data for each. The RAM allocation should also be enough to take immediate snapshots of all possible freeze frames associated with all DTCs that may occur in very quick succession; so no information is lost while the data is then written to NVM (which happens within a few seconds).

Note: freeze frames are stored at the rate of 8 bytes every 10 ms and freeze frame data is only removed from the buffer once it has been successfully stored in NVM. As a result, if multiple DTCs become active in quick succession, the buffer may become filled and the data of subsequent freeze frames may be lost. In this case, the likelihood of a particular DTCs freeze frame being captured will not just depend upon the order in which each fault actually occurred, but also on the rate at which the application processes each of the DTCs in question.

The integer for the statement must be in the range [0, 8191] bytes.

3

The optional max-num-of-j1979-ff assignment statement specifies the upper limit to the number of J1979 freeze frame instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 254].

4

The optional max-num-of-j1939-dm4-ff assignment statement specifies the upper limit to the number of J1939 DM4 freeze frame instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 137].

5

The optional max-num-of-j1939-dm25-ff assignment statement specifies the upper limit to the number of J1939 expanded freeze frame (DM25) instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 254].

6

The optional max-num-of-uds-snapshot-ff assignment statement specifies the upper limit to the number of ISO 14229-1 (UDS) snapshot instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 254].

7

The optional num-of-j1939-dm25-ff-spns assignment statement specifies the number of SPNs that will be included in a J1939 expanded freeze frame (DM25).

The integer for the statement must be in the range [0, 255].

8

The optional j1939-dm25-ff-name assignment statement identifies the calibration vector used to define the the SPNs that are included in a J1939 expanded freeze frame (DM25).

The string identifier must follow the naming convention defined in Section 8.1.5.2, “DDE naming rules (prefix_style)”.

9

The optional ff-store-by-dtc-severity assignment statement specifies if freeze frames corresponding to DTCs of lower emissions severity must be deleted in order to make space for latest freeze frames of higher severity.

When set to true the platform shall attempt to delete freeze frames corresponding to DTCs of lower emissions severity in order to make space for latest freeze frames of higher severity. If omitted or set to false, latest freeze frames will be discarded if there is no space to store them.

10

The optional freeze-frame compound statement groups information about freeze frames. This compound statement is covered in Section 8.1.4.26, “Compound statement: freeze-frame” in more detail.

Note: prior to flashing a module after changing any of the above parameters, all DTCs must first be cleared. This will result in all freeze frame data being deleted. This is because freeze frame data is not deleted as a result of re-flashing the module. This means that the stored freeze frame data from a previous version of the application code may negatively affect the operation of freeze frames in the new version of the code, for example by taking up space in NVM.

8.1.4.26. Compound statement: freeze-frame

The optional freeze-frame compound statement, which can be repeated, can contain the following statements:

freeze-frame
{
    name = identifier; 1
    protocol <diagnostic standard> 2 { ... } 3
    protocol <diagnostic standard> { ... }
    protocol <diagnostic standard> { ... }
}

1

The required name assignment statement identifies a 'set' of freeze frames uniquely at the application code level. A PFF_FF_CONST_T data structure identified using this name is provided to the application. The code identifier consists of the name prefixed with "pff_".

A freeze frame 'set' may contain 1 to 4 freeze frames. Each freeze frame in a set must be of a different type, e.g. J1979, UDS snapshot, J1939-DM4 or J1939-DM25.

2

The placeholder <diagnostic standard> identifies the diagnostic standard that a freeze frame in the set adheres to. Replace <diagnostic standard> with one of the supported standards which are:

  • j1979
  • j1939
  • uds

Specifying a diagnostic standard is a required statement.

3

The protocol compound statement groups information about a freeze frame. This compound statement is covered in Section 8.1.4.27, “Compound statement: protocol” in more detail.

8.1.4.27. Compound statement: protocol

The protocol compound statement can contain the following statements:

protocol <diagnostic standard>
{
    type = <freeze frame type>; 1
    dde-entry = vector; 2
    length = integer; 3
}

1

Some diagnostic standards may support multiple types of freeze frame. The J1939 diagnostic standard supports two types of freeze frame: Freeze Frame Parameters (DM4) and Expanded Freeze Frames (DM25). The placeholder <freeze frame type> identifies the freeze frame type within a diagnostic standard which the freeze frame adheres to. Replace <freeze frame type> with one of the supported freeze frame types which are:

  • dm4
  • dm25

The platform currently supports a single UDS freeze frame type, but the type identifier is required to promote application compatibility with future versions of the platform. Supported UDS freeze frame types:

  • snapshot

Specifying a freeze frame type is only required for J1939 and UDS. It should be omitted for J1979.

2

The required dde-entry assignment statement identifies the vector entry in the DDE (see Section 8.1.5, “DDE specification”) which lists the parameter identifiers. Using a calibration vector allows the parameters in the list to be re-calibrated at run-time.

The calibration vector must contain U8s for J1979 freeze frames U16s for UDS snapshot freeze frames and U32s for J1939 DM4 freeze frames.

This field is not required for DM25, as DM25 requires only one list.

3

The required length assignment statement identifies the number of parameters in the parameter list. This has a maximum value of 255.

This field is not required for DM25.

8.1.4.28. Compound statement: dtc-data

The optional dtc-data compound statement can contain the following statements:

dtc-data
{
    storage = storage-type; 1
    dtc-lamp-state-priority = lamp-priority-type; 2
    dtc-transition-prev-active-to-pending = boolean; 3
    table identifier; 4

    dtc { ... } 5

    dtc-j1939 { ... } 6

}

1

The required storage assignment statement identifies what memory device will be used to store diagnostic trouble code information across power cycles. See Section A.1, “ECU hardware reference documentation” for which memory types are supported for each target ECU.

The value of storage-type must be battery-backed-ram or flash.

2

The optional dtc-lamp-state-priority assignment statement specifies the priority scheme that will be used to calculate the desired state for each lamp when multiple DTCs are active which each require a different state for a lamp. Lamp states are prioritised so that the highest-priority state is selected as the desired state for the lamp.

The value of dtc-lamp-state-priority must be on-fast-slow-off or fast-slow-on-off. If this statement is omitted, on-fast-slow-off is selected by default. The priority scheme on-fast-slow-off selects continuous-on as the highest-priority state, followed by fast flash, followed by slow flash, followed by off. The priority scheme fast-slow-on-off selects fast flash as the highest-priority state, followed by slow flash, followed by continuous-on, followed by off.

Note that if fast-slow-on-off is selected, care must be taken when configuring desired lamp states for each DTC to ensure that MIL behaviour remains compatible with relevant OBD regulations. CARB requires that emissions-related DTCs set the MIL continuous-on during a drive cycle, for instance, meaning that DTCs should only be allowed to flash the MIL if the fault prevents the engine running and hence a drive cycle being started.

3

The optional transition-prev-active-to-pending assignment statement specifies whether faults that recur when a DTC is the "previously active" state should cause the DTC to return to "pending" state (if true) or "active" state (if false). See DTC state transition diagrams for further details.

If this statement is omitted, true is selected by default.

4

The optional table assignment statement, which can be repeated, identifies a table for grouping DTCs together.

The statement's identifier must not be repeated in other table statements.

5

The optional dtc compound statement identifies a diagnostic trouble code and assigns the DTC to a table. The same DTC can be reported over J1939, ISO diagnostics, or both. The compound statement is covered in Section 8.1.4.29, “Compound statement: dtc (or alternatively dtc-j1939)” in more detail.

6

The optional dtc-j1939 compound statement is an alternative name for dtc retained for backwards compatibility. The compound statement is covered in Section 8.1.4.29, “Compound statement: dtc (or alternatively dtc-j1939)” in more detail.

8.1.4.29. Compound statement: dtc (or alternatively dtc-j1939)

The optional dtc (or dtc-j1939) compound statement, which can be repeated, can contain the following statements:

dtc
{
    name  = identifier; 1
    table = identifier; 2

    spn = integer; 3
    fmi = integer;
    cm  = integer;

    iso_16bit-id = integer; 4

    emissions-severity = emissions-severity;  5
    uds-severity = uds-severity;  6

    lamps-to-be-set = hexadecimal value;  7
    permanent-storage = boolean;  8
    use-conditions-to-clear-perm = boolean;  9
    dc-count-limit = integer;  10
    error-free-dc-limit = integer | never;  11
    self-heal-wup-limit = integer | never;  12
    fault-symptom = integer;  13
    non-erasable = boolean;  14
    reg-exh-emission-lvl-exceedance = boolean;  15
    has-torque-derate = boolean;  16
    time-to-derate = integer;  17
    time-to-deactivate = integer | never;  18
    time-to-clear = integer | never;  19
    freeze-frame-name = identifier; 20
  }

1

The required name assignment statement identifies the diagnostic trouble code uniquely at the application code level.

The statement's identifier must have been specified as a table in the dtc-data compound statement (see Section 8.1.4.28, “Compound statement: dtc-data”).

2

The required table assignment statement, identifies the table group for this DTC.

The statement's identifier must have been specified as a table in the dtc-data compound statement (see Section 8.1.4.28, “Compound statement: dtc-data”). Tables are provided for convenient application management of groups of DTCs.

3

The optional spn, fmi and cm assignment statements gives the diagnostic trouble code's unique J1939 identifier. They are all required if the DTC is to be reported over J1939 but can all be omitted if the DTC is only to be reported over ISO protocols.

The acceptable value range of each statement is given in Table 8.4, “Value ranges for J1939 PDUs”.

Table 8.4. Value ranges for J1939 PDUs

StatementRange
spn[0, 524287]
fmi[0, 31]
cm[0, 1]

4

The optional iso-16bit-id assignment statement gives the diagnostic trouble code's unique 16-bit identifier when reported over ISO protocols (J1979, Keyword Protocol 2000-3 and UDS). This is required if the DTC is to be reported over ISO protocols but can be omitted if the DTC is only to be reported over J1939.

UDS uses 3-byte DTCs; when reported over UDS service $19, the highest byte is currently set to zero and only the lower two bytes are set according to this parameter, following the defined ISO 15031-6 reporting convention. In the future a new parameter may be introduced to specify the full 24-bit UDS DTC ID.

The acceptable value range is [0, 65535].

5

The optional emissions-severity assignment statement decides whether this DTC is reported by J1979 service $03 (request emission-related diagnostic trouble codes) and cleared by service $04 (clear/reset emission-related diagnostic information). If this DTC is of a severity as high, or higher, than that declared in the emissions-report-min-severity statement (see Section 8.1.4.18, “Compound statement: iso-diagnostics”), it is included in those emissions-related services.

In future, this may be used to decide which message(s) to include this DTC in for the World-Wide Harmonized (WWH) OBD-related services including J1939 messages DM42 to DM52.

The value of emissions-severity must be one of sev-a (highest), sev-b1, sev-b2, sev-c, or sev-none (lowest).

6

The optional uds-severity assignment statement decides which severity this DTC has for reporting in relevant UDS $19 requests.

The value of emissions-severity must be one of uds-sev-check-imm (highest), uds-sev-next-halt, uds-sev-maint-only, or uds-sev-none (lowest).

7

The optional lamps-to-be-set assignment statement gives the 8-bit lamp information associated with each of the diagnostic trouble code. This information will be used when platform is responsible for DTC state handling. The value of lamps-to-be-set will indicate which lamps should be illuminated when the corresponding DTC becomes Active.

The bit information for lamps-to-be-set is given in Table 8.5, “Bit information for the lamps to be set per DTC”.

Table 8.5. Bit information for the lamps to be set per DTC

BitsLamp Type
7-8MIL lamp
5-6Red Stop Lamp
3-4Amber Warning Lamp
1-2Protect Lamp


The two bits associated with each lamp type are used to decide the illumination type as given in Table 8.6, “Bit information per lamp type”.

Table 8.6. Bit information per lamp type

BitsIllumination type
0 0Slow Flash
0 1Fast Flash
1 0Continuous On
1 1Unavailable


The acceptable value range is [00, FF].

8

The optional permanent-storage assignment statement is used to decide if the stored Active Diagnostic Trouble Code is of type Permanent as defined by CARB. permanent-storage must be set to either false (not stored as Permanent) or true (stored as Permanent).

9

The optional use-conditions-to-clear-perm assignment statement is used to meet CARB requirements on clearing permanent DTCs. Under CARB 1971.1, a permanent DTC must not be cleared immediately on an OBD request to clear DTCs. Instead the request is stored, and section (d)(2.3.1)(C) specifies conditions which must be met before a permanent DTC may be cleared. When (or if) these conditions are met, the DTC is cleared.

If the DTC relates to a monitor which is subject to the minimum ratio requirements of 1971.1 section (d)(3.2) (e.g. catalyst, EGR system, fuel system), the DTC may be cleared at the end of the next drive cycle in which the test has run at least once and no fault is detected. For this behaviour, use-conditions-to-clear-perm must be set to false.

If the DTC relates to any other monitor, the DTC may only be cleared after the end of a drive cycle in which certain vehicle operating conditions (running time, engine speed, vehicle speed) as specified in 1971.1 section (d)(2.3.1)(C)(ii)b.3. are met, and subsequently (possibly in a later drive cycle) the test has run at least once and no fault is detected. For this behaviour, use-conditions-to-clear-perm must be set to true. Under 1971.1 section (d)(2.3.1)(C)(ii)c., manufacturers are also permitted to impose the latter conditions on all permanent DTCs (including those whose monitors are subject to minimum ratio requirements) if they wish.

If the DTC is not permanent (i.e. permanent-storage is not set to true), this statement has no effect.

Note that the conditions on clearing permanent DTCs only applies when the DTCs are Active. DTCs in Pending or Previously Active state are not affected, and will be cleared by an OBD clear request as normal.

10

The optional dc-count-limit assignment statement is used to decide the number of failed drive cycles required for a DTC in state Pending to progress to state Active. This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 255].

11

The optional error-free-dc-limit assignment statement is used to decide the number of error free drive cycles required for a DTC in state Active to progress to state Previously active/Inactive. This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 254].

This statement may also be set to "never" if the DTC is not permitted to transition to Previously Active based on the number of error free drive cycles. This is not required under CARB or Euro regulations, but may be required for manufacturer-specific DTCs.

12

The optional self-heal-wup-limit assignment statement is used to decide the number of error free warm-up cycles required for a DTC in state Previously Active/Inactive to progress to state Clear This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 254].

This statement may also be set to "never" if the DTC is not permitted to transition to Clear based on the number of error free warm-up cycles. This is required for certain classes of DTCs under Euro regulations.

13

The optional fault-symptom assignment statement is used to set the fault symptom of the DTC

The acceptable value range is [0, 15].

14

The optional non-erasable assignment statement is used to specify whether the DTC is non-erasable, as specified by Euro regulations (directive 2005-EC-78).

If a DTC is specified as non-erasable, an Active DTC may only be cleared by the self-healing process. Using a diagnostic scan tool to request that DTCs be cleared will result in an Active non-erasable DTC transitioning to Previously Active, but the DTC will remain present until cleared by self-healing.

15

The optional reg-exh-emission-lvl-exceedance assignment statement is used to decide whether the DTC is to be considered for the regulated exhaust emission level exceedance. If not specified, a default of false is assumed.

16

The optional has-torque-derate assignment statement is used to decide whether the DTC has a torque derate. If not specified, a default of false is assumed.

17

The optional time-to-derate assignment statement is used to set the time in seconds the malfunction has until derate occurs. If not specified, a default of 62.5hrs is assumed.

The acceptable value range is [0, 62.5] hours, or [0, 225000] seconds.

18

The optional time-to-deactivate assignment statement is used to set the engine running time in seconds with no fault present for a DTC in state Active to progress to state Previously Active/Inactive.

This statement may also be set to "never" if the DTC is not permitted to transition to Previously Active/Inactive based on the engine running time. Euro regulations permit this, but CARB regulations do not. If not specified, a default of "never" is assumed.

If this is enabled, the DTC will progress to state Previously Active/Inactive when sufficient drive cycles are completed without fault (see error-free-dc-limit) or sufficient engine running time elapses without fault, whichever happens first.

19

The optional time-to-clear assignment statement is used to set the engine running time in seconds with no fault present for a DTC in state Previously Active/Inactive to progress to state Clear.

This statement may also be set to "never" if the DTC is not permitted to transition to Clear based on the engine running time. Euro regulations permit this, but CARB regulations do not. If not specified, a default of "never" is assumed.

If this is enabled and transition based on warm-up cycles is also enabled (see self-heal-wup-limit), the DTC will progress to state Clear when sufficient warm-up cycles are completed without fault or sufficient engine running time elapses without fault, whichever happens first.

20

The required name assignment statement identifies the freeze frame associated with this dtc.

This should match the name of one of the defined freeze frames, as described in section Section 8.1.4.26, “Compound statement: freeze-frame”.

8.1.4.30. Compound statement: pid-data

The optional pid-data compound statement can contain the following statements:

pid-data
{
    pid { ... } 1
    pid { ... }
}

1

Each optional pid compound statement identifies a diagnostic parameter to be accessed by ID (PID). The compound statement is covered in Section 8.1.4.31, “Compound statement: pid” in more detail.

8.1.4.31. Compound statement: pid

The optional pid compound statement, which can be repeated, can contain the following statements:

pid
{
    name = identifier; 1
    iso-16bit-id = integer; 2
    byte-length = integer; 3
    allow-ioctrl = true or false; 4
    input-byte-length = integer; 5
    j1979-8bit-id = integer; 6
    kwp-8bit-id = integer; 7
    j1939-spn-id = integer; 8
    resend-input-as-output = true or false; 9
    nonvolatile = true or false; 10
    min-length = integer; 11
    max-length = integer; 12
    alphanumeric = true or false; 13
    control-enable-mask-length = integer; 14
    iso-scaling-bytes = byte-list; 15
}

1

The required name assignment statement identifies the PID uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the PID.

2

The required iso-16bit-id assignment statement specifies the numeric ID by which this PID is accessed by an external tool, e.g. using Keyword Protocol 2000-3/UDS service 0x22.

The integer for the statement must be in the range [0, 65535], and the same value cannot be used for two or more different PIDs.

3

The required byte-length assignment statement specifies the number of bytes this PID consists of. For example, 2 bytes may be used to convey an engine speed value, but 12 bytes for a Vehicle Identification Number (VIN) string.

The integer for the statement must be in the range [1, 255].

4

The optional allow-ioctrl assignment statement specifies whether or not the external test tool is allowed to override or freeze the PID values using inputOutputControlByIdentifier services in Keyword Protocol 2000-3 and UDS. If not specified, a default of false is assumed.

Allowing such overrides significantly increases the RAM consumed by the PID.

5

The optional input-byte-length assignment statement specifies the number of controlOptionRecord bytes that are expected for this PID when an override value is sent by the test tool, so it is only relevant if allow-ioctrl = true.

If omitted, the same length as byte-length is assumed. Otherwise, this allows a PID to be configured to accept data that does not have a one-to-one match with its normal data in terms of length. The override data can still be obtained in such cases using ppid_get_override_data().

The integer for the statement must be in the range [1, 255].

6

The optional j1979-8bit-id assignment statement specifies the 8-bit ID to be used for J1979 service $01 request.

The integer for the statement must be in the range [0, 255], and the same value cannot be used for two or more different PIDs.

7

The optional kwp-8bit-id assignment statement specifies the 8-bit LocalIdentifier to be used for KW2000-3 services $21 and $30.

The integer for the statement must be in the range [0, 255], and the same value cannot be used for two or more different PIDs.

8

The optional j1939-spn-id assignment statement specifies the J1939 SPN.

The integer for the statement must be in the range [0, 524287], and the same value cannot be used for two or more different PIDs.

9

The optional resend-input-as-output assignment statement controls the data being returned to the tool and read by the application.

If set true, override values sent by the test tool (controlOptionRecord data) temporarily replace the data in the PID as read by ppid_get_pid(), and echoed to the test tool as ControlStatusRecord bytes.

If set false, override values sent by the test tool do not overwrite the data in the PID, but can still be checked by using ppid_get_override_data(). This is appropriate if the input-byte-length differs from the byte-length.

The is applicable only for the PIDs that have allow-ioctrl set to true.

10

The optional nonvolatile assignment statement determines if the PID is stored in NVM.

If not defined, it will be set to FALSE by default.

11

The optional min-length assignment statement specifies the minimum number of bytes this PID consists of. Note: min-length only applies to non-volatile PIDs.

The integer for the statement must be in the range [1, 255].

12

The optional max-length assignment statement specifies the maximum number of bytes this PID consists of. Note: max-length only applies to non-volatile PIDs.

The integer for the statement must be in the range [1, 255].

13

The optional alphanumeric assignment statement determines the byte ordering of J1939 SPN data. If set TRUE, the data is treated as alphanumeric with the most significant byte transmitted first. If set FALSE the least significant byte is transmitted first.

If not defined, it will be set to FALSE by default.

14

The optional control-enable-mask-length assignment statement specifies how many bytes should be reserved for optional controlEnableMask data sent by the test tool. The bytes (if supplied by the tool) can be retrieved using ppid_get_override_data().

It is the responsibility of the application to act appropriately on any controlEnableMask bytes, e.g. by restricting the override of physical outputs only to selected signals.

The integer for the statement must be in the range [0, 255], and defaults to zero.

15

The optional iso-scaling-bytes assignment statement specifies the scaling bytes to be transmitted in response to a service $24 request.

The scaling bytes are entered as a comma-separated list of integer values in either decimal or hex. Example: iso-scaling-bytes = 0x32, 75, 123, 0x7F;

If not defined, scaling bytes will not be used for this PID.

8.1.4.32. Compound statement: dte-data

The optional dte-data compound statement can contain the following statements:

dte-data
{
    dte { ... } 1
    dte { ... }
}

1

Each optional dte compound statement identifies a Diagnostic Test Entity. The compound statement is covered in Section 8.1.4.33, “Compound statement: dte” in more detail.

8.1.4.33. Compound statement: dte

The optional dte compound statement, which can be repeated, can contain the following statements:

dte
{
    name = identifier; 1
    dte-id = integer; 2
    dte-dme-id = integer; 3
    j1939-tid = integer; 4
    iso-tid = integer; 5
    dte-mon-id = integer; 6
    scaling-id = integer; 7
    slot-id = integer; 8
    component-id = integer; 9
    dte-spn = integer; 10
    dte-fmi = integer; 11
    test-lim-min = integer; 12
    test-lim-max = integer; 13
}

1

The required name assignment statement identifies the DTE uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the DTE.

2

The required dte-id assignment statement identifies the identifier for the DTE uniquely.

An error is raised if a duplicate DTE ID is found. .

3

The required dte-dme-id assignment statement identifies the DME to which the DTE belongs.

A warning is raised if the assigned ID is not defined with a Section 8.1.4.35, “Compound statement: dme” statement.

4

The optional j1939-tid assignment statement identifies the J1939 specified Test ID that requires ratio monitoring.

Either this or the iso-tid (or both) must be assigned to a valid value. An error is raised if both iso-tid and j1939-tid assignments are skipped.

5

The optional iso-tid assignment statement identifies the ISO specified Test ID that requires ratio monitoring.

Either this or the j1939-tid (or both) must be assigned to a valid value. An error is raised if both iso-tid and j1939-tid assignments are skipped.

6

The optional dte-mon-id assignment statement identifies the Monitor ID to which the DTE belongs.

This is applicable only for reporting for ISO diagnostics.

7

The optional scaling-id assignment statement identifies scaling and unit to be used by the external test equipment to calculate and display the test values/ results.

This is applicable only for reporting for ISO diagnostics.

8

The optional slot-id assignment statement identifies the SLOT for the DTE.

This is applicable only for reporting for J1939 diagnostics.

9

The optional component-id assignment statement identifies the Component for the DTE.

This is applicable only for reporting for J1939 diagnostics.

10

The optional dte-spn assignment statement identifies the SPN associated with the DTE.

This is applicable only for reporting for J1939 diagnostics.

11

The optional dte-fmi assignment statement identifies the FMI associated with the DTE.

This is applicable only for reporting for J1939 diagnostics.

12

The optional test-lim-min assignment statement identifies minimum limit of the test value for the test Pass/Fail criteria.

This is the scaled value of the test limits (matching the scaling-id defined above). This should be in the range [0, 65535]. If not defined, it will be set to 0 by default.

13

The optional test-lim-max assignment statement identifies maximum limit of the test value for the test Pass/Fail criteria.

This is the scaled value of the test limits (matching the scaling-id defined above). This should be in the range [0, 65535]. If not defined, it will be set to 65535 by default.

8.1.4.34. Compound statement: dme-data

The optional dme-data compound statement can contain the following statements:

dme-data
{
    dme { ... } 1
    dme { ... }
}

1

Each optional dme compound statement identifies a Diagnostic Monitor Entity. The compound statement is covered in Section 8.1.4.35, “Compound statement: dme” in more detail.

8.1.4.35. Compound statement: dme

The optional dme compound statement, which can be repeated, can contain the following statements:

dme
{
    name = identifier; 1
    dme-id = integer; 2
    dme-mon-id = integer; 3
    monitor-group = monitor-group; 4
    dme-spn = integer; 5
    readiness-count-lim = integer; 6
}

1

The required name assignment statement identifies the DME uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the DME.

2

The required dme-id assignment statement is an arbitrary integer value used to reference this DME.

An error is raised if a duplicate DME ID is found. .

3

The optional dme-mon-id assignment statement identifies the OBD Monitor ID corresponding to this DME. The OBD Monitor ID is used to identify the supported monitors while servicing the ISO J1979 service request $06.

This is applicable only for reporting for ISO diagnostics. Either this or the dme-spn (or both) must be assigned to a valid value.

4

The optional monitor-group assignment statement decides which Monitor group this DME belongs to (used for response to service $09 (ReadVehicleInformation), InfoTypes $08 and $0B.

The J1979 spec dated Sept 2010 lists the mapping of Monitor ID to Group in appendix D.

The value of monitor-group must be one of air, bp, cat-bank1, cat-bank2, egr, egs, evap, fuel, nads, ncat, nmhc-cat, o2s-bank1, o2s-bank2, so2s-bank1, so2s-bank2, opm, or other (default).

5

The optional dme-spn assignment statement identifies the SPN associated with the DME.

This is applicable only for reporting for J1939 diagnostics. Either this or the dme-mon-id (or both) must be assigned to a valid value.

An error is raised if both dme-mon-id and dme-spn assignments are skipped.

6

The optional readiness-count-lim assignment statement identifies the number of times monitor has to be run before declared as Readiness COMPLETE.

If not defined, it will be set to 0 by default.

8.1.4.36. Compound statement: adaptives

The optional adaptives compound statement can contain the following statements:

adaptives
{
    storage = storage-type; 1

    adaptive-list = adaptive-list; 2

}

1

The required storage assignment statement identifies what memory device will be used to store adaptive information across power cycles. See Section A.1, “ECU hardware reference documentation” for which memory types are supported for each target ECU.

The value of storage-type must be battery-backed-ram or flash.

2

The optional adaptive-list assignment statement, which can be repeated, identifies the DDEs which are treated as non-volatile adaptives. The adaptive-list must be the name of one DDE, or the names of multiple DDEs separated by commas.

The interface tool will report an error if any DDE is repeated.

8.1.4.37. Compound statement: routine-data

The optional routine-data compound statement can contain the following statements:

routine-data
{
    routine { ... } 1
    routine { ... }
}

1

Each optional routine compound statement identifies a diagnostic routine to be accessed by routine ID. The compound statement is covered in Section 8.1.4.38, “Compound statement: routine” in more detail.

8.1.4.38. Compound statement: routine

The optional routine compound statement, which can be repeated, can contain the following statements:

routine
{
    name = identifier; 1
    iso-16bit-id = integer; 2
    routine-type-timed = true or false; 3
    rcor-byte-length = integer; 4
    results-byte-length = integer; 5
    status-record-byte-length = integer; 6
}

1

The required name assignment statement identifies the routine uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the routine.

2

The required iso-16bit-id assignment statement specifies the numeric ID by which this routine is accessed by an external tool using UDS service 0x31.

The integer for the statement must be in the range [0, 65535], and the same value cannot be used for two or more different routines. Note: routine IDs 0x0202, 0x0203, 0xFF00, and 0xFF01 are reserved by the platform and cannot be used by the application.

3

The required routine-type-timed assignment statement specifies whether or not the routine is "Method A" (untimed) or "Method B" (timed) as specified in ISO 14229-1. A value of true means that the routine is "Method B" (timed).

4

The optional rcor-byte-length assignment statement specifies the number of bytes in the routineControlOptionRecord for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default.

5

The optional results-byte-length assignment statement specifies the number of bytes that will be returned as "routine results" in response to a results request for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default.

6

The optional status-record-byte-length assignment statement specifies the number of bytes in the statusRecord for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default.

8.1.4.39. Compound statement: tunes

The optional tunes compound statement is reserved for future use.

8.1.4.40. Compound statement: ddes

The optional ddes compound statement can contain the following statements:

ddes
{
    include-dde-tabbed        string; 1
    include-dde-tabbed-prefix string; 2
    include-dde-tabbed-c      string; 3
    include-dde-units         string; 4

    generate-library-ddes = true or false; 5
}

1

The optional include-dde-tabbed assignment statement (became deprecated at version 1.8.1), which can be repeated, identifies a prefix-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a prefix-style tabbed DDE file is described in detail in Section 8.1.5.1, “Data dictionary format (prefix-style)”.

2

The optional include-dde-tabbed-prefix assignment statement, which can be repeated, identifies a prefix-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a prefix-style tabbed DDE file is described in detail in Section 8.1.5.1, “Data dictionary format (prefix-style)”.

3

The optional include-dde-tabbed-c assignment statement, which can be repeated, identifies a C-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a C-style tabbed DDE file is described in detail in Section 8.1.5.3, “Data dictionary format (C-style)”.

4

The optional include-dde-units assignment statement, which can be repeated, identifies a units file to read and include in any ASAP2 generation.

The format of a units file is described in detail in Section 8.1.6, “Units file”.

5

The required generate-library-ddes assignment statement identifies whether to generate library based DDEs or not (see Section 8.1.7, “Automatic ASAP2 entries” for more).

8.1.5. DDE specification

The OpenECU library can interact with calibration tools to read and write application data while the application is executing on the target. To support the interface between the calibration tool and the application, a data description file is required so the calibration tool understands how the application memory is laid out. To support this, the interface tool can read a set of application data dictionary files and create the calibration data description files.

The application data is described in a set of data dictionary files. A data dictionary file is a simple tab delimited text file format and must contain at minimum: the name, default value and type for calibratables; the name and type for displayables. When an application is built, the information stored in the data-dictionary files are transformed into an ASAP2 file for use with a calibration tool.

Note that non-ASCII characters appearing in the data dictionary may not be interpreted correctly by the calibration tool reading the resultant ASAP2 files, since different calibration tools use different extended encoding conventions. It is best therefore to stick to ASCII characters within the data dictionary.

There are two supported data dictionary file formats: prefix-style (described in Section 8.1.5.1, “Data dictionary format (prefix-style)”) and C-style (described in Section 8.1.5.3, “Data dictionary format (C-style)”).

8.1.5.1. Data dictionary format (prefix-style)

Each prefix-style data dictionary follows a simple format, separated into columns and will look something like:

Name            Value  Units  Type    Accuracy  Min  Max  Description
moi_pressure           kPa    F32     0.01      20   80   Pressure reading
moi_temperature        degC   F32     0.01      -40  150  Temperature reading

To help readability, comment lines can be inserted into a data dictionary file. Comment lines are ignored and start with the ** character sequence. For example:

Name            Value  Units  Type    Accuracy  Min  Max  Description
** A comment line
moi_pressure           kPa    F32     0.01      20   80   Pressure reading

** Another comment line
moi_temperature        degC   F32     0.01      -40  150  Temperature reading

Each column has a heading, followed by as many data dictionary entries as necessary. Each column is separated by a TAB character and because of this, Excel is a very useful tool for editing the files (in Excel, save the file as Text (tab delimited) *.txt).

8.1.5.1.1. DDE columns

Each column has a use as described in Table 8.7, “Data dictionary columns (prefix-style)”.

Table 8.7. Data dictionary columns (prefix-style)

ColumnDescription
NameThe name of the data dictionary entry. The name must conform to the naming convention detailed in Section 8.1.5.2, “DDE naming rules (prefix_style)”.
ValueThe value of a calibration constant, 1d or 2d map. A value should not be created for a non-calibration variable.
UnitsThe engineering units for this entry (can be restricted to a set of possibilities with a units file (Section 8.1.6, “Units file”)).
DescriptionA description of the data dictionary entry. Must not contain single or double quotes.
TypeAny one of S8, U8, S16, U16, S32 U32, F32 or BOOL. The type must match the type assigned to the signal by C source code (the interface tool does not check correct type assignment).
AccuracyThe number of decimal digits to display when viewing the data dictionary entry with a calibration tool. For instance, 1 shows no digits after the decimal point, 0.01 shows two digits after the decimal point.
MinThe minimum expected value for this data dictionary entry.
MaxThe maximum expected value for this data dictionary entry.
ScaleThis column is optional. It specifies the amount by which the displayed value will be scaled from the raw value read from the ECU.
OffsetThis column is optional. It specifies the amount by which the displayed value will be offset from the raw value read from the ECU.
EnumsA comma separated list of data dictionary entries which provide the possible values this data dictionary entry can be.
DeclReserved for future use.
DefnReserved for future use.
LookupReserved for future use, do not use.
GroupReserved for future use, do not use.
RateReserved for future use, do not use.

An example of how the data dictionary can be used to name application variables, constants and map look-ups is given below. Each entry follows the naming convention laid out in (Section 8.1.5.2, “DDE naming rules (prefix_style)”). Explore the C-API examples for more examples (Section 4.6.8, “Examples”).

Name           Value               Units  Type    Min Max  Description

** example of a signal DDE
moi_pressure                       kPa    F32     20  80   Example of a named signal

** example of a constant lookup DDE
moic_constant  50                  kPa    F32     20  80   Example of a calibration constant

** example of set of a 1D table/map lookup DDEs
moim_1d_map_x  [20 40 80]          kPa    F32     20  80   Example of a x-axis for a 1d map
moim_1d_map_z  [0  0  1]           state  BOOL    0   1    Example of a z-data for a 1d map

** example of set of a 2D table/map lookup DDEs
moim_2d_map_x  [20 40]             kPa    F32     20  80   Example of a x-axis for a 2d map
moim_2d_map_y  [1  5  10]          sec    F32     0   25   Example of a y-axis for a 2d map
moim_2d_map_z  [0  1; 4  5; 8  9]  steps  F32     0   100  Example of a z-data for a 2d map

** example of set of an array DDE
moiv           [1 2 3 5 8 13]      counts F32     0   10   Example of an array

Instead of using values to represent discrete states, enumerations can be used instead. These represent the discrete states using a textual name rather than a number. For instance, in the following example, moi_state can have two enumerations: MOI_RUNNING which represents the value 0 and MOI_STOPPED which represents the value 1.

Name         Value  Units  Type    Min  Max  Enums                     Description

moi_state           state  F32     0    1    MOI_RUNNING, MOI_STOPPED  Example of a st ...

MOI_RUNNING  0      enum   F32                                         Enumeration for ...
MOI_STOPPED  1      enum   F32                                         Enumeration for ...

When each data dictionary file is read by the interface tool, the contents are checked for consistency. A complete list of checks is given in Appendix B, OpenECU error and warning codes.

8.1.5.2. DDE naming rules (prefix_style)

The interface tool makes use of a naming convention to help make names and variables more readily understandable by humans. All names consist of a prefix, a descriptive body, and an optional suffix, separated by underscore characters:

The prefix consists of three or four lower case letters, these being:

The item type letter is as follows:

Table 8.8. Variable naming convention (prefix-style)

Named item typeType letter
Displayable signals(no type letter)
Calibration scalarsc
Calibration mapsm
Arraysv

Axes and map data for lookup tables require an addition suffix. 1-d lookup tables have two parameters as follows:

Table 8.9. 1-d map lookup naming convention (prefix-style)

Application parameterSuffixExample
Vector of input values_xvaim_fuel_cell_temp_x
Vector of output values_zvaim_fuel_cell_temp_z

2-d lookup tables have three parameters as follows:

Table 8.10. 2-d map lookup naming convention (prefix-style)

Application parameterSuffixExample
Row_xsffm_base_fuel_x
Column_ysffm_base_fuel_y
Table_zsffm_base_fuel_z

8.1.5.3. Data dictionary format (C-style)

A C-style data dictionary file has a similar layout to a prefix-style data dictionary (described in detail in Section 8.1.5.1, “Data dictionary format (prefix-style)”). The primary differences between the two formats is in column use and DDE naming.

8.1.5.3.1. DDE columns

Each column has a use as described in Table 8.11, “Data dictionary columns (C-style)”.

Table 8.11. Data dictionary columns (C-style)

ColumnDescription
NameThe name of the data dictionary entry. The name must conform to the naming convention detailed in Section 8.1.5.3.2, “DDE naming rules (C-style)”.
UnitsThe engineering units for this entry (can be restricted to a set of possibilities with a units file (Section 8.1.6, “Units file”)).
DescriptionA description of the data dictionary entry. Must not contain single or double quotes.
AccuracyThe number of decimal digits to display when viewing the data dictionary entry with a calibration tool. For instance, 1 shows no digits after the decimal point, 0.01 shows two digits after the decimal point.
MinThe minimum expected value for this data dictionary entry.
MaxThe maximum expected value for this data dictionary entry.
ScaleThis column is optional. It specifies the amount by which the displayed value will be scaled from the raw value read from the ECU.
OffsetThis column is optional. It specifies the amount by which the displayed value will be offset from the raw value read from the ECU.
ClassThis is the class of DDE. Further details are given in Table 8.12, “Classes of DDE”.
XaxisFor a 1d or 2d map entry, this is the name of the DDE to the corresponding X-axis information.
YaxisFor a 2d map entry, this is the name of then DDE to the corresponding Y-axis information.
LookupFor a 1d map entry, this is the name of the DDE used to index the X-axis. For a 2d map entry, this is the name of the DDEs used to index the X-axis and then the Y-axis, separated by a comma. The lookup information can be used by a calibration tool to show the current map lookup location in real-time.
GroupA comma separated list of groups. Each group must start with a “/” and be followed by an ASAP2 identifier, e.g., “/Group_name”. Groups can be combined to form a heirarchy, e.g., “/Group_name/Function/A”. Each group for a DDE is used to generate a heirachy of ASAP2 FUNCTIONS which a calibration tool uses to present groups of DDE to the user.
RateReserved for future use.

In comparison with the prefix-style DD format, some columns are not used because information can be extracted from the compiler's ELF file (for instance, variable types and enumeration identifiers).

An example of how the data dictionary can be used to name application variables, constants and map look-ups is given below. Each entry follows the naming convention laid out in (Section 8.1.5.3.2, “DDE naming rules (C-style)”). Explore the C-API examples for more examples (Section 4.6.8, “Examples”).

Name                          Units  Class  Min Max  Description

** example of a simple variable reference (displayable)
vehicle_speed                 mph    d      0   200  Filtered vehicle ...

** example of a simple variable reference (calibration)
ign_supplies_vbat             flag   c      0   1    1 if ignition and...

** example of an array variable reference
analog_values[0].fault        flag   d      0   1    1 if A/D is sense...

The C-style file format has a couple of additional columns: Xaxis, Yaxis and Lookup; which are used to provide additional information about maps.

The Xaxis and Yaxis columns are used to specify the axis information for a map. The map itself can be 1d or 2d in size. The Lookup column is used to specify the DDEs used to lookup the x and y axes of a map. The calibration tool can use the lookup DDEs to show where the map was last indexed. An example of a 1d map would be:

Name                          Units  Class  Min Max  Xaxis          Lookup

** example of a simple variable reference (displayable)
inlet_pressure                kPa    d      0   200

** example of a 1D table/map with lookup
pressure_axis                 kPa    caxis  20  80
position_map                  steps  cmap   0   100  pressure_axis  inlet_pressure

The Class column specifies whether the DDE is a calibration (write-only) or displayable (read-only).

Displayable

Can be read by a tool external to the ECU while the application is running. Displayables typically refer to variables held in RAM, but can also refer to variables in other memory spaces.

Calibration

Can be written by a tool external to the ECU while the application is running. Calibrations can be scalar (single variable), map (one or two axes, plus a lookup table), string (array of ASCII characters), or vector/array (array of variables).

Table 8.12. Classes of DDE

ClassDescription
cDDE is treated as a scalar calibration.
cmapDDE is treated as a map calibration.
caxisDDE is treated as an axis calibration.
cstringDDE is treated as a string calibration.
carrayDDE is treated as an array calibration.
dDDE is treated as a scalar displayable.
darrayDDE is treated as an array displayable.

8.1.5.3.2. DDE naming rules (C-style)

C-style DDE names closely match the equivalent C identifier for a variable. Structure members can be referenced, as can array indexes and ranges of array indexes. For instance, given the following C code snippet:

typedef struct { real_t a; real_t b; } AB_T;
typedef struct { real_t idx; AB_T list[10]; } DATA_T;
uint32_t var;
real_t axis[4];
DATA_T data[3];

the data can be accessed through various names:

Table 8.13. Examples of C-style DDE names

NamesDescription
varrefers to scalar variable of same name
axis[0]refers to scalar variable of array, element 0
axis[0..3]refers to scalar variables, elements 0 through 3
axis[2..]refers to scalar variables, elements 2 through 3
axis[..2]refers to scalar variables, elements 0 through 2
axis[..]refers to scalar variables, elements 0 through 3
data[0].idxrefers to scalar variable, the idx struct member from data element 0
data[..].list[..].arefers to scalar variables, the a struct member from all elements in data[].list[]

As can be seen in the examples, references to arrays can be explicit (e.g., axis[0]) or ranged (e.g., axis[..]). When a range is provided and the lower or upper bound is not specified, the interface tool will use the lower or upper bound extracted from the compiler's ELF file (if such a bound is specified).

Note

A C-style DDE which refers to a C array, must have an equivalent C variable where the array size is given explicitly. For instance, in the following snippet, array_sized[] is acceptable while array_unsized[] is not.

F32 array_sized[3]  = { 1, 2, 3 };
F32 array_unsized[] = { 1, 2, 3 };

This requirement is derived from the amount of information embedded in the ELF file. Implicitly sized arrays have pointer type with no size information, neither of which an ASAP2 file can support.

Note

C-style DDE names cannot refer to C variables which are of pointer or bit-field type. These are not supported by the ASAP2 and calibration tool combinations supported by OpenECU.

8.1.6. Units file

A units file is a simple text file format, where each line represents a single allowable unit. When a model is loaded, the data dictionary entries and unit entries are read, and any data dictionary what does not use one of the unit entries raises a warning.

A units file for a model must have the file-name model_name_units.txt where model_name is replaced by the name of the model. An example units file for a model named read_sensor would be named read_sensor_units.txt and might look like:

degC
kPa

In this example, only two units, degC and kPa can be used for a data dictionary entry.

To help readability, comment lines can be inserted into the units file. Comment lines are ignored and start with a ** or -- character sequence. For example:

** Allowable units for the read_sensor model
degC
kPa

8.1.7. Automatic ASAP2 entries

When an application is built, a number of ASAP2 entries are automatically generated. These entries reflect a number of application properties and run-time parameters which are useful to monitor during development and deployment.

The sections below give a complete list of automatically generated ASAP2 entries.

Note

When using PiSnoop be sure to load the ASAP2 (.a2l) file symbols to view these parameters. In many cases they are aliases for C variables with different names in the .elf file, and some have necessary scale factors applied in the ASAP2 attributes.

8.1.7.1. Boot build information

The boot software runs when the ECU is turned on. It conditions the ECU for running the reprogramming software or application software. The version and build date of this software is available through the following ASAP2 entries.

Table 8.14. Automatic ASAP2 entries for boot build information

ASAP2 nameDescriptionUnits
mpl_boot_ver_majorThe boot software major version number.-
mpl_boot_ver_minorThe boot software minor version number.-
mpl_boot_ver_subThe boot software sub-minor version number.-
mpl_boot_build_dayThe numerical day when the boot software was created.days
mpl_boot_build_monthThe numerical month when the boot software was created.months
mpl_boot_build_yearThe numerical year when the boot software was created.years
mpl_boot_part_num_groupThe Group ID numerical value of the boot software part number.-
mpl_boot_part_num_letterThe Group Letter ASCII value of the boot software part number.-
mpl_boot_part_num_idThe Part ID numerical value of the boot software part number.-
mpl_boot_part_num_issueThe Issue numerical value of the boot software part number.-

Past and current boot code version numbering is given in Section 8.1.8, “OpenECU software versioning”.

8.1.7.2. Reprogramming build information

The ECU's reprogramming mode is started as described in Section 3.3.11, “Program the ECU”. The reprogramming code communicates using CCP (version 2.1) and provides a calibration tool with a mechanism to change the application software and/or calibration.

Table 8.15. Automatic ASAP2 entries for reprogramming build information (M220, M221, M250, M460, M461, M670)

ASAP2 nameDescriptionUnits
mpl_prg_ver_majorThe reprogramming software major version number.-
mpl_prg_ver_minorThe reprogramming software minor version number.-
mpl_prg_ver_subThe reprogramming software sub-minor version number.-
mpl_prg_build_dayThe numerical day when the reprogramming software was created.days
mpl_prg_build_monthThe numerical month when the reprogramming software was created.months
mpl_prg_build_yearThe numerical year when the reprogramming software was created.years
mpl_prg_part_num_groupThe Group ID numerical value of the reprogramming software part number.-
mpl_prg_part_num_letterThe Group Letter ASCII value of the reprogramming software part number.-
mpl_prg_part_num_idThe Part ID numerical value of the reprogramming software part number.-
mpl_prg_part_num_issueThe Issue numerical value of the reprogramming software part number.-

Past and current boot code version numbering is given in Section 8.1.8, “OpenECU software versioning”.

8.1.7.3. Platform build information

The platform software creates an environment where by the application software can execute and access the target ECU hardware.

Table 8.16. Automatic ASAP2 entries for platform build information

ASAP2 nameDescriptionUnits
mpl_plat_ver_majorThe platform software major version number.-
mpl_plat_ver_minorThe platform software minor version number.-
mpl_plat_ver_subThe platform software sub-minor version number.-
mpl_plat_build_dayThe numerical day when the platform software was created.days
mpl_plat_build_monthThe numerical month when the platform software was created.months
mpl_plat_build_yearThe numerical year when the platform software was created.years
mpls_plat_build_timeThe date and time when the platform was created as a text string.-
mpls_plat_copyrightThe platform's copyright notice.-
mpls_plat_targetThe hardware target the application was built to be run on as a text string.-
mpls_plat_versionThe version of the platform the application was built against as a text string.-
mpl_plat_part_num_groupThe Group ID numerical value of the platform part number the application was build against.-
mpl_plat_part_num_letterThe Group Letter ASCII value of the platform part number the application was build against.-
mpl_plat_part_num_idThe Part ID numerical value of the platform part number the application was build against.-
mpl_plat_part_num_issueThe Issue numerical value of the platform part number the application was build against.-

Past and current boot code version numbering is given in Section 8.1.8, “OpenECU software versioning”.

8.1.7.4. Application build information

When the application is built, the automatically generated application code and the platform software are combined, and the result is the application software configured for the target ECU hardware.

The application name, description and copyright, as well as the time and date when the application was built, is available through ASAP2 entries. This information is useful when confirming what the ECU is actually executing.

Table 8.17. Automatic ASAP2 entries for application build information

ASAP2 nameDescriptionUnits
mpl_app_ver_majorThe application software major version number.-
mpl_app_ver_minorThe application software minor version number.-
mpl_app_ver_subThe application software sub-minor version number.-
mpl_app_build_secThe seconds when the application software was built.seconds
mpl_app_build_minThe minute when the application software was built.minutes
mpl_app_build_hourThe hour (in 24 hour format) when the application software was built.hours
mpl_app_build_dayThe numerical day when the application software was built.days
mpl_app_build_monthThe numerical month when the application software was built.months
mpl_app_build_yearThe numerical year when the application software was built.years
mpls_app_build_timeThe date and time when the application was built as a text string.-
mpls_app_copyrightThe copyright notice for the application.-
mpls_app_descriptionThe application description.-
mpls_app_nameThe name of the built application.-
mpls_app_versionThe application version number as a text string.-

8.1.7.5. Application and library task timing information

When the application is executing, the platform is maintaining a series of tasks that iterate the application at periodic rates (and possibly on an angular rate if engine functionality is required). These tasks take an amount of time to execute and the following ASAP2 entries record how long the last ran.

Table 8.18. Automatic ASAP2 entries for application rate task timing information

ASAP2 nameDescriptionUnits
mpl_tt_[capi-task-name]The duration of the last application iteration for a particular task.microseconds

When the application is executing, the platform is maintaining a series of tasks that support the application. These tasks perform basic input and output support as well as general housekeeping. Each task takes some time to execute and the following entries record the last execution time of each.

Table 8.19. Automatic ASAP2 entries for auxiliary task timing information

ASAP2 nameDescriptionUnits
mpl_tt_pan_taskThe duration of angular platform task. This task supports the angular application iteration.microseconds
mpl_tt_pan_knockThe duration of angular knock support task.microseconds
mpl_tt_pan_knock_refThe duration of angular knock reference support task.microseconds
mpl_tt_pcx_tcan_callbackThe duration of the CAN receive and transmit (event) support task.microseconds
mpl_tt_pcx_qemptierThe duration of the CAN receive and transmit (polled) support task.microseconds
mpl_tt_pcx_qemptier_mcp2515The duration of the CAN receive and transmit (event) support task.microseconds
mpl_tt_psp_receiveThe duration of the serial input and output support task.microseconds
mpl_tt_psc_watchdogThe duration of the watchdog support task.microseconds
mpl_tt_pcp_clientThe duration of the CCP support task. This task provides CCP support for the calibration tool.microseconds
mpl_tt_ppp_clientThe duration of the PixCal/tuning comms protocol task. This task provides support for tunable parameters via the PixCal calibration tool.microseconds

These entries support development by showing how long the software takes to run on the target hardware. As development progresses, new functionality can be compared to previous functionality to assess how much processing time is consumed.

The assessment can be made by noting how frequently the tasks run and how long they take, giving an estimated total consumption.

Table 8.20. Automatic ASAP2 entries for CPU loading information

ASAP2 nameDescriptionUnits
mpl_cpu_loadedThe amount of CPU used by the application and platform software in the last 50 milliseconds as a percentage. The CCP task may cause the loading to reach 100 percent under certain conditions but this is normal. The long running CCP task will not cause application iterations or other functionality to be delayed.percent

Some target ECU support loading measurement for processing devices other than the CPU. The eTPU device, or devices, are used for simple and complex I/O processing.

Table 8.21. Automatic ASAP2 entries for eTPU loading information

ASAP2 nameDescriptionUnits
mpl_etpu_a_loadedThe amount of eTPU (device A) used by the application and platform software in the last 50 milliseconds as a percentage.percent
mpl_etpu_b_loadedThe amount of eTPU (device B) used by the application and platform software in the last 50 milliseconds as a percentage.percent

Although previous entries record how long the last execution took, it is useful to know the longest execution that has occurred since power up. There are ASAP2 entries to support this.

Table 8.22. Automatic ASAP2 entries for maximum application rate task timing information

ASAP2 nameDescriptionUnits
mpl_mtt_[name]The largest value of the corresponding application duration ASAP2 variable seen since the last power up or reset.microseconds
mpl_max_cpu_loadedThe largest value of mpl_cpu_loaded seen since the last power up or reset.percent
mpl_max_etpu_a_loadedThe largest value of mpl_etpu_a_loaded seen since the last power up or reset.percent
mpl_max_etpu_b_loadedThe largest value of mpl_etpu_b_loaded seen since the last power up or reset.percent

Note that the maximum task duration entries record the longest execution seen since power up and not the worst case execution time of the task. It could be that a task will take longer to run if given different stimuli. OpenECU does not support the direct derivation of worst case execution times.

There is also a seconds counter which is cleared to zero when the ECU is turned on or resets. The counter can be used to determine if the ECU is resetting on a regular or irregular basis.

Table 8.23. Automatic ASAP2 entries for run-time information

ASAP2 nameDescriptionUnits
mpl_run_timeA seconds counter of the time since power up; range [0, 4294967294].seconds

Expected and unexpected resets are logged and counted. There are ASAP2 entries to report reset counts.

Table 8.24. Automatic ASAP2 entries for reset information (M110, M220, M250, M460, M461)

ASAP2 nameDescriptionUnits
mpl_unstable_reset_countNumber of resets since power-up, or since the application was last stable.events
mpl_reset_countNumber of resets since power-up.events

Table 8.25. Automatic ASAP2 entries for number of instances of period overruns of periodic tasks

ASAP2 nameDescriptionUnits
mpl_ovrc_[name]The number of times the task has taken longer that its period to run.count

8.1.7.6. Memory use information

The platform software provides support for the application execution through the tasks identified above. Each of these tasks requires some memory to record its state and the platform does so dynamically by storing this information on the stack.

Table 8.26. Automatic ASAP2 entries for memory use information

ASAP2 nameDescriptionUnits
mpl_max_used_stackThe amount of stack used since power up by the application software.bytes

The size of the stack can be modified via the interface file, see Section 8.1.4.9, “Compound statement: os-native”.

8.1.7.7. Memory error correction events

Some ECUs provide memory error correction functionality. Not all memory errors can be corrected and in all conditions except during initialisation, reading a non-correctable memory area will cause the ECU to reset. During initialisation, the software prevents resets when checking adaptive, DTC and Tune memory to determine if those memory regions have become corrupt. A non-correctable memory area detected during initialisation checks is logged in the following automatic ASAP2 variables.

Table 8.27. Automatic ASAP2 entries for memory error correction events

ASAP2 nameDescriptionUnits
mpl_ecc_ram_addressAddress of last RAM non-correctable ECC error, zero if no error has occurred.address
mpl_ecc_flash_addressAddress of last Flash non-correctable ECC error, zero if no error has occurred.address

8.1.7.8. Floating point conditions

On those ECUs which support floating-point arithmetic, some ECUs provide status information relating to floating-point operations. Given pmax as the most positive normalized value (farthest from zero), pmin the smallest positive normalized value (closest to zero), nmax the most negative normalized value (farthest from zero) and nmin the smallest normalized negative value (closest to zero), floating-point conditions are reflected in the automatic ASAP2 variables in the following table.

Table 8.28. Automatic ASAP2 entries for floating point conditions

ASAP2 nameDescriptionUnits
mpl_flp_overflow Set if floating-point overflow has occurred since the last reset, clear otherwise. An overflow is said to have occurred if the numerically correct result is such that result > pmax, or result < nmax. See the processor's reference manual for more. flag
mpl_flp_underflow Set if floating-point underflow has occurred since the last reset, clear otherwise. An underflow is said to have occurred if the numerically correct result is such that 0 < result < pmin, or nmin < result < 0. See the processor's reference manual for more. flag
mpl_flp_div_by_zero Set if floating-point division by zero has occurred since the last reset, clear otherwise. A divide by zero condition arises when the floating-point operation is executed with a +/-0 divisor value and a finite normalized nonzero dividend value. flag
mpl_flp_inexact Set if an inexact floating-point result has occurred since the last reset, clear otherwise. An inexact condition arises when the result of a floating-point operation requires rounding (is inexact), or if an overflow or underflow condition arises. flag
mpl_flp_invalid Set if an invalid floating-point result has occurred since the last reset, clear otherwise. An invalid condition arises when an operand in a floating-point operation contains a denormalized value, infinitity or NaN, or if both operands in a floating-point divide operation are +/-0. flag

Note

The platform is likely to cause the inexact condition to occur due to rounding. While the platform has been written to avoid other conditions (such as divide by zero), extreme values passed by the application to the platform may result in the platform causing other conditions to occur.

8.1.7.9. J1939 related information

The following ASAP2 entries are provided to work with J1939.

Table 8.29. Automatic ASAP2 entries for J1939 related information

ASAP2 nameDescriptionUnits
pj1939c_node_addr_0The preferred node address for this ECU. Sampled on power-up only.-

8.1.8. OpenECU software versioning

Each target contains a set of software components, each identified by three numbers of the form x.y.z. The first number, x, identifies the major version of the software component. The other numbers, y.z identify the minor and sub-minor versions.

Table 8.30. Software component versions (for M110-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.801.9.036T-068886-ISS-3
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).806.9.036T-068887-ISS-3
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).816.9.036T-068888-ISS-3
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).806.9.036T-068889-ISS-3
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).816.9.036T-068890-ISS-3
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).806.9.036T-068891-ISS-3
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).816.9.036T-068892-ISS-3
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).801.9.036T-068893-ISS-3
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).801.9.036T-070106-ISS-3
Platform library, application support to access ECU functionality.801.9.036T-068894-ISS-1

Table 8.31. Software component versions (for M220-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.331.9.036T-068517-ISS-30
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).336.9.036T-068465-ISS-29
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).346.9.036T-068466-ISS-29
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).336.9.036T-068564-ISS-11
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).346.9.036T-068565-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).336.9.036T-068518-ISS-30
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).346.9.036T-068519-ISS-30
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).331.9.036T-068841-ISS-6
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).331.9.036T-070107-ISS-6
Platform library, application support to access ECU functionality.331.9.036T-068520-ISS-20

Table 8.32. Software component versions (for M220-0AU)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.331.9.036T-068517-ISS-29
Reprogramming code, handles CCP, J1939 and/or UDS communications (default CCP baud rate, 500kbps).336.9.036T-068465-ISS-28
Reprogramming code, handles CCP, J1939 and/or UDS communications (default CCP baud rate, 250kbps).346.9.036T-068466-ISS-28
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).336.9.036T-068564-ISS-10
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).346.9.036T-068565-ISS-10
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).336.9.036T-068518-ISS-29
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).346.9.036T-068519-ISS-29
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).331.9.036T-068841-ISS-6
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).331.9.036T-070107-ISS-6
Platform library, application support to access ECU functionality.331.9.036T-068520-ISS-20

Table 8.33. Software component versions (for M221-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.701.9.036T-068707-ISS-11
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).706.9.036T-068708-ISS-10
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).716.9.036T-068709-ISS-10
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).706.9.036T-068710-ISS-11
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).716.9.036T-068711-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).706.9.036T-068712-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).716.9.036T-068713-ISS-11
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).701.9.036T-068842-ISS-5
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).701.9.036T-070108-ISS-5
Platform library, application support to access ECU functionality.701.9.036T-068714-ISS-2

Table 8.34. Software component versions (for M250-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.291.9.036T-068521-ISS-30
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).296.9.036T-068300-ISS-29
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).306.9.036T-068301-ISS-29
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).296.9.036T-068566-ISS-11
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).306.9.036T-068567-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).296.9.036T-068522-ISS-30
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).306.9.036T-068523-ISS-30
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).291.9.036T-068843-ISS-5
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).701.9.036T-070109-ISS-5
Platform library, application support to access ECU functionality.291.9.036T-068524-ISS-20

Table 8.35. Software component versions (for M460-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.221.9.036T-068525-ISS-30
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).226.9.036T-068304-ISS-30
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).236.9.036T-068305-ISS-30
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).226.9.036T-068568-ISS-11
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).236.9.036T-068569-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).226.9.036T-068526-ISS-30
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).236.9.036T-068527-ISS-30
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).221.9.036T-068844-ISS-5
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).701.9.036T-070110-ISS-5
Platform library, application support to access ECU functionality.221.9.036T-068528-ISS-20

Table 8.36. Software component versions (for M461-000)

ProcessorComponentVersionPart-number
Primary, MPC5534Boot code, selects system mode to enter on reset.271.9.036T-068529-ISS-30
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 500kbps).276.9.036T-068306-ISS-29
Reprogramming code, handles CCP and/or UDS communications (default CCP baud rate, 250kbps).286.9.036T-068307-ISS-29
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).276.9.036T-068570-ISS-11
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).286.9.036T-068571-ISS-11
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).276.9.036T-068530-ISS-30
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).286.9.036T-068531-ISS-30
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).271.9.036T-068845-ISS-5
ETAC, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).701.9.036T-070111-ISS-5
Platform library, application support to access ECU functionality.271.9.036T-068532-ISS-20

Table 8.37. Software component versions (for M670-000)

ProcessorComponentVersionPart-number
Primary, MPC5674FCombined firmware code, Combined boot and reprogramming code (default CCP baud rate, 500kbps).506.9.036T-068815-ISS-9
Combined firmware code, Combined boot and reprogramming code (default CCP baud rate, 250kbps).511.9.036T-068816-ISS-9
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 500kbps).506.9.036T-068817-ISS-9
Firmware upgrade, application to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps).511.9.036T-068818-ISS-9
ETAC for primary processor, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 500kbps).501.9.036T-068835-ISS-8
ETAC for primary processor, hardware embedded test application code to support parametric, function and design validation testing (CAN baud rate, 250kbps).701.9.036T-070112-ISS-8
ETAC for secondary processor, hardware embedded test application code to support parametric, function and design validation testing.501.9.036T-068877-ISS-6
ETAC for secondary processor, hardware embedded test application code to support parametric, function and design validation testing.501.9.036T-068836-ISS-6
Platform library, application support to access ECU functionality.501.9.036T-068819-ISS-20

When providing technical support, Pi may need to know the version numbers for the software components.

Details on how to find out the version numbers for Main processor are given in Section 8.1.7, “Automatic ASAP2 entries”.

Version numbers for HCS12 processor can be retrieved by uploading the software, with FEPS signal applied. Contact technical support for more details.

8.2. Supporting build scripts

At steps 4 and 5 of the build process (see Section 4.6.1, “Building an application”) the compiled and linked application is transformed into two objects:

Figure 8.2. Finishing a build

Finishing a build

  1. During step 4, the compiled and linked image is transformed into a binary image. The binary image can be used by a reprogramming tool or calibration tool to reprogram the ECU.

    The sub-steps required to complete this step vary depending on the compiler (see Section 8.2.1, “Creating a binary image with a supported compiler” for more).

  2. During step 5, the compiled and linked image is transformed into an ASAP2 file. The ASAP2 file can be used by a reprogramming tool or calibration tool to reprogram the ECU or view the application data in real-time.

    The interface tool is used to create the ASAP2 file. See Section 8.1, “Interface and DDE tool” for details on how to use the interface tool, or inspect the batch files provided with the sample applications for concrete examples on how to use the tool.

8.2.1. Creating a binary image with a supported compiler

Step 4 can be broken out into three stages: creating the binary images which make up the target data; patching the library header (see Section 5.3.1.9, “Library header”); and creating S-records for the reprogramming or calibration tool.

Figure 8.3. Building the binary images

Building the binary images

  1. During step 4, Diab's ddump or GNU's objcopy tool is used to extract the binary images from the compiled and linked application (an ELF file). The tool extracts binary data based on linker section names.

  2. During step 6, the OpenECU CAPI-interface tool's --output-s-rec option is used to insert information into the headers located in both the library and calibration binary images. The tool inserts information about the build into the header and adds a check-sum (which the bootloader uses after ECU reset to determine whether the target ECU application code is intact or not (see Section 4.3, “System modes”).

    The tool also transforms the binary data in S-record format, which most reprogramming and calibration tools read.

  3. During step 7, there is no need to check-sum the adaptive data and OpenECU's gen_s37_from_bin tool is used to convert the binary image directly to S-record format.

  4. During step 8, the S-record files can be left as individual files (each to be programmed separately), or can be combined into a single S-record file using the operating system's copy command.

For details of each step, inspect the batch files provided with the sample applications for concrete examples on how to use the tools.

Appendix A. Reference documentation

A.1. ECU hardware reference documentation

For each ECU, there is a technical specification which provides an overview of the electronics and components of the ECU, including a list of connectors, pin outs, pin capabilities, flash codes, and so on. These technical specifications are available from the Windows Start button and from the following links.

Generic ECUs

Available from Pi for general use.

M110-000 technical specificationHTMLPDF
M220-000 technical specificationHTMLPDF
M221-000 technical specificationHTMLPDF
M250-000 technical specificationHTMLPDF
M460-000 technical specificationHTMLPDF
M461-000 technical specificationHTMLPDF
M670-000 technical specificationHTMLPDF

Customer ECUs

No Cutomer-specific ECUs are currently supported.

Further information about ECUs, including simplified I/O schematics and mechanical drawings, can be downloaded from the website (registration or purchase of ECU required) or requested through OpenECU technical support as described in Appendix J, Contact information.

Appendix B. OpenECU error and warning codes

This appendix provides additional information on messages generated by OpenECU. Whenever OpenECU encounters an issue, it reports the problem as an error message or as a warning message. Each message contains an integer code which can be used to index the following list.

B.1. Interface tool messages

B.1.1. Command line option messages

The interface tool can generate the following error and warning messages when it processes the command line options presented to the tool.

  1. (error 100): unrecognised command line arguments, try -h or --help for more.

    The interface tool has detected that there are command line options which mean nothing to the tool. See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  2. (error 101) file 'file name': could not open interface file for reading, 'error message'.

    The interface tool could not read the interface file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  3. (error 102) file 'file name': could not open AST debug file for writing, 'error message'.

    The interface tool could not create or write to the first debug file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  4. (error 103) file 'file name': could not open AST debug file for writing, 'error message'.

    The interface tool could not create or write to the second debug file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  5. (error 104) file 'file name': could not open code file for writing, 'error message'.

    The interface tool could not create or write to the first code file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  6. (error 105) file 'file name': could not open code file for writing, 'error message'.

    The interface tool could not create or write to the second code file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  7. (error 106) file 'file name': could not open m-script file for writing, 'error message'.

    The interface tool could not create or write to the MATLAB m-script file, call file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  8. (error 107) file 'file name': could not open generic ASAP2 file for writing, 'error message'.

    The interface tool could not create or write to the generic ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  9. (error 108) file 'file name': could not open INCA ASAP2 file for writing, 'error message'.

    The interface tool could not create or write to the ETAS INCA ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  10. (error 109) file 'file name': could not open Vision ASAP2 file for writing, 'error message'.

    The interface tool could not create or write to the ATI Vision ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  11. (error 110): at least one command option required an ASAP2 file to be generated but no MAP file or ELF information file was specified. Try -h or --help for more information.

    The interface tool has been asked to generate an ASAP2 file but has not been told the MAP or ELF information file to derive the addresses of DDEs. See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  12. (error 111): the asap2 naming pattern must be one of 'prefix_name', 'prefix.name', 'prefix.name_prefix', 'name', 'name_prefix'.

    The interface tool has been told to transform the DDE names when generating an ASAP2 file, but the interface tool does not understand the transformation required (there are only a few pre-determined transforms). See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  13. (error 112): the boolean type must be specified as 'u8' or 'float'.

    The interface tool has been told to generate ASAP2 boolean types with a specific type, but the interface tool does not understand the type provided. See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  14. (error 113): you may specify a Diab or GCC MAP file OR an ELF information file as input, but not both.

    The interface tool has been given more than one of a Diab MAP file, a GCC MAP file, Diab ddump file, or a GCC objdump file as input but does not know which to use. Specify only one MAP file or ELF information file as input. See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  15. (error 114): you cannot specify data dictionary generation using --output-elf-contents without also specifying an ELF information file to be read.

    Using the command line option --output-elf-contents the interface tool has been told to generate a data dictionary file from the contents of a Diab ddump or GCC objdump file (derived from an ELF file) but no such file has been specified with the --diab-ddumpfile option or --gcc-objfile option. See Section 8.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

  16. (error 115) file 'file name': could not open DDE file for writing, 'error message'.

    The interface tool could not write to the data dictionary file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

  17. (error 116) file 'file name': could not open [type of] file for writing, 'error message'.

    The interface tool could not create or write to the file specified by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

  18. (error 117): you cannot specify address list output using --output-address-list without also specifying a ELF information file to be read.

    The interface tool has been told which file to output the address list to, but it has not been told which Diab ddump or GCC objdump file to read this information from.

  19. (error 118): the compiler must be 'diab_5_5_1_0', 'diab_5_8' or 'diab_5_9'.

    The interface tool has been told which compiler is being used, but it does not recognise the compiler so identified.

  20. (error 119) file 'file name': could not open output linker file for writing, 'error message'.

    The interface tool could not write to the output linker file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

  21. (error 120): to generate a linker file output you must specify the OpenECU installation base path using the --oe-base-path option.

    The interface tool can only output linker file using the --output-linker-file command line option if the --oe-base-path option is also used to specify the path to the OpenECU installation.

  22. (error 121) file 'file name': could not open linker source file for reading, 'error message'.

    The interface tool could not read from the linker source file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  23. (error 122): the compiler must be specified when outputting a linker file for the 'target name' target.

    For any target that supports more than one compiler, the interface tool needs to be passed the compiler id using the --compiler-id command line option when outputting the linker file using the --output-linker-file option.

  24. (error 123): no input program images. Please specify values for --img-app and --img-cal.

    In order to use the --output-s-rec option, the options --img-app and --img-cal must be specified.

  25. (error 124): no diab mapfile. please specify value for --diab-mapfile.

    In order to use the --output-s-rec option, the option --diab-mapfile must be specified.

  26. (error 125): could not open s-record file for writing.

    The tool tried to create the file specified by --output-s-rec , but failed. This often means that the file already exists and is read-only, or the file was specified in a non-existing directory.

  27. (error 126): could not open application image file for reading.

    The tool tried to read the file specified by --img-app , but failed. This often means that the file does not exist.

  28. (error 127): could not open calibration image file for reading.

    The tool tried to read the file specified by --img-cal, but failed. This often means that the file does not exist.

  29. (error 128): could not open linker file excerpt for reading.

    The tool tried to read the file specified by --ld-excerpt-file, but failed. This often means that the file does not exist.

  30. (error 129): cannot check data dictionary entity data types using --check-dde-data-types.

    The tool received an error when checking for the ELF file. When using the --check-dde-data-types option, the ELF file must be specified.

  31. (error 130): Unable to validate license.

    The tool received an error while verifying the license. Verify that OpenECU is installed correctly with a valid license.

B.1.2. File handling messages

  1. (error 200): found internal error — attempting to set the handle for file 'filename' a second time.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  2. (error 201) file 'file name': could not close file.

    The interface tool could not close the file given by 'file name' after the file was opened to be read or written to. In this case, the interface tool may leave a temporary file called 'file name' after the tool completes.

  3. (error 202): found internal error — cannot remove file 'file name' when the type of file is unknown.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  4. (error 203) file 'file name': could not delete temporary file.

    The interface tool could not close the file given by 'file name' after the file was opened to be read or written to. In this case, the interface tool may leave a temporary file called 'file name' after the tool completes.

  5. (error 204): found internal error — repeated file registration for 'file name'.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

B.1.3. Interface file messages

  1. (error 500) line 'number' of 'file name': incomplete string literal, or string literal containing unsupported characters.

    The interface tool has read an interface file called 'file name' and found an error at line 'number' containing a string without a closing quote, or a string containing unsupported characters (only the printable ASCII characters are valid (ranging from character 32 (space) through to character 126 (tilde)). Change the interface file to contain a valid string.

  2. (error 501) line 'number' of 'file name': incomplete comment.

    The interface tool has read an interface file called 'file name' and found an error at line 'number' containing a comment without the final */ characters. Change the interface file to complete the comment.

  3. (error 502) line 'number' of 'file name': unexpected character 'letter'.

    The interface tool has read an interface file called 'file name' and found an error at line 'number' containing text which the tool does not expect to see. See Section 8.1.4, “Interface file contents” for a description of what the interface file can contain.

  4. (error 503) line 'number' of 'file name': could not read number.

    The interface tool has read an interface file called 'file name' and at line 'number' the interface tool could not convert the text into a number. Adjust the number to be valid and in the range [0, 2147483647].

  5. (error 504) line 'number' of 'file name': number must be positive.

    The interface tool has read an interface file called 'file name' and at line 'number' the interface tool found an unexpected negative number. Adjust the number to be in the range [0, 2147483647].

  6. (error 505) line 'number' of 'file name': number must be less than 2147483648.

    The interface tool has read an interface file called 'file name' and at line 'number' found a number which was too large. Adjust the number to be in the range [0, 2147483647].

  7. (error 506) line 'number' of 'file name': cannot use the '-' character in an identifier.

    The interface tool has read an interface file called 'file name' and found a '-' character as part of an identifier at line 'number'. Rename the identifier without the '-' character.

  8. (error 600): found internal error — unexpected error.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  9. (error 601) line 'number' of 'file name': repeated identifier.

    The interface tool has read an interface file called 'file name' and at line 'number' has found an identifier that has been used elsewhere in the interface file. All identifiers must be unique.

  10. (error 602) line 'number' of 'file name': identifier is more than 31 characters in length.

    The interface tool has read an interface file called 'file name' and at line 'number' has found an identifier with more than 31 characters. All identifiers must be limited to a maximum of 31 characters.

  11. (error 603) line 'number' of 'file name': unexpected input.

    The interface tool has read an interface file called 'file name' and at line 'number' has found a syntax error. See Section 8.1.4, “Interface file contents” for a description of what the interface file can contain.

  12. (error 604) line 'number' of 'file name': unexpected end of file.

    The interface tool has read an interface file called 'file name' and at line 'number' has encountered the end of the file while still expecting to see more detail in the interface file. This may occur if there is a missing close brace (}) in the file. See Section 8.1.4, “Interface file contents” for a description of what the interface file can contain.

B.1.4. DDE processing messages

  1. (error 700) file 'file name': could not open tabbed DDE file for reading, 'error message'.

    The interface tool could not read the DDE file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  2. (error 800) file 'file name': could not open units file for reading, 'error message'.

    The interface tool could not read the units file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  3. (error 900) line 'number' of 'file name': from within the 'compound' statement, there is a missing 'assignment' statement.

    The interface tool has read an interface specification file called 'file name' and at line 'number' has found a compound statement with a missing assignment statement called 'assignment'. In this case, the interface tool is expecting the assignment statement to be present (i.e., the assignment statement is not optional).

  4. (error 901) file 'file name': within the interface file, there is a missing 'compound' statement.

    The interface tool has read an interface specification file called 'file name' and at line 'number' has found that the file is missing a compound statement called 'compound'. In this case, the interface tool is expecting the compound statement to be present (i.e., the statement is not optional).

  5. (error 1001): line 'number' of 'file name': 'dde name' is an invalid name for a data dictionary entry (must be greater than 3 characters long).

    All data dictionary entry names must be greater than 3 characters long. Change the name so it is at least 4 characters in length.

  6. (error 1002): line 'number' of 'file name': 'dde name' is an invalid name for a data dictionary entry (must be less than 256 characters long).

  7. (error 1003): line 'number' of 'file name': 'dde name' is an invalid name for a prefix-style data dictionary entry (must not start with a digit or a '_' character).

    To provide compatibility with C compilers, prefix-style DDE names must not start with a digit. If DDE names must start with an underscore then move the DDE to a C-style DDE file.

  8. (error 1004): line 'number' of 'file name': 'dde name' is an invalid name for a prefix-style data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

    C compilers disallow certain characters to appear in variable names. Change the name to avoid the use of these characters.

  9. (error 1005): line 'number' of 'file name': 'dde name' is an invalid name for a calibration map (must end in '_x' or '_y' or '_z').

    The tool has recognised that the DDE forms part of a calibration map but does not conform to the rules for naming these entities. See Section 8.1.5.2, “DDE naming rules (prefix_style)” for more details.

  10. (error 1006): line 'number' of 'file name': 'dde name' is an invalid name for an item which is not a calibration map (must not end in '_x' or '_y' or '_z').

    The tool has recognised that the DDE does not form part of a calibration map and does not conform to the rules for naming these entities. See Section 8.1.5.2, “DDE naming rules (prefix_style)” for more details.

  11. (error 1007): line 'number' of 'file name': 'dde name' is a calibration but has no value.

    The entry is a calibration of some sort but does not contain a default calibration value, which it must do.

  12. (error 1008): line 'number' of 'file name': 'dde name' has an invalid value 'text of value'.

    The tool could not convert the text of the value into a numeric value. All numeric values must be scalar and represent a real value. The following are examples of valid values: 3.14, 10, 10., .001, 1e8, 3.14e-10, 0e0.

  13. (error 1009): line 'number' of 'file name': 'dde name' must be a vector or a matrix surrounded by '[' and ']').

    The tool has recognised that the entry forms part of a calibration map but that the value or values supplied are not valid expressions, either of a vector or of a matrix. Values for an axis (_x or _y) should be given as a vector. Values for the data points (_z) should be given as a vector for 1-d maps or as a matrix for 2-d maps.

    vector

    A vector takes the form [numbers separated by spaces]. An example of a vector containing three elements would be: [10, 15, 20].

    matrix

    A matrix takes the form [vectors separated by semicolons]. An example of a matrix containing three rows and columns would be: [1 2 3; 10 20 30; 100; 200; 300].

  14. (error 1010): line 'number' of 'file name': the row sizes for 'dde name' differ."

    The tool requires map axes and map data to match in size. For instance, a 1-d map with 5 elements in the x-axis, requires 5 elements in the z-data. Change the axis and data elements to match in size.

  15. (error 1011): line 'number' of 'file name': the row size for 'dde name' must be at least 2 entries.

    The tool requires that map axes and map data have at least 2 elements. For instance, if a 1-d map had 1 element for the x-axis and therefore 1 element for the z-data, the map lookup would be equivalent to a scalar variable.

  16. (error 1012): line 'number' of 'file name': the row data for 'dde name' must be 1xN matrix.

    The tool requires that any map axis be a vector (a 1xN matrix), the OpenECU 1-d and 2-d map lookup functions do not work with other sized matrices.

  17. (error 1013): line 'number' of 'file name': the units for 'dde name' is too long (must be less than 'number' characters long).

    The units field must be less than 32 characters long by default so that it can be exported into other file formats (e.g., ASAP2 file) without issues. Either change the units so it contains less than 32 characters, or change the limit using the C-API interface tool command line option '-n' or '--name-length'.

  18. (error 1014): line 'number' of 'file name': the units for 'dde name' cannot contain single quote characters.

    The units field must not contain single quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

  19. (error 1015): line 'number' of 'file name': the units for 'dde name' cannot contain double quote characters.

    The units field must not contain double quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

  20. (error 1016): line 'number' of 'file name': the description for 'dde name' is too long (must be less than 256 characters long).

    The description field must contain less than 256 characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

  21. (error 1017): line 'number' of 'file name': the description for 'dde name' cannot contain single quote characters.

    The description field must not contain single quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

  22. (error 1018): line 'number' of 'file name': the description for 'dde name' cannot contain double quote characters.

    The description field must not contain double quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

  23. (error 1019): line 'number' of 'file name': 'dde name' has an unspecified type (must be one of: int8_T, S8, uint8_T, U8, int16_T, S16, uint16_T, U16, int32_T, S32, uint32_T, U32, real_T, F32, BOOL).

    The type of the DDE must be specified for ASAP2 generation.

  24. (error 1020): line 'number' of 'file name': 'dde name' has an invalid type 'type text' (must be one of: int8_T, S8, uint8_T, U8, int16_T, S16, uint16_T, U16, int32_T, S32, uint32_T, U32, real_T, F32, BOOL).

    The type of the DDE must be well defined for ASAP2 generation.

  25. (error 1021): line 'number' of 'file name': 'dde name' represents map calibration data and must have a real_T or F32 type.

    OpenECU 1-d and 2-d map lookup functions only work with floating point types. Change the type of the map axis or map data to be real_T or F32.

  26. (error 1022): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the accuracy column.

    The tool was expecting to find a number in the accuracy field but found something else instead.

  27. (error 1023): line 'number' of 'file name': 'dde name' has a maximum value but no minimum.

    The tool expects to see both a minimum and a maximum for the DDE if one or the other is present. The DDE must either have no minimum and maximum specified or both.

  28. (error 1024): line 'number' of 'file name': 'dde name' has a minimum value but no maximum.

    The tool expects to see both a minimum and a maximum for the DDE if one or the other is present. The DDE must either have no minimum and maximum specified or both.

  29. (error 1025): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the minimum value.

    The tool was expecting to find a number in the minimum field but found something else instead.

  30. (error 1026): line 'number' of 'file name': 'dde name' has boolean type so its minimum must be zero.

    The type of the DDE is a boolean, so the minimum value must be zero but the tool found a different value for the minimum field.

  31. (error 1027): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the maximum value.

    The tool was expecting to find a number in the maximum field but found something else instead.

  32. (error 1028): line 'number' of 'file name': 'dde name' has boolean type so its maximum must be one.

    The type of the DDE is a boolean, so the maximum value must be one but the tool found a different value for the maximum field.

  33. (error 1029): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the scale value.

    The tool was expecting to find a number in the scale field but found something else instead.

  34. (error 1030): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the offset value.

    The tool was expecting to find a number in the scale field but found something else instead.

  35. (error 1032): line 'number' of 'file name': 'dde name' has a different matrix size from the X-axis matrix size.

    The tool has detected that the z-data matrix size in for the x-axis differs in size from the x-axis. The size of the axes and data must match.

  36. (error 1033): line 'number' of 'file name': 'dde name' has a different matrix size from the Y-axis matrix size.

    The tool has detected that the z-data matrix size in for the y-axis differs in size from the y-axis. The size of the axes and data must match.

  37. (error 1034): line 'number' of 'file name': 'dde name' has multiple rows but no Y-axis data dictionary entry.

    The tool has detected that the z-data for a map contains data for both the x and y axes but no y-axis DDE has been declared.

  38. (error 1035): line 'number' of 'file name': 'dde name' does not have a corresponding X-axis data dictionary entry.

    The tool has detected that there is z-data for a map lookup but no corresponding x-axis DDE has been declared.

  39. (error 1036): line 'number' of 'file name': 'dde name' must be a scalar.

    The tool has read more than one value for the scalar calibration. Only one value can be specified.

  40. (error 1037): line 'number' of 'file name': an unnamed column was found — skipping entire data dictionary.

    The tool has found a column without a name. This can occur if two tab characters are placed next to each other

    Name Value Units Description Type Accuracy Min Max Offset Scale Cref

  41. (error 1038): line 'number' of 'file name': column 'name' is only allowed in 'style'-style data dictionaries — skipping entire 'style'-style data dictionary.

    The tool has found a column in the title line of the data dictionary that it does not recognise. The only valid column names in a prefix-style data dictionary file are:

    Name Value Units Description Type Enums Accuracy Min Max Offset Scale Cref

    The only valid column names in a C-style data dictionary file are:

    Name Units Description Accuracy Min Max Offset Scale Class Xaxis Yaxis Lookup

  42. (error 1039): line 'number' of 'file name': 'dde name' is an invalid Cref for a data dictionary entry (must not start with a digit).

    The tool has found an invalid name for the Cref column. This is an internal error. Please contact OpenECU support.

  43. (error 1040): line 'number' of 'file name': 'dde name' is an invalid Cref for a data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

    The tool has found an invalid name for the Cref column. This is an internal error. Please contact OpenECU support.

  44. (error 1041): line 'number' of 'file name': 'dde name' is a reserved name for a data dictionary entry (must not use the 'mpl' prefix).

    The tool has found a DDE with a name which starts with mpl. This prefix is reserved for OpenECU use. Rename the DDE variable using a different prefix.

  45. (error 1042): line 'number' of 'file name': the 'field_name' field must be present in [style]-style data dictionaries — skipping entire data dictionary.

    The tool has found the title line but could not locate all the necessary fields/columns. At a minimum, the following fields/columns must be present in prefix-style data dictionaries:

    Name Value Units Description Type Min Max

    And for C-style data dictionaries, the following fields/columns must be present:

    Name Units Description Class Min Max

    In both cases, the Name field must be first.

  46. (error 1043): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must be greater than 3 characters long).

    All data dictionary entry enumeration names must be greater than 3 characters long. Change the name so it is at least 4 characters in length.

  47. (error 1044): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must be less than 'number' characters long).

    Some C compilers disallow names that contain more than 31 characters. Some ASAP2 calibration tools disallow names that contain more than 32 characters. Either change the name so it contains less than the character limit, or change the limit using the C-API interface tool command line option '-n' or '--name-length'.

  48. (error 1045): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must not start with a digit or a '_' character).

    C compilers disallow names that start with a digit or '_' character. Change the DDE name to start with a letter.

  49. (error 1046): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

    C compilers disallow certain characters to appear in names. Change the name to avoid the use of these characters.

  50. (error 1047): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must not end in '_x' or '_y' or '_z').

    The tool has recognised that the referenced enumeration looks like a map DDE. Rename the enumeration reference so it does not end like a map.

  51. (error 1048): line 'number' of 'file name': 'dde name' is a reserved name for a data dictionary enumeration entry (must not use the 'mpl' prefix).

    The tool has found a DDE with an enumerated name which starts with mpl. This prefix is reserved for OpenECU use. Rename the DDE variable using a different prefix.

  52. (error 1049): line 'number' of 'file name': 'dde name' uses an enumeration 'enum name' that is not declared in any data dictionary.

    The tool has found an enumeration reference for the DDE named 'dde name' that does not exist in any data dictionary. Change the enumeration reference to a data dictionary entry that does exist.

  53. (error 1050): line 'number' of 'file name': 'dde name' uses an enumeration 'enum_name' which has a non-scalar value.

    The tool has found a reference to an enumeration which has a non-scalar value. All enumerations must be single valued entries.

  54. (error 1051): line 'number' of 'file name': 'dde name' uses enumerations 'enum_name' and 'enum_name' which have the same value.

    The tool has found a data dictionary entry which refers to two enumerations but both enumerations have the same value. Enumerations for one data dictionary entry must have unique values.

  55. (error 1052): line 'number' of 'file name': 'dde name' has a value less than its type allows.

    The tool has found a value for a data dictionary entry which has a value outside the range of its type.

  56. (error 1053): line 'number' of 'file name': 'dde name' has a value greater than its type allows.

    The tool has found a value for a data dictionary entry which has a value outside the range of its type.

  57. (error 1054): line 'number' of 'file name': 'dde name' must not have a scale value of zero.

    The tool has found a DDE with a scaling factor of zero. This is disallowed, as the reciprocal of the factor is used by OpenECU tools and calibration tools.

  58. (error 1055): line 'number' of 'file name': 'dde name' has no corresponding DDE called 'z-data dde name'.

    The tool has found a x-axis DDE without a corresponding z-axis DDE, both are needed to create a 1-d map.

  59. (error 1056): line 'number' of 'file name': 'dde name' has no corresponding DDE called 'z-data dde name'.

    The tool has found a y-axis DDE without a corresponding z-axis DDE, both are needed to create a 2-d map.

  60. (error 1057): line 'number' of 'file name': 'dde name' is a displayable with a value.

    The tool has found a displayable DDE with a value, only calibration DDEs can have values.

  61. (error 1058): line 'number' of 'file name': 'dde name' has a minimum smaller than its type allows.

    The tool has found a DDE which has a minimum value less than the type of the DDE can store. The minimum or type must be adjusted.

  62. (error 1059): line 'number' of 'file name': 'dde name' has a maximum larger than its type allows.

    The tool has found a DDE which has a maximum value greater than the type of the DDE can store. The maximum or type must be adjusted.

  63. (error 1060): line 'number' of 'file name': 'dde name' has duplicated enumeration 'enum name'."

    The tool has found a DDE which has a repeated enumeration in the DDE's enumeration list. Duplicated enumerations are disallowed.

  64. (error 1061): line 'number' of 'file name': 'class' is an invalid Class for a data dictionary entry (must be one of: 'c', 'cmap', 'caxis', 'cstring', 'carray', 'd', 'darray').

    The string 'class' given in the Class column is not one of the allowed types for this DDE.

  65. (error 1062): line 'number' of 'file name': enum 'c identifier' has an invalid byte size = 'bytes'.

    The interface tool has found an enumeration with name 'c identifier' which has a byte size it does not recognise. If this error occurs please contact OpenECU technical support.

  66. (error 1063): line 'number' of 'file name': variable 'c identifier' is a pointer; this is not supported for ASAP2 generation.

    The interface tool can generate ASAP2 files but ASAP2 files cannot represent pointers. DDE references to C variables which have pointer type are therefore rejected.

  67. (error 1064): line 'number' of 'file name': variable 'c identifier' is a bitfield; this is not supported for ASAP2 generation.

    The interface tool cannot yet generate ASAP2 files that access bitfields. Adjust the data structure to avoid using bitfields or copy the bitfields of interest to other variables which are accessible.

  68. (error 1065): line 'number' of 'file name': variable 'c identifier' has a type not currently supported for ASAP2 generation of 'value'.

    The interface tool has found type information for a C variable that it does not know how to handle. If this message occurs, please contact OpenECU technical support.

  69. (error 1066): line 'number' of 'file name': variable 'c identifier' has class cstring but is not a byte array.

    A C-style DDE has been classed as a string but the type of the equivilent C variable is not signed or unsigned char (wide characters are not supported). Either change the C variable to have an appropriate type of change the class of DDE.

  70. (error 1067): line 'number' of 'file name': variable 'dde name' is not class cmap yet has Xaxis, Yaxis and/or Lookup entries.

    A C-style DDE has information in the Xaxis, Yaxis or Lookup columns but the DDE is not a calibration map. Only calibration maps should have information in the Xaxis, Yaxis or Lookup columns.

  71. (error 1068): line 'number' of 'file name': variable 'dde name' used in map must have real_T (float) type.

    OpenECU 1-d and 2-d map lookup functions only work with floating point types. Change the type of the map axis or map data to be real_T or F32.

  72. (error 1069): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which caused an unexpected error.

    An internal error has occurred in the interface tool. If this error occurs, please contact OpenECU technical support.

  73. (error 1070): line 'number' of 'file name': variable 'dde name' has x and y Lookup entries 'string' but no Yaxis entry.

    The calibration map with 'dde name' is 2d and has an x-axis Lookup DDE but no y-axis Lookup DDE. Calibration maps must have a lookup DDE for each map axis.

  74. (error 1071): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which is not found in ELF data.

    The lookup DDE 'name' for calibration map DDE 'dde name' doesn't exist in the Diab ddump file. Check that the spelling is correct, that the equivalent C variable is declared and not optimised away by the compiler.

  75. (error 1072): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which has no corresponding DDE, removing lookup variables from map.

    The lookup DDE 'name' for calibration map DDE 'dde name' doesn't exist as a DDE in any of the other DDE files. The lookup DDE must be declared in one of the DDE files.

  76. (error 1073): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which does not have Class 'd'.

    The lookup DDE 'name' for calibration map DDE 'dde name' is declared as something other than a displayable (Class column set to 'd'). Only displayable variables can be used as lookups to calibration maps.

  77. (error 1074): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which does not have type real_T (float).

    The lookup DDE 'name' for a calibration map DDE 'dde name' must have single precision floating point type to correctly match the C-API to the map lookup functions.

  78. (error 1075): line 'number' of 'file name': variable 'dde name' has Xaxis and Yaxis but only one Lookup entry; should have nothing or two.

    The calibration map with 'dde name' is 2d and has one lookup DDE. Calibration maps must have a lookup DDE for each map axis. Check that the Lookup column does not specify only a y-axis lookup DDE.

  79. (error 1076): line 'number' of 'file name': 'dde name' is not found in the ELF information file output, contains an out of range array index, or is declared but not referenced in the source code.

    A DDE is declared in the data dictionary but the corresponding varaible could not be found in the Diab ddump or GNU objdump output file. Check the name for spelling mistakes or add the corresponding variable to the application C code.

  80. (error 1077): line 'number' of 'file name': map variable 'dde name' has no Xaxis or Yaxis specified.

    A calibration map specified by a C-style DDE has neither the Xaxis and Yaxis DDEs specified. A 1d calibration map must have the Xaxis specified, a 2d calibration map must have both the Xaxis and Yaxis specified.

  81. (error 1078): line 'number' of 'file name': 'dde name' is not found in the ddump ELF file output, contains an out of range array index, or is declared but not referenced in the source code.

    The name for a C-style data dictionary entity wasn't present in the final linked application image and therefore cannot be processed. Check the name for spelling mistakes or add the corresponding variable to the application C code.

  82. (error 1079): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must resolve to a C identifier).

    The name for a C-style data dictionary entity doesn't conform to the allowed scheme (as defined in Section 8.1.5.3.2, “DDE naming rules (C-style)”). The name of the DDE must be changed.

  83. (error 1080): line 'number' of 'file name': variable 'dde name' has Lookup entry 'string' but should have one identifier or two separated by a comma.

    The Lookup column for DDE 'dde name' has an unexcepted value of 'string'. Instead the Lookup column should have one DDE name or two DDE names separated by a comma.

  84. (error 1081): line 'number' of 'file name': unexpected information at end of line — skipping entire data dictionary.

    The tool has found a DDE line containing more information that there are columns. Remove the additional information and tab characters, or declare an additional column in the title line of the DDE file.

  85. (error 1082): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must not start with a digit character).

    To provide compatibility with C compilers, C-style DDE names must not start with a digit.

  86. (error 1083): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_', '.', '[', ']').

    The interface tool accepts a subset of the C lanaguage syntax for variable names, array and structure member access. See Section 8.1.5.3.2, “DDE naming rules (C-style)” for more details.

  87. (error 1085): line 'number' of 'file name': column 'name' is unrecognised — skipping entire data dictionary.

    The tool has found a column with a name it does not recognise, i.e., not one of the allowed column names. The only valid column names in a prefix-style data dictionary file are:

    Name Value Units Description Type Enums Accuracy Min Max Offset Scale Cref

    The only valid column names in a C-style data dictionary file are:

    Name Units Description Accuracy Min Max Offset Scale Class Xaxis Yaxis Lookup

  88. (error 1086): line 'number' of 'file name': DDE 'dde name' has Lookup entry 'string' but should have none, one or two identifiers separated by a comma.

    The Lookup column for DDE 'dde name' has an unexcepted value of 'string'. Instead the Lookup column should have one DDE name or two DDE names separated by a comma.

  89. (error 1087): line 'number' of 'file name': 'dde name' is a constant but has no value.

    The entry is a constant but does not contain a default value, which it must do.

  90. (error 1100) file 'file name': could not open 'ELF-type' output file for reading, 'error message'.

    The interface tool could not read the Diab ddump or GNU objdump file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  91. (error 1101): file 'file name': variable with no name attribute in ELF information file at line 'number'.

    The interface tool has found an unnamed attribute in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  92. (error 1102): file 'file name': 'object' with no type attribute in ELF information file at line 'number'.

    The interface tool has found a variable or typedef declaration without additional type information in the Diab ddump or GCC objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  93. (error 1103): file 'file name': referenced ID not found in ELF information file at line 'number'.

    The interface tool has found a reference in the ELF information file with no corresponding entry, as if the Diab ddump or GNU objdump file was incomplete. If this error occurs please contact OpenECU technical support.

  94. (error 1104): file 'file name': nested array in ELF information file at line 'number'.

    The interface tool has found a nested array reference in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  95. (error 1105): file 'file name': structure element with unreadable offset in ELF information file at line 'number'.

    The interface tool has found a structure member in the Diab ddump or GNU objdump file but could not read the offset information, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  96. (error 1106): file 'file name': structure element with no offset in ELF information file at line 'number'.

    The interface tool has found a structure member that the Diab ddump or GNU objdump file has no offset information for, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  97. (error 1107): file 'file name': variable with no byte size in ELF information file at line 'number'.

    The interface tool has found a variable without size information in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

  98. (error 1108): file 'file name': DIE with two identically named attributes found.

    The interface tool has found two identically named attributes in the contents of the Diab ddump file 'file name'. This is an unexpected condition, please contact OpenECU technical support if this message occurs.

  99. (error 1109): file 'file name': two DIEs with same tag 'name' found in ELF information file.

    The interface tool has found two identically named DIEs in the contents of the Diab ddump or GNU objdump file 'file name'. This is an unexpected condition, please contact OpenECU technical support if this message occurs.

  100. (error 1110): auto-generated data dictionary output from the C-API has been fed back in as input; this is disallowed to avoid the possibility of attempting to write a file which is simultaneously being used as input.

    The interface tool rejects attempts to read the autogenerated data dictionary file the interface tool itself generates. Instead, the autogenerated data dictionary entities of interest should be copied to a separate data dictionary file and included.

  101. (error 1112): file 'file name': no match for 'dde name' in ELF information file.

    The interface tool found an array which was too small or could not find an array element while decoding the 'dde name' DDE. Check that the 'dde name' exists as a C variable and that the variable has not been optimised away by the compiler.

  102. (error 1113): file 'file name': no match for 'dde name' in ELF information file — array bound exceeded.

    The interface tool has found a matching C variable for the DDE 'dde name' but one of the array range specifiers in the DDE is outside the bounds of the equivalent array range of the C variable.

  103. (error 1114): file 'file name': unexpected section type 'name' in ELF information file.

    The interface tool found an ELF section in the Diab ddump or GNU objdump file it wasn't expecting. If this error occurs, please contact OpenECU technical support.

  104. (error 1115): file 'file name': no debug variables or section information found in ELF information file — is this a Diab 5.5.1.0 (or later) ddump -Dht file?

    The interface tool could read the Diab ddump or GNU objdump file but did not find any C variable or ELF section information. Check that the correct file was specified in the command line options.

  105. (error 1116): file 'file name': no match for 'dde name' in ELF information file.

    The interface tool could not find information about DDE 'dde name' in the Diab ddump or GNU objdump output file. This may occur if there is no equivilent C variable with the same name as the DDE.

  106. (error 1117): line 'number' of file 'file name': 'dde name' has an invalid number 'number' for the sample rate value.

    The interface tool expects the sample rate value to be a natural integer.

  107. (error 1118): line 'number' of file 'file name': the group for 'dde name' cannot contain single quote characters.

    The interface tool expects each group name to avoid the use of the single quote character ', to avoid issues with ASAP2 validation by calibration tools.

  108. (error 1119): line 'number' of file 'file name': the group for 'dde name' cannot contain double quote characters.

    The interface tool expects each group name to avoid the use of the double quote character ", to avoid issues with ASAP2 validation by calibration tools.

  109. (error 1120): line 'number' of file 'file name': the group for 'dde name' is invalid (group must start with a '/' character).

    The interface tool expects each group name to be empty or start with a / character denoting the top of the hierachy. In this case, the group is not empty, change the group string to start with a / character.

  110. (error 1200): line 'number' of file 'file name': there must be no more than 8 DAQ rasters defined for CCP messaging.

    The platform software does not support more than 8 DAQ rasters. Reduce the total number of rasters to 8 or less.

  111. (error 1201): line 'number' of file 'file name': the total size of the CCP DAQ rasters must be no more than 254.

    The CCP protocol does not support more than 254 ODTs for all of the defined rasters. Reduce the size of each raster to total less than the allowed limit.

  112. (error 1202): line 'number' of file 'file name': the CCP DAQ raster name '%s' must not be repeated.

    When generating an ASAP2 file, the interface tool requires that the name of each CCP DAQ raster is unique. This avoids situations where a calibration tool displays the same raster name for different rasters, making the selection of raster ambiguous.

  113. (error 1203): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate not smaller than 5 milliseconds.

    The platform software supports CCP DAQ rasters with a base period of 5 milliseconds. Increase the raster rate to be at least 5 milliseconds.

  114. (error 1204): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate not exceeding 10 seconds.

    The platform software supports CCP DAQ rasters with a maximum period of 10 seconds. Reduce the raster rate to at least 10 seconds.

  115. (error 1205): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate that is a multiple of 5 milliseconds.

    The platform software supports CCP DAQ rasters with a period resolution of 5 milliseconds. Adjust the raster rate to be a multiple of 5 milliseconds.

  116. (error 1206): line 'number' of file 'file name': the CCP DAQ raster named '%s' must have have at least one ODT.

    The platform software does supports CCP DAQ rasters with one or more ODTs. Increase the raster size to at least 1.

  117. (warning 1207): line 'number' of file 'file name': the CCP DAQ raster rate '%s' is repeated and may confuse some calibration tools.

    Not all calibration tools support multiple CCP DAQ rasters with the same periodic rate (for example, INCA v.5.1.2). Workaround the calibration tool issue by changing the periodic rates of rasters to differ.

  1. (warning 2001): line 'number' of 'file name': 'dde name' has type 'type' which supports at most 'x' digits of display after the decimal point.

    The tool has detected that the type of the element can support a certain number of digits after the decimal point, but the DDE accuracy field asks for more digits to be displayed. The tool reduces the number of digits to be displayed after the decimal point to the maximum supported by the type.

  2. (warning 2002): line 'number' of 'file name': 'dde name' has a value less than the minimum specified.

    The minimum specified for the DDE is greater than the minimum value given. The minimum field is adjusted to the minimum of the values.

  3. (warning 2003): line 'number' of 'file name': 'dde name' has a minimum greater than the maximum.

    The tool was expecting to see a minimum value less than the maximum value but this was not the case.

  4. (warning 2004): line 'number' of 'file name': 'dde name' has a value greater than the maximum specified.

    The maximum specified for the DDE is greater than the maximum value given. The maximum field is adjusted to the maximum of the values.

  5. (warning 2005): file 'file name': repeated unit 'units'.

    The tool has read the unit 'units' more than once. The redundant copy (or copies) can be removed from the units file.

  6. (warning 2006): file 'file name': empty units file.

    A units file is present but it contains no unit definitions (the file contains whitespace or comments only).

  7. (warning 2007): line 'number' of 'file name': the unit 'unit name' for DDE 'dde name' is not in the units file.

    The tool has read a DDE with a unit definition that does not match any from the units file. Edit the unit definition for that DDE to match any unit definition in the units file, or extend the units file accordingly.

  8. (warning 2008): file 'file name': found an empty tabbed DDE file.

    A tabbed DDE file is present but it contains no DDE definitions (the file contains whitespace or comments only).

  9. (warning 2009): file 'file name': found repeated DDE 'dde name', discarding DDE.

    A repeated DDE named 'dde name' was found in file file name. The original DDE is retained and the duplicate is ignored.

  10. (warning 2010): line 'number' of 'file name': variable 'c identifier' occurs at more than one address.

    The interface tool has found more than address in memory for the same C variable and does not know which address to use. If this warning occurs please contact OpenECU technical support.

  11. (warning 2011): line 'number' of 'file name': ignoring variable 'dde name' for which no type information was obtained from the ELF information file; this may occur if it is declared but not actually used in source code, or if you specify a containing structure instead of a specific element within it.

    The interface tool found a DDE which had no corresponding type information. The DDE information was either derived from a Diab MAP file (which does not contain type information), or the DDE was declared but not used in the source code, or the DDE name refers to a structure rather than a structure member. If a Diab MAP file was used, consider using the Diab ELF file instead, otherwise check the DDE name use in the application source.

  12. Warning (2501): 'dde_name' is an unrecognised map type. Skipping this DDE.

    The tool has found a data dictionary entry which appears as if it were a map but does not follow the naming convention specified in Section 8.1.5.2, “DDE naming rules (prefix_style)”.

  13. Warning (2502): 'dde_name' must be a 1xN vector. Skipping this DDE.

    The tool has found a data dictionary entry which is an array or a axis DDE but the data for the DDE isn't a vector (as required).

  14. Warning (2503): 'dde_name' must be a MxN matrix. Skipping this DDE.

    The tool has found a data dictionary entry which is the z-data for a map but the data for the DDE isn't a 2-D matrix (as required).

  15. Warning (2504): 'dde_name' the x-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector. Skipping this DDE.

    The tool has found a data dictionary entry which has a x-axis DDE which isn't a vector (as required).

  16. Warning (2505): 'dde_name' the size of the x-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector (where N > 1). Skipping this DDE.

    The tool has found a data dictionary entry for an x-axis with only one element. X-axis DDEs should have at least two elements.

  17. Warning (2506): 'dde_name' the size of the x-axis DDE 'dde_name' differs from the number of columns in the map DDE 'map_dde_name'. Skipping this DDE.

    The tool has found a data dictionary entry for an x-axis which does not match the size of the corresponding z-data map DDE.

  18. Warning (2507): 'dde_name' the y-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector. Skipping this DDE.

    The tool has found a data dictionary entry which has a y-axis DDE which isn't a vector (as required).

  19. Warning (2508): 'dde_name' the size of the y-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector (where N > 1). Skipping this DDE.

    The tool has found a data dictionary entry for a y-axis with only one element. Y-axis DDEs should have at least two elements.

  20. Warning (2509): 'dde_name' the size of the y-axis DDE 'dde_name' differs from the number of columns in the map DDE 'map_dde_name'. Skipping this DDE.

    The tool has found a data dictionary entry for a y-axis which does not match the size of the corresponding z-data map DDE.

B.1.5. Automatic DDE generation messages

  1. (error 400): found internal error while searching for an 'os-native' statement — not found but should be present.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  2. (error 402): while creating automatic adaptive DDE 'dde name' an existing DDE of the same name was found — do not replicate adaptive DDEs in DDE files.

    The interface tool has tried to create an automatic adaptive DDE for the corresponding DDE named 'dde name' but found that one is already present. This situation occurs because one of the DDE files contains a definition for a DDE that the interface tool requires — rename the DDE.

  3. (error 403): there is no DDE for the adaptive 'adaptive name'.

    The interface tool has read an interface file which declares some adaptive data using the adaptive-list statement (see Section 8.1.4.36, “Compound statement: adaptives”) but there is no corresponding DDE for the 'adaptive name'. Update one of the DDE files to include a definition of the adaptive data.

  4. (error 404): while creating automatic tune DDE 'dde name' an existing DDE of the same name was found -- do not replicate tune DDEs in DDE files.

    The interface tool has tried to create an automatic Tune DDE for the corresponding DDE named 'dde name' but found that one is already present. This situation occurs because one of the DDE files contains a definition for a DDE that the interface tool requires — rename the DDE.

  5. (error 405): there is no DDE for the tune 'tune name'.

    The interface tool has read an interface file which declares some Tune data using the tune-list statement (see Section 8.1.4.39, “Compound statement: tunes”) but there is no corresponding DDE for the 'tune name'. Update one of the DDE files to include a definition of the adaptive data.

  6. (error 406): found internal error — could not find 'named' node.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  7. (error 407): found internal error — could not find 'named' declaration.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

B.1.6. Code generation messages

  1. (error 950): line 'number' of 'file name': from within the 'compound' statement, there is a missing 'assignment' statement.

    The interface tool has read an interface specification file and found a compound statement with a missing assignment statement called 'assignment'. In this case, the interface tool is expecting the assignment statement to be present (i.e., the assignment statement is not optional).

  2. (error 950): within the 'compound' statement, at least one of these lists of statements must be provided completely (entries marked * are already present):

    (error 950): 1. 'list-of-statements'

    (error 950): 2. 'list-of-statements'

    The interface tool has read an interface specification file and found a compound statement with a missing assignment statement. In this case, the interface tool is expecting the compound statement to contain assignment statements from one of the lists presented (i.e., some assignment statements are not optional).

  3. (error 951): within the interface file, there is a missing 'compound' statement.

    The interface tool has read an interface specification file and found that the file is missing a compound statement called 'compound'. In this case, the interface tool is expecting the compound statement to be present (i.e., the statement is not optional). Missing assignment statements are marked by the absence of an asterisk.

  4. (error 951): within the interface file, at least one of these lists of statements must be provided completely (entries marked * are already present):

    (error 951): 1. 'list-of-statements'

    (error 951): 2. 'list-of-statements'

    The interface tool has read an interface specification file and found a compound statement with a missing assignment statement. In this case, the interface tool is expecting the compound statement to contain assignment statements from one of the lists presented (i.e., some assignment statements are not optional). Missing assignment statements are marked by the absence of an asterisk.

  5. (error 3090): incorrect declarations in target-ecu statement

    The interface tool has not been able to identify the target based on the declarations given in the target-ecu statement. See error text emitted for specific information.

  6. (error 3091): more than one target-ecu statement is present.

    The interface tool has found more than one target-ecu compound statement in an interface file, where the tool was expecting only one.

  7. (error 3092): no target-ecu statement specified.

    The interface tool has found no target-ecu statement in an interface file, when the tool was expecting one.

  8. (error 3093): missing declarations in target-ecu statement.

    The interface tool has found that required declarations were missing from the target-ecu compound statement. See the error text emitted for further details.

  9. (error 3094): multiple declarations in target-ecu statement.

    The interface tool has found multiple declarations in the target-ecu compound statement. See the error text emitted for further details.

  10. (error 3095): 'hw-issue-number' outside range [0, 65535].

    The interface tool has found a hw-issue-number outside the value range of [0, 65535].

  11. (error 3096): 'hw-option' must be a three-character text string.

    The interface tool has found a hw-option text string that was not three characters long.

  12. (error 3101): more than one application statement is present.

    The interface tool has found more than one application compound statement in an interface file, where the tool was expected only one.

  13. (error 3102): miscellaneous error in application statements.

    This error code is emitted for a variety of issues with application statements. See error text emitted for details of problem identified.

  14. (error 3103): 'version' outside range [0, 65535]

    The interface tool has found a major-version, minor-version or subminor-version number outside the value range of [0, 65535].

  15. (error 3121): more than one memory-config statement is present

    The interface tool has found a repeated memory-config compound statement in an interface file (the tool expects only one).

  16. (error 3123): memory configuration is not supported on this target

    Only certain targets support memory configuration. Please consult Appendix D, Memory configurations for further details.

  17. (error 3131): more than one os-native statement is present.

    The interface tool has found a repeated os-native compound statement in an interface file (the tool expects only one).

  18. (error 3141): more than one stack-size statement specified.

    The interface tool has found a repeated stack-size statement in an interface file (the tool expects only one).

  19. (error 3142): no stack-size statement specified.

    The interface tool has not found the stack-size statement in an interface file (the tool was expecting one).

  20. (error 3143): stack size less than 1024 bytes.

    The interface tool has found a stack-size statement specifying less than 1024 bytes (the tool requires at least 1024 bytes to be specified).

  21. (error 3151): miscellaneous task statement error.

    The interface tool reports this error code for several different errors relating to OS task declarations. See emitted error text for details of the problem identified.

  22. (error 3152): no task statement specified.

    The interface tool has found no tasks specified in an os-native compound statement (the tool expects at least one).

  23. (error 3153): more than 12 tasks specified.

    The interface tool has found more than 12 tasks specified in an os-native compound statement (the tool expected less than 12).

  24. (error 3154): task has no specified 'name' statement.

    The interface tool has found a task compound statement without a required 'name' statement.

  25. (error 3155): duplicate task name for task 'name' already exists.

    The interface tool has found a task named 'name' more than once (all task names must be unique).

  26. (error 3156): an existing task 'name' already has a priority of 'value'.

    The interface tool has found a task with a priority of 'value' but the priority value is not unique (all task priority values must be unique).

  27. (error 3157): task rate less than 1 millisecond.

    The interface tool has found a task with a period less than one millisecond (the tool does not support task rates less than one millisecond).

  28. (error 3158): task rate greater than 1 hour.

    The interface tool has found a task with a period greater than one hour (the tool does not support task rates greater than one hour).

  29. (warning 3163): offset greater than twice period for task.

    The interface tool has found a task with an offset (delay before first execution) time that is more than twice the task period. This is allowed but the warning is generated in case the long offset was specified accidentally.

  30. (error 3166): more than one task declared 'tdc-firing'.

    The interface tool has found more than one top-dead-centre triggered angular task. Currently only one such task is supported.

  31. (error 3167): tasks with a 'tdc-firing' trigger are only supported by (xxx) targets.

    The interface tool has found an angle-triggered task specified for an ECU target which does not yet support angular tasks.

  32. (error 3168): more than one task declared 'crank-sync-point'.

    The interface tool has found more than one crank sync-point triggered angular task. Currently only one such task is supported.

  33. (error 3169): tasks with a 'crank-sync-point' trigger are only supported by (xxx) targets.

    The interface tool has found an angle-triggered task specified for an ECU target which does not yet support angular tasks.

  34. (error 3171): resource has no specified name statement.

    The interface tool has found a resource compound statement without a required name statement.

  35. (error 3172): attempt to rename resource 'name'.

    The interface tool has found a resource compound statement with a repeated name statement.

  36. (error 3173): resource with name 'name' already exists.

    The interface tool has found a resource compound statement with a name statement identical to another resource statement (all resource names must be unique).

  37. (error 3174): task 'name' already present in used-by-task statement.

    The interface tool has found a used-by-task statement which repeats a reference to a task (all references must be unique).

  38. (error 3175): task 'name' in used-by-task statement is not declared.

    The interface tool has found a used-by-task statement which refers to a task which is not specified.

  39. (error 3181): more than one can-messaging statement is present.

    The interface tool has found a repeated can-messaging compound statement (the tool expects to find only one).

  40. (error 3182): number of CAN receive messages is reassigned.

    The interface tool has found a repeated number-of-receive-messages statement (the tool expects to find only one).

  41. (error 3183): number of CAN receive messages is outside the range [0,100].

    The interface tool has found a number-of-receive-messages statement with a value outside the valid range of [0, 100].

  42. (error 3184): number of CAN transmit messages is outside the range [0,100].

    The interface tool has found a number-of-transmit-messages statement with a value outside the valid range of [0, 100].

  43. (error 3191): more than one PGN pdu-datapage statement specified.

    The interface tool has found a repeated pdu-datapage statement within a pgn-receive compound statement (the tool expects to see only one).

  44. (error 3201): more than one ccp-messaging statement is present.

    The interface tool has found a repeated ccp-messaging statement (the tool expects only one).

  45. (error 3202): miscellaneous CCP-related error.

    The interface tool reports this error code for several reasons relating to CAN Calibration Protocol statements. See error text emitted for details of problem.

  46. (error 3203): CCP CRO identifier of 'value' is outside the range [0,2047].

    The CRO identifier was specified to be in standard ID mode, and the interface tool has found a cro statement with value outside the valid range.

  47. (error 3204): CCP DTO identifier of 'value' is outside the range [0,2047].

    The DTO identifier was specified to be in standard ID mode, and the interface tool has found a dto statement with value outside the valid range.

  48. (error 3205): CCP CRO and DTO identifiers both have the same value of 'value'.

    The interface tool has found a cro and dto statement with identical CAN identifier values (the CRO and DTO CAN identifiers must be unique).

  49. (error 3206): CCP station address identifier of 'value' is outside the range [0,255].

    The interface tool has found a station-address statement with value outside the valid range.

  50. (error 3207): CCP bus 'value' is outside the range [0,2] supported by target 'name'.

    The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

  51. (error 3208): CCP baud rate of 'value' kBps is not supported.

    The interface tool has found a baud statement with an unsupported value. See Section 8.1.4.15, “Compound statement: ccp-messaging” for supported baud rates.

  52. (error 3209): more than one cro-ext-id statement specified.

    The interface tool has found more than one cro-ext-id statement in the c-api interface file.

  53. (error 3210): more than one dto-ext-id statement specified.

    The interface tool has found more than one dto-ext-id statement in the c-api interface file.

  54. (error 3211): CCP CRO identifier of 'value' is outside the range [0,536870911].

    The CRO identifier was specified to be in extended ID mode, but the cro statement still specifes a value outside of the 29 bit range. range.

  55. (error 3212): CCP DTO identifier of 'value' is outside the range [0,536870911].

    The DTO identifier was specified to be in extended ID mode, but the dto statement still specifes a value outside of the 29 bit range.

  56. (error 3221): more than one j1939-messaging statement is present.

    The interface tool has found a repeated j1939-messaging compound statement (the tool expects only one).

  57. (error 3223): J1939 CAN bus 'value' is outside the range [0,2] supported by target 'name'.

    The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

  58. (error 3224): J1939 message buffer size 'value' is outside the range [8,1785]")

    The interface tool has found a size-of-message-buffer statement with a value outside the valid range.

  59. (error 3225): J1939 number of simultaneous receive messages value of 'value' is outside the range [1,20].

    The interface tool has found a num-simultaneous-rx statement with a value outside the valid range.

  60. (error 3226): J1939 number of simultaneous transmit messages value of 'value' is outside the range [1,20].

    The interface tool has found a num-simultaneous-tx statement with a value outside the valid range.

  61. (error 3227): J1939 num-rx-tx value of 'value' is outside the range [1,100].

    The interface tool has found a num-rx-tx statement with value outside the valid range.

  62. (error 3236): miscellaneous J1939-related error.

    The interface tool reports this error code for several different issues related to J1939 declarations. See error text emitted for details of problem.

  63. (error 3241): J1939 node address of 'value' is reserved and cannot be used in the list of DMx nodes.

    The interface tool has found the address 254 or 255 in a listen-for-dm1-message or listen-for-dm2-message statement (addresses 254 and 255 are reserved by the J1939 protocol).

  64. (error 3242): J1939 node address of 'value' is an address of one of the channels on this node.

    The interface tool has found a listen-for-dm1-message or listen-for-dm2-message statement which refers to an address of this node (the tool will not listen for its own DM1 and DM2 messages).

  65. (error 3251): more than one J1939 this-node statement is present.

    The interface tool has found a repeated this-node statement within a j1939-messaging compound statement (the tool expects only one).

  66. (error 3252): miscellaneous J1939-related error.

    The interface tool reports this error code for several different issues related to J1939 declarations. See error text emitted for details of problem.

  67. (error 3253): J1939 node address cannot be 254 or 255.

    The interface tool has found a this-node compound statement containing an address statement using a reserved address (valid address range is [0, 253]).

  68. (error 3254): J1939 node industry-group value of 'value' is outside range of [0,7].

    The interface tool has found a this-node compound statement containing an industry-group statement with invalid value.

  69. (error 3255): J1939 node vehicle-system-instance value of 'value' is outside range of [0,15].

    The interface tool has found a this-node compound statement containing a vehicle-system-instance statement with invalid value.

  70. (error 3256): J1939 node vehicle-system value of 'value' is outside range of [0,127].

    The interface tool has found a this-node compound statement containing a vehicle-system statement with invalid value.

  71. (error 3257): J1939 node function value of 'value' is outside range of [0,255].

    The interface tool has found a this-node compound statement containing a function statement with invalid value.

  72. (error 3258): J1939 node function-instance value of 'value' is outside range of [0,31].

    The interface tool has found a this-node compound statement containing a function-instance statement with invalid value.

  73. (error 3259): J1939 node ecu-instance value of 'value' is outside range of [0,7].

    The interface tool has found a this-node compound statement containing an ecu-instance statement with invalid value.

  74. (error 3260): J1939 node manufacturer-code value of 'value' is outside range of [0,2047].

    The interface tool has found a this-node compound statement containing a manufacturer-code statement with invalid value.

  75. (error 3261): J1939 node identify-number value of 'value' is outside range of [0,2097151].

    The interface tool has found a this-node compound statement containing an identify-number statement with invalid value.

  76. (error 3271): more than one PGN size statement specified.

    The interface tool has found a pgn-receive compound statement containing a repeated size statement (the tool expects only one).

  77. (error 3276): J1939 PGN has a size outside the range of [0,1785] bytes.

    The interface tool has found a pgn-receive compound statement containing a size statement with an invalid value.

  78. (error 3277): J1939 PGN has a size larger than the J1939 message buffer.

    The interface tool has found a pgn-receive compound statement containing a size statement with a value greater than the value specified in the J1939 size-of-message-buffer statement. All J1939 messages must not exceed the size specified in the size-of-message-buffer statement.

  79. (error 3278): duplicate PGN requested information found.

    The interface tool has found a more than one pgn-receive compound statement with the same PGN (the tool expects only one).

  80. (error 3291): miscellaneous J1939 PGN-related error.

    The interface tool reports this error code for several different issues related to J1939 PGN declarations. See error text emitted for details of problem.

  81. (error 3292): pdu-datapage value of 'value' is outside the range [0,1].

    The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-datapage statement with an invalid value.

  82. (error 3293): pdu-format value of 'value' is outside the range [0,255].

    The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-format statement with an invalid value.

  83. (error 3294): pdu-specific value of 'value' is outside the range [0,255].

    The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-specific statement with an invalid value.

  84. (error 3295): J1939 PGN has a PDU format less than 240 and a PDU specific value that is non-zero.

    The interface tool has found a pgn-receive or pgn-requested compound statement where the PDU1 format requires the PDU specific to be specified as zero (the library substitutes the destination address automatically).

  85. (error 3296): duplicate PGN receive information found.

    The interface tool has found a more than one pgn-requested compound statement with the same PGN (the tool expects only one).

  86. (error 3297): duplicate PID ID found.

    The interface tool has found more than one PID with its j1979-8bit-id statement set to the same identifier.

  87. (error 3298): duplicate PID ID found.

    The interface tool has found more than one PID with its kwp-8bit-id statement set to the same identifier.

  88. (error 3299): duplicate PID ID found.

    The interface tool has found more than one PID with its iso-16bit-id statement set to the same identifier.

  89. (error 3300): duplicate DTE ID 'id' found

    The interface tool has found a DTE identifier 'id' more than once (DTE IDs must be unique).

  90. (error 3301): more than one DTC storage statement specified.

    The interface tool has found a dtc-data compound statement with a repeated storage statement (the tool expects one).

  91. (error 3302): target 'name' does not support battery backed RAM storage.

    The interface tool has found a dtc-data compound statement containing a storage statement which specifies battery backed RAM for a target which does not implement battery backed RAM.

  92. (error 3303): DTCs are not supported for target 'name'.

    The interface tool has found a dtc-data compound statement for a target which does not support DTCs.

  93. (error 3304): duplicate DME ID 'id' found

    The interface tool has found a DME identifier 'id' more than once (DME IDs must be unique).

  94. (error 3305): undeclared Monitor group ID 'id' used

    The interface tool has found that the Monitor group ID 'id' defined for the DTE is not defined (each DTE must be associated with a Monitor that exists).

  95. (error 3311): miscellaneous DTC error.

    The interface tool reports this error code for several issues relating to J1939 and ISO-15765 Diagnostic Trouble Codes. See error text emitted for details of problem.

  96. (error 3312): duplicate DTC named 'name' specified.

    The interface tool has found a dtc- compound statement containing a name statement specifying an identical name to another object (the tool expects all names to be unique).

  97. (error 3313): DTC uses an undeclared table 'name'.

    The interface tool has found a dtc compound statement containing a table statement that refers to an unspecified table.

  98. (error 3314): J1939 DTC SPN value of 'value' is outside the range [0,524287].

    The interface tool has found a dtc-j1939 compound statement containing a spn statement with an invalid value.

  99. (error 3315): J1939 DTC FMI value of 'value' is outside the range [0,31].

    The interface tool has found a dtc-j1939 compound statement containing a fmi statement with an invalid value.

  100. (error 3316): J1939 DTC CM value of 'value' is outside the range [0,1].

    The interface tool has found a dtc-j1939 compound statement containing a cm statement with an invalid value.

  101. (error 3317): duplicate DTE ID 'id' specified

    The interface tool has found a DTE identifier 'id' more than once (DTE IDs must be unique).

  102. (error 3318): duplicate DME ID 'id' specified

    The interface tool has found a DME identifier 'id' more than once (DME IDs must be unique).

  103. (warning 3319): DTE uses an undefined DME 'id'

    The interface tool has found that the DME ID 'id' defined within the DTE is not defined (each DTE should be associated with a DME that exists, otherwise it is orphaned).

  104. (warning 3320): no DTEs have been defined for this DME 'id'

    The interface tool has found that the DME ID 'id' has not been associated with any DTE. This is allowed, but a warning is raised to check if it is intentional.

  105. (warning 3321): ISO diagnostics physical address and functional address receive IDs are the same

    The interface tool has found that the same ID has been used for the Physical and Functional Rx on ISO-15765 comms. This is currently allowed, but a warning is raised in case this was unintentional.

  106. (error 3341): adaptive adaptive name has already been specified.

    The interface tool has found more the same adaptive parameter name listed more than once.

  107. (error 3345): more than one adaptive storage statement specified.

    The adaptive storage statement specifies where adaptives should be stored when the ECU is not powered (e.g. flash, battery-backed RAM). Only one such statement is allowed.

  108. (error 3346): target target_name does not support battery backed RAM storage.

    The adaptive storage statement specifies where adaptives should be stored when the ECU is not powered (e.g. flash, battery-backed RAM). Here a target ECU has been specified which does not support battery backed RAM storage.

  109. (error 3351): Tunes are not supported for target 'name'.

    The interface tool has found a tunes compound statement for a target which does not support Tunes.

  110. (error 3352): no application statement specified.

    The interface tool has found no application statement in an interface file, when the tool was expecting one.

  111. (error 3353): no os-native statement specified.

    The interface tool has not found the os-native compound statement in an interface file (the tool was expecting one).

  112. (error 3354): task 'name' has no specified 'priority' statement.

    The interface tool has found a task compound statement without a required 'priority' statement.

  113. (error 3355): task 'name' has no specified 'period' statement.

    The interface tool has found a task compound statement for a periodic task which has no (or zero) repetition time period specified.

  114. (error 3356): task 'name' has a specified 'period' statement.

    The interface tool has found a task compound statement for a non-periodic (e.g. angular) task which has a repetition time period specified.

  115. (error 3357): task 'name' has no specified 'function' statement.

    The interface tool has found a task compound statement for a task which has no C function specified.

  116. (error 3358): resource 'name' has no specified used-by-task statement.

    The interface tool has found a resource compound statement without a required used-by-task statement.

  117. (error 3359): number of CAN transmit messages is reassigned.

    The interface tool has found a repeated number-of-transmit-messages statement (the tool expects to find only one).

  118. (error 3360): more than one DTC lamp state priority statement specified.

    The interface tool has found a dtc-data compound statement with a repeated dtc-lamp-state-priority statement (the tool expects at most one).

  119. (error 3361): more than one DTC transition previously active to pending statement specified.

    The interface tool has found a dtc-data compound statement with a repeated dtc-transition-prev-active-to-pending statement (the tool expects at most one).

  120. (error 3401): PID ID out of range.

    The interface tool has found a diagnostic PID with an out of range 16-bit ID number.

  121. (error 3402): ISO diagnostics receive ID is outside the range

    The interface tool has found an receive ID beyond permitted range for ISO-15765 (permitted range is [0, 0x7FF] for standard ID and [0, 0x1FFFFFF] for extended ID).

  122. (error 3403): ISO diagnostics physical address receive ID is same as the transmit ID

    The interface tool has found that the same ID has been used for the Physical Rx and Tx IDs for ISO-15765 (the receive and transmit IDs have to be different).

  123. (error 3404): ISO diagnostic tx buffer size must be in range [1, 4095]

    The interface tool has found that the Tx buffer size defined for ISO-15765 is out of allowed range.

  124. (error 3405): ISO diagnostic rx buffer size must be in range [1, 4095]

    The interface tool has found that the Rx buffer size defined for ISO-15765 is out of allowed range.

  125. (error 3406): more than one ISO Diagnostic can-bus statement specified

    The interface tool has found a repeated ccp-messaging statement (the tool expects only one).

  126. (error 3407): PID ID out of range.

    The interface tool has found a diagnostic PID with an out of range 8-bit ID number.

  127. (error 3408): J1939 dm7-req-buf-size value of 'value' is outside the range [1,10]

    The interface tool has found that the DM7 request buffer/ queue size is out of allowed range.

  128. (error 3409): duplicate AECD number error.

    The interface tool has found a more than one aecd compound statement with the same AECD number (the tool expects only one).

  129. (error 3410): test map position out of range.

    The interface tool has found a test map position outside the permitted range of [1, 64].

  130. (error 3411): test ID is out of range.

    The interface tool has found a test ID outside the permitted range of [1, 0xFF].

  131. (error 3412): test map position redefined.

    The interface tool has found a test map position that has been assigned to more than one test ID.

  132. (error 3413): DTC time-to-derate value out of range.

    The interface tool has found a DTC time-to-derate value outside the permitted range of [0, 225000] seconds.

  133. (error 3414): J1939 Suspect Parameter Number (SPN) out of range.

    The interface tool has found a J1939 SPN outside the permitted range of [0, 524287].

  134. (error 3415): J1939 multiframe-priority value out of range.

    The interface tool has found the J1939 multiframe-priority value outside the permitted range of [0, 7].

  135. (error 3416): ISO bus 'value' is outside the range [0,2] supported by target 'name'.

    The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

  136. (error 3421): ISO diagnostic maximum number of UDS dynamically defined identifiers must be in range [0, 255].

  137. (error 3422): ISO diagnostic maximum number of UDS periodic identifiers must be in range [0, 254].

  138. (error 3423): ISO diagnostic periodic ID base period must be in range [20, 65530].

  139. (error 3430): DTC extended data record number 'value' is outside the range [1,239].

    The interface tool has found a DTC extended data record number outside of the permitted range of [1,239].

  140. (error 3572): target declaration in target-ecu statement.

    The interface tool has found a target declaration in the target-ecu statement for an interface file. The use of target declarations is now deprecated and will become illegal in a future release. Please delete this declaration.

  141. (error 3501): DTE or DME identifier is not defined.

    The interface tool has found a dte statement without the required dte-id or a dme statement without the required dme-id statement.

  142. (error 3503): Routine identifier is not defined.

    The interface tool has found a routine statement without the required iso-16bit-id statement.

  143. (error 3504): Routine identifier is reserved by the platform.

    The interface tool has found a routine statement that has the iso-16bit-id statement set to a routine ID that is reserved by the platform software. Please select a different routine ID.

  144. (error 3505): Duplicate routine ID found.

    The interface tool has found more than one UDS service $31 routine with its iso-16bit-id statement set to the same identifier.

  145. (error 3506): Routine data byte length outside of range [0, 4095]

    The interface tool has found that the byte length for a UDS service $31 data item is out of allowed range of [0, 4095].

  146. (error 3572): target declaration in target-ecu statement.

    The interface tool has found a target declaration in the target-ecu statement for an interface file. The use of target declarations is now deprecated and will become illegal in a future release. Please delete this declaration.

  147. (error 3574): missing hw-part-number declaration in target-ecu statement.

    The interface tool has found the hw-part-number declaration to be missing from the target-ecu statement for an interface file. A default hw-part-number as displayed in the warning text emitted has been reconstructed using the target declaration instead. Please note that the use of target declarations is now deprecated and will become illegal in a future release. Please replace this declaration with the correct hw-part-number, hw-issue-number and hw-option declarations instead.

  148. (error 3575): missing hw-issue-number declaration in target-ecu statement.

    The interface tool has found the hw-issue-number declaration to be missing from the target-ecu statement for an interface file. A default hw-issue-number as displayed in the warning text emitted has been reconstructed using the target declaration instead. Please note that the use of target declarations is now deprecated and will become illegal in a future release. Please replace this declaration with the correct hw-part-number, hw-issue-number and hw-option declarations instead.

  149. (error 3576): multiple security settings for CCP privilege level

    The interface tool has found multiple security statements specifying settings for the same CCP privilege level in the ccp-messaging statement for an interface file. At most one security statement must exist for a CCP privilege level.

  150. (error 3577): parameter 'dde-entry' missing from J1979 freeze frames declaration

    The interface tool has found the dde-entry declaration to be missing from the declaration of a J1979 protocol freeze frame.

  151. (error 3578): parameter 'dde-entry' missing from uds snapshot declaration.

    The interface tool has found the dde-entry declaration to be missing from the declaration of a UDS protocol freeze frame.

  152. (error 3579): parameter 'dde-entry' missing from J1939 dm4 freeze frame declaration.

    The interface tool has found the dde-entry declaration to be missing from the declaration of a J1939 protocol dm4 freeze frame.

  153. (error 3580): type option 'type' unknown, expecting one of: dm4, dm25.

    The interface tool has found an invalid type declaration for a J1939 freeze frame.

  154. (error 3581): type option 'type' unknown, expecting one of: snapshot.

    The interface tool has found an invalid type declaration for a UDS freeze frame.

B.1.7. ASAP2 generation messages

  1. (error 300) file 'file name': could not open map file for reading, 'error message'.

    The interface tool could not read the mapfile given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

  2. (error 3001) file 'file name': label 'name' is not defined by 'map file' but is required for ASAP2 generation.

    The interface tool has read a DDE called 'name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP file called 'map file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern).

  3. (error 3002) file 'file name': label 'name' is not defined by 'file' but is required for ASAP2 generation of DDE 'dde name'.

    The interface tool has read a DDE called 'dde name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP or ddump file called 'file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern).

  4. (error 3003): found internal error while creating an ASAP2 entry for DDE 'dde name' — no X-axis DDE 'name' found.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  5. (error 3004): found internal error while creating an ASAP2 entry for DDE 'dde name' — no Y-axis DDE 'name' found.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  6. (error 3005): found internal error while creating an ASAP2 entry for DDE 'dde name' — DDE class 'type' is unsupported.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  7. (error 3006): found internal error while searching for an 'os-native' statement — not found but should be present.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  8. (error 3007): found internal error while searching for task 'name' required by an ATI shadow table — not found but should be present.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  9. (error 3008): found internal error while creating a unique ASAP2 identifier for DDE 'dde name' — too many unique conversions.

    The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

  10. (warning 3009) line 'number' of 'file name': the DDE name 'dde name' is either too long for an ASAP2 identifier (max 32 characters), or clashes with another identifier, and has been changed to 'short dde name' for ASAP2 file generation.

    The interface tool has read a DDE file called 'file name' and at line 'number' has found a DDE called 'dde name' which is too long for an ASAP2 file. The DDE has been changed to 'short dde name' which is guaranteed to be unique and be less than 33 characters long.

  11. (warning 3010) file 'file name': label 'name' is not defined by 'map file' but is required for ASAP2 generation, DDE not added to ASAP2 file.

    The interface tool has read a DDE called 'name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP file called 'map file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern), or because the DDE file is out of date. The warning does not stop generation of the ASAP2 file, but the DDE will not be added to the ASAP2 file.

  12. (error 3011): found internal error while creating an ASAP2 entry for DDE 'dde name' -- X-axis 'dde' must have at least two elements. (Note unspecified array size in code is currently read as one element.)

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  13. (error 3012): found internal error while creating an ASAP2 entry for DDE 'dde name' — X-axis DDE 'name' must be 'caxis' Class.

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  14. (error 3013): found internal error while creating an ASAP2 entry for DDE 'dde name' — Y-axis DDE 'name' must be 'caxis' Class.

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  15. (error 3014): found internal error while creating an ASAP2 entry for DDE 'dde name' -- Y-axis DDE 'name' must be 1-D array.

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  16. (error 3015): found internal error while creating an ASAP2 entry for DDE 'dde name' -- Y-axis 'dde' must have at least two elements. (Note unspecified array size in code is currently read as one element.)

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  17. (error 3016): found internal error while creating an ASAP2 entry for DDE '%s' — Y-axis DDE '%s' must also be in C-style data dictionary

    If the calibration map DDE 'dde name' is declared in a C-style data dictionary file then the x-axis DDE 'name' must also be declared in a C-style data dictionary. It is not possible to mix axis and map definitions between prefix and C style data dictionaries.

  18. (error 3017): found internal error while creating an ASAP2 entry for DDE 'dde name' — X-axis DDE 'name' must also be in C-style data dictionary.

    If the calibration map DDE 'dde name' is declared in a C-style data dictionary file then the y-axis DDE 'name' must also be declared in a C-style data dictionary. It is not possible to mix axis and map definitions between prefix and C style data dictionaries.

  19. (error 3018): found internal error while creating an ASAP2 entry for DDE 'dde name' -- map array must be array.

    The interface tool needs to generate an ASAP2 map definition but has found an internal error.

  20. (error 3019): found internal error while creating an ASAP2 entry for DDE 'dde name' — 2D array but only Xaxis specified.

    The interface tool needs to generate an ASAP2 map definition for a two-dimensional calibration map DDE 'dde name' but only one axis has been specified. Both the Xaxis and Yaxis columns must be specified.

  21. (error 3020): found internal error while creating an ASAP2 entry for DDE 'dde name' -- array size incompatible with axis size(s).

    The interface tool needs to generate an ASAP2 map definition for a calibration map DDE 'dde name' but the equivalent C variable does not match the size of the map axes. For instance, a map with 4 elements in the x-axis and 10 elements in the y-axis, must have an equivalent C variable with 40 elements.

  22. (warning 3021) file 'file name': one-dimensional array expected for 'dde name'; now treated as such.

    A DDE called 'dde name' is expected to be a one dimensional array (for instance, because it's Class column specifies the DDE to be an axis or a string) but the equivalent C variable is not one dimensional (but should be).

  23. (error 3022): file 'file name': label 'dde name' according to 'file' has more than 3 final array dimensions.

    The interface tool can generate ASAP2 entities with up to 3 dimensions but no more, because the ASAP2 syntax does not allow further dimensions. However, the interface tool will break up arrays with more than 1 or 2 dimensions into multiple DDEs of smaller dimension. If this error occurs, please contain OpenECU technical support.

  24. (error 3023): C-style data dictionary specified in dde_filename not allowed without ELF information file.

    For ASAP2 generation, C-style data dictionaries can only be used if a Diab ddump or GNU objdumb ELF information file file is also specified (not just a map file). Otherwise the tool cannot obtain the types and sizes of the variables detailed in the data dictionary.

  25. (error 3024): found internal error while creating an ASAP2 entry for DDE 'dde name' -- X-axis DDE 'name' must be 1-D array.

    The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

  26. (warning 3025): string array 'dde name' had zero size, so a default size of 'bytes' has been used, hence it may display incorrectly.

    The DDE string 'dde name' has an equivalent C variable in the Diab ddump file with no information about the string's size. The interface tool generates an entry for the DDE but with a size 'bytes' long which probably does not match the actual string length. To avoid this, use an explicit array size in the C declaration.

  27. (error 3026): found internal error while creating an ASAP2 entry for DDE 'dde name' — too many array dimensions for map data.

    The interface tool needs to generate an ASAP2 map definition for a calibration map DDE 'dde name' but the equivalent C variable has more dimensions than the calibration map.

  28. (warning 3028): the application name, 'name', contains characters not supported by ASAP2 standards; the application name has been replaced with 'updated name'.

    The application name generated in the ASAP2 file contained characters that were unacceptable in accordance to ASAP2 standards. The calibration tool Vector CANape doesn't support use of such ASAP2 files. The C-API interface tool has been updated to generate ASAP2 files containing characters of the application name that are in accordance with the standards.

  29. (error 3332) shadow table references task (task) but that task as not been declared.

    The shadow table entry must reference a declared task. This is the task which is to carry out the calibration tool writes. Here a task is referenced which has not been declared.

  30. (error 3333) more than four shadow-table statements are present.

    The tool does not currently support more than four shadow table statements.

  31. (warning 3334) shadow table must have number of entries in the range [1, 256].

    The number of entries in the shadow table is not within the supported range.

B.1.8. ELF to DDE generation messages

  1. (error 4001): C-style data dictionary specified in 'file name' not allowed without ELF ddump output.

    The interface tool has been asked to generate a C-style DDE file from the Diab ddump input file but a Diab MAP file has been specified instead. Change from the MAP file to the ddump file.

B.1.9. Data type checks between ELF and DDE messages

  1. (warning 5001): the DDE [name] is not defined by [ELF-file] and may be redundant, consider removing from DD file.

    The interface tool has identified that a data dictionary entry with a given name was not found in the ELF file. This may indicate that the DDE is no longer required and can be removed from the data dictionary. Or this may indicate that Simulink Coder has not generated a variable for the DDE and a change is necessary to the model or model configuration.

  2. (warning 5002): the automatically added DDE [name] is not defined by [ELF-file], please contact OpenECU technical support.

    The interface tool has identified that a data dictionary entry with a given name was not found in the ELF file. The data dictionary entry was automatically added by the C-API tool, and failures of this type are not expected. Please contact OpenECU technical support if this warning occurs.

  3. (warning 5003): the DDE [name] is defined with data type [a] but the ELF uses data type [b].

    The interface tool has identified that a data dictionary entry with a given name and given data type a, but that Simulink Coder generated a variable using data type b. This can lead to the calibration tool incorrectly displaying the value of a signal. To remove the warning, change the DDE data type to match that generated by Simulink Coder.

Appendix C. Supporting tools

C.1. Introduction

This section provides a quick introduction to the tools that support OpenECU, both supplied by Pi Innovo and those by other companies. The section is intended to be a first step with the tools when used with OpenECU.

For tools that are supplied by other companies, additional details about how to use the tools can be found in their respective manuals. Pi Innovo will not provide technical support in the use of these tools.

The sections on the calibration tools (Section C.3, “ATI Vision”, Section C.5, “Vector CANape”, Section C.4, “ETAS INCA”) and on a free programming tool called FreeCCP (Section C.6, “FreeCCP”) assume that the step1 example application (see Chapter 3, Quick start for details) has been built using the default CCP settings (Table 4.2, “CCP defaults”) and that the user is familiar with the installation of the calibration tool.

C.2. PiSnoop

Pi Innovo's PiSnoop tool has many functions that are useful in typical OpenECU developments. It offers a cost-effective alternative to traditional calibration tools, but its emphasis is more on software development than calibration. Therefore it presents an interface that is part way to a debugger in terms of watch and memory windows, but typically interacts with the ECU via CCP, just like a calibration tool.

A demo version of PiSnoop is available from our website) in which all features may be tried out, but with some limitations on the number or duration of operations. This provides a route to getting up and running right away with OpenECU.

PiSnoop is under continual development, so this manual does not attempt to document how to use it with OpenECU in detail as is done for the other tools below. Instead, see the online help that is included in the PiSnoop installation (including the specific OpenECU application note) for up-to-date guidance. In brief however, capabilities include:

  • Works with any Vector, Kvaser or PEAK-System (PCAN) CAN interface on Windows XP or higher.

  • Loads symbols (parameter names, addresses, types and descriptions) from ASAP2 (.a2l) files...

  • ... but can also load symbols from the linker output (.elf) files, giving access to all static C language objects present including arrays, structure elements, pointers and bitfields, without needing data dictionary entries. In Simulink builds, this means Real-Time Workshop structures such as rtDWork and rtB can be explored, making "hidden" block-related values, present in the autocode, available for debug purposes.

  • ECU memory access and flash reprogramming via CCP, with seed-key security support and fast DAQ data-logging, which tolerates ECU power cycling.

  • Reloading symbols and/or reprogramming the ECU after rebuilding is a single-click operation.

  • Calibration parameter value changes can be uploaded by name to a file, to use for download or flash reprogramming with a different build later.

  • Watch, map lookup and raw memory windows to view and edit ECU memory or offline file images.

  • CAN traffic generation and monitoring/logging with .dbc file support for named messages and signals.

  • ISO 15765-2 (UDS/Keyword Protocol/J1979) and J1939 diagnostic messaging windows.

  • UDS/Keyword Protocol can be used as an alternative memory access and flash reprogramming protocol, with seed-key security support.

  • ASAP3 support is provided to enable test automation.

  • Extensible through plug-in architecture supporting new protocols, hardware interfaces and custom windows.

C.2.1. Example Screenshots

This shows how calibration parameters and RAM variables can be accessed and logged together in debugger-style watch windows. Parameters can be loaded from ASAP2 (.a2l) and linker (.elf) files simultaneously. Structures, pointers, bitfields and arrays can be explored:

Debugger-style memory windows can be used to view and edit memory contents. Known symbols loaded from .a2l or .elf files are highlighted when the mouse pointer is placed over their locations:

Further windows are integrated for CAN and diagnostic functions. For example, arbitrary CAN traffic can be generated by hand or using a .dbc file:

Similarly, CAN traffic can be monitored and logged:

C.3. ATI Vision

ATI Vision by Accurate Technologies is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU.

C.3.1. Creating a new project and strategy in ATI Vision

The following instructions assume the user is using a supported version. These instructions were transcribed against a supported version but it may be that these instructions match other versions of the tool.

They also assume that an ATI Vision Hub is used. If another communications device is used, the user will need to deviate from these instructions.

  1. Install ATI vision, the installer may reboot your machine. Once windows is restarted, it will detect new USB hardware (assuming the hub is plugged in: if not, plug it in).

    Ask windows to install the USB hardware software from the "device software" directory located where you just installed ATI vision, e.g., c:\program files\Accurate Technologies\ati vision\device software.

    Start Vision and you will be presented with a window similar to the following:

  2. Next, you must create a project to details how ATI Vision will communicate with the OpenECU device.

    Create a new project using the menu option File->New, then select Project.

    and save it somewhere on your hard-disk (here, it has been saved using the name "example_project").

    Next, add a device by right clicking on the Computer item and selecting "Add Device..."

    Select USB port and in the subsequent dialog, accept all the defaults and select OK.

    Next, add a device by right clicking on the USB item and selecting "Add Device..."

    Select VISION Network Hub in the subsequent dialog and select OK.

    Accept the default hub name and in the subsequent dialog properties defaults by selecting OK.

    Next, add another device by right clicking on the VisionHub item and selecting "Add Device..."

    Select a VNI CAN device type, accept the default name and in the subsequent dialog, accept the defaults by selecting OK.

    Next, add another device by right clicking on the VNICAN item and selecting "Add Device..."

    Select the CCP Controller Device, accept the default name and in the subsequent dialog, accept the defaults by selecting OK. This has told the Vision tool that you will be communicating to a CCP compatible device over CAN via the Vision Hub connected to the PC via a USB cable.

  3. Next, you must create a strategy file to hold both the calibration data and program data. Select File->New, then Strategy File.

    The main Vision window will change and you will be presented with the import wizard. Select the ASAP2 description file item.

    For the step1 example, select the step1_tool_vision.a2l file from the location where you built it (note that the following diagrams show an older version of the step1 application called step1_r12_g800).

    It is important to keep the "Strategy Presets" text box clear and to tick the "Delete existing data items from before importing" check-box. This ensures that the memory and CCP settings are taken from the ASAP2 file and that subsequent imports of the same strategy will clear out previous ASAP entries before loading the latest.

    When using the C-API and C-style data dictionaries the Structure naming selection becomes important as well. Selecting Names separated with underscores keeps the names of DDEs as close as possible to the original DDE name.

    Click Import to read in the ASAP2 file, then click on the More button.

    Select import memory image, then select Motorola S-record File, then browse and select the step1_image_small.s37 file from the place where you built it.

    Select Import, then Finish. The Wizard dialog box now closes.

    Note

    You must now save this strategy (menu option File->Save) and change back to the project file by clicking on the "example_project" tab at the bottom of the Vision window.

C.3.2. Downloading an application with an ATI Vision strategy

The following instructions assume the user is using a supported version of ATI Vision. These instructions were transcribed against a supported version but it may be that these instructions match other versions of the tool.

They also assume that an ATI Vision Hub is used. If another communications device is used, the user will need to deviate from these instructions.

  1. Add this strategy to the tree list by right clicking on the PCM item and selecting "Add Strategy...", browse to the location where you saved the strategy file and select it.

    This will add two items to the tree view, one for the strategy and one for the calibration data immediately below it.

  2. If CCP seed/key security is to be used, copy the relevant DLL(s) into the same location as the strategy file.

  3. To try out the connection, go online by selecting the menu option Project->Online.

    The tree view will change to show that each of the devices previously added are communicating correctly:

    and brings up a dialog box:

    If any of the devices show a yellow or red mark, then there is a physical disconnection or CCP communications error (e.g., different settings for CCP in the OpenECU device and the application). The dialog box will not pop-up and you will not be able to Flash the device. Go back and check that each of the settings corresponds to physical devices and CCP settings, check that CAN is connected to the correct pins and try again.

    To program the OpenECU device with the strategy, select Flash then OK. This brings up a dialog box which shows which memory regions on the OpenECU device to program. Select Start to program the device.

    Note

    In order to reprogram or Flash the OpenECU device, the OpenECU device must be in reprogramming mode. For details on how to enter reprogramming mode refer to Section 3.3.11, “Program the ECU”

    Once programmed, the FEPS must be disconnected (if used) and the OpenECU device power cycled. This reboots the OpenECU and starts to run the application.

  4. You can now view ASAP2 entries by creating a screen and adding the application signals and calibrations you wish to see. Select File->New, then Screen File. The main window will change. Right click on the background and select "Add Control".

    For now, we will only look at scalar values by selecting Data List items, but 1-d and 2-d maps are supported, as well as recorders etc..

    Select Data List and you will be presented with a dialog box which lists the ASAP2 entries.

    Double click on stp_ect_state and then select OK. You will be presented with the current value of stp_ect_state in real-time.

At this point, you have managed to connect ATI Vision to OpenECU, download the step1 application and view one application signal in real-time. Please refer to the ATI Vision user manual for more details about how to use ATI Vision.

C.3.3. Configuring two OpenECUs on the same CAN bus with ATI Vision

When connecting to a single OpenECU for the first time, the tool and OpenECU settings will probably use the default CCP settings (as described in Table 4.2, “CCP defaults”). The example which follows assumes the default CCP settings.

The above diagram shows ATI Vision with a single strategy using the default CCP settings. A similarly configured OpenECU is connected to ATI Vision via the CAN bus to the Vision Hub, and from the Hub to the PC via a USB cable. Your setup may vary depending on what equipment you have (for instance, you may have two ATI Hubs but the overall concept of configuring the additional OpenECU's remains).

When a second OpenECU is first required, a second application will be built into a second strategy which must use different CCP settings from the first strategy. The tool settings may follow the example default settings for two OpenECUs.

The diagram shows ATI Vision with two strategies: strategy A using the default CCP settings (as in the single OpenECU example above); strategy B using different CCP settings. The CCP settings distinguish between the two OpenECUs. Two OpenECUs are connected to the Hub allowing ATI Vision to communicate with both.

As this is the first time the second OpenECU has been connected to the CAN bus, it uses the default CCP settings. When the user selects strategy B in Vision, Vision uses the strategy B CCP CAN identifiers but there is no OpenECU with matching CCP settings. Without any response Vision shows the OpenECU for strategy B as offline.

Follow this procedure to program OpenECU B with strategy B for the first time:

  1. Disconnect OpenECU A from the CAN bus. This prevents OpenECU A from interfering with communications to OpenECU B.

  2. Right click on strategy B and select Open File. The screen will change.

  3. Select File -> Properties and change to the Device Settings tab in the new dialog.

    Change the CRO CAN identifier to 1785 and the DTO CAN identifier to 1784, then select File -> Save.

  4. Change back to the Project tab (so you can see both strategy A and strategy B), right click on strategy B and select Reload File. This brings the CRO and DTO changes into strategy B.

    Your setup is now configured as:

    If strategy B is selected, ATI Vision will show OpenECU B as online.

  5. Reprogram OpenECU B with strategy B (see Section C.3, “ATI Vision” and Section 3.3.11, “Program the ECU” for more).

  6. Once reprogrammed, power cycle OpenECU B. ATI Vision will show OpenECU B as offline.

  7. Right click on strategy B and select Open File. Select File -> Properties, change to the Device Settings tab in the new dialog, change the CRO CAN identifier to 1787 and the DTO CAN identifier to 1786, then select File -> Save.

  8. Change back to the Project tab (so you can see both strategy A and strategy B), right click on strategy B and select Reload File.

    Your setup is now configured as:

  9. Reconnect OpenECU A to the CAN bus. Select strategy A to communicate with OpenECU A, or select strategy B to communicate with OpenECU B.

Note

The above procedure is equally applicable when reprogramming a single OpenECU to new CCP settings. Ensure there is only one OpenECU connected to the CAN bus, build the application with the new CCP settings, import into Vision, adjust the CCP settings in Vision to that of the connected OpenECU, reprogram the OpenECU and reset it, then adjust the CCP settings in Vision to that of the application.

C.3.4. Configuring CCP seed/key security with ATI Vision

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 8.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”.

CCP seed/key security requires that a Win32 DLL is built containing a function which will generate a key value from a seed value supplied by the ECU. The name and function prototype are specified in the ASAP1A and ASAP2 standards to be

BOOL SEEDKEYAPI ASAP1A_CCP_ComputeKeyFromSeed(BYTE           *Seed,
                                              unsigned short  SizeSeed,
                                              BYTE           *Key,
                                              unsigned short  MaxSizeKey,
                                              unsigned short *SizeKey);
// Seed: Pointer to seed data
// SizeSeed:Size of seed data (length of ‚Seed‘)
// Key: Pointer, where DLL should insert the calculated key data.
// MaxSizeKey: Maximum size of ‚Key‘.
// SizeKey: Should be set from DLL corresponding to the number of data
// inserted to ‚Key‘ (at most ‚MaxSizeKey‘)
// Result: The value FALSE (= 0) indicates that the key could not be
// calculated from seed data (e.g. ‚MaxSizeKey‘ is too small).
// TRUE (!= 0) indicates success of key calculation.

Vision allows differently-named functions to be used, which may be convenient in cases such as supplying a single DLL containing multiple different seed/key algorithms for different strategies). Note though that this may make seed/key DLLs for Vision incompatibile with other calibrations tools which require a single function per DLL with a fixed name per the ASAP standard.

C.4. ETAS INCA

INCA by ETAS GmbH is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU.

The following instructions assume the user is using version 5.1.2. These instructions were transcribed against this version but it may be that these instructions match other versions of the tool.

The instructions also assume that ES 580 CAN card is used. If another communications device is used, the user will need to deviate from these instructions.

  1. Start INCA and you will be presented with a window similar to the following:

  2. Select the menu option Database->New to create a new database. This database will contain the binary image of the built application and calibration and other items used to calibrate the OpenECU device.

    Type in a suitable name: the example here uses example_database and select OK.

    Next, select the menu option Edit->Add->ECU Project (a2l) and browse to your built application, e.g., step1_tool_inca.a2l. The example shows an older step1_r12_g800 application.

    Once loaded, the INCA main window updates.

    Next, select the menu option Edit->Add->Workspace and accept the default name, then select the menu option Project->Add Project/Dataset:

    and a new dialog appears. Select the project you just added then OK. The main window will have updated to show the project in window 5.

    Select the offline item in window 5, then select device->new device

    Select an appropriate CCP compatible device. In this example, the PC running INCA has a ES 580 CAN card attached, so the related CCP item is selected.

  3. Next, double click on the workspace item in window 1. If there is an error in the CCP configuration or in the wiring to the OpenECU device, the INCA log window will show that INCA could not communicate with the OpenECU device. If this occurs, check the CCP settings and wiring.

    If the memory pages dialog does not pop-up, the select the menu option Hardware->Manage memory pages

    Select Flash programming, then do it. If this is the first time INCA has been used or if OpenECU was installed without the option to Patch INCA, you will be asked to browse to a ProF configuration file.

    Note

    The INCA tool makes a distinction between the base calibration (reference page) and a derived calibration (working page). Be sure to download the reference page to start with.

    Select the "Install..." button and browse to the install location of OpenECU, .../tools_integration/inca_prof and select OK.

    This will have installed the INCA ProF configuration file for OpenECU. Select it then OK.

    This brings up the ProF settings dialog.

    Select Flash strategy and calibration (or Flash strategy, calibration and tunes if using Tunes in your application — the step1 application does not use Tunes), then OK.

    Note

    In order to reprogram or Flash the OpenECU device, the OpenECU device must be in reprogramming mode. For details on how to enter reprogramming mode refer to Section 3.3.11, “Program the ECU”.

    This brings up the ProF control flow dialog box which shows the progress of programming the OpenECU device.

    Press Close when it has finished and Close in the manage memory pages dialog.

  4. Next, to view a measurable, select the menu option Variables->Select...

    and from the dialog that pops up, select those signals or calibrations to view. Here, the stp_ect_state signal has been selected and will be updated every 100 milliseconds.

    Select the Configure button, followed by the OK button on the next dialog.

    Finally, to display the data of the selected item in real-time, select the menu option Measurement->Start Visualisation. You will be presented with the current value of stp_ect_state in real-time.

At this point, you have managed to connect ETAS INCA to OpenECU, download the step1 application and view one application signal in real-time. Please refer to the ETAS INCA user manual for more details about how to use INCA.

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 8.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”. However this feature is not officially supported by OpenECU for use with ETAS INCA. As a result this feature has not been formally tested with INCA, and no support will be provided for configuring INCA to support seed/key security.

C.5. Vector CANape

CANape by Vector Informatik GmbH is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU.

The following instructions are for version 8.0. Other versions may differ.

The instructions also assume that CANcaseXL is used. If another communications device is used, the user may need to deviate from these instructions.

  1. Start CANape and you will be asked to accept a disclaimer. After this you will see the following:

  2. Select 'Create new project' and press 'OK'. You will then be asked for a project name. Enter a suitable name, click 'Next' and then browse to a suitable directory to save the project, click 'Next' and then 'Finish'. You should now see the following:

    Select the menu option Device->New from database... and browse to where your model_name_canape.a2l file is located and select Open. If the device is connected correctly and configured with the appropriate baud rate then you should see no errors or warning. The a2l file contains the CAN configuration as set by the model. It also has the relevant information for the flash, cal and RAM locations. CANape will use these values with no further configuration input required from the user.

    If CCP seed/key security is required for an operation, the DLL implementing the appropriate key-generation algorithm must be placed in the same directory as the CANape project. Note that CCP seed/key security is disabled by default in the model_name_canape.a2l file.

    Having set up the project (and CCP security if required), select the menu option Flash->Download file to flash... and browse to your built application, e.g., step1_m460_image_small.hex. Depending on the size of the memory region to be flashed, it may be necessary to increase the flash clear timeout parameter in CANape.

    At the bottom left of the window the progress bar should be seen to advance until programming is complete.

    Next, select the menu option Measurement->Measurement configuration... and the following window will appear:

    The Simulink model name should be visible in the left hand pane under 'Measurement signals'. Right click on the model name and select 'Insert signal' from the menu that appears. The Database selection window should then appear, listing all of the model signals and calibrateable values.

    Double click on each signal of interest so that their text colour changes to blue. Close both windows and accept changes and you will return to the main window. Now select the menu option Display->Display windows->Numeric window, an empty numeric display will appear. Right click on this numeric display and select 'Insert measurement signal...' the following appears:

  3. Next, right click and select 'Insert signal' on each parameter that you want to monitor in the numeric window

    To access calibration values select the menu option Display->Calibration windows->Calibration window, then scroll down to find calibration parameters and select the ones that are required.

At this point, you have managed to connect Vector CANape to OpenECU, downloaded the step1 application and viewed some signals in real-time. Please refer to the Vector CANape user manual for more details about how to use CANape.

C.5.1. Configuring CCP seed/key security with Vector CANape

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 8.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”.

CCP seed/key security requires that a Win32 DLL is built containing a function which will generate a key value from a seed value supplied by the ECU. The name and function prototype are specified in the ASAP1A and ASAP2 standards to be

BOOL SEEDKEYAPI ASAP1A_CCP_ComputeKeyFromSeed (BYTE *Seed, unsigned short SizeSeed, BYTE *Key, unsigned short MaxSizeKey, unsigned short *SizeKey); // Seed: Pointer to seed data // SizeSeed:Size of seed data (length of ‚Seed‘) // Key: Pointer, where DLL should insert the calculated key data. // MaxSizeKey: Maximum size of ‚Key‘. // SizeKey: Should be set from DLL corresponding to the number of data // inserted to ‚Key‘ (at most ‚MaxSizeKey‘) // Result: The value FALSE (= 0) indicates that the key could not be // calculated from seed data (e.g. ‚MaxSizeKey‘ is too small). // TRUE (!= 0) indicates success of key calculation.

Some calibration tools allow different function names to be used, but CANape does not. Each seed/key algorithm must therefore be provided in a separate DLL and referenced appropriately. Section 4.3.1.1 "CCP Parameters" of the CANape user manual specifies this in more detail.

C.6. FreeCCP

FreeCCP is a command line tool which can program an OpenECU with a built application. It requires a Vector or Kvaser CAN card.

This tool is provided free and unsupported by Pi Innovo. Users are permitted to use this software for commercial and non-commercial purposes.

Note

On 64-bit Windows 7 PCs, FreeCCP does not currently work with Vector interfaces, but does with Kvaser interfaces.

Note

FreeCCP is now deprecated, and so may be removed from future releases of OpenECU. Please contact support if you would like a free trial of PiSnoop to get started with OpenECU, even if you intend to migrate to a third-party calibration tool. See also Section C.2, “PiSnoop”.

C.6.1. Programming an OpenECU

To program an OpenECU with a built application using a Kvaser CAN card, issue the following at the command line:

oe_freeccp -kvaser -f <application_name>_image_small.s37

where <application_name> is replaced by the name of the application. For instance, with the step1 application for the M670 target, the command to issue would be:

oe_freeccp -kvaser -f step1_m670_image_small.s37

Note

When running from the Windows command line, add the path to the freeccp tool to the system PATH environment variable.

C.6.2. Choosing the CAN card device (Kvaser)

The tool supports using a variety of Kvaser CAN cards. To use this interface use the -kvaser command line option.

oe_freeccp -kvaser -f <application_name>_image_small.s37

C.6.3. Choosing the CAN card device (Vector)

The tool supports using a variety of Vector CAN cards. The tool defaults to using a CANcardX interface, but can connect to others using the following options: -cancardxl or -pci.

The options are added to the command for reprogramming, so as an extension to programming an OpenECU device with the step1 application, choosing the AC2 PCI option would be:

oe_freeccp -pci -f step1_image_small.s37

C.6.4. Choosing the CCP settings

Without additional command line parameters, the tool uses the default CCP settings from (Table 4.2, “CCP defaults”. To make the tool use alternative CCP settings, use the following options:

-croid    <standard can identifier>
-dtoid    <standard can identifier>
-targetid <station address>
-b        <baud rate in kBps>

So for instance, if the CCP settings were:

CCP optionSetting
CRO message identifier400
DTO message identifier401
Station address2
CAN baud rate500 kBps

then the command to issue to download the step1 application using a Vector CAN card would be:

oe_freeccp -croid 400 -dtoid 401 -targetid 2 -b 500 -f step1_image_small.s37

CCP seed/key security as described in Section 5.16.1.4, “CCP seed/key security” is not supported by FreeCCP. FreeCCP cannot therefore carry out operations for which the currently-running application requires security to be unlocked. This may make it unsuitable for use with production-level software.

C.6.5. Checking that the OpenECU device is active

The tool supports a function to determine if it can communicate with an OpenECU device or not, rather than programming the device. This can be used to check the wiring between the OpenECU and CAN card.

To check the CCP connection using a Vector CAN card, issue the command:

oe_freeccp -check

Appendix D. Memory configurations

Some OpenECU targets support different configurations of the ECU's application, calibration and RAM memory sizes, allowing design trade offs to be made whilst developing the application. There are two broad classes of ECUs:

Fleet ECUs

Lower-cost that developer ECUs due to the lack of run-time calibration support. These ECUs are intended to be used for fleet trials or production, and are not intended to be used for bench or dyno activities, especially those that require calibration support. Typically, fleet ECUs do not include external RAM.

Developer ECUs

Higher-cost that fleet ECUs due to support for run-time calibration. These ECUs are intended to be used for development activities such as dyno cell calibration or HIL based testing. Typically, developer ECUs do include external RAM.

Some configurations support running identical software on fleet and developer units. An application can be built, run and calibrated on a developer ECU, then transfered to a fleet ECU of the same family and type as the developer unit, and run unmodified. An example of this would be memory configuration A for the M220, and memory configuration D for the M670. The same application, calibration and RAM memory sizes are available with and without run-time calibration support. An application built for M220 memory configuration A will run on both M220 developer and fleet units without modification.

M110

The following memory configurations are available.

Table D.1. Memory configurations supported



Configuration

App size
(KiB)

Cal size
(KiB)

RAM size
(KiB)

External RAM
required?
Run-time
calibration
supported?
A [a]5123232NY
B5124816NY
C5121648NY
D51225664NN

[a] If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.


M220, M250, M460, M461

The following memory configurations are available.

Table D.2. Memory configurations supported



Configuration

App size
(KiB)

Cal size
(KiB)

RAM size
(KiB)

External RAM
required?
Run-time
calibration
supported?
A [a] 51225664NN
51225664YY
B512256832YY
C640128192YY
D76864768YY

[a] If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.


Most of these configurations require the external RAM available with developer units. If an application using such a memory configuration is loaded onto an ECU with no external tab board RAM available, the ECU will entry reprogramming mode with a flash code of 1-1-7 (repeated resets).

M670

The following memory configurations are available.

Table D.3. Memory configurations supported



Configuration

App size
(KiB)

Cal size
(KiB)

RAM size
(KiB)

External RAM
required?
Run-time
calibration
supported?
A [a] 3072128128NY
B307264192NY
C307219264NY
D3072512256NN
3072512256YY

[a] If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.


Other targets

No other targets support memory configuration.

Appendix E. ASAP2 compliance

The OpenECU generation of ASAP2 files is against a sub-set of version 1.40 of the standard.

Warning

OpenECU does not adhere to the ASAP2 rule which governs the length of identifiers. OpenECU may generate identifiers with more than 32 characters.

Appendix F. CCP compliance

The OpenECU implementation of CCP is against a sub-set of version 2.1 of the standard and supports the following commands:

Table F.1. Supported CCP commands

CCP commandCommand valueOptionalNotes
CONNECT1 Reprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one.
SET_MTA2 Supports one MTA. Addresses must not be extended.
DNLOAD3  
UPLOAD4  
START_STOP6  
DISCONNECT7 Reprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one.
START_STOP_ALL8yes 
SET_S_STATUS12yes 
GET_S_STATUS13yes 
BUILD_CKHSUM14yesImplements the 16 bit CCITT CRC (shift register initially set to 0xFFFF, non-reflected form).
SHORT_UP15yesExpects no address extension. Does not change MTA.
CLEAR_MEMORY16yes 
GET_SEED18yesNot supported before platform version 1.8.6.
UNLOCK19yesNot supported before platform version 1.8.6.
GET_DAQ_SIZE20 Ignores any attempt to set the DAQ CAN message identifier to anything other than the DTO CAN message identifier.
SET_DAQ_PTR21  
WRITE_DAQ22  
EXCHANGE_ID23  Access to the ECU's type, manufacturing data, and if available, the application defined name. See Section F.1, “EXCHANGE_ID message handling” for details.
PROGRAM24yesIf the length to program is specified as zero, reprogramming code will treat this as a special signal to indicate that programming has finished.
GET_CCP_VERSION27 Returns 2.1.
PROGRAM_634yes 
DNLOAD_635yes 

Some older versions of software (prior to platform version 1.6.0, or prior to RPRG version x.6.0) support a larger number of CCP commands. In addition to the commands above, these older versions also supported the following commands:

Table F.2. Supported CCP commands (in older versions of ECUs)

CCP commandCommand valueOptionalNotes
TEST5yesReprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one.
GET_ACTV_CAL_PG9yesOnly one page of calibration is supported.
SELECT_CAL_PAGE17yesOnly one calibration page is supported at a fixed address.
MOVE25yes 
DIAG_SERVICE32 Replied to as "unavailable".
ACTION_SERVICE33 Replied to as "unavailable".

All other commands are replied to as "unknown command".

F.1. EXCHANGE_ID message handling

The ASAP1b standard for CCP defines the EXCHANGE_ID message as follows:

Table F.3. Original EXCHANGE_ID message

PositionTypeDescription
0byteCommand Code = EXCHANGE_ID 0x17
1byteCommand Counter = CTR
2...bytesCCP master device ID information (optional and implementation specific)

OpenECU will interpret the master device ID information to determine how to setup the Memory Transfer Address (MTA0) for later uploading.

Table F.4. Modified EXCHANGE_ID message

PositionTypeDescription
0byteCommand Code = EXCHANGE_ID 0x17
1byteCommand Counter = CTR
2..4bytesIgnored
5..6byte Manufacturing data key
See Table F.6, “EXCHANGE_ID manufacturing data key values and binary format”
7bytes Selection
See Table F.5, “EXCHANGE_ID selection values”

The message is processed by the ECU by inspecting the selection in position 7:

Table F.5. EXCHANGE_ID selection values

ValueDescription
1 If the ECU contains manufacturing data and the manufacturing data key in position 5..6 is valid for the ECU, then set the MTA0 to the address of the manufacturing data in binary format. Valid key values and the structure of the data is defined in Table F.6, “EXCHANGE_ID manufacturing data key values and binary format”.
Otherwise, leave MTA0 unmodified and set an appropriate error code in the response message.
Note that some older M220, M250, M460 and M461 variants do not contain manufacturing data.
2 If running in application mode then set MTA0 to null terminated ASCII string defined by the application using the C-API tool name application statement.
Otherwise, sets MTA0 as if the EXCHANGE_ID selection value were zero.
any other value Set MTA0 to the address of a null terminated ASCII string of the ECU family. The string has the form “OpenECU-[name]”. For example, “OpenECU-M220”.

Position 5 (MSB) and 6 (LSB) is interpreted as the manufacturing data identifier:

Table F.6. EXCHANGE_ID manufacturing data key values and binary format

Position [a] Description [b]
Key = 1, Serial number
0..3Serial number
Key = 2, Date of manufacture
The date is composed as (shift) dd:mm:yyyy, where the shift identifies the team involved in the manufacturing process.
0The team shift at time of manufacture
1The day of the month of manufacture, range [1, 31]
2The month of manufacture, range [1, 12]
3..4The year of manufacture, range [2010, ...]
Key = 3, Engineering part number
The engineering part number matches the pattern: prefix letter engineering-part-number. For instance, the engineering part number assigned to the M250-000 is '01T068165', where '01' represents the prefix, 'T' represents the letter and '068165' represents the engineering part number.
0The part number prefix, range [0, 99]
1The part number letter, represented in ASCII, range [A-Z]
2..5The engineering part number, range [0, 999999]
Key = 4, ECU mod and issue numbers
The issue level represents a specific design of PCB. Changes to the issue level may have an effect on the software version.
The modification level represents what changes were performed to the PCB after manufacturing to correct issue level design mistakes. Changes to the modification level should not have an effect on the software version.
0The PCB issue level, range [0, 255]
1The PCB modification level, range [0, 255]
Key = 5, Factory part number
For instance, the factory part number could be '450FT1034', where '450' represents the part_num[0], 'F' represents the letter[0], 'T' represents the letter[1], and '1034' represents the part_num[1].
0..1First number of identifier, range [0, 65535]
2..3Second number of identifier, range [0, 65535]
4..5Characters used to separate identifier numbers, represented in ASCII, range [A-Z]
Key = 6, Factory part number build type
0..1The factory part number build type, represented in ASCII, range [A-Z]

[a] All data is arranged in MSB format.

[b] Not all keys are available on all ECUs.


Appendix G. CCP troubleshooting guide

This section describes a troubleshooting procedure for when CCP communications can not be established:

This section explains the symptoms and the solution using examples of a system with an ATI Hub and ATI Vision. Specific issues with ATI products are not addressed in this document as are issues with other system configurations such as ATI's Kvaser and ETAS' INCA, although the overall symptoms and resolutions remain the same.

Note

This guide is provided to help diagnose issues when connecting OpenECU with ATI Vision, and is a reference only. Please direct technical support questions regarding ATI products, to ATI. Pi can supply support for Pi products only.

If at the end of following this guide, the OpenECU module will not communicate to ATI Vision, please get in touch with OpenECU technical support (see Appendix J, Contact information).

G.1. Anatomy of an ATI Hub

As a reference to the following troubleshooting guide, this diagram outlines the major interfaces to the ATI Hub. Please refer to the ATI Vision User Guide for further details.

G.2. No communication between PC and ATI Hub

G.2.1. Symptoms

ATI Vision indicates that the Hub and its components are offline. No transmission data rate is shown as no data is communicated. In this case, ATI Vision shows red crosses against “VisionHub”, “VNICAN” and “PCM” while in online mode. The red crosses disappear when while in offline mode.

G.2.2. Possible causes

There are several potential reasons why there are no communications between the computer and the ATI Hub. Also see the Help instructions in ATI Vision's User Guide for further description of how to use the ATI Hub.

G.2.2.1. ATI Hub is not powered up/switched on

Troubleshoot

  • Check that the “Power LED” on the ATI Hub is illuminated.

Solution

  1. Check that the “Power switch” is in the ON position (pointing upwards).

  2. Check that the 12V DC is applied on the power connector at the back of the ATI Hub.

  3. Check the fuse at the back of the ATI Hub is intact.

G.2.2.2. ATI Hub is not connected to the computer correctly

Troubleshoot

Solution

  1. Check that the USB cable between the ATI hub and the computer is connected properly.

  2. Ensure that the correct USB driver is installed on the computer (contact ATI Technical Support for more details about the correct USB driver).

G.3. No communication between PC and OpenECU

G.3.1. Symptoms

ATI Vision indicates that the PCM is offline. A transmission data rate is shown between the computer USB and the Vision Hub. In this case, ATI Vision shows a red cross on “PCM” while in online mode. The red cross disappears and no data transmission rate is reported while in offline mode.

G.3.2. Possible causes

G.3.2.1. OpenECU module is not powered-up

Troubleshoot

  • Visually check for the response from actuators that are driven by the OpenECU module (lamps, relays, DC motors, etc.) during power-up. When the observed actuator response is not as expected, then the OpenECU module is not powered up correctly.

  • Check that the 5V sensor reference output on the OpenECU module is present. When the reference line voltage does not match the expected 5V, then the module is not powered up correctly.

  • Measure the current drawn by the OpenECU module (electrical current into all VPWR input pins). When the total current is less than 250mA, then the module is not powered up correctly.

Solution

  1. When fused, check that all fuses are intact.

  2. Check that all VPWR pins have a DC voltage supply of 9V to 16V.

  3. Check that all PWRGND connections are connected to ground.

G.3.2.2. OpenECU module is not connected to the ATI Hub correctly

Troubleshoot

Solution

  1. Remove all devices from the CAN bus except the OpenECU module and the ATI Hub.

    Note

    When communications are established, then the cause may be in the disconnected device(s). Terminating resistors, different CAN baud rate or clashing CAN message ID's are potential causes. Further investigation will be required but is outside the scope of this trouble shooting guide.

  2. Check the 15 pin D-type connector on the back of the ATI Hub if fixed securely.

  3. Check that the ATI CAN connections are fitted correctly. CAN-High (white) and CAN-Low (blue) are connected to the corresponding pins of the OpenECU module.

G.3.2.3. OpenECU module resets continuously

Troubleshoot

Solution

  1. Power down the OpenECU module.

  2. Apply 18V DC to the FEPS input pin of the OpenECU module (i.e. use an external power supply between the FEPS pin and ground).

  3. Power up the OpenECU module (powering up with 18V applied to the FEPS pin, forces the OpenECU module to enter reprogramming mode).

  4. When communications is established, flash the module with the strategy that is known to be working. Continue with the following steps:

    1. Wait for flashing to complete.

    2. Remove the 18V DC power from the FEPS input pin of the OpenECU module.

    3. Power cycle the module.

      Note

      Continuous module resets can be caused by a mistake in the strategy model (e.g. divide by zero) or when a model takes too long to run in its allotted time budget (e.g., a 1ms model rate takes longer than 1ms to complete). It is good practice to review the source model for potential causes of the reset.

  5. When communications is not established, the OpenECU module is not resetting continuously and the problem is potentially with the CAN configuration (see Section G.3.2.4, “CAN baud rate between OpenECU and ATI disagree” and Section G.3.2.5, “CCP CRO and DTO values do not agree with OpenECU”).

G.3.2.4. CAN baud rate between OpenECU and ATI disagree

Troubleshoot

Solution

  1. In ATI Vision, right click on “VNICAN” and select the menu option Properties.

  2. Select the Settings tab.

  3. Select a Bus Frequency of what is expected to match the strategy that is currently flashed onto the module.

    Note

    When the version of the latest strategy is known, then the bus frequencies of that strategy can be found by opening the strategy in ATI Vision and selecting the menu option File > Properties. The frequency is displayed as “Baudrate” in the Device Settings tab. If the strategy is unknown, then it will be any of the following possible frequencies: 33.333, 50, 62.5, 83.333, 100, 125, 250, 500 or 1000 kBps. Select one at a time until communications are established.

  4. When communications is still not established, then the most likely cause is a mismatch of the CRO and DTO vales between the active strategy in the project and the strategy that is currently flashed onto the module. See Section G.3.2.5, “CCP CRO and DTO values do not agree with OpenECU” on how to change CRO and DTO values.

  5. When communications is established, flash the module with the strategy that has the new desired bus frequency.

  6. Power cycle the module when flashing has completed.

  7. In ATI Vision, right click on “VNICAN” and select the menu option Properties.

  8. Highlight the Settings tab.

  9. Select a “Bus Frequency” of the strategy that is flashed onto the module.

G.3.2.5. CCP CRO and DTO values do not agree with OpenECU

Troubleshoot

Solution

Note

You will need to know the CRO and DTO values of the strategy that was last successfully flashed onto module. These values can either be found in the corresponding MATLAB model or from the corresponding strategy (VST) file. Use steps 2 to 6 below to find out what the existing values are. Because the CRO and DTO can be any CAN identifier number, it will be very difficult to establish communications without knowing the values used in the strategy that is currently flashed onto the modules.

  1. Create a copy of the strategy file that needs to be flashed onto the module.

  2. Opening it in ATI Vision and selecting the menu option File > Properties.

  3. In the Device Settings tab, highlight CRO and press the Edit button. Enter the CRO number of the strategy that is currently flashed onto the module and select the OK.

  4. In the Device Settings tab, highlight DTO and press the Edit button. Enter the DTO number of the strategy that is currently flashed onto the module and select the OK.

  5. Save the modified strategy file.

  6. Attach the modified strategy file to the PCM in ATI Vision and make active.

  7. When communications is established, flash the module with the strategy.

  8. Power cycle the module when flashing has completed (comms should no longer be established).

  9. Attach the version of the strategy file with the original CRO and DTO values to the PCM in ATI Vision and make active.

G.3.2.6. CCP seed/key has not been configured, or is using incorrect algorithm(s)

Troubleshoot

Solution

  1. Check the directory where the Vision strategy file is located. If this directory does not contain a DLL file and the strategy is known to require CCP seed/key security, then copy the relevant file to this directory.

  2. If the directory contains one or more DLL files but CCP seed/key security is still not available, it is possible that the DLL file in this directory may have the correct name but the wrong algorithm. (It may be the algorithm for a different manufacturer or platform, for example). Locate the correct DLL file(s) providing CCP seed/key security algorithms for this application, and copy the file(s) to this directory.

Appendix H. Change log

H.1.1.  Release 2.9.0 (r2020-1)

Release labelled release-2.9.0-r2020-1 from 13 April 2020. This release is marked as general meaning the release has been regression tested and is intended for general use. The following table provides quick access to each of the changes.


H.1.1.1. New features

New features introduced by this version, or significant changes to existing features.

Code generation

Integration with code-generation tools, such as MathWorks Real-Time Workshop for Simulink, and the C-API tool for OpenECU.

  • Added TargetLink integration block

    CR 4257 (F), affects Sim-API and C-API

    A new block ptl_TargetLinkIntegration was added to easily integrate TargetLink production code from a TargetLink model into an OpenECU model.

Communications

External communication mechanisms and protocol support for both reprogramming and application mode, including CCP, SAE-J1939 and ISO-15765 over CAN.

  • XETK implementation

    CR 15487 (F), affects Sim-API and C-API

    This change affects hardware design and platform code to include an XETK interface. This interface significantly increases data flowrate in comparison to CAN based CCP.

Diagnostics (communications and fault handling)

Diagnostic trouble codes and read/write parameter IDs are supported over the ISO-15765 and SAE-J1939 protocols.

  • Added J1939 multibus support

    CR 23456 (F), affects Sim-API and C-API

    OpenECU now supports J1939 communication on all CAN buses simultaneously. Each bus can be used as a single J1939 node.

Target ECU

OpenECU software supports a number of ECUs. Each target ECU has differing capabilities across connectors, input/output conditioning circuitry, memory, processors and architectures.

  • Added support for M220-0AU target

    CR 21547 (F), affects Sim-API and C-API

    Added support for the M220-0AU target, which supports M220-0AU and M220-XAU hardware options. This target differs from the M220-000 target in that it no longer supports any angular features, but adds support for quadrature decode inputs, 3 phase hall decode inputs, and a PWM output with synchronous analog input sampling. These new features can be used with the following blocks pdx_QuadratureDecode, pdx_QuadratureDecodeAndFrequencyInput, pdx_HallDecodeInput, and pdx_PWMOutputWithSyncSampling. See the user guide for details on each of the added interfaces.

Third party tool support

OpenECU builds on, and utilises, various tools from third parties, including C compilers, calibration tools and operating systems. See the third party tool requirements section for a complete list of required and options software, and the versions supported.

  • Added support for MATLAB R2019a, R2019b, and R2020a

    CR 23687 (F), affects Sim-API

    OpenECU now integrates with MATLAB R2019a, R2019b, and R2020a. Starting with these releases, the build process has been updated based on the Toolchain approach instead of the Template Makefile approach. The format of the text printed to the Diagnostic Viewer during the build process has been modified due to this process, but the build process is functionally equivalent. No changes to application models are necessary.

  • Added a Simulink interface to configure application and calibration checksums

    CR 22868 (F), affects Sim-API and C-API

    Previously, application and calibration checksums could only be configured by modifying a makefile. Now, checksum configuration has been added to the Simulink model code generation configuration paramters for all OpenECU models

H.1.1.2. Fixes and improvements

Fixes or improvements to existing features with details of why they were previously wrong.

Application programming interface

The programming interface for linking the application to each ECU. OpenECU developer software presents two interfaces, one for C and one for Simulink. See the third party tool requirements section for a list of C compilers, their versions and versions of Simulink supported by OpenECU developer software.

  • Prevent unnecessary model searches in the Simulink block callback functions.

    CR 24368 (F), affects Sim-API and C-API

    Several OpenECU Simulink blocks have callback functions which search the model to cross-check configuration settings or parameters. If several blocks require the same information, it is stored in persistent memory so that the model does not have to be searched multiple times. This change fixes a bug where the information was not always being stored in persistent memory, causing some searches to be performed many times.

  • Added Generic Key Field to PREG Retrieve Key block.

    CR 23508 (F), affects Sim-API and C-API

    Added a new field to the PREG Retrieve Key block for the SimAPI to allow users to be able to enter any generic key ID from the registry to retrieve it's corresponding value. Fixes an issue where the serial number in modern ECUs is not stored at the same key as the Legacy ECUs, and thus this field now allows users to enter the key manually in order to get the correct serial number depending on the ECU.

  • Fixed PCX queue emptier task which failed to run due to concurrency issues

    CR 23263 (F), affects Sim-API and C-API

    The pcx_qemptier_task was stopping even when there were still CAN messages queued for transmit and the task was not able to be rescheduled. The root cause was that the status variable controlling the pcx_qemptier_task was being incorrectly cleared even when there were CAN messages queued. This was because the read-modify-write operation of the variable was not protected. This variable was being altered from outside the interrupt context and was causing corruption and inconsistent memory states. The issue was fixed by suspending the scheduler around the read-modify-write of this status variable.

  • Resolved bug in ppid_pid where it was not accepting symbols for mask parameters

    CR 20001 (F), affects Sim-API and C-API

    Previously, the mask parameters for the ppid_pid block did not accept symbols and it would throw errors. A fix for this was identifid and applied.

  • Fixed Injection Duration limits to be from 0ms to 2097ms

    CR 18639 (F), affects Sim-API and C-API

    The pan_InjectorConfig block only allowed the injection durations within 0.1ms and 1ms. This limation was only software and the ptpu code accepted durations of [0, 4000]. This mismatch in the duration ranges was fixed.

  • Fixed issue where a function call generator triggering a referenced model subsystem caused build errors.

    CR 17877 (F), affects Sim-API

    When using a triggered subsystem in a referenced model, Simulink generates an asynchronous sample time in the referenced model and when building that referenced model and generating the corresponding capi file, it generates an angular task wherever it finds an asynchronous sample time. For targets, such has the M110, that do not support angular functionality this results in a build error. To fix this, the angular task is only generated if the model is not a referenced model, and if it is Simulink simply ignores it.

  • Fixed 'ModelReferenceCompliant' option to be set properly in the STF callback

    CR 15600 (F), affects Sim-API

    Model that were based on openecu_ert.tlc were reporting that they were not model reference compliant, this implies that the 'ModelReferenceCompliant' option was not being set correctly in the STF callback. The cause for this issue was that when setting the ModelReferenceCompliant option the oe_is_ert() function was being used however that function sometimes returned the incorrect model if the focus of the Simulink GUI changed during the callback. This implementation has been fixed to correctly set the ModelReferenceCompliant option when required.

  • Reformatted ADD_INCLUDES build path to use "/" style slashes instead of "\" slashes

    CR 15559 (F), affects Sim-API

    When compiling a Simulink model using GCC, that includes a custom C header file, the mk_model_common Makefile formats the path to these custom header files using Windows style "\" slashes instead of "/" which caused the model to not build successfully. This issue was fixed by reformatting "/" slashes with "\" slashes in all instances of the ADD_INCLUDES variable.

  • Fix broken mask worker for the ppid_Scaling block

    CR 15374 (F), affects Sim-API

    Previously, when using the ppid_Scaling block MATLAB would throw an error about a syntax error in the ppid_scaling_worker function, making the block unusable. This has been resolved and the block now works as expected.

  • Changed put_Identification block so that it now requires version numbers to be in the range [0, 255]

    CR 15259 (F), affects Sim-API and C-API

    In pfs.h, the app major/minor/sub-minor versions are all stored as U8's, but the put_Identification block allows for U16's to be set. In pfsl_fill_metadata() in pfs.c, the major/minor/sub-minor versions are all clipped to 255 just before writing the file to flash, but in pfs_fstat() in pfs.c, the version of the file read from flash are compared against the unclipped U16 value of the versions (i.e. "this_ver_wrote" field would be set to 0 for an app version > 255).

  • Fixed issue in Quadrature decode blocks to show correct IO for M670 and M110 ECUs.

    CR 14992 (F), affects Sim-API

    The pdx_QuadratureDecode and pdx_QuadratureDecodeAndFrequencyInput blocks incorrectly relied on an old obsolete IO mapping file, put_io_mapping.m, to populate the primary and secondary channels instead of using the new mapping file, oe_mapping_io.m. This issue has been fixed and those blocks now use the newer file.

Calibration

Integration with calibration tools (such as ATI Vision) and mechanisms to read application data and write application calibration in real-time whilst the application runs. See the systems requirements section for a list of calibration tools and their versions supported by OpenECU developer software.

  • Added support for extended CCP IDs

    CR 25148 (F), affects Sim-API and C-API

    Added support for extended CCp IDs in A2L files for ATI Vision, INCA, and Canape. When building an application with the CCP setting "Use SRC extended ID" or "Use DTO extended ID" All A2L files that contain CCP information now properly set bit 31.

  • A2L variables not generated

    CR 15568 (F), affects Sim-API and C-API

    Fixed issue where some variables would not be generated or grouped correctly during A2L generation.

Code generation

Integration with code-generation tools, such as MathWorks Real-Time Workshop for Simulink, and the C-API tool for OpenECU.

  • Removed support for MATLAB 2013, MATLAB 2014, and RSIM

    CR 25028 (F), affects Sim-API

    Support for MATLAB 2013 and 2014 has been removed. Support for RSIM Simulink Code Generation has been removed.

  • Fixed CAPI A2L file generation regex bug

    CR 24598 (F), affects Sim-API and C-API

    In the capi_parse_dwarf python script that parses gcc's objdumb output, there was a bug in the regular expression that captures the tag of a debugging information entry (DIE). Previously the regex assumed that were would only ever be one digit for each DIE entry tag, this was found to be incorrect as the number could be more than 1 digit. The regex in question has now been updated to address this.

  • Revised RSIM deprecation message and recommendation

    CR 23281 (F), affects Sim-API

    It is recommended to use the blocks under "OpenECU/RealTime Workshop Utilities" to switch the build configuration from RSIM to ERT or RTMODEL.

  • Fix referenced model build errors with GCC

    CR 22637 (F), affects Sim-API and C-API

    This change fixes a build error where referenced models would not build with the GCC compiler due to backslashes '\' in some of the file paths.

  • Fix model reference builds including lower level model archives

    CR 22353 (F), affects Sim-API and C-API

    Previously, if a block in a model reference hierarchy included other model reference blocks multiple times in a hierarchy of model reference blocks, a build error could be raised due to duplicate instances of the archive files of the blocks. Now, the model reference archives are not included within other model reference archives, and all archives are linked together only when the top level model is built.

  • Resolved issue with put_Calmap2d block code generation when using the GCC compiler

    CR 18364 (F), affects Sim-API

    When using the put_Calmap2d block and building a model with the GCC compiler, the auto generated code attaches a OE_CAL identifier to one of the local variables used to call the C-API function for this block. In GCC this OE_CAL identifier is a section attribute and thus they can not be specified for local variables and the build fails. A fix was made to change how the code was generated by the build process such that the OE_CAL attribute is not used.

  • ASAP2 generation with Simulink data dictionaries

    CR 18344 (F), affects Sim-API

    Fixed a problem that excluded data dictionary files if the model was using a simulink data dictionary.

  • Added support for mpl data entries in Simulink ASAP2 files

    CR 18181 (F), affects Sim-API

    Previously .a2l files directly generated by Simulink would omit the standard platform mpl_ variables. These are now included in .a2l files directly generated by Simulink.

  • Warn and omit prefix-style a2l variable names less than four characters long

    CR 17975 (F), affects Sim-API and C-API

    Prefix-style data dictionary entries require that all variable names be at least four characters long. Any variables that do not meet this criteria (when using prefix-style data dictionary entries) are now omitted from the a2l file and appropriate warnings are produced.

  • Fixed inconsistencies in prefix-style DDE generation with 1x1 vector values

    CR 15407 (F), affects Sim-API and C-API

    Previously, prefix-style DDE files from simulink data dictionaries could be generated with both vector-prefixed names and scalar values. Now prefix-style ddes will generate with the variable type specified in the prefixed name.

  • Reduced missing x or y dde errors to warnings

    CR 15407 (F), affects Sim-API and C-API

    Previously an error would be produced if an x or y lookup dde were not found in the .elf file. This error has been replaced with a warning.

Communications

External communication mechanisms and protocol support for both reprogramming and application mode, including CCP, SAE-J1939 and ISO-15765 over CAN.

  • Fixed issues with CANdb message packing.

    CR 23130 (F), affects Sim-API and C-API

    Fixed packing of CANdb signals of "float" value type. Previously, scaling and offset were not applied to signals of this type.

    Fixed potential corruption of adjacent signals while packing fields that are not byte-aligned.

Examples

To help introduce OpenECU applications, the software is provided with a number of examples. There are sets of examples for each interface, one set for C and one set for Simulink.

  • Fix Two pot demo with S-Function

    CR 25255 (F), affects Sim-API

    The two pot demo with S-Function was previously implemented as a non-inlined S-Function, which is not supported by the OpenECU developer platform. This has been fixed, and the documentation updated. Further changes were made to detect and raise an error if a non-inlined S-Function is used within an application model, which could have undefined behavior.

  • Cleanup of SENT example for M110 and M670

    CR 21598 (F), affects Sim-API and C-API

    Previously the signal names in the model referenced pin XG4 which was not the correct pin used in the example for either target. The signal names have now been left generic to avoid confusion.

Input/output drivers

Each target ECU is designed with a different set of input and output conditioning circuitry. Interfaces provide access, from simple low-side digital output drive to stepper motor output drive and crank trigger wheel input decoding.

  • pdx_Monitor functionality removed from the M110 platform

    CR 25413 (F), affects Sim-API and C-API

    pdx_Monitor conflicts with the other functions that are available on the A4, A13, B2, B3, B6, B13, B14, and B16 connector pins. Similar diagnostic capabilities can be achieved using the other input blocks.

  • Angular analog inputs sync issue resolved.

    CR 23581 (F), affects Sim-API and C-API

    This change resolves incorrect behavior of angular analog inputs when the sync offset is non-zero and the initialization routine runs after the first cycle. Also, a data-type issue is resolved in which the block pan_AngularAnalogInputVariable was referencing the input port for cylinder number for the angle datatype.

  • DI Pulse Spacing

    CR 22460 (F), affects Sim-API and C-API

    In previous releases, DI injector pulses with less than 0.2msec spacing could be cancelled due to interaction with the current control circuity programming. This has now been resolved for pulse spacing down to the level allowed at build (0.1ms).

  • Improvements in range of useable injection angles.

    CR 22006 (F), affects Sim-API and C-API

    • When the commanded injection angle plus the cylinder offset crossed a threshold (by advancing) which caused the timing to wrap from -360 to +360 (+ = retard), the injection would skip. Now resolved.

    • Attempts to operate at low speed (less than ~150rpm) would lead to erratic injection behavior. Now resolved.

    • Injection scheduling and drop dead angles were previously limited to 0 to 719.9 (although larger ranges of injector on angles were accepted, because only positive drop dead angles were accepted, use of negative injection angles was limited). Now injector start angles and drop dead angles of -720 to 720 are accepted in the pan_Injection_DI block.

  • Angular outputs no longer latch when duration is greater than 1 cycle

    CR 15473 (F), affects Sim-API and C-API

    The angular output was observed to latch to the active state when:

    • the requested duration was greater than one engine cycle.

    • allow cycle repeat was set to zero (false).

    • no further pulse requests were made.

    This modification prevents this situation.

Target ECU

OpenECU software supports a number of ECUs. Each target ECU has differing capabilities across connectors, input/output conditioning circuitry, memory, processors and architectures.

  • Fixed potential pfs_flush_all lockup.

    CR 24617 (F), affects Sim-API and C-API

    Fixed potential ECU lockup when using pfs_flush_all.

  • Added warnings for incorrect tlc configurations

    CR 23842 (F), affects Sim-API and C-API

    Added warnings for when the selected tlc file does not match the configuration model default.

  • Fixed UDS transport protocol.

    CR 23760 (F), affects Sim-API and C-API

    Fixed UDS messages longer then 8 bytes timing out.

    Note

    To enable this functionality, the ECU's firmware must be upgraded to revision 2.9.0-r2020-1 or later. To upgrade the ECU's firmware please contact OpenECU technical support as described in Appendix J, Contact information.

  • Embedded software optimizations

    CR 23335 (F), affects Sim-API and C-API

    Optimizations were made to improve CPU throughput in the following areas: DTC match iterator, CAN buffer copies, CAN callbacks, and TLE8110 SPI driver.

User documentation

User documentation covers technical specifications for each ECU, user guides or reference manuals, installation guides and release notes, in HTML and PDF formats.

  • Corrected and added information in the M670 Tech Spec

    CR 24819 (F), affects Sim-API and C-API

    Corrected information on pins Y18 and Y53 and added missing information in sections 4.10. Analogue inputs and 4.32. Digital outputs.

  • Fixes issue in MATLAB R2018B where the images in the Simulink user guide are not displaying

    CR 22121 (F), affects Sim-API and C-API

    Previously, when the OpenECU Simulink User Guide was opened from within MATLAB 2018 or higher, all images and CSS files could not be found by MATLAB and resulted in formatting issues. A possible cause for this could be that in newer versions of MATLAB some sort of check was put into place that prevented it from accessing resources (such as images) that are not in the same directory as the HTML files. A fix was made to remedy this by setting the help location in MATLAB to a base folder that has these images, CSS and HTML files as subdirectories, and also moving the table of contents that links to each HTML file to this folder as-well.

  • Corrected information in the M670 Tech Spec

    CR 22059 (F), affects Sim-API and C-API

    Digital inputs XF3, Y34, and Z12 previously displayed a voltage range of 0V to 5V. Those pins have been corrected to say 0V to VPwr, but it has been noted that 0V to 5V is preferred.

  • Updated the M220 Technical Specification with a note about Hall effect sensors

    CR 17928 (F), affects Sim-API and C-API

    The note reads: Reading a Hall effect sensor may require an external pull up resistor or a pull up resistor added as a custom option.

H.1.1.3. Outstanding issues

  • Simultaneous receive of J1939 PGNs on multiple buses

    CR 25039 (F), affects Sim-API and C-API

    When the same PGN is received on multiple buses within the same model iteration, including DM7 test requests or PG requests, unexpected behavior may occur.

  • Limitations on M110 CAN channels C and D

    CR 21783 (F), affects Sim-API and C-API

    The M110 uses a SPI-to-CAN ASIC for CAN channels C and D. There are known limitations on these CAN buses which can limit the message bandwidth capability, and occasionally CAN message data may get corrupted.

  • Errors integrating with ETAS INCA calibration tool during OpenECU installation

    CR 10955 (F), affects Sim-API and C-API

    When integrating OpenECU with the ETAS INCA calibration tool during OpenECU installation, there is a problem with part of the installation procedure. Selecting the Integration -> INCA-ProF Integration option when choosing components to install is necessary to generate the target-specific ProF configuration files in the OpenECU installed directory (under tool_integration\inca_prof).

    However, when later in the installation process the user is invited to “Choose INCA Updates” (with a list of any currently installed versions of INCA), the user should select "None". This step copies the ProF files into the ETAS INCA installed location, however it does not correctly adjust the paths to those files. This causes errors when attempting to use these ProF files.

    Instead the ProF files should be installed directly using the ETAS INCA tool (after installing OpenECU) using the procedure described in the Appendix of the OpenECU User Guide on how to use INCA with OpenECU (under section “Supporting Tools”).

  • Manufacturing data retrieval disabled while in reprogramming mode

    CR 10386 (F), affects Sim-API and C-API

    The firmware is unable to retrieve manufacturing data via an EXCHANGE_ID request while in reprogramming mode. This feature has been temporarily disabled while ECC recovery is enabled in reprogramming mode.

    Note

    To enable this functionality, the ECU's firmware must be upgraded to revision 2.9.0-r2020-1 or later. To upgrade the ECU's firmware please contact OpenECU technical support as described in Appendix J, Contact information.

  • Peak and hold injector outputs fails when an out of range current or frequency request is made by the application

    CR 8766 (W), affects Sim-API and C-API

    Current or frequency requests in the range specified by the user guide are correctly generated.

  • Cannot generate a peak current for a shorter duration that the minimum duty cycle

    CR 8766 (W), affects Sim-API and C-API

  • J1939 PG transmit and PG receive interfaces do not correctly determine the CAN bus off condition

    CR 8754 (W), affects Sim-API and C-API

    Both the PG transmit and PG receive interfaces will report an error if the CAN bus is detected as bus-off when the interface runs (as well as other conditions). During testing, it has been shown that the bus-off condition is not detected correctly and thus any bus-off condition does not contribute to the error report. The application must determine the bus-off condition using the CAN status interface rather than relying on the PG transmit and receive interfaces for full error reporting.

  • Cannot define a DME without an associated DTE

    CR 8752 (W), affects Sim-API and C-API

    The ppr_DiagnosticMonitorEntity block to update the numerator, denominator and ratio outputs incorrectly assumes that at least one DTE will be found belonging to that DME. Otherwise it returns an error, and the values for the numerator, denominator and ratio are indeterminate and should not be relied on. As a work around, an application must assign at least one DTE to every DME.

  • Application scheduled tasks immediately after software initialisation completes can be delayed by up to 11 milliseconds

    CR 8743 (W), affects Sim-API and C-API

    Thereafter, the task schedule continues as expected.

  • DM30 test result reporting is not currently correct

    CR 8630 (W), affects Sim-API

    DM30 does not currently report results correctly for DM7 TIDs 248-250. All DM30 results are reported as if TID 247 (return all scaled test results for one SPN) was requested, instead of reporting a single test result. The suggested work around is for single tests to be reported via the generic j1939_PGTransmit block.

  • The adaptive blocks do not generate properly on the Real-Time Workshop Embedded Coder target when Global data is placed in a seperate file

    CR 8499 (W), affects Sim-API

    The default values of adaptive parameters are stored in a defined section of memory in the calibration region. When these calibrations are defined in a seperate file, the compiler does not place them in the proper region of memory, and thus they are disabled. The workaround is to place all global data in the same file as the source file.

  • Negative responses to J1979 services not supported for physically addressed requests

    CR 8259 (W), affects Sim-API and C-API

    J1979 SEP2010 section 6.2.4.3.7 specifies that if any of services $00 to $0F are not supported, the ECU shall not respond. However, the ECU does give a negative response here for physically addressed requests.

  • Negative responses to incorrectly formatted J1979 messages

    CR 8259 (W), affects Sim-API and C-API

    On certain J1979 ISO 15765-4 services, the ECU generates a negative response to incorrectly formatted request messages in contradiction to the standard. No response is preferred in this situation. This affects services $03, $06, $07 and $0A. See also CR8153.

  • Avoiding processor exceptions if NULL dereferenced in customer application during flash erase

    CR 8211 (F), affects C-API

    See CR 8211 (F) for detail. It is still possible for a bad access to cause an exception which will continue to occur until the flash operation has completed. If it does, a continuous loop is effectively entered until the flash operation is over. If that operation is an erase, it may take long enough for a watchdog exception to take place. Therefore this issue remains open for further action in future to address this scenario. Note however that this type of exception pattern occurs only very rarely even if NULL is repeatedly read during flash operations, so it is now very much less probable that a customer application will cause a reset in the manner described.

  • The pan_AngularAnalogInputConfig block does not dynamically change the I/O channel drop down selection, when the group drop down selection is changed

    CR 7370 (W), affects Sim-API

    Work around this issue by selecting the required group, closing the block mask parameter dialog, opening the block mask parameter dialog again, then select the required I/O channel.

  • Incorrect flagging of duplicate PGN information

    CR 7082 (W), affects Sim-API and C-API

    During the build process, checks are performed in case any PGNs have been duplicated. Unfortunately, these checks sometimes flag duplications erroneously.

  • Channel checking for synchronised PWM output blocks

    CR 7072 (W), affects Sim-API and C-API

    The Simulink interface does not prevent an application model from using the same channels in both a Synchronised PWM output block and in another PWM output block. It is up to the developer to avoid this erroneous double assignment.

  • Check for initial frequency does not allow for clock source

    CR 7070 (W), affects Sim-API and C-API

    The check for initial frequency for Peak and Hold Injector, PWM and SPWM blocks does not yet take into account the clock source selected. So, for example, if the slow clock is selected and an initial frequency of greater-than 40Hz is selected, an error will not be generated when the model is updated. The frequency will however be clipped to the allowed range at run-time.

  • Warnings about the pan_InjectorCompConfigDI and pan_SparkConfig blocks

    CR 6502 (W), affects Sim-API

    MATLAB may print a set of warnings relating to instatiating these blocks, referring to an invalid setting. The warnings will not affect the use of the blocks once placed in a model and configured.

  • Partially verified synchronised PWM functionality

    CR 5787 (W), affects Sim-API and C-API

    The synchronised PWM functionality is designed for driving injectors with peak and hold current. As such, it has only been validated with master frequency equal to slave frequency. Further testing needs to be performed to characterise the functionality.

  • Some J1939 functionality does not adhere to the J1939 standard

    CR 5786 (W), affects Sim-API and C-API

    There is a known issue with the J1939 protocol stack implemented in the OpenECU platform:

    The J1939 feature assumes that it will be running on a fixed address network. Incorrect operation may occur if address claiming is used by other ECUs on the bus.

  • Support for ETAS INCA v5.1.2 has not been fully verified

    CR 1875 (W), affects Sim-API and C-API

    The last time integration of OpenECU with INCA was tested was some time back, when support for INCA was first introduced. Since then, ETAS have produced newer versions of INCA but no further work to validate integration has taken place.

Appendix I. Glossary of terms

Glossary

ADC

Analogue to Digital Converter — a mechanism to read an analogue voltage signal and convert to a digital value.

ASAP2

A standardized description data format for calibration data — for more information refer to ASAM Standards: ASAM MCD 2MC / ASAP2 at the ASAM Web site (http://www.asam.de).

CAN

Controller Area Network — more information can be found on the Bosch web site (http://www.can.bosch.com).

CANdb

CAN Database — a CANdb file contains information regarding CAN messages transmitted between CAN nodes in a network. CANdb files (which usually have the file extension .dbc can be edited with tools supplied by Vector CANtech, Inc. (http://www.vector-cantech.com).

CCP

CAN Calibration Protocol — for more information refer to ASAM Standards: ASAM MCD: MCD 1a at the ASAM Web site (http://www.asam.de).

CRO

Command Receive Object — the CAN identifier of the CCP message, sent by a calibration tool to command the ECU to perform an action.

DTO

Data Transmission Object — the CAN identifier of the CCP message, sent by the ECU with the results of a commanded action.

ECU

Electronic Control Unit — for instance, an OpenECU device.

KAPWR

Keep Alive Power — apply power to this pin while the module is is otherwise powered down to retain the values of any adaptive data or Tunes until the module is next powered up again (see the technical specification for each target for details).

H-Bridge

An H-bridge is an electronic circuit which enables a voltage to be applied across a load in either direction. These circuits are used to allow to supply loads such as DC motors forwards and backwards.

Hall

Hall Effect Sensor — typical sensor used for cam and shaft position sensing.

HIL

Hardware In the Loop — a term used to indicate the replacement of the plant by a simulator (e.g., Pi Innovo's AutoSim — www.piautosim.com).

J1939

SAE J1939 — a vehicle bus standard used for communications and diagnostics among vehicle components, originally for the heavy duty truck industry in the USA.

MIOS

Modular Input Output System — a sub-processor of the OpenECU main processor used to encode and decode digital signals.

MISRA

The Motor Industry Software Reliability Association produced a set of guidelines for developing vehicle software — for more information refer to Development Guidelines for Vehicle Based Software at the MISRA Web site (http://www.misra.org.uk).

QADC

Queued Analogue to Digital Converted — a sub-processor of the OpenECU main processor used to convert analogue input signals to a quantized digital representation.

PixCal

A simplified calibration tool based on Microsoft Excel that requires only a RS232 UART port to communicate with OpenECU. PixCal supports Tunes but not general calibrations and displayables.

NOTE: PixCal is no longer supported by Pi Innovo.

PWM

Pulse Width Modulation — a digital pulse train, where the ratio of the high time to the low time of a single cycle represents the duty cycle of the PWM signal.

RS232

RS232 is an electrical signalling specification published by the Electronic Industries Association (EIA). It is a standard for serial transmission of data between two devices.

RTOS

Real-Time Operating System — a low level piece of software that executes tasks or model iterations in real-time in a periodic fashion.

SIL

Safety Integrity Level — the likelihood of a safety related system achieving the safety functions under all the stated conditions within a stated period of time. References to SIL in the OpenECU user manual refer to the MISRA guidelines.

SPI

Serial Peripheral Interface — a sub-processor of the OpenECU main processor used to communicate with other devices.

TDC

Top Dead Center

TPU

Time Processing Unit — a sub-processor of the OpenECU main processor used to encode and decode digital signals.

VRS

Variable Reluctance Sensor — typical sensor type for crank, cam or shaft position sensing.

Appendix J. Contact information

If you have questions, or are experiencing issues with OpenECU please see the FAQ website:

If you still have questions after searching through the FAQ, or want to discuss sales or proposals, you can contact main office:

Tel
+1 734 656 0140
Fax
+1 734 656 0141

during normal working hours (Mon to Fri, 0930 to 1700 EST).