⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash_pb.c

📁 Luminary Micro BLDC motor control software
💻 C
📖 第 1 页 / 共 2 页
字号:
//*****************************************************************************
//
// flash_pb.c - Flash parameter block functions.
//
// Copyright (c) 2007-2008 Luminary Micro, Inc.  All rights reserved.
// 
// Software License Agreement
// 
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
// 
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  You may not combine
// this software with "viral" open-source software in order to form a larger
// program.  Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
// 
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 716 of the BLDC motor application.
//
//*****************************************************************************

#include "../../DriverLib/hw_types.h"
#include "../../DriverLib/src/flash.h"
#include "../../DriverLib/src/sysctl.h"
#include "flash_pb.h"

//*****************************************************************************
//
//! \page flash_pb_intro Introduction
//!
//! This module provides a fault-tolerant, persistent storage mechanism for the
//! parameter block of the motor drive.  The last several pages of flash are
//! used for the storage; more than one page is required in order to be
//! fault-tolerant.
//!
//! Parameter blocks are an array of bytes that contain the persistent
//! parameters of the motor drive.  The only special requirement for the
//! parameter block is that the first byte is a sequence number (explained
//! later) and the second byte is a checksum used to validate the correctness
//! of the data (the checksum byte is the byte such that the sum of all bytes
//! in the parameter block is zero).
//!
//! The portion of flash for parameter block storage is split into N
//! equal-sized regions, where each region is the size of a parameter block.
//! Each region is scanned at startup; the region that has a valid checksum and
//! has the highest sequence number (with special consideration given to
//! wrapping back to zero) is considered to be the current parameter block.
//! The contents of this region of flash are loaded into SRAM as the current
//! parameters for the motor drive.
//!
//! Saving new parameter blocks involves three steps:
//!
//! - Setting the sequence number such that it is one greater than the sequence
//!   number of the latest parameter block in flash.
//! - Computing the checksum of the parameter block.
//! - Writing the parameter block into the storage immediately following the
//!   latest parameter block in flash; if that storage is at the start of an
//!   erase block, that block is erased first.
//!
//! By this process, there is always a valid parameter block in flash.  If
//! power is lost while writing a new parameter block, the checksum will not
//! match and the partially written parameter block will be ignored.  This is
//! what makes this fault-tolerant.
//!
//! Another benefit of this scheme is that it provides wear leveling on the
//! flash.  Since multiple parameter blocks fit into each erase block of flash,
//! and multiple erase blocks are used for parameter block storage, it takes
//! quite a few parameter block saves before flash is re-written.
//!
//! In order to make this efficient and effective, two conditions must be met.
//! The first is that at least two erase blocks of flash must be dedicated to
//! parameter block storage.  If not, fault tolerance can not be guaranteed
//! since an erase of the single block will leave a window where there are no
//! valid parameter blocks in flash.  The second condition is that the size of
//! the parameter block must be an integral divisor of the size of an erase
//! block of flash.  If not, a parameter block will end up spanning between
//! two erase blocks of flash, making it more difficult to manage.
//!
//! When the microcontroller is initially programmed, the flash blocks used for
//! parameter block storage are left in an erased state.  The default settings
//! in the motor drive application are therefore used initially.
//!
//! The code for handling the flash parameter blocks is contained in
//! <tt>flash_pb.c</tt>, with <tt>flash_pb.h</tt> containing the definitions
//! for the functions exported to the remainder of the application.
//
//*****************************************************************************

//*****************************************************************************
//
//! \defgroup flash_pb_api Definitions
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! The address of the beginning of the flash used for storing parameter
//! blocks; this must be the start of an erase block in the flash.
//
//*****************************************************************************
static unsigned char *g_pucFlashPBStart;

//*****************************************************************************
//
//! The address of the end of the flash used for storing parameter blocks; this
//! must be the start of an erase block in the flash, or the first location
//! after the end of the flash array if the last erase block is used for
//! storing parameters.
//
//*****************************************************************************
static unsigned char *g_pucFlashPBEnd;

//*****************************************************************************
//
//! The size of the parameter block when stored in flash; this must be a power
//! of two less than or equal to 1024.
//
//*****************************************************************************
static unsigned long g_ulFlashPBSize;

//*****************************************************************************
//
//! The address of the most recent parameter block in flash.
//
//*****************************************************************************
static unsigned char *g_pucFlashPBCurrent;

//*****************************************************************************
//
//! Determines if the parameter block at the given address is valid.
//!
//! \param pucOffset is the address of the parameter block to check.
//!
//! This function will compute the checksum of a parameter block in flash to
//! determine if it is valid.
//!
//! \return Returns one if the parameter block is valid and zero if it is not.
//
//*****************************************************************************
static unsigned long
FlashPBIsValid(unsigned char *pucOffset)
{
    unsigned long ulIdx, ulSum;

    //
    // Loop through the bytes in the block, computing the checksum.
    //
    for(ulIdx = 0, ulSum = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
    {
        ulSum += pucOffset[ulIdx];
    }

    //
    // The checksum should be zero, so return a failure if it is not.
    //
    if((ulSum & 255) != 0)
    {
        return(0);
    }

    //
    // This is a valid parameter block.
    //
    return(1);
}

//*****************************************************************************
//
//! Gets the address of the most recent parameter block.
//!
//! This function returns the address of the most recent parameter block that
//! is stored in flash.
//!
//! \return Returns the address of the most recent parameter block, or NULL if
//! there are no valid parameter blocks in flash.
//
//*****************************************************************************
unsigned char *
FlashPBGet(void)
{
    //
    // See if there is a valid parameter block.
    //
    if(g_pucFlashPBCurrent)
    {
        //
        // Return the address of the most recent parameter block.
        //
        return(g_pucFlashPBCurrent);
    }

    //
    // There are no valid parameter blocks in flash, so return NULL.
    //
    return(0);
}

//*****************************************************************************
//
//! Writes a new parameter block to flash.
//!
//! \param pucBuffer is the address of the parameter block to be written to
//! flash.
//!
//! This function will write a parameter block to flash.  The parameter block
//! is written to the next available portion of the parameter block space in
//! flash, being careful to keep the previous parameter block intact in case
//! there is a power loss or fault mid-way through the save process.
//!
//! \return None.
//
//*****************************************************************************
void
FlashPBSave(unsigned char *pucBuffer)
{
    unsigned char *pucNew;
    unsigned long ulIdx, ulSum;

    //
    // See if there is a valid parameter block in flash.
    //
    if(g_pucFlashPBCurrent)
    {
        //
        // Set the sequence number to one greater than the most recent
        // parameter block.
        //
        pucBuffer[0] = g_pucFlashPBCurrent[0] + 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -