Development of TFT Cluster Speedometer Software Component
1.Development of TFT Cluster Speedometer Software Component
Cluster Instrument receives the signals from other ECU via CAN bus interface. It also receives commands from the driver via steering wheel buttons. The signals are then processed by the Cluster ECU, after which the Cluster ECU may send the vehicle information to the LCD or light the LEDs and so forth, according to the results. Therefore, the Cluster ECU can be viewed as a carrier of the information flow.
Following are workflow of project
- simulink model file
- SLDD file
- requirement tagging report
- model advisor JMAAB
- fixed-point tool
- SLDV design error detection report
- functional test MIL,SIL harness,coverage reports
- SLDV test genration report
- Auto code generation report,main,c&h files

Requirements:
Calculating TFT Display Speed:
|
Average Vehicle Speed would be displayed only if its between 2 kmph & 250 kmph. Any value outside this range will be discarded by its lower limit & upper limit |
|||||||||||||||||||||||||||||||||||||
|
When Average Vehicle Speed is < 2 kmph, DisplaySpeed = 2 kmph |
|||||||||||||||||||||||||||||||||||||
|
When Average Vehicle Speed is in between 2 kmph & 250 kmph, Display Speed = Average Vehicle Speed |
|||||||||||||||||||||||||||||||||||||
|
When Average Vehicle Speed is > 250 kmph, Display Speed = 250 kmph
1.2 Main Data Filtering:
1.3 Auxiliary Data Filtering:
1.4 TFT Speed Output:
|
|||||||||||||||||||||||||||||||||||||
7. Functional test MIL,SIL harness,coverage reports




Code Generation :

Project_2.h
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: Project_2.h
*
* Code generated for Simulink model 'Project_2'.
*
* Model version : 3.33
* Simulink Coder version : 9.7 (R2022a) 13-Nov-2021
* C/C++ source code generated on : Mon Dec 25 16:16:00 2023
*
* Target selection: ert.tlc
* Embedded hardware selection: Intel->x86-64 (Windows64)
* Code generation objectives: Unspecified
* Validation result: Not run
*/
#ifndef RTW_HEADER_Project_2_h_
#define RTW_HEADER_Project_2_h_
#ifndef Project_2_COMMON_INCLUDES_
#define Project_2_COMMON_INCLUDES_
#include "rtwtypes.h"
#endif /* Project_2_COMMON_INCLUDES_ */
#include "Project_2_types.h"
/* Macros for accessing real-time model data structure */
#ifndef rtmGetErrorStatus
#define rtmGetErrorStatus(rtm) ((rtm)->errorStatus)
#endif
#ifndef rtmSetErrorStatus
#define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val))
#endif
/* Block signals (default storage) */
typedef struct {
int16_T DisplaySpeed_Filter; /* '<S2>/Subtract' */
} B_Project_2_T;
/* External inputs (root inport signals with default storage) */
typedef struct {
uint16_T Timer_Input; /* '<Root>/Timer_Input' */
uint16_T Average_VehicleSpeed; /* '<Root>/Average_VehicleSpeed' */
uint8_T In_MainFilt_SpeedValue; /* '<Root>/In_MainFilt_SpeedValue' */
uint8_T In_AuxillaryFilt_SpeedValue;/* '<Root>/In_AuxillaryFilt_SpeedValue' */
} ExtU_Project_2_T;
/* External outputs (root outports fed by signals with default storage) */
typedef struct {
uint16_T Out_VehicleSpeedDisplay; /* '<Root>/Out_VehicleSpeedDisplay' */
} ExtY_Project_2_T;
/* Real-time Model Data Structure */
struct tag_RTM_Project_2_T {
const char_T * volatile errorStatus;
/*
* Timing:
* The following substructure contains information regarding
* the timing information for the model.
*/
struct {
struct {
uint8_T TID[2];
} TaskCounters;
} Timing;
};
/* Block signals (default storage) */
extern B_Project_2_T Project_2_B;
/* External inputs (root inport signals with default storage) */
extern ExtU_Project_2_T Project_2_U;
/* External outputs (root outports fed by signals with default storage) */
extern ExtY_Project_2_T Project_2_Y;
/* Model entry point functions */
extern void Project_2_initialize(void);
extern void Project_2_step(void);
extern void Project_2_terminate(void);
/* Real-time Model object */
extern RT_MODEL_Project_2_T *const Project_2_M;
/*-
* These blocks were eliminated from the model due to optimizations:
*
* Block '<S7>/Data Type Duplicate' : Unused code path elimination
* Block '<S7>/Data Type Propagation' : Unused code path elimination
* Block '<S1>/Scope' : Unused code path elimination
* Block '<S1>/Scope1' : Unused code path elimination
* Block '<S1>/Scope2' : Unused code path elimination
* Block '<S1>/Scope3' : Unused code path elimination
* Block '<S6>/Scope' : Unused code path elimination
* Block '<Root>/Subsystem_boundary_DTC4' : Eliminate redundant data type conversion
* Block '<Root>/Subsystem_boundary_DTC5' : Eliminate redundant data type conversion
* Block '<Root>/Subsystem_boundary_DTC6' : Eliminate redundant data type conversion
* Block '<Root>/Subsystem_boundary_DTC7' : Eliminate redundant data type conversion
*/
/*-
* The generated code includes comments that allow you to trace directly
* back to the appropriate location in the model. The basic format
* is <system>/block_name, where system is the system number (uniquely
* assigned by Simulink) and block_name is the name of the block.
*
* Use the MATLAB hilite_system command to trace the generated code back
* to the model. For example,
*
* hilite_system('<S3>') - opens system 3
* hilite_system('<S3>/Kp') - opens and selects block Kp which resides in S3
*
* Here is the system hierarchy for this model
*
* '<Root>' : 'Project_2'
* '<S1>' : 'Project_2/Subsystem1'
* '<S2>' : 'Project_2/Subsystem1/Auxillary_Data_Filtering'
* '<S3>' : 'Project_2/Subsystem1/Compare To Zero'
* '<S4>' : 'Project_2/Subsystem1/Input_Processing'
* '<S5>' : 'Project_2/Subsystem1/Main_Data_Filtering'
* '<S6>' : 'Project_2/Subsystem1/TFT_Speed_Output'
* '<S7>' : 'Project_2/Subsystem1/Input_Processing/Saturation Dynamic'
*/
#endif /* RTW_HEADER_Project_2_h_ */
/*
* File trailer for generated code.
*
* [EOF]
*/
Project_2.c
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: Project_2.c
*
* Code generated for Simulink model 'Project_2'.
*
* Model version : 3.33
* Simulink Coder version : 9.7 (R2022a) 13-Nov-2021
* C/C++ source code generated on : Mon Dec 25 16:16:00 2023
*
* Target selection: ert.tlc
* Embedded hardware selection: Intel->x86-64 (Windows64)
* Code generation objectives: Unspecified
* Validation result: Not run
*/
#include "Project_2.h"
#include "rtwtypes.h"
#include "Project_2_private.h"
/* Block signals (default storage) */
B_Project_2_T Project_2_B;
/* External inputs (root inport signals with default storage) */
ExtU_Project_2_T Project_2_U;
/* External outputs (root outports fed by signals with default storage) */
ExtY_Project_2_T Project_2_Y;
/* Real-time model */
static RT_MODEL_Project_2_T Project_2_M_;
RT_MODEL_Project_2_T *const Project_2_M = &Project_2_M_;
static void rate_scheduler(void);
int16_T div_s16s32_floor(int32_T numerator, int32_T denominator)
{
int16_T quotient;
if (denominator == 0) {
quotient = (int16_T)(numerator >= 0 ? 32767 : -32768);
/* Divide by zero handler */
} else {
uint32_T absDenominator;
uint32_T absNumerator;
uint32_T tempAbsQuotient;
boolean_T quotientNeedsNegation;
absNumerator = numerator < 0 ? ~(uint32_T)numerator + 1U : (uint32_T)
numerator;
absDenominator = denominator < 0 ? ~(uint32_T)denominator + 1U : (uint32_T)
denominator;
quotientNeedsNegation = ((numerator < 0) != (denominator < 0));
tempAbsQuotient = absNumerator / absDenominator;
if (quotientNeedsNegation) {
absNumerator %= absDenominator;
if (absNumerator > 0U) {
tempAbsQuotient++;
}
}
quotient = (int16_T)(quotientNeedsNegation ? (int32_T)(int16_T)-(int32_T)
tempAbsQuotient : (int32_T)(int16_T)tempAbsQuotient);
}
return quotient;
}
/*
* This function updates active task flag for each subrate.
* The function is called at model base rate, hence the
* generated code self-manages all its subrates.
*/
static void rate_scheduler(void)
{
/* Compute which subrates run during the next base time step. Subrates
* are an integer multiple of the base rate counter. Therefore, the subtask
* counter is reset when it reaches its limit (zero means run).
*/
(Project_2_M->Timing.TaskCounters.TID[1])++;
if ((Project_2_M->Timing.TaskCounters.TID[1]) > 9) {/* Sample time: [0.01s, 0.0s] */
Project_2_M->Timing.TaskCounters.TID[1] = 0;
}
}
/* Model step function */
void Project_2_step(void)
{
if (Project_2_M->Timing.TaskCounters.TID[1] == 0) {
int16_T rtb_Subtract;
uint16_T rtb_Subtract_0;
uint16_T rtb_Switch2;
/* Outputs for Atomic SubSystem: '<Root>/Subsystem1' */
/* Switch: '<S7>/Switch2' incorporates:
* Constant: '<S4>/HighLimit_VehcileSpeed'
* Inport: '<Root>/Average_VehicleSpeed'
* RelationalOperator: '<S7>/LowerRelop1'
* RelationalOperator: '<S7>/UpperRelop'
* Switch: '<S7>/Switch'
*/
if (Project_2_U.Average_VehicleSpeed > 32000) {
rtb_Switch2 = 32000U;
} else if (Project_2_U.Average_VehicleSpeed < 256) {
/* Switch: '<S7>/Switch' incorporates:
* Constant: '<S4>/LowLimit_VehcileSpeed1'
* Switch: '<S7>/Switch2'
*/
rtb_Switch2 = 256U;
} else {
rtb_Switch2 = Project_2_U.Average_VehicleSpeed;
}
/* End of Switch: '<S7>/Switch2' */
/* Outputs for Enabled SubSystem: '<S1>/Auxillary_Data_Filtering' incorporates:
* EnablePort: '<S2>/Enable'
*/
/* Outputs for Enabled SubSystem: '<S1>/Main_Data_Filtering' incorporates:
* EnablePort: '<S5>/Enable'
*/
/* RelationalOperator: '<S3>/Compare' incorporates:
* Constant: '<S3>/Constant'
* Inport: '<Root>/Timer_Input'
* Math: '<S1>/Rem'
*/
if ((uint16_T)(Project_2_U.Timer_Input % 10) == 0) {
int32_T tmp;
/* Product: '<S5>/Divide' incorporates:
* Gain: '<S5>/Gain'
* Inport: '<Root>/In_MainFilt_SpeedValue'
* Switch: '<S7>/Switch2'
*/
tmp = (int32_T)((uint32_T)Project_2_U.In_MainFilt_SpeedValue << 3);
if ((uint32_T)tmp == 0U) {
rtb_Subtract_0 = MAX_uint16_T;
/* Divide by zero handler */
} else {
rtb_Subtract_0 = (uint16_T)((uint32_T)(uint16_T)((21299U * rtb_Switch2) >>
7) / tmp);
}
/* Sum: '<S2>/Subtract' incorporates:
* Constant: '<S2>/Constant'
* Constant: '<S5>/Constant'
* Gain: '<S2>/Gain'
* Inport: '<Root>/In_AuxillaryFilt_SpeedValue'
* Product: '<S2>/Divide'
* Product: '<S5>/Divide'
* Sum: '<S5>/Subtract'
*/
Project_2_B.DisplaySpeed_Filter = (int16_T)(((div_s16s32_floor((((int16_T)
(((rtb_Subtract_0 << 14) - 52429) >> 13) * 25559) >> 15) << 4,
Project_2_U.In_AuxillaryFilt_SpeedValue) << 15) - 31457) >> 15);
}
/* End of RelationalOperator: '<S3>/Compare' */
/* End of Outputs for SubSystem: '<S1>/Main_Data_Filtering' */
/* End of Outputs for SubSystem: '<S1>/Auxillary_Data_Filtering' */
/* Sum: '<S6>/Subtract' incorporates:
* Sum: '<S2>/Subtract'
* Switch: '<S7>/Switch2'
*/
rtb_Subtract = (int16_T)((rtb_Switch2 - (Project_2_B.DisplaySpeed_Filter <<
2)) >> 1);
/* Abs: '<S6>/Abs' incorporates:
* Sum: '<S6>/Subtract'
*/
if (rtb_Subtract < 0) {
rtb_Subtract_0 = (uint16_T)((uint32_T)-rtb_Subtract >> 3);
} else {
rtb_Subtract_0 = (uint16_T)((uint32_T)rtb_Subtract >> 3);
}
/* End of Abs: '<S6>/Abs' */
/* Switch: '<S6>/Switch' incorporates:
* RelationalOperator: '<S6>/GreaterThan'
*/
if (rtb_Subtract_0 > 12) {
/* DataTypeConversion: '<Root>/Out_VehicleSpeedDisplay_boundary_DTC1' incorporates:
* Switch: '<S7>/Switch2'
*/
rtb_Subtract = (int16_T)((uint32_T)rtb_Switch2 >> 6);
if (rtb_Subtract <= 0) {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = 0U;
} else if (rtb_Subtract > 511) {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = MAX_uint16_T;
} else {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = (uint16_T)(rtb_Subtract << 7);
}
} else {
/* DataTypeConversion: '<Root>/Out_VehicleSpeedDisplay_boundary_DTC1' incorporates:
* Sum: '<S2>/Subtract'
*/
rtb_Subtract = (int16_T)(Project_2_B.DisplaySpeed_Filter >> 4);
if (rtb_Subtract <= 0) {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = 0U;
} else if (rtb_Subtract > 511) {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = MAX_uint16_T;
} else {
/* Outport: '<Root>/Out_VehicleSpeedDisplay' */
Project_2_Y.Out_VehicleSpeedDisplay = (uint16_T)(rtb_Subtract << 7);
}
}
/* End of Switch: '<S6>/Switch' */
/* End of Outputs for SubSystem: '<Root>/Subsystem1' */
}
rate_scheduler();
}
/* Model initialize function */
void Project_2_initialize(void)
{
/* (no initialization code required) */
}
/* Model terminate function */
void Project_2_terminate(void)
{
/* (no terminate code required) */
}
/*
* File trailer for generated code.
*
* [EOF]
*/













