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

📄 main.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************/
/*                                                                     */
/*   Module:  main.c                                                   */
/*   Release: 2004.5                                                   */
/*   Version: 2003.1                                                   */
/*   Purpose: TargetFFS Powerloss Recovery Test                        */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*   This program simulates using TargetFFS to hold both the current   */
/*   version of an application and an upgrade that is being downloaded */
/*   over a network. After the download is complete, the current copy  */
/*   is deleted. Subsequent boots use the latest version.              */
/*                                                                     */
/*   This application tests TargetFFS's powerloss recovery. Two files  */
/*   are used: "exe1" and "exe2". At startup, the program checks that  */
/*   at least one of these files exists and ends with a valid four     */
/*   byte checksum. When files are written, they are padded to a       */
/*   multiple of four bytes before the checksum is appended.           */
/*                                                                     */
/*   If both files exist and have valid checksums, the most recent     */
/*   becomes the boot file. The other file is used for the next down-  */
/*   load. The program enters an infinite loop in which a new upgrade  */
/*   is loaded, the old boot file is deleted, and then the boot and    */
/*   upgrade file names are swapped.                                   */
/*                                                                     */
/*   The test is performed by "randomly" removing power while the      */
/*   application is running. It is a fatal error if the program is not */
/*   able to mount the flash volume and find at least one valid file.  */
/*                                                                     */
/*   Before the test can be run, the volume must be formatted and      */
/*   written with at least one valid file.                             */
/*                                                                     */
/***********************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <targetos.h>
#include <kernel.h>
#include <sys.h>
#include "../../posix.h"

/***********************************************************************/
/* Configuration                                                       */
/***********************************************************************/
#define ID_REG          0
#define CWD_WD1         1
#define CWD_WD2         2

/***********************************************************************/
/* Local Function Definitions                                          */
/***********************************************************************/

/***********************************************************************/
/*       error: Print error message and call fatal error handler       */
/*                                                                     */
/*       Input: msg = pointer to error message                         */
/*                                                                     */
/***********************************************************************/
static void error(char *msg)
{
  perror(msg);
  taskSleep(50);
  SysFatalError(errno);
}

/***********************************************************************/
/*    download: Simulate downloading a new executable over a network   */
/*              connection. Just write a file with semi-random values  */
/*              with a length that is a multiple of four bytes, then   */
/*              append a 32-bit checksum.                              */
/*                                                                     */
/*       Input: fname = the name of the file to be created             */
/*                                                                     */
/***********************************************************************/
static void download(char *fname)
{
  int fid, length, rc;
  ui32 i, checksum;

  /*-------------------------------------------------------------------*/
  /* Create the download file.                                         */
  /*-------------------------------------------------------------------*/
  fid = open(fname, O_WRONLY | O_CREAT | O_TRUNC,
             S_IRUSR | S_IWUSR | S_IXUSR);

  /*-------------------------------------------------------------------*/
  /* Choose a somewhat random length >= 128KB.                         */
  /*-------------------------------------------------------------------*/
  length = (128 * 1024 + (rand() % 2048)) & ~3;

  /*-------------------------------------------------------------------*/
  /* Fill the download file with data.                                 */
  /*-------------------------------------------------------------------*/
  length >>= 2;
  checksum = 0;
  for (i = 0; i < length; ++i)
  {
    checksum += i;
    rc = write(fid, &i, sizeof(i));
    if (rc != sizeof(i))
      error("Unable to write file data");
  }

  /*-------------------------------------------------------------------*/
  /* Write the 32-bit checksum.                                        */
  /*-------------------------------------------------------------------*/
  rc = write(fid, &checksum, sizeof(checksum));
  if (rc != sizeof(checksum))
    error("Unable to write file checksum");

  /*-------------------------------------------------------------------*/
  /* Close the file, flushing its contents to flash.                   */
  /*-------------------------------------------------------------------*/
  close(fid);
}

/***********************************************************************/
/*       valid: Check if file identifier is valid, the file length is  */
/*              non-zero and a multiple of four bytes, and the file    */
/*              ends with a 32-bit checksum of the previous contents.  */
/*                                                                     */
/*       Input: fid = identifier of file to be checked                 */
/*                                                                     */
/***********************************************************************/
static int valid(int fid)
{
  int rc, length;
  struct stat sbuf;
  ui32 lword, expected, checksum;

  /*-------------------------------------------------------------------*/
  /* Check if the file identifier is valid.                            */
  /*-------------------------------------------------------------------*/
  if (fid == -1)
    return FALSE;

  /*-------------------------------------------------------------------*/
  /* Read the file state information.                                  */
  /*-------------------------------------------------------------------*/
  if (fstat(fid, &sbuf))
    error("fstat() error in valid()");

  /*-------------------------------------------------------------------*/
  /* Return FALSE if the length is zero or not a multiple of four.     */
  /*-------------------------------------------------------------------*/
  length = sbuf.st_size;
  if ((length == 0) || (length & 3))
    return FALSE;

  /*-------------------------------------------------------------------*/
  /* Read and checksum all but the last four bytes.                    */
  /*-------------------------------------------------------------------*/
  length >>= 2;
  expected = checksum = 0;
  while (--length)
  {
    rc = read(fid, &lword, sizeof(lword));
    if (rc == -1)
      error("read() returned -1 while reading data");

    if (lword != expected)
      error("data error");

    checksum += lword;
    ++expected;
  }

  /*-------------------------------------------------------------------*/
  /* Read and verify the checksum.                                     */
  /*-------------------------------------------------------------------*/
  rc = read(fid, &lword, sizeof(lword));
  if (rc == -1)
    error("read() returned -1 while reading checksum");
  return lword == checksum;
}

/***********************************************************************/
/*     prepare: Verify most recent boot image and then load a new one  */
/*                                                                     */
/*       Input: vol_name = pointer to volume name                      */
/*                                                                     */
/***********************************************************************/
static void prepare(char *vol_name)
{
  /*-------------------------------------------------------------------*/
  /* Format and mount the volume.                                      */
  /*-------------------------------------------------------------------*/
  if (format(vol_name))
    error("format flash failed");
  if (mount(vol_name))
    error("Unable to mount flash volume!");
  if (chdir(vol_name))
    error("Unable to 'cd' to flash directory!");

  /*-------------------------------------------------------------------*/
  /* Change to volume's root directory and install "exe1".             */
  /*-------------------------------------------------------------------*/
  download("exe1");

  /*-------------------------------------------------------------------*/
  /* Unmount the volume.                                               */
  /*-------------------------------------------------------------------*/
  if (unmount(vol_name))
    error("Unable to unmount flash volume!");
}

/***********************************************************************/
/*        boot: Verify most recent boot image and then load a new one  */
/*                                                                     */
/*       Input: vol_name = pointer to volume name                      */
/*                                                                     */
/***********************************************************************/
static void boot(char *vol_name)
{
  int fid1, fid2, valid1, valid2;
  char *boot, *path, *upgrade;

  /*-------------------------------------------------------------------*/
  /* Mount the volume and change to its root directory.                */
  /*-------------------------------------------------------------------*/
  if (mount(vol_name))
    error("Unable to mount flash volume!");
  if (chdir(vol_name))
    error("Unable to 'cd' to flash directory!");

  /*-------------------------------------------------------------------*/
  /* Attempt to open both files. Ensure at least one exists.           */
  /*-------------------------------------------------------------------*/
  fid1 = open("exe1", O_RDONLY);
  fid2 = open("exe2", O_RDONLY);
  if ((fid1 == -1) && (fid2 == -1))
    error("Neither file exists!");

⌨️ 快捷键说明

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