lin_frame_management.c
来自「芯科原厂所有c8051fxx程序的例子。」· C语言 代码 · 共 792 行 · 第 1/2 页
C
792 行
// Copyright (c) 2006 SILICON LABORATORIES, INC.
//
// FILE NAME : LIN_Frame_Management.c
// TARGET MCU : C8051F52xA-53xA
// DESCRIPTION : Defines frames and schedules and implements scheduleing
// routines.
//
// This file contains definitions for all frames and schedules, as well as
// routines that manage the frame scheduling of the LIN API.
//
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
//
#include <c8051F520.h>
#include "LIN.h"
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
//
// These variables are used globally in LIN_Frame_Management.c:
//
// 1. frame_direction - This variable holds the direction of the frame.
//
// 2. sw_slave_collision_resolution_schedule - This is the resolution schedule
// used by frames with frame ID SW_SLAVE_EVENT_TRIGGERED_ID
// when a collision occurs. It is declared extern here so that
// application_frame_descriptor can declare a pointer to it.
//
// 3. collision - This bit is set when the master task detects that a collision
// may have occurred and cleared once the collision resolution
// schedule it selected.
//
// 4. schedule_controller_std_ifc - This is the data structure which manages
// all schedules on interface std_ifc.
//
l_u8 frame_direction;
#if (LIN_MODE == LIN_MASTER)
extern l_schedule sw_slave_collision_resolution_schedule;
l_bool collision = 0;
l_schedule_controller schedule_controller_std_ifc =
{
L_NULL_SCHEDULE,
NORMAL_SCHEDULE,
0x00,
0x00,
L_NULL_SCHEDULE,
0x00,
L_NULL_SCHEDULE,
0x00
};
#endif
//-----------------------------------------------------------------------------
// Frame Definitions
//-----------------------------------------------------------------------------
//
// application_frame_descriptor is an array which holds definitions for all
// frames transmitted in the LIN application. The format of the
// l_frame struct is as follows:
//
// { frame_id, frame_len, frame_direction, frame_type, frame_checksum,
// (collision_resolution_schedule (master only)) }
//
// where:
//
// 1. frame_id - The ID of the frame.
//
// 2. frame_len - The number of bytes of frame data. May be any integer
// value between one and eight.
//
// 3. frame_direction - Determines whether the frame data will be
// transmitted (OUT_FRAME), received (IN_FRAME), or ignored
// (IGNORE_FRAME).
//
// 4. frame_type - Defines the type of frame. Can be UNCONDITIONAL_FRAME,
// EVENT_TRIGGERED_FRAME, or SPORADIC_FRAME.
//
// 5. frame_checksum - The type of checksum associated with the frame.
// May be CLASSIC_CHECKSUM, ENHANCED_CHECKSUM, or VARIABLE_CHECKSUM.
// VARIABLE_CHECKSUM should be used for sporadic frame slots which may
// have associated frames of either checksum type.
//
// 6. collision_resolution_schedule - A pointer to the schedule to use if
// a collision occurs while this frame is being transmitted. If the
// frame type is not EVENT_TRIGGERED_FRAME, this pointer should always
// be L_NULL_SCHEDULE.
//
#if (LIN_MODE == LIN_MASTER)
l_frame diagnostic_frame_descriptor[] =
{
// Master request frame is sent from the master to the slaves.
MASTER_REQUEST_FRAME_ID,
MASTER_REQUEST_FRAME_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
CLASSIC_CHECKSUM,
L_NULL_SCHEDULE,
// Slave request frames are sent from a slave to the master and other
// other slaves on the bus.
SLAVE_RESPONSE_FRAME_ID,
SLAVE_RESPONSE_FRAME_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
CLASSIC_CHECKSUM,
L_NULL_SCHEDULE
};
#elif (LIN_MODE == LIN_SLAVE)
l_frame diagnostic_frame_descriptor[] =
{
// Master request frame is sent from the master to the slaves.
MASTER_REQUEST_FRAME_ID,
MASTER_REQUEST_FRAME_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
CLASSIC_CHECKSUM,
// Slave request frames are sent from a slave to the master and other
// other slaves on the bus.
SLAVE_RESPONSE_FRAME_ID,
SLAVE_RESPONSE_FRAME_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
CLASSIC_CHECKSUM
};
#endif
#if (LIN_MODE == LIN_MASTER)
l_frame application_frame_descriptor[] =
{
// Frame ID 0 is a sporadic frame slot where the LIN master will send the
// the value of signals led_slave_id_0, led_slave_id_1,
// and led_slave_id_2.
LED_SLAVE_SPORADIC_ID,
LED_SLAVE_SPORADIC_ID_LEN,
OUT_FRAME,
SPORADIC_FRAME,
VARIABLE_CHECKSUM,
L_NULL_SCHEDULE,
// Frame ID 1 sends led_slave_id_0, led_slave_id_1, and
// led_slave_id_2 from the master to the slaves.
LED_SLAVE_UNCONDITIONAL_ID,
LED_SLAVE_UNCONDITIONAL_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
L_NULL_SCHEDULE,
// Frame ID 2 is an event-triggered frame that requests the slaves
// to send the value of their sw_slave_id_x signals if the values have
// changed.
SW_SLAVE_EVENT_TRIGGERED_ID,
SW_SLAVE_EVENT_TRIGGERED_ID_LEN,
IN_FRAME,
EVENT_TRIGGERED_FRAME,
ENHANCED_CHECKSUM,
&sw_slave_collision_resolution_schedule,
// Frame ID 3 is an unconditional frame to send sw_slave_id_0 from
// LIN_SLAVE_ID_0 to LIN_MASTER.
SW_SLAVE_ID_0_UNCONDITIONAL_ID,
SW_SLAVE_ID_0_UNCONDITIONAL_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
L_NULL_SCHEDULE,
// Frame ID 4 is an unconditional frame to send sw_slave_id_1 from
// LIN_SLAVE_ID_1 to LIN_MASTER.
SW_SLAVE_ID_1_UNCONDITIONAL_ID,
SW_SLAVE_ID_1_UNCONDITIONAL_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
L_NULL_SCHEDULE,
// Frame ID 5 is an unconditional frame to send sw_slave_id_2 from
// LIN_SLAVE_ID_2 to LIN_MASTER.
SW_SLAVE_ID_2_UNCONDITIONAL_ID,
SW_SLAVE_ID_2_UNCONDITIONAL_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
L_NULL_SCHEDULE
};
#elif (LIN_MODE == LIN_SLAVE)
l_frame application_frame_descriptor[] =
{
// Frame ID 1 sends led_slave_id_0, led_slave_id_1, and
// led_slave_id_2 from the master to the slaves.
LED_SLAVE_UNCONDITIONAL_ID,
LED_SLAVE_UNCONDITIONAL_ID_LEN,
IN_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
// Frame ID 2 is an event-triggered frame that requests the slaves
// to send the value of their sw_slave_id_x signals if the values have
// changed.
SW_SLAVE_EVENT_TRIGGERED_ID,
SW_SLAVE_EVENT_TRIGGERED_ID_LEN,
OUT_FRAME,
EVENT_TRIGGERED_FRAME,
ENHANCED_CHECKSUM,
#if (LIN_SLAVE_ID == LIN_SLAVE_ID_0)
// Frame ID 3 is an unconditional frame to send sw_slave_id_0 from
// LIN_SLAVE_ID_0 to LIN_MASTER.
SW_SLAVE_ID_0_UNCONDITIONAL_ID,
SW_SLAVE_ID_0_UNCONDITIONAL_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_1)
// Frame ID 4 is an unconditional frame to send sw_slave_id_1 from
// LIN_SLAVE_ID_1 to LIN_MASTER.
SW_SLAVE_ID_1_UNCONDITIONAL_ID,
SW_SLAVE_ID_1_UNCONDITIONAL_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM,
#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_2)
// Frame ID 5 is an unconditional frame to send sw_slave_id_2 from
// LIN_SLAVE_ID_2 to LIN_MASTER.
SW_SLAVE_ID_2_UNCONDITIONAL_ID,
SW_SLAVE_ID_2_UNCONDITIONAL_ID_LEN,
OUT_FRAME,
UNCONDITIONAL_FRAME,
ENHANCED_CHECKSUM
#endif
};
#endif
#if (LIN_MODE == LIN_MASTER)
//-----------------------------------------------------------------------------
// Schedule Definitions
//-----------------------------------------------------------------------------
//
// Schedules are defined here. A schedule is a variable of type l_schedule.
// Each entry in the schedule is a variable of type l_schedule_entry.
// l_schedule is an array of l_schedule_entry objects.
//
// Struct l_frame_entry consists of two members:
//
// 1. frame_ptr - This is a pointer to a frame (type l_frame).
//
// 2. delay_num_ticks - The number of system ticks the master task should
// wait before sending the next frame in the schedule. The minimum value
// for delay_num_ticks can be calculated using the macro
// _FRAME_LENGTH_SYSTEM_TICKS() (see LIN_Frame_Management.h).
//
// The application may define multiple schedules and switch between them using
// the l_sch_set_ifc () Core API call.
//
// These schedules should be defined with the extern keyword in
// LIN_Signal.h so they can be accessed by other modules which may
// call l_sch_set_ifc ().
//
l_schedule normal_schedule =
{
&application_frame_descriptor[0], _FRAME_LENGTH_SYSTEM_TICKS (LED_SLAVE_SPORADIC_ID_LEN),
&application_frame_descriptor[2], _FRAME_LENGTH_SYSTEM_TICKS (SW_SLAVE_EVENT_TRIGGERED_ID_LEN),
L_NULL_SCHEDULE_ENTRY
};
l_schedule sw_slave_collision_resolution_schedule =
{
&application_frame_descriptor[3], _FRAME_LENGTH_SYSTEM_TICKS (SW_SLAVE_ID_0_UNCONDITIONAL_ID_LEN),
&application_frame_descriptor[4], _FRAME_LENGTH_SYSTEM_TICKS (SW_SLAVE_ID_1_UNCONDITIONAL_ID_LEN),
&application_frame_descriptor[5], _FRAME_LENGTH_SYSTEM_TICKS (SW_SLAVE_ID_2_UNCONDITIONAL_ID_LEN),
L_NULL_SCHEDULE_ENTRY
};
l_schedule diagnostic_master_request_schedule =
{
&diagnostic_frame_descriptor[0], _FRAME_LENGTH_SYSTEM_TICKS (MASTER_REQUEST_FRAME_ID_LEN),
L_NULL_SCHEDULE_ENTRY
};
#endif // LIN_MODE == LIN_MASTER
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// l_get_frame ()
//-----------------------------------------------------------------------------
//
// Given a frame ID, this function returns a pointer to the entry in
// application_frame_descriptor or diagnostic_frame_descriptor with a
// matching ID. Returns L_NULL_FRAME if the frame is not found.
//
// Parameters:
//
// 1. frame_id - The frame ID to search for.
//
//
l_frame * l_get_frame (l_u8 frame_id)
{
l_frame * frame_ptr;
l_u8 i;
l_bool frame_found;
// Point to the first frame in application_frame_descriptor.
frame_ptr = &application_frame_descriptor;
// Set frame_found to false.
frame_found = 0;
// Loop through application_frame_descriptor until the entry with ID
// frame_id is found or all entries have been searched.
for (i = 0; i < (sizeof (application_frame_descriptor) / sizeof (l_frame)); i++)
{
if (frame_id == frame_ptr->frame_id)
{
frame_found = 1;
break;
}
// Increment frame_ptr.
frame_ptr++;
}
// If the frame is not found in application_frame_descriptor, look in
// diagnostic_frame_descriptor.
if (!frame_found)
{
// Point to the first frame in diagnostic_frame_descriptor.
frame_ptr = &diagnostic_frame_descriptor;
for (i = 0; i < (sizeof (diagnostic_frame_descriptor) / sizeof (l_frame)); i++)
{
if (frame_id == frame_ptr->frame_id)
{
frame_found = 1;
break;
}
// Increment frame_ptr
frame_ptr++;
}
}
// If the frame was not found, return L_NULL_FRAME.
if(!frame_found)
frame_ptr = L_NULL_FRAME;
return (frame_ptr);
}
#if (LIN_MODE == LIN_MASTER)
//-----------------------------------------------------------------------------
// l_sch_tick_std_ifc ()
//-----------------------------------------------------------------------------
//
// This function sends the next frame when it is due, updates all signal values
// associated with interface std_ifc, and updates
// schedule_controller_std_ifc.
//
// The period at which this function is called sets the time base tick, so it
// must be called periodically within the allowable jitter.
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?