flash.c
Go to the documentation of this file.
00001 /*
00002  * $Id: flash.c,v 1.12 2003/12/02 08:25:00 troth Exp $
00003  *
00004  ****************************************************************************
00005  *
00006  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
00007  * Copyright (C) 2001, 2002, 2003  Theodore A. Roth
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  ****************************************************************************
00024  */
00025 
00026 /**
00027  * \file flash.c
00028  * \brief Flash memory methods
00029  *
00030  * This module provides functions for reading and writing to flash memory.
00031  * Flash memory is the program (.text) memory in AVR's Harvard architecture.
00032  * It is completely separate from RAM, which is simulated in the memory.c
00033  * file.
00034  */
00035 
00036 #include <config.h>
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <sys/types.h>
00043 #include <sys/stat.h>
00044 #include <fcntl.h>
00045 #include <errno.h>
00046 
00047 #include "avrerror.h"
00048 #include "avrmalloc.h"
00049 #include "avrclass.h"
00050 #include "utils.h"
00051 
00052 #include "storage.h"
00053 #include "flash.h"
00054 
00055 #include "display.h"
00056 
00057 /***************************************************************************\
00058  *
00059  * Local Static Function Prototypes
00060  *
00061 \***************************************************************************/
00062 
00063 static int flash_load_from_bin_file (Flash *flash, char *file);
00064 
00065 /***************************************************************************\
00066  *
00067  * Flash(Storage) Methods
00068  *
00069 \***************************************************************************/
00070 
00071 /**
00072  * \brief Reads a 16-bit word from flash.
00073  * \return A word.
00074  */
00075 
00076 extern inline uint16_t flash_read (Flash *flash, int addr);
00077 
00078 /**
00079  * \brief Reads a 16-bit word from flash.
00080  * \param flash A pointer to a flash object.
00081  * \param addr The address to which to write.
00082  * \param val The byte to write there.
00083  */
00084 
00085 void
00086 flash_write (Flash *flash, int addr, uint16_t val)
00087 {
00088     display_flash (addr, 1, &val);
00089     storage_writew ((Storage *)flash, addr * 2, val);
00090 }
00091 
00092 /** \brief Write the low-order byte of an address.
00093  *
00094  * AVRs are little-endian, so lo8 bits in odd addresses.
00095  */
00096 
00097 void
00098 flash_write_lo8 (Flash *flash, int addr, uint8_t val)
00099 {
00100     storage_writeb ((Storage *)flash, addr * 2 + 1, val);
00101 }
00102 
00103 /** \brief Write the high-order byte of an address.
00104  *
00105  * AVRs are little-endian, so hi8 bits in even addresses.
00106  */
00107 
00108 void
00109 flash_write_hi8 (Flash *flash, int addr, uint8_t val)
00110 {
00111     storage_writeb ((Storage *)flash, addr * 2, val);
00112 }
00113 
00114 /** \brief Allocate a new Flash object. */
00115 
00116 Flash *
00117 flash_new (int size)
00118 {
00119     Flash *flash;
00120 
00121     flash = avr_new (Flash, 1);
00122     flash_construct (flash, size);
00123     class_overload_destroy ((AvrClass *)flash, flash_destroy);
00124 
00125     return flash;
00126 }
00127 
00128 /** \brief Constructor for the flash object. */
00129 
00130 void
00131 flash_construct (Flash *flash, int size)
00132 {
00133     int base = 0;
00134     int i;
00135 
00136     if (flash == NULL)
00137         avr_error ("passed null ptr");
00138 
00139     storage_construct ((Storage *)flash, base, size);
00140 
00141     /* Init the flash to ones. */
00142     for (i = 0; i < size; i++)
00143         storage_writeb ((Storage *)flash, i, 0xff);
00144 }
00145 
00146 /**
00147  * \brief Destructor for the flash class.
00148  *
00149  * Not to be called directly, except by a derived class.
00150  * Called via class_unref.
00151  */
00152 void
00153 flash_destroy (void *flash)
00154 {
00155     if (flash == NULL)
00156         return;
00157 
00158     storage_destroy (flash);
00159 }
00160 
00161 /** \brief Load program data into flash from a file. */
00162 
00163 int
00164 flash_load_from_file (Flash *flash, char *file, int format)
00165 {
00166     switch (format)
00167     {
00168         case FFMT_BIN:
00169             return flash_load_from_bin_file (flash, file);
00170         case FFMT_IHEX:
00171         case FFMT_ELF:
00172         default:
00173             avr_warning ("Unsupported file format\n");
00174     }
00175 
00176     return -1;
00177 }
00178 
00179 static int
00180 flash_load_from_bin_file (Flash *flash, char *file)
00181 {
00182     int fd, res;
00183     int addr = 0;
00184     uint16_t inst;
00185 
00186     fd = open (file, O_RDONLY);
00187     if (fd < 0)
00188         avr_error ("Couldn't open binary flash image file: %s: %s", file,
00189                    strerror (errno));
00190 
00191     while ((res = read (fd, &inst, sizeof (inst))) != 0)
00192     {
00193         if (res == -1)
00194             avr_error ("Error reading binary flash image file: %s: %s", file,
00195                        strerror (errno));
00196 
00197         flash_write (flash, addr, inst);
00198 
00199         addr++;
00200     }
00201 
00202     close (fd);
00203 
00204     return 0;
00205 }
00206 
00207 /** \brief Accessor method to get the size of a flash. */
00208 
00209 int
00210 flash_get_size (Flash *flash)
00211 {
00212     return storage_get_size ((Storage *)flash);
00213 }
00214 
00215 /**
00216  * \brief Dump the contents of the flash to a file descriptor in text format.
00217  *
00218  * \param flash A pointer to a flash object.
00219  * \param f_core An open file descriptor.
00220  */
00221 
00222 void
00223 flash_dump_core (Flash *flash, FILE * f_core)
00224 {
00225     int size = storage_get_size ((Storage *)flash) / 2;
00226     int i;
00227     int dup = 0;
00228     int ndat = 8;
00229     char line[80];
00230     char last_line[80];
00231     char buf[80];
00232 
00233     line[0] = last_line[0] = '\0';
00234 
00235     fprintf (f_core, "Program Flash Memory Dump:\n");
00236     for (i = 0; i < size; i++)
00237     {
00238         if (((i % ndat) == 0) && strlen (line))
00239         {
00240             if (strncmp (line, last_line, 80) == 0)
00241             {
00242                 dup++;
00243             }
00244             else
00245             {
00246                 if (dup > 0)
00247                     fprintf (f_core, "  -- last line repeats --\n");
00248                 fprintf (f_core, "%04x : %s\n", i - ndat, line);
00249                 dup = 0;
00250             }
00251             strncpy (last_line, line, 80);
00252             line[0] = '\0';
00253         }
00254         snprintf (buf, 80, "%04x ", flash_read (flash, i));
00255         strncat (line, buf, 80);
00256     }
00257     if (dup > 0)
00258     {
00259         fprintf (f_core, "  -- last line repeats --\n");
00260         fprintf (f_core, "%04x : %s\n", i - ndat, line);
00261     }
00262 }