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 + -
显示快捷键?