Absender: Benjamin Benz
Datum: Fr, 22.06.2007 16:27:10
In-reply-to:
<46756694.9010906@xxxxxx>
References:
<BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx> <45ED3B46.4030400@xxxxxx> <45EF385C.3080609@xxxxxx> <A2ED0A68-A8F1-438A-B1E3-18033ED489E3@xxxxxxxxxxxxxxx> <45F135B9.5030203@xxxxxx> <45F13A91.6090904@xxxxxxxx> <D053B7F5-6BDD-4052-B45F-28FCF0EF45F8@xxxxxxxxxxxxxxx> <45F2B74F.8090706@xxxxxx> <38A4BFD9-CA32-436A-9A1E-B4E6E0652A5D@xxxxxxxxxxxxxxx> <463E0782.1050406@xxxxxx> <0FBD95CF-DA3B-461B-B12B-9FDCD84984D2@xxxxxxxxxxxxxxx> <463F3E0A.7020605@xxxxxx> <8D5B90F4-74FD-45D4-B5B8-DDCAC0B81932@xxxxxxxxxxxxxxx> <464092F7.30605@xxxxxx> <465DB1F9.5030404@xxxxxx> <CF925D4D-FD5A-4581-8480-1C5D35EFEDC9@xxxxxxxxxxxxxxx> <4663027F.4040301@xxxxxx> <F71477F0-03AD-4F06-87E3-AC5DA5BFD1B2@xxxxxxxxxxxxxxx> <466D6849.1020109@xxxxxx> <46756694.9010906@xxxxxx>
Hi, danke erst einmal für den Patch. Leider könnte es noch ein wenig dauern, bis wir ihn getestet haben und er dann einen Weg ins SVN-Repository findet. Die Projekt-Maintainer haben leider alle gerade viel anderes um die Ohren. Bis dahin habe ich den Patch aber einmal auf die neue "Leserpatches-Seite im Wiki (http://www.heise.de/ct/projekte/machmit/ctbot/wiki/Patches) eingetragen. Vielleicht will ihn ja noch wer anders ausprobieren. MfG Benjamin Benz Achim Pankalla wrote: > hallo, > wie angekündigt nun eine neue version von der eeprom-emulation. sie > benötigt kein linker-script mehr und auch keine zusätzlichen tools, nur > die schon mitgelieferten. compiler und linker versionen sollten keine > rolle spielen. > unter w32 geht alles wunderbar, erfahrung unter linux und macos fehlen > noch, da wäre ich noch für infos dankbar. > alles weitere findet ihr in der docu. > der patch enthält die eeprom-emulation und einige anpassungen an den > restlichen kode, weil bisher kein eeprom unter dem pc da war. getestet > habe ich es mit bot_turn und der sensor-kalibrierung. > viel spass damit > achim pankalla > > > ------------------------------------------------------------------------ > > Index: E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_calibrate_sharps.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_calibrate_sharps.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_calibrate_sharps.c (working copy) > @@ -1,314 +1,312 @@ > -/* > - * c't-Bot > - * > - * This program is free software; you can redistribute it > - * and/or modify it under the terms of the GNU General > - * Public License as published by the Free Software > - * Foundation; either version 2 of the License, or (at your > - * option) any later version. > - * This program is distributed in the hope that it will be > - * useful, but WITHOUT ANY WARRANTY; without even the implied > - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR > - * PURPOSE. See the GNU General Public License for more details. > - * You should have received a copy of the GNU General Public > - * License along with this program; if not, write to the Free > - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, > - * MA 02111-1307, USA. > - * > - */ > - > -/*! > - * @file behaviour_calibrate_sharps.c > - * @brief Kalibriert die Distanzsensoren des Bots > - * > - * Einige Zeilen sind auskommentiert. Sie waren dazu gedacht, die Kalibrierung zu automatisieren, > - * das geht aber zurzeit (noch) nicht, weil die Positionsbestimmung fuer kleine Distanzen etwas > - * zu ungenau ist (=> Encoderdatenauswertung checken!) > - * > - * @author Timo Sandmann (mail@xxxxxxxxxxxxxxx) > - * @date 21.04.2007 > - */ > - > -#include "bot-logic/bot-logik.h" > - > -#ifdef BEHAVIOUR_CALIBRATE_SHARPS_AVAILABLE > -#include <math.h> > -#include <stdio.h> > -#include <string.h> > - > -#include "sensor.h" > -#include "display.h" > -#include "gui.h" > -#include "rc5-codes.h" > -#include "log.h" > - > -#ifdef MCU > - #include <avr/eeprom.h> > -#else > - /* derzeit kein EEPROM fuer PC vorhanden, Daten liegen einfach im RAM */ > - #define eeprom_write_byte(ptr, x) *ptr = x > - #define eeprom_write_block(pRam, pEeprom, n) memcpy(pEeprom, pRam, n) // eeprom_write_block ist andersrum! > -#endif > - > -//static Behaviour_t* data = NULL; > -//static float start_x = 0; > -//static float start_head = 0; > -static uint8_t last_toggle = 0; /*!< letztes Toggle-Bit der Distsensoren */ > -static uint8_t step = 0; /*!< Abstand zum naechsten Messpunkt [cm] */ > -static uint8_t count = 0; /*!< aktueller Messpunkt */ > -static int16_t distL = 0; /*!< Rohdaten des linken Sharps */ > -static int16_t distR = 0; /*!< Rohdaten des rechten Sharps */ > -static uint8_t distance = 0; /*!< Entfernung zum Hindernis [cm] */ > -static int8_t measure_count = 0; /*!< Counter fuer Sharp-Messungen */ > -static uint8_t userinput_done = 0; /*!< 1: User war schon fleissig, 0: warten */ > - > -static distSens_t buffer[2][14]; /*!< Puffer des Kalibrierungsergebnisses im RAM */ > -static uint8_t volt_offset = 0; /*!< Offset des Spannungswertes */ > - > -static void (* pNextJob)(void) = NULL; /*!< naechste Teilaufgabe */ > -static void (* pLastJob)(void) = NULL; /*!< letzte Teilaufgabe (vor Stopp) */ > - > -static void goto_next_pos(void); /*!< Stellt den Bot auf die naechste Position bzw. laesst den User das tun */ > - > -static const uint8_t max_steps = 14; /*!< Anzahl der Entfernungen, an denen gemessen wird */ > - > -///*! > -// * @brief Hilfsfunktion fuer wait_for_stop() > -// * @see wait_for_stop() > -// */ > -//static void wait_for_stop_helper(void) { > -// speedWishLeft = BOT_SPEED_STOP; > -// speedWishRight = BOT_SPEED_STOP; > -// > -// /* Nachlauf abwarten */ > -// if (fabs(v_enc_left) < 1.0f && fabs(v_enc_right) < 1.0f) { > -// /* zurueck zum Aufrufer */ > -// pNextJob = pLastJob; // wurde zuvor von wait_for_stop() gerettet > -// } > -//} > -// > -///*! > -// * @brief Haelt den Bot an und wartet den Nachlauf ab > -// * anschliessend geht's mit dem Aufrufer weiter > -// */ > -//static inline void wait_for_stop(void) { > -// pLastJob = pNextJob; > -// pNextJob = wait_for_stop_helper; > -//} > - > -/*! > - * @brief Hilfsfunktion fuer wait_for_userinput() > - * @see wait_for_userinput() > - */ > -static void wait_for_userinput_helper(void) { > - /* Einagbe abwarten */ > - if (userinput_done) { > - userinput_done = 0; > - /* zurueck zum Aufrufer */ > - pNextJob = pLastJob; // wurde zuvor von wait_for_userinput() gerettet > - } > -} > - > -/*! > - * @brief Haelt den Bot an und wartet eine Useraktion ab > - * anschliessend geht's mit dem Aufrufer weiter > - */ > -static inline void wait_for_userinput(void) { > - pLastJob = pNextJob; > - pNextJob = wait_for_userinput_helper; > -} > - > -/*! > - * @brief Berechnet die aktuelle Entfernung eines Sensors zum Ausganspunkt / dem Hindernis > - * @param sensor 0: links, 1: rechts > - */ > -static int16_t calc_distance(uint8_t sensor) { > -// float dHead = (start_head - heading) * 2.0f*M_PI/360.0f; > -// float dX = start_x - x_enc; > -// float s_m = dX / cos(dHead); > -// float dS = tan(dHead) * DISTSENSOR_POS_SW; > -// float result = sensor == 0 ? s_m - dS : s_m + dS; > -// return result; > - return distance * 10; // cm in mm umrechnen > -} > - > -/*! > - * @brief Schreibt Spannung und Entfernung in den RAM-Puffer > - */ > -static void update_data(void) { > - int16_t dist = calc_distance(0); > -// LOG_INFO("%u: links: %d", count, dist); > - buffer[0][count].dist = dist/5; > - buffer[0][count].voltage = distL; > - dist = calc_distance(1); > -// LOG_INFO("%u: rechts: %d", count, dist); > - buffer[1][count].dist = dist/5; > - buffer[1][count].voltage = distR; > - > - if (count != max_steps-1) > - /* neue Entfernung */ > - pNextJob = goto_next_pos; > - else { > - /* fertig */ > - count++; > - pNextJob = NULL; > - } > -} > - > -/*! > - * @brief Misst die Entfernung mit den Sharps > - */ > -static void measure_distance(void) { > - if (last_toggle != sensDistLToggle) { > - /* auf neue Messung pruefen */ > - last_toggle = sensDistLToggle; > - measure_count++; > - } > - /* zweimal vier Messungen abwarten */ > - if (measure_count == 4) { > - distL = (float)sensDistL / 8.0f - volt_offset; > - distR = (float)sensDistR / 8.0f - volt_offset; > - } else if (measure_count == 8) { > - distL += (float)sensDistL / 8.0f - volt_offset; > - distR += (float)sensDistR / 8.0f - volt_offset; > - distL >>= 1; > - distR >>= 1; > - if (distL > 255 || distR > 255) { > - /* Offset zu kleine => erhoehen und neu messen */ > - volt_offset += 5; > -// LOG_INFO("Offset-Update auf %u", volt_offset); > - } else { > - /* Messwerte ok */ > - last_toggle = 1; > - pNextJob = update_data; > - } > - measure_count = 0; > - } > -} > - > -/*! > - * @brief Stellt den Bot auf die naechste Position bzw. laesst den User das tun > - */ > -static void goto_next_pos(void) { > - //bot_drive_distance(data, 0, -50, step); // step cm zurueck > - distance += step; > - count++; > - pNextJob = measure_distance; > - wait_for_userinput(); > -} > - > -/*! > - * @brief Ersetzt die Sensorauswertungsfunktion, damit wir hier die Rohdaten bekommen > - * @param p_sens Zeiger auf den (Ziel-)Sensorwert > - * @param p_toggle Zeiger auf die Toggle-Variable des Zielsensors > - * @param ptr Zeiger auf auf Sensorrohdaten im EEPROM fuer p_sens > - * @param volt Spannungs-Ist-Wert, zu dem die Distanz gesucht wird > - */ > -void sensor_dist_direct(int16_t *const p_sens, uint8_t *const p_toggle, const distSens_t *ptr, int16_t volt) { > - *p_sens = volt; > - *p_toggle = ~*p_toggle; > -} > - > -/*! > - * @brief Das eigentliche Verhalten > - * @param data Zeiger auf den Verhaltensdatensatz des Aufrufers > - * @see bot_calibrate_sharps() > - * Die Funktionalitaet des Verhaltens ist aufgeteilt in: > - * @see goto_next_pos(), @see measure_distance(), @see update_data() > - */ > -void bot_calibrate_sharps_behaviour(Behaviour_t *data) { > - if (pNextJob) pNextJob(); > - else { > - /* fertig! */ > - display_clear(); > - sensor_update_distance = sensor_dist_lookup; // Sensorauswertung wieder aktivieren > - /* Puffer ins EEPROM schreiben */ > - eeprom_write_byte((uint8_t*)&sensDistOffset, volt_offset); > - eeprom_write_block(buffer[0], (uint8_t*)sensDistDataL, max_steps*sizeof(distSens_t)); > - eeprom_write_block(buffer[1], (uint8_t*)sensDistDataR, max_steps*sizeof(distSens_t)); > - return_from_behaviour(data); > - /* Fuer sensor_correction.h formatierte Logausgabe, erleichtert das Speichern der Init-EEPROM- / Sim-Werte */ > - LOG_INFO("SENSDIST_OFFSET %u", volt_offset); > - char tmp_s[14*7+1]; // 14 Zeichen pro Durchlauf + '\0' > - uint8_t i, j, k; > - LOG_INFO("SENSDIST_DATA_LEFT:"); > - for (k=0; k<2; k++) { > - for (j=0; j<2; j++) { > - tmp_s[0] = '\0'; > - for (i=0; i<max_steps/2; i++) { > - sprintf(tmp_s, "%s{%u/2,%u/5},", tmp_s, buffer[k][i+j*max_steps/2].voltage*2, buffer[k][i+j*max_steps/2].dist*5); > - } > - if (j==1) tmp_s[strlen(tmp_s)-1] = '\0'; // kein Komma ausgeben, falls letzter Wert > - LOG_INFO("%s \\", tmp_s); > - } > - if (k==0) LOG_INFO("SENSDIST_DATA_RIGHT:"); > - } > - } > -} > - > -/*! > - * @brief Kalibriert die Distanzsensoren des ct-Bots > - * @param caller Zeiger auf den Verhaltensdatensatz des Aufrufers > - */ > -void bot_calibrate_sharps(Behaviour_t *caller) { > - /* Inits */ > -// data = caller; > -// start_head = heading; > -// start_x = x_enc + 100; > - last_toggle = 1; > - measure_count = -4; > - step = 5; > - distance = 10; > - volt_offset = 0; > - count = 0; > - userinput_done = 0; > - > - sensor_update_distance = sensor_dist_direct; // Sensorauswertung deaktivieren > - > - uint8_t i; > - for (i=0; i<sizeof(screen_functions)/sizeof(screen_functions[0]); i++) { > - if (screen_functions[i] == bot_calibrate_sharps_display) break; > - } > - display_screen = i; > - display_clear(); > - > - /* Als erstes Entfernung / Spannung messen */ > - pNextJob = measure_distance; > - > - wait_for_userinput(); > - > - /* Verhalten an */ > - switch_to_behaviour(caller, bot_calibrate_sharps_behaviour, OVERRIDE); > -} > - > -/*! > - * @brief Displayhandler fuer bot_calibrate_sharps-Verhalten > - */ > -void bot_calibrate_sharps_display(void) { > - /* Displayausgabe */ > - display_cursor(1,1); > - if (count != max_steps && pNextJob == wait_for_userinput_helper) { > - display_printf("Sharp-Kalibr. %2u/%2u", count+1 , max_steps); > - display_cursor(2,1); > - display_printf("Bot bitte auf %2u cm", distance); > - display_cursor(3,1); > - display_printf("stellen und mit"); > - display_cursor(4,1); > - display_printf("\"Mute\" bestaetigen"); > - > - /* Keyhandler */ > - if (RC5_Code == RC5_CODE_MUTE) { > - userinput_done = 1; > - RC5_Code = 0; > - } > - } else if (pNextJob != NULL) { > - display_cursor(2,1); > - display_printf("thinking... "); > - } else if (count == max_steps) { > - display_printf("fertig :-)"); > - } else { > - display_printf("run calibrate_sharps"); > - } > -} > - > -#endif // BEHAVIOUR_CALIBRATE_SHARPS_AVAILABLE > +/* > + * c't-Bot > + * > + * This program is free software; you can redistribute it > + * and/or modify it under the terms of the GNU General > + * Public License as published by the Free Software > + * Foundation; either version 2 of the License, or (at your > + * option) any later version. > + * This program is distributed in the hope that it will be > + * useful, but WITHOUT ANY WARRANTY; without even the implied > + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR > + * PURPOSE. See the GNU General Public License for more details. > + * You should have received a copy of the GNU General Public > + * License along with this program; if not, write to the Free > + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307, USA. > + * > + */ > + > +/*! > + * @file behaviour_calibrate_sharps.c > + * @brief Kalibriert die Distanzsensoren des Bots > + * > + * Einige Zeilen sind auskommentiert. Sie waren dazu gedacht, die Kalibrierung zu automatisieren, > + * das geht aber zurzeit (noch) nicht, weil die Positionsbestimmung fuer kleine Distanzen etwas > + * zu ungenau ist (=> Encoderdatenauswertung checken!) > + * > + * @author Timo Sandmann (mail@xxxxxxxxxxxxxxx) > + * @date 21.04.2007 > + */ > + > +#include "bot-logic/bot-logik.h" > + > +#ifdef BEHAVIOUR_CALIBRATE_SHARPS_AVAILABLE > +#include <math.h> > +#include <stdio.h> > +#include <string.h> > + > +#include "sensor.h" > +#include "display.h" > +#include "gui.h" > +#include "rc5-codes.h" > +#include "log.h" > + > +#ifdef MCU > + #include <avr/eeprom.h> > +#else > + #include "eeprom-emu.h" > +#endif > + > +//static Behaviour_t* data = NULL; > +//static float start_x = 0; > +//static float start_head = 0; > +static uint8_t last_toggle = 0; /*!< letztes Toggle-Bit der Distsensoren */ > +static uint8_t step = 0; /*!< Abstand zum naechsten Messpunkt [cm] */ > +static uint8_t count = 0; /*!< aktueller Messpunkt */ > +static int16_t distL = 0; /*!< Rohdaten des linken Sharps */ > +static int16_t distR = 0; /*!< Rohdaten des rechten Sharps */ > +static uint8_t distance = 0; /*!< Entfernung zum Hindernis [cm] */ > +static int8_t measure_count = 0; /*!< Counter fuer Sharp-Messungen */ > +static uint8_t userinput_done = 0; /*!< 1: User war schon fleissig, 0: warten */ > + > +static distSens_t buffer[2][14]; /*!< Puffer des Kalibrierungsergebnisses im RAM */ > +static uint8_t volt_offset = 0; /*!< Offset des Spannungswertes */ > + > +static void (* pNextJob)(void) = NULL; /*!< naechste Teilaufgabe */ > +static void (* pLastJob)(void) = NULL; /*!< letzte Teilaufgabe (vor Stopp) */ > + > +static void goto_next_pos(void); /*!< Stellt den Bot auf die naechste Position bzw. laesst den User das tun */ > + > +static const uint8_t max_steps = 14; /*!< Anzahl der Entfernungen, an denen gemessen wird */ > + > +///*! > +// * @brief Hilfsfunktion fuer wait_for_stop() > +// * @see wait_for_stop() > +// */ > +//static void wait_for_stop_helper(void) { > +// speedWishLeft = BOT_SPEED_STOP; > +// speedWishRight = BOT_SPEED_STOP; > +// > +// /* Nachlauf abwarten */ > +// if (fabs(v_enc_left) < 1.0f && fabs(v_enc_right) < 1.0f) { > +// /* zurueck zum Aufrufer */ > +// pNextJob = pLastJob; // wurde zuvor von wait_for_stop() gerettet > +// } > +//} > +// > +///*! > +// * @brief Haelt den Bot an und wartet den Nachlauf ab > +// * anschliessend geht's mit dem Aufrufer weiter > +// */ > +//static inline void wait_for_stop(void) { > +// pLastJob = pNextJob; > +// pNextJob = wait_for_stop_helper; > +//} > + > +/*! > + * @brief Hilfsfunktion fuer wait_for_userinput() > + * @see wait_for_userinput() > + */ > +static void wait_for_userinput_helper(void) { > + /* Einagbe abwarten */ > + if (userinput_done) { > + userinput_done = 0; > + /* zurueck zum Aufrufer */ > + pNextJob = pLastJob; // wurde zuvor von wait_for_userinput() gerettet > + } > +} > + > +/*! > + * @brief Haelt den Bot an und wartet eine Useraktion ab > + * anschliessend geht's mit dem Aufrufer weiter > + */ > +static inline void wait_for_userinput(void) { > + pLastJob = pNextJob; > + pNextJob = wait_for_userinput_helper; > +} > + > +/*! > + * @brief Berechnet die aktuelle Entfernung eines Sensors zum Ausganspunkt / dem Hindernis > + * @param sensor 0: links, 1: rechts > + */ > +static int16_t calc_distance(uint8_t sensor) { > +// float dHead = (start_head - heading) * 2.0f*M_PI/360.0f; > +// float dX = start_x - x_enc; > +// float s_m = dX / cos(dHead); > +// float dS = tan(dHead) * DISTSENSOR_POS_SW; > +// float result = sensor == 0 ? s_m - dS : s_m + dS; > +// return result; > + return distance * 10; // cm in mm umrechnen > +} > + > +/*! > + * @brief Schreibt Spannung und Entfernung in den RAM-Puffer > + */ > +static void update_data(void) { > + int16_t dist = calc_distance(0); > +// LOG_INFO("%u: links: %d", count, dist); > + buffer[0][count].dist = dist/5; > + buffer[0][count].voltage = distL; > + dist = calc_distance(1); > +// LOG_INFO("%u: rechts: %d", count, dist); > + buffer[1][count].dist = dist/5; > + buffer[1][count].voltage = distR; > + > + if (count != max_steps-1) > + /* neue Entfernung */ > + pNextJob = goto_next_pos; > + else { > + /* fertig */ > + count++; > + pNextJob = NULL; > + } > +} > + > +/*! > + * @brief Misst die Entfernung mit den Sharps > + */ > +static void measure_distance(void) { > + if (last_toggle != sensDistLToggle) { > + /* auf neue Messung pruefen */ > + last_toggle = sensDistLToggle; > + measure_count++; > + } > + /* zweimal vier Messungen abwarten */ > + if (measure_count == 4) { > + distL = (float)sensDistL / 8.0f - volt_offset; > + distR = (float)sensDistR / 8.0f - volt_offset; > + } else if (measure_count == 8) { > + distL += (float)sensDistL / 8.0f - volt_offset; > + distR += (float)sensDistR / 8.0f - volt_offset; > + distL >>= 1; > + distR >>= 1; > + if (distL > 255 || distR > 255) { > + /* Offset zu kleine => erhoehen und neu messen */ > + volt_offset += 5; > +// LOG_INFO("Offset-Update auf %u", volt_offset); > + } else { > + /* Messwerte ok */ > + last_toggle = 1; > + pNextJob = update_data; > + } > + measure_count = 0; > + } > +} > + > +/*! > + * @brief Stellt den Bot auf die naechste Position bzw. laesst den User das tun > + */ > +static void goto_next_pos(void) { > + //bot_drive_distance(data, 0, -50, step); // step cm zurueck > + distance += step; > + count++; > + pNextJob = measure_distance; > + wait_for_userinput(); > +} > + > +/*! > + * @brief Ersetzt die Sensorauswertungsfunktion, damit wir hier die Rohdaten bekommen > + * @param p_sens Zeiger auf den (Ziel-)Sensorwert > + * @param p_toggle Zeiger auf die Toggle-Variable des Zielsensors > + * @param ptr Zeiger auf auf Sensorrohdaten im EEPROM fuer p_sens > + * @param volt Spannungs-Ist-Wert, zu dem die Distanz gesucht wird > + */ > +void sensor_dist_direct(int16_t *const p_sens, uint8_t *const p_toggle, const distSens_t *ptr, int16_t volt) { > + *p_sens = volt; > + *p_toggle = ~*p_toggle; > +} > + > +/*! > + * @brief Das eigentliche Verhalten > + * @param data Zeiger auf den Verhaltensdatensatz des Aufrufers > + * @see bot_calibrate_sharps() > + * Die Funktionalitaet des Verhaltens ist aufgeteilt in: > + * @see goto_next_pos(), @see measure_distance(), @see update_data() > + */ > +void bot_calibrate_sharps_behaviour(Behaviour_t *data) { > + if (pNextJob) pNextJob(); > + else { > + /* fertig! */ > + display_clear(); > + sensor_update_distance = sensor_dist_lookup; // Sensorauswertung wieder aktivieren > + /* Puffer ins EEPROM schreiben */ > + eeprom_write_byte((uint8_t*)&sensDistOffset, volt_offset); > + eeprom_write_block(buffer[0], (uint8_t*)sensDistDataL, max_steps*sizeof(distSens_t)); > + eeprom_write_block(buffer[1], (uint8_t*)sensDistDataR, max_steps*sizeof(distSens_t)); > + return_from_behaviour(data); > + /* Fuer sensor_correction.h formatierte Logausgabe, erleichtert das Speichern der Init-EEPROM- / Sim-Werte */ > + LOG_INFO("SENSDIST_OFFSET %u", volt_offset); > + char tmp_s[14*7+1]; // 14 Zeichen pro Durchlauf + '\0' > + uint8_t i, j, k; > + LOG_INFO("SENSDIST_DATA_LEFT:"); > + for (k=0; k<2; k++) { > + for (j=0; j<2; j++) { > + tmp_s[0] = '\0'; > + for (i=0; i<max_steps/2; i++) { > + sprintf(tmp_s, "%s{%u/2,%u/5},", tmp_s, buffer[k][i+j*max_steps/2].voltage*2, buffer[k][i+j*max_steps/2].dist*5); > + } > + if (j==1) tmp_s[strlen(tmp_s)-1] = '\0'; // kein Komma ausgeben, falls letzter Wert > + LOG_INFO("%s \\", tmp_s); > + } > + if (k==0) LOG_INFO("SENSDIST_DATA_RIGHT:"); > + } > + } > +} > + > +/*! > + * @brief Kalibriert die Distanzsensoren des ct-Bots > + * @param caller Zeiger auf den Verhaltensdatensatz des Aufrufers > + */ > +void bot_calibrate_sharps(Behaviour_t *caller) { > + /* Inits */ > +// data = caller; > +// start_head = heading; > +// start_x = x_enc + 100; > + last_toggle = 1; > + measure_count = -4; > + step = 5; > + distance = 10; > + volt_offset = 0; > + count = 0; > + userinput_done = 0; > + > + sensor_update_distance = sensor_dist_direct; // Sensorauswertung deaktivieren > + > + uint8_t i; > + for (i=0; i<sizeof(screen_functions)/sizeof(screen_functions[0]); i++) { > + if (screen_functions[i] == bot_calibrate_sharps_display) break; > + } > + display_screen = i; > + display_clear(); > + > + /* Als erstes Entfernung / Spannung messen */ > + pNextJob = measure_distance; > + > + wait_for_userinput(); > + > + /* Verhalten an */ > + switch_to_behaviour(caller, bot_calibrate_sharps_behaviour, OVERRIDE); > +} > + > +/*! > + * @brief Displayhandler fuer bot_calibrate_sharps-Verhalten > + */ > +void bot_calibrate_sharps_display(void) { > + /* Displayausgabe */ > + display_cursor(1,1); > + if (count != max_steps && pNextJob == wait_for_userinput_helper) { > + display_printf("Sharp-Kalibr. %2u/%2u", count+1 , max_steps); > + display_cursor(2,1); > + display_printf("Bot bitte auf %2u cm", distance); > + display_cursor(3,1); > + display_printf("stellen und mit"); > + display_cursor(4,1); > + display_printf("\"Mute\" bestaetigen"); > + > + /* Keyhandler */ > + if (RC5_Code == RC5_CODE_MUTE) { > + userinput_done = 1; > + RC5_Code = 0; > + } > + } else if (pNextJob != NULL) { > + display_cursor(2,1); > + display_printf("thinking... "); > + } else if (count == max_steps) { > + display_printf("fertig :-)"); > + } else { > + display_printf("run calibrate_sharps"); > + } > +} > + > +#endif // BEHAVIOUR_CALIBRATE_SHARPS_AVAILABLE > Index: E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_turn.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_turn.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/bot-logic/behaviour_turn.c (working copy) > @@ -33,16 +33,14 @@ > #include <avr/eeprom.h> > #define ANGLE_CORRECT 1 /*!< Drehfehler-Init */ > #else > - /* derzeit kein EEPROM fuer PC vorhanden, Daten liegen einfach im RAM */ > - #define eeprom_read_byte(x) *x /*!< Pseudo-EEPROM-Funktion fuer PC */ > - #define eeprom_write_byte(ptr, x) *ptr = x /*!< Pseudo-EEPROM-Funktion fuer PC */ > + #include "eeprom-emu.h" > #define ANGLE_CORRECT 0 /*!< Drehfehler-Init */ > #endif // MCU > > /* EEPROM-Variablen immer deklarieren, damit die Adressen sich nicht veraendern je nach #define */ > -uint8 EE_SECTION err15=ANGLE_CORRECT *1; /*!< Fehler bei Drehungen unter 15 Grad */ > -uint8 EE_SECTION err45=ANGLE_CORRECT *2; /*!< Fehler bei Drehungen zwischen 15 und 45 Grad */ > -uint8 EE_SECTION err_big=ANGLE_CORRECT *4; /*!< Fehler bei groesseren Drehungen */ > +uint8 EEPROM err15=ANGLE_CORRECT *1; /*!< Fehler bei Drehungen unter 15 Grad */ > +uint8 EEPROM err45=ANGLE_CORRECT *2; /*!< Fehler bei Drehungen zwischen 15 und 45 Grad */ > +uint8 EEPROM err_big=ANGLE_CORRECT *4; /*!< Fehler bei groesseren Drehungen */ > > > #ifdef BEHAVIOUR_TURN_AVAILABLE > Index: E:/eclipse/ct-bot test/ct-Bot/motor.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/motor.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/motor.c (working copy) > @@ -46,6 +46,9 @@ > #ifdef MCU > #include <avr/eeprom.h> > #endif > +#ifdef PC > + #include "eeprom-emu.h" > +#endif > > int16 speed_l = 0; /*!< Sollgeschwindigkeit linker Motor */ > int16 speed_r = 0; /*!< Sollgeschwindigkeit rechter Motor */ > @@ -86,11 +89,9 @@ > // static volatile uint8 acc_test[2]; /*!< nur Testcase */ > // static volatile uint16 acc_test_dt[2]; /*!< nur Testcase */ > #endif // SPEED_CONTROL_AVAILABLE > -#ifdef MCU > - /* EEPROM-Variable immer deklarieren, damit die Adresse sich nicht veraendert je nach #define */ > - /*! EEPROM-Kopie von pwm_values */ > - uint8_t __attribute__ ((section (".eeprom"),aligned (1))) pwmSlow[4] = {255, 255, 255, 255}; > -#endif > + > +/* EEPROM-Variable immer deklarieren, damit die Adresse sich nicht veraendert je nach #define */ > +uint8_t EEPROM pwmSlow[4] = {255, 255, 255, 255}; /*!< EEPROM-Kopie von pwm_values */ > > direction_t direction; /*!< Drehrichtung der Motoren */ > > Index: E:/eclipse/ct-bot test/ct-Bot/include/eeprom-emu.h > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/include/eeprom-emu.h (revision 0) > +++ E:/eclipse/ct-bot test/ct-Bot/include/eeprom-emu.h (revision 0) > @@ -0,0 +1,67 @@ > +/* > + * c't-Bot > + * > + * This program is free software; you can redistribute it > + * and/or modify it under the terms of the GNU General > + * Public License as published by the Free Software > + * Foundation; either version 2 of the License, or (at your > + * option) any later version. > + * This program is distributed in the hope that it will be > + * useful, but WITHOUT ANY WARRANTY; without even the implied > + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR > + * PURPOSE. See the GNU General Public License for more details. > + * You should have received a copy of the GNU General Public > + * License along with this program; if not, write to the Free > + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307, USA. > + * > + */ > + > +/* @file eeprom-emu.h > + * @brief Low-Level Routinen fuer den Zugriff auf das EEPROM des c't-Bots > + * @author Achim Pankalla (achim.pankalla@xxxxxx) > + * @date 01.03.07 > +*/ > +#ifndef eeprom_emu_H_ > +#define eeprom_emu_H_ > + > +#ifdef PC > +#include <stddef.h> > + > +/*! > + * Flagge die bei Wahr die EEPROM Datei mit den Werten der EEP Datei initialisiert. > + */ > +extern uint8 eeprom_init; > + > +/*! > + * Initialisiert den EEPROM-Manager fuer den Simulierten Bot. Danach steht dem PC-Bot > + * auch ein EEPROM zur Verfuegung. > + */ > +extern void init_eeprom_man(void); > + > +/*! > + * Speichern Daten im EEPROM. > + * @param address Adresse im EEPROM zwischen 0 und 1023. > + * @param data Variable mit den abzulegenen Daten. > + */ > +extern void eeprom_write_byte(uint8 *adr, uint8 value); > +extern void eeprom_write_word(uint16 *adr, uint16 value); > + > +/*! > + * Laden Daten aus dem EEPROM. > + * @param address Adresse im EEPROM zwischen 0 und 1023. > + * @return Wert der Speicheraddresse im EEPROM > + */ > +extern uint8 eeprom_read_byte(uint8 *adr); > +extern uint16 eeprom_read_word(uint16 *adr); > + > +/*! > + * Kopiert ein Block aus den EEPROM oder in das EEPROM > + * @param address Adresse im Speicher. > + * @param address Adresse im EEPROM. > + */ > +extern void eeprom_read_block(void *pointer_ram, const void *pointer_eeprom, size_t size); > +extern void eeprom_write_block(const void *pointer_ram, void *pointer_eeprom, size_t size); > + > +#endif > +#endif > Index: E:/eclipse/ct-bot test/ct-Bot/include/global.h > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/include/global.h (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/include/global.h (working copy) > @@ -60,11 +60,12 @@ > #define On 1 /*!< An */ > #define Off 0 /*!< Aus */ > > + #ifdef PC /*!< Unterscheidung der EEPROM definition */ > + #define EEPROM __attribute__ ((section (".eeprom"),aligned(1))) > + #endif > #ifdef MCU > - #define EE_SECTION __attribute__ ((section (".eeprom"),aligned (1))) /*!< Shortcut fuer EEPROM-Section */ > - #else > - #define EE_SECTION /*!< Shortcut fuer EEPROM-Section */ > - #endif // MCU > + #define EEPROM __attribute__ ((section (".eeprom"))) > + #endif > > #define binary(var,bit) ((var >> bit)&1) /*!< gibt das Bit "bit" von "var" zurueck */ > > Index: E:/eclipse/ct-bot test/ct-Bot/include/gui.h > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/include/gui.h (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/include/gui.h (working copy) > @@ -31,9 +31,7 @@ > > extern int8 max_screens; /*!< Anzahl der zurzeit registrierten Screens */ > extern void (* screen_functions[DISPLAY_SCREENS])(void); /*!< hier liegen die Zeiger auf die Display-Funktionen */ > -#ifdef MCU > - extern uint8 __attribute__ ((section (".eeprom"))) resetsEEPROM; /*!< Reset-Counter-Wert im EEPROM */ > -#endif > +extern uint8 EEPROM resetsEEPROM; /*!< Reset-Counter-Wert im EEPROM */ > > /*! > * @brief Display-Screen Anzeige > Index: E:/eclipse/ct-bot test/ct-Bot/mcu/mini-fat.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/mcu/mini-fat.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/mcu/mini-fat.c (working copy) > @@ -31,7 +31,7 @@ > #ifdef MCU > #include "avr/eeprom.h" > /* EEPROM-Variable immer deklarieren, damit die Adresse sich nicht veraendert je nach #define */ > -uint32 __attribute__ ((section (".eeprom"))) eefat[10] = {0}; /*!< EEPROM-Cache fuer FAT-Eintraege */ > +uint32 EEPROM eefat[10] = {0}; /*!< EEPROM-Cache fuer FAT-Eintraege */ > > #ifdef MMC_AVAILABLE > > Index: E:/eclipse/ct-bot test/ct-Bot/sensor.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/sensor.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/sensor.c (working copy) > @@ -41,9 +41,8 @@ > #ifdef MCU > #include <avr/eeprom.h> > #else > - /* derzeit kein EEPROM fuer PC vorhanden, Daten liegen einfach im RAM */ > - #define eeprom_read_byte(x) *x /*!< Pseudo-EEPROM-Funktion fuer PC */ > -#endif // MCU > + #include "eeprom-emu.h" > +#endif > > // Defines einiger, haeufiger benoetigter Konstanten > #define DEG2RAD (2*M_PI/360) /*!< Umrechnung von Grad nach Bogenmass */ > @@ -59,9 +58,9 @@ > /*! Zeiger auf die Auswertungsfunktion fuer die Distanzsensordaten, const. solange sie nicht kalibriert werden */ > void (* sensor_update_distance)(int16* const p_sens, uint8* const p_toggle, const distSens_t* ptr, int16 volt) = sensor_dist_lookup; > > -distSens_t EE_SECTION sensDistDataL[] = SENSDIST_DATA_LEFT; /*!< kalibrierte Referenzdaten fuer linken IR-Sensor */ > -distSens_t EE_SECTION sensDistDataR[] = SENSDIST_DATA_RIGHT; /*!< kalibrierte Referenzdaten fuer rechten IR-Sensor */ > -uint8_t EE_SECTION sensDistOffset = SENSDIST_OFFSET; /*!< Spannungs-Offset IR-Sensoren */ > +distSens_t EEPROM sensDistDataL[] = SENSDIST_DATA_LEFT; /*!< kalibrierte Referenzdaten fuer linken IR-Sensor */ > +distSens_t EEPROM sensDistDataR[] = SENSDIST_DATA_RIGHT; /*!< kalibrierte Referenzdaten fuer rechten IR-Sensor */ > +uint8_t EEPROM sensDistOffset = SENSDIST_OFFSET; /*!< Spannungs-Offset IR-Sensoren */ > > int16 sensBorderL=0; /*!< Abgrundsensor links */ > int16 sensBorderR=0; /*!< Abgrundsensor rechts */ > @@ -163,7 +162,7 @@ > else volt = (volt_16 >> 3) - offset; > > /* Spannung in LT-Table suchen */ > - uint8 pivot = eeprom_read_byte(&ptr[n-1].voltage); // in welcher Region muessen wir suchen? > + uint8 pivot = eeprom_read_byte((uint8*)&ptr[n-1].voltage); // in welcher Region muessen wir suchen? > if (volt > pivot) { > /* in unterer Haelfte suchen */ > i = 0; > @@ -175,7 +174,7 @@ > } > uint8_t tmp=0; > for (; i<n; i++) { > - tmp = eeprom_read_byte(&ptr->voltage); > + tmp = eeprom_read_byte((uint8*)&ptr->voltage); > if (volt > tmp) // aufsteigend suchen, damit der kritische Fall (kleine Entfernung) schneller gefunden wird > break; // ptr zeigt jetzt auf die naechst kleinere Spannung > ptr++; > @@ -187,7 +186,7 @@ > } > > /* Entfernung berechnen und speichern */ > - uint8 distance = lin_interpolate(eeprom_read_byte(&(ptr-1)->voltage), eeprom_read_byte(&(ptr-1)->dist), tmp, eeprom_read_byte(&ptr->dist), volt); > + uint8 distance = lin_interpolate(eeprom_read_byte((uint8*)&(ptr-1)->voltage), eeprom_read_byte((uint8*)&(ptr-1)->dist), tmp, eeprom_read_byte((uint8*)&ptr->dist), volt); > *p_sens = distance >= SENS_IR_MAX_DIST/5 ? SENS_IR_INFINITE : distance * 5; // Distanz ist gefuenftelt in den Ref.-Daten; > > /* Sensorupdate-Info toggeln */ > Index: E:/eclipse/ct-bot test/ct-Bot/pc/mini-fat.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/pc/mini-fat.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/pc/mini-fat.c (working copy) > @@ -36,6 +36,9 @@ > #include "mmc-vm.h" > #include "mmc-emu.h" > > +/* EEPROM-Variable immer deklarieren, damit die Adresse sich nicht veraendert je nach #define */ > +uint32 EEPROM eefat[10] = {0}; /*!< EEPROM-Cache fuer FAT-Eintraege */ > + > /*! > * Erzeugt eine Datei, die an den ersten Bytes die ID enthaelt. Dann folgen 512 - sizeof(id) nullen > * Danach kommen so viele size kByte Nullen > Index: E:/eclipse/ct-bot test/ct-Bot/pc/eeprom-emu_pc.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/pc/eeprom-emu_pc.c (revision 0) > +++ E:/eclipse/ct-bot test/ct-Bot/pc/eeprom-emu_pc.c (revision 0) > @@ -0,0 +1,455 @@ > +/* > + * c't-Bot > + * > + * This program is free software; you can redistribute it > + * and/or modify it under the terms of the GNU General > + * Public License as published by the Free Software > + * Foundation; either version 2 of the License, or (at your > + * option) any later version. > + * This program is distributed in the hope that it will be > + * useful, but WITHOUT ANY WARRANTY; without even the implied > + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR > + * PURPOSE. See the GNU General Public License for more details. > + * You should have received a copy of the GNU General Public > + * License along with this program; if not, write to the Free > + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307, USA. > + * > + */ > + > +/* @file eeprom-emu_pc.c > + * @brief Low-Level Routinen fuer den Zugriff auf das emulierte EEPROM des Sim-c't-Bots > + * @author Achim Pankalla (achim.pankalla@xxxxxx) > + * @date 07.06.2007 > +*/ > + > +#include "ct-Bot.h" > + > +#ifdef PC > + > +#include <stdio.h> > +#include <string.h> > + > +#include "log.h" > + > +extern uint8 EEPROM resetsEEPROM; /*!< Reset-Counter-Wert im EEPROM als Sectionreferenz*/ > +extern uint8 __attribute__ ((section (".s1eeprom"))) __attribute__((aligned(1))) _eeprom_start1__; > +extern uint8 __attribute__ ((section (".s2eeprom"))) __attribute__((aligned(1))) _eeprom_start2__; > + > +/*! Normiert PC EEPROM Adressen*/ > +#define EEPROM_ADDR(x) ((uint32)x - (uint32)&_eeprom_start2__ - ((uint32)&_eeprom_start2__ - (uint32)&_eeprom_start1__)) > +/*! Defines zum Mitloggen von EEPROM Zugriffen*/ > +#define LOG_LOAD if(addrconv) {LOG_DEBUG("LOAD: %s : %d", ctab[lastctabi].varname, (uint16)dataline[0] + (uint16)dataline[1]*256);}\ > + else {LOG_DEBUG("load-addr=0x%x/%d", address,(uint16)dataline[0] + (uint16)dataline[1]*256);} > +#define LOG_STORE if(addrconv) {LOG_DEBUG("STORE: %s : %d", ctab[lastctabi].varname, data);}\ > + else {LOG_DEBUG("load-addr=0x%x/%d", address, data);} > + > +#ifdef __AVR_ATmega644__ /*! Dieser Prozessor hat 2048Bytes EEPROM*/ > + #define EE_SIZE 2048 > +#else > + #define EE_SIZE 1024 > +#endif > + > +#define EEPROM_FILENAME "./eeprom.bin" /*<! Name und Pfad der EEPROM Datei. Verzeichnis muss existieren. Backslash doppeln!*/ > +#define MAX_VAR 200 /*<! Maximale Anszahl von Variablen*/ > +#define EEMAP_MCU "../debug-mcu-w32/eeprom_mcu.map" /*<! Pfade fuer MAP / EEP Dateien */ > +#define EEMAP_PC "./eeprom_pc.map" > +#define EEP_PC "./ct-bot.eep" > + > +typedef struct addrtab { /*<! Spezieller Datentype fuer Adresskonvertierung*/ > + char varname[20]; > + uint32 simaddr; > + uint32 botaddr; > + uint32 size; > + uint32 access; > + } AddrCTab; > + > +static AddrCTab ctab[MAX_VAR]; /*<! Adresskonvertierungstabelle */ > +static uint16 tsize=0; /*<! Anzahl Eintraege in der Tabelle */ > +static uint8 addrconv = 0; /*<! Adresskonvertierung ein-/ausschalten*/ > +static uint16 lastctabi = 0; /*<! Letzter Zugriffsindex auf ctab*/ > +uint8 eeprom_init = 0; /*<! Flagge fuer EEPROM Initialsierung*/ > + > +/*! > + * Diese Funktion konvertiert die Adressen der EEPROM Variablen des PC so, > + * das sie den Adressen im realen ct-bot entsprechen. Dafuer wird mit der Funktion > + * create_ctab ein Adresstabelle angelegt, diese nutzt diese Funktion. > + * @param address Adresse im EEPROM zwischen 0 und EE_SIZE-1. > + * @return Die neue Adresse für den realen Bot. > + */ > +static uint32 conv_eeaddr(uint32 addr){ > + int8 i; > + int32 adiff; > + > + if(!addrconv) //Keine Adresskonvertierung > + return(addr); > + for(i=0; i<tsize; i++){ > + adiff = addr - ctab[i].simaddr; > + if(adiff < 0) > + return(0xffffffff); > + if(adiff < ctab[i].size){ > + lastctabi = i; //Letzer guelten Index merken > + return(ctab[i].botaddr + adiff); > + } > + } > + return(0xffffffff); > +} > + > +/*! > + * Diese Funktion uberprueft das vorhanden sein der eeprom.bin und initialisiert sie > + * gegebenenfalls mit der Initwerten der eep Datei. > + * Es wird dabei die Adresskovertierung benutzt, wenn die EEPROM Simulation im MCU-Modus > + * ist. > + * ----- > + * 0 = EEPROM Datei OK > + * 1 = Fehler aufgetreten > + * ----- > + * @param initfile EEP Datei des PC Kodes. > + * @return Status der Funktion > + */ > +static uint16 check_eeprom_file(char *initfile){ > + FILE *fpr, *fpw; //Filepointer fuer Dateizugriffe > + uint16 i; //Laufvariable > + char data[2]; //Datenspeicher > + > + /*eeprom file vorhanden*/ > + if(!(fpw = fopen(EEPROM_FILENAME, "r+b"))){ //Testen, ob Datei vorhanden ist. > + int16 i; //Laufvariable > + > + if(!(fpw = fopen(EEPROM_FILENAME, "w+b"))){ //wenn nicht, dann erstellen > + LOG_INFO("->Kann EEPROM-Datei nicht erstellen"); > + return(1); > + } > + for(i = 0; i < EE_SIZE; i++) //Leeres EEPROM erstellen > + fwrite("\377", 1, 1, fpw); > + fclose(fpw); > + LOG_INFO("->Leere EEPROM-Datei erstellt"); > + } > + > + /*Initialsieren der eeprom.bin, wenn gewuenscht*/ > + if(eeprom_init){ > + if(!(fpr = fopen(initfile, "rb"))){ //Datei oeffnen > + LOG_INFO("->EEP nicht gefunden"); > + return(1); > + } > + if(!(fpw = fopen(EEPROM_FILENAME, "rb+"))){ //Datei oeffnen > + LOG_INFO("->EEPROM-Datei kann nicht beschrieben werden"); > + return(1); > + } > + > + /*EEP-Datei in EEPROM-Datei kopieren*/ > + for(i=0; i<EE_SIZE; i++){ > + /*Daten kopieren*/ > + if(!fread(data, 1, 1, fpr)) > + break; > + if(addrconv){ //EEPROM-Datei im MCU-Modus > + uint32 naddr;//Konvertierte Adresse > + > + naddr = conv_eeaddr((uint32)i); > + if(naddr != 0xffffffff){ > + fseek(fpw, (int32)naddr, SEEK_SET); > + } > + else{ > + continue; //Nichts schreiben Adresse nicht belegt > + } > + } > + fwrite(data, 1, 1, fpw); > + } > + fclose(fpr); > + fclose(fpw); > + LOG_INFO("->EEPROM-Datei mit Daten init."); > + } > + return(0); > +} > + > +/*! > + * Diese Funktion erstellt aus den beiden im Post erstellten MAP Dateien eine Tabelle > + * zum umrechnen der PC-Adressen in die des Winavr Compiler. Dadurch kann die EEPROM > + * Datei in einen zum EEPROM des Bot kompatiblen Format gehalten werden. > + * Wichtige Informationen werden über LOG_INFO angezeigt. > + * ---- > + * Ergebniskodes der Funktion > + * 0 = Fehlerfrei > + * 1 = Sim Mapfile nicht vorhanden > + * 2 = Bot Mapfile nicht vorhanden > + * 3 = Unterschiedlicher Variablenbestand > + * 4 = Zuviele Variablen > + * 5 = EEPROM voll > + * 6 = Unterschiedliche Variablenanzahl > + * > + * @param simfile MAP mit den Adressen der EEPROM-Variablen in der PC EXE. > + * @param botfile MAP mit den Adressen der EEPROM-Variablen im MCU EXE. > + * @return Statuskodes. > + */ > +static uint16 create_ctab(char *simfile, char *botfile){ > + FILE *fps, *fpb; > + char sline[250], bline[250]; //Textzeilen aus Dateien > + char d[30], d1[30], d2[30], vname_s[30], vname_b[20]; //Dummy und Variablennamen > + int32 addr_s, addr_b; //Adressen der Variablen > + char saddr[30], ssize[30]; //Stringvarianten fuer die Bot Daten > + uint32 size; //Variablengroesse > + int16 i, ii; //Laufvariablen > + uint16 vc = 0; //Variablenzaehler > + > + /*Dateien oeffnen*/ > + if(!(fps=fopen(simfile,"r"))){ > + LOG_INFO("->EEPROM-MAP fuer PC fehlt"); > + return(1); > + } > + if(!(fpb=fopen(botfile,"r"))){ > + LOG_INFO("->EEPROM-MAP fuer MCU fehlt"); > + return(2); > + } > + > + /*Anzahl Variablen vergleichen*/ > + while(fgets(sline, 249, fps)) vc++; > + while(fgets(sline, 249, fpb)) vc--; > + if(vc){ > + fclose(fps); > + fclose(fpb); > + LOG_INFO("->Unterschiedliche Variablenanzahl"); > + return(6); > + } > + rewind(fps); > + rewind(fpb); > + > + /*Tabelle erstellen*/ > + while(fgets(sline, 249, fps)){ > + rewind(fpb); > + sscanf(&sline[47], "%x %s", &addr_s, vname_s); > + while(fgets(bline, 249, fpb)){ > + /*Variablennamen suchen*/ > + sscanf(&bline[4], "%s %s %s %s %s %s", d1, d, d, d, d2, vname_b); > + sprintf(saddr, "0x%s", d1); > + sscanf(saddr, "%x", &addr_b); > + sprintf(ssize, "0x%s", &d2[4]); > + sscanf(ssize, "%x", &size); > + if(!strcmp(&vname_s[1], vname_b)){ > + /*Daten kopieren*/ > + strcpy(ctab[tsize].varname, vname_b); > + ctab[tsize].simaddr = addr_s; > + ctab[tsize].botaddr = addr_b; > + ctab[tsize].size = size; > + ctab[tsize++].access = 0; > + > + /*Fehlerabbrueche*/ > + if(tsize == MAX_VAR){ > + LOG_INFO("->Mehr als %n Variablen",MAX_VAR); > + return(4); > + } > + if(addr_s > EE_SIZE){ > + LOG_INFO("->EEPROM voll"); > + return(5); > + } > + > + /*Erfolg markieren*/ > + addr_b = -1; > + break; > + } > + } > + if(addr_b > -1){ //Keine passende Variable gefunden > + LOG_INFO("->Unterschiedliche Variablen"); > + return(3); > + } > + } > + > + /*Dateien schliessen*/ > + fclose(fps); > + fclose(fpb); > + > + /*Tabelle nach Sim-Adressen sortieren*/ > + for(ii=tsize-1; ii > 0; ii--){ > + for(i=0; i < ii; i++){ > + if(ctab[i].simaddr > ctab[i+1].simaddr){ > + long simaddr, botaddr, size; > + char vname[30]; > + > + /*Daten umkopieren*/ > + strcpy(vname, ctab[i+1].varname); > + simaddr = ctab[i+1].simaddr; > + botaddr = ctab[i+1].botaddr; > + size = ctab[i+1].size; > + > + strcpy(ctab[i+1].varname, ctab[i].varname); > + ctab[i+1].simaddr = ctab[i].simaddr; > + ctab[i+1].botaddr = ctab[i].botaddr; > + ctab[i+1].size = ctab[i].size; > + > + strcpy(ctab[i].varname, vname); > + ctab[i].simaddr = simaddr; > + ctab[i].botaddr = botaddr; > + ctab[i].size = size; > + } > + } > + } > + return(0); > +} > + > +/*! > + * Diese Funktion initialisiert die eeprom-emulation. Sie sorgt für die Erstellung der > + * eeprom.bin, falls nicht vorhanden und erstellt ueber eine Hilfsfunktion eine Adress- > + * konvertierungstabelle fuer die EEPROM-Adressen, wenn die benoetigten Daten vorliegen. > + * Statusinformationen werden ueber DEBUG_INFO angezeigt. > + */ > +void init_eeprom_man(void){ > + uint16 status; //Status von create_ctab > + uint16 sflag; //Sectionstatus > + > + LOG_INFO("EEPROM-Manager"); > + > + /*Adresskonvertierungstabelle anlegen*/ > + if((status=create_ctab(EEMAP_PC, EEMAP_MCU))){ > + LOG_INFO("->EEPROM im PC-Modus"); > + } > + else { > + LOG_INFO("->EEPROM im MCU-Modus"); > + addrconv = 1; > + } > + > + /*Sections ueberpruefen*/ > + if((&_eeprom_start2__ - &_eeprom_start1__) > 0 && (&resetsEEPROM - &_eeprom_start2__) >0){ > + LOG_INFO("->Sections liegen wohl korrekt"); > + LOG_INFO("->Section Abstand 0x%X", (&_eeprom_start2__ - &_eeprom_start1__)); > + sflag = 0; > + } > + else{ > + LOG_INFO("->Sections liegen falsch"); > + sflag = 1; > + } > + > + /*eeprom.bin checken*/ > + if(sflag || check_eeprom_file(EEP_PC)){ > + LOG_INFO("EEPROM-Emulation fehlerhaft"); > + } > + else{ > + LOG_INFO("->EEPROM Groesse %d Bytes", EE_SIZE); > + LOG_INFO("EEPROM-Emulation einsatzbereit"); > + } > + return; > +} > + > +/*! > + * Traegt die uebergebenen Daten in das simulierte EEPROM ein. Dieses simulierte EEPROM > + * besteht aus einer Datei. > + * Es koennen Bytes (uint8 size = 1) und Integer (uint16 size = 2) uebergeben werden. > + * @param address Adresse im EEPROM zwischen 0 und EE_SIZE-1. > + * @param data Daten die abgelegt werden sollen. > + * @param size Groesse der Daten in Byte. > + */ > +static void store_parameter(uint16 address, uint16 data, uint8 size) { > + FILE *fpw; //Dateizeiger > + uint8 dataline[2]; //Speicher fuer Datenausgabe > + > +// LOG_STORE > + if(address > (size == 1 ? EE_SIZE-1 : EE_SIZE-2)) //Adresse checken > + return; > + > + if(!(fpw = fopen(EEPROM_FILENAME, "r+b"))){ //Testen, ob Datei vorhanden ist. > + return; > + } > + > + //Daten eintragen > + fseek(fpw, address, SEEK_SET); //Schreibzeiger setzen > + dataline[0] = data%256; > + dataline[1] = data/256; > + fwrite(dataline, 1, size, fpw); //Daten schreiben > + > + fclose(fpw); > + return; > +} > + > +/*! > + * Liest die gewuenschten Daten aus eine simulierten EEPROM. Dieses simulierte EEPROM > + * besteht aus der Datei eeprom.bin. > + * @param address Adresse im EEPROM zwischen 0 und EE_SIZE-1. > + * @param size Groesse der Daten in Byte. > + * @return Aus dem EEPROM gelesener Wert. > + */ > +static uint16 load_parameter(uint16 address, uint8 size) { > + FILE *fpr; //Dateizeiger > + uint8 dataline[2] = {0,0}; //String fuer Datenausgabe > + > + if(address > (size == 1 ? EE_SIZE-1 : EE_SIZE-2)) //Adresse checken > + return((size == 1 ? 0xff : 0xffff)); > + > + if(!(fpr = fopen(EEPROM_FILENAME, "rb"))){ //Datei oeffnen > + return((size == 1 ? 0xff : 0xffff)); > + } > + > + //Daten eintragen > + fseek(fpr, address, SEEK_SET); //Lesezeiger setzen > + fread(dataline, 1, size, fpr); //Daten lesen); > + fclose(fpr); > +// LOG_LOAD > + return((uint16)dataline[0] + (uint16)dataline[1]*256); > +} > + > +/*! > + * Liest ein Byte aus den simulierten EEPROM > + * @param addr Adresse im EEPROM > + * @return Aus dem EEPROM gelesener Wert. > + */ > +uint8 eeprom_read_byte(uint8 *addr) { > + return((uint8)load_parameter((uint16)conv_eeaddr(EEPROM_ADDR(addr)), 1)); > +} > + > +/*! > + * Liest ein Word aus den simulierten EEPROM > + * @param addr Adresse im EEPROM > + * @return Aus dem EEPROM gelesener Wert. > + */ > +uint16 eeprom_read_word(uint16 *addr) { > + return(load_parameter((uint16)conv_eeaddr(EEPROM_ADDR(addr)), 2)); > +} > + > +/*! > + * Schreibt ein Byte in das simulierte EEPROM > + * @param addr Adresse im EEPROM > + * @param Zu schreibender Wert. > + */ > +void eeprom_write_byte(uint8 *addr, uint8 value) { > + store_parameter((uint16)conv_eeaddr(EEPROM_ADDR(addr)), (uint16)value, 1); > +} > + > +/*! > + * Schreibt ein Word in das simulierte EEPROM > + * @param addr Adresse im EEPROM > + * @param Zu schreibender Wert. > + */ > +void eeprom_write_word(uint16 *addr, uint16 value) { > + store_parameter((uint16)conv_eeaddr(EEPROM_ADDR(addr)), value, 2); > +} > + > +/*! > + * Liest ein Speicherblock aus dem simulierte EEPROM > + * @param pointer_ram Adresse im Hauptspeicher > + * @param pointer_eeprom Adresse im EEPROM > + * @param Groesze des Block. > + */ > +void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, size_t size) { > + uint32 i; > + uint8 *ram; > + > + ram = (uint8 *)pointer_ram; > + for(i=0; i< size; i++){ > + ram[i]=(uint16)load_parameter((uint16)conv_eeaddr(EEPROM_ADDR(pointer_eeprom)) + i, 1); > + } > +} > + > +/*! > + * Schreibt ein Speicherblock in das simulierte EEPROM > + * @param pointer_ram Adresse im Hauptspeicher > + * @param pointer_eeprom Adresse im EEPROM > + * @param Groesze des Block. > + */ > +void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom, size_t size) { > + uint32 i; > + uint8 *ram; > + > + ram = (uint8 *)pointer_ram; > + for(i=0; i< size; i++){ > + store_parameter((uint16)conv_eeaddr(EEPROM_ADDR(pointer_eeprom)) + i, (uint16)ram[i] ,1); > + } > +} > + > +#endif > Index: E:/eclipse/ct-bot test/ct-Bot/Documentation/eeprom-simulation.html > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/Documentation/eeprom-simulation.html (revision 0) > +++ E:/eclipse/ct-bot test/ct-Bot/Documentation/eeprom-simulation.html (revision 0) > @@ -0,0 +1,245 @@ > +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> > +<HTML> > +<HEAD> > + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> > + <TITLE></TITLE> > + <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.2 (Win32)"> > + <META NAME="AUTHOR" CONTENT="Achim Pankalla"> > + <META NAME="CREATED" CONTENT="20060528;19455600"> > + <META NAME="CHANGEDBY" CONTENT="Achim Pankalla"> > + <META NAME="CHANGED" CONTENT="20070617;18142584"> > + <STYLE TYPE="text/css"> > + <!-- > + @page { size: 21cm 29.7cm; margin: 2cm } > + P { margin-bottom: 0.21cm } > + --> > + </STYLE> > +</HEAD> > +<BODY LANG="de-DE" DIR="LTR"> > +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><B>EEPROM Simulation für > +PC</B></P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Author: </B></FONT> > +</P> > +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>Achim Pankalla > +(achim.pankalla@xxxxxx)</FONT></P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><B>Beschreibung:</B></P> > +<P ALIGN=LEFT STYLE="margin-bottom: 0cm; font-style: normal">Die > +EEPROM Simulation für den PC stellt das EEPROM des <I>Atmel > +MEGA32(664) Prozessor</I> auch dem Simulierten ct-bot zur Verfügung. > +Der Zugriff auf dieses EEPROM erfolgt über gleichnamige > +Funktionen, wie sie auch der avr-gcc besitzt und auch die > +Variablendefinition erfolgt über die gleichen Konstrukte. Eine > +Unterscheidung über #ifdef's ist also nicht notwendig.<BR>Durch > +diese EEPROM-Simulation, ist der Simulator dem realen Bot ein schritt > +näher gekommen und Programme mit EEPROM-Zugriffe können mit > +der Simulation getestet werden. Mehr noch, sie können auch das > +Simulierte EEPROM auf den ct-bot übertragen oder das EEPROM vom > +ct-bot abziehen und für die Simulation nutzen.</P> > +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Implementierung:</B></P> > +<P STYLE="margin-bottom: 0cm">Alle Funktionen und Einstellungen der > +EEPROM Simulation findet Sie in den Dateien <I>pc/eeprom-emu_pc.c</I> > +und <I>include/eeprom-emu.h</I>. Das EEPROM selbst wird durch eine > +Binäre Datei (genau 1K bzw. 2K gross) repräsentiert (und > +kann so mit einen HexEditor bearbeitet werden), deren Pfad in der > +C-Datei festgelegt wird. Standard Pfad ist das Heimatverzeichnis des > +Ct-Sim. Natürlich können Sie das jederzeit ändern, > +dies geht über die Konstante <FONT COLOR="#000000"><FONT FACE="Courier New, monospace"><FONT SIZE=2>EEPROM_FILENAME.</FONT></FONT></FONT> > +<FONT FACE="Times New Roman, serif">Der Name </FONT><FONT FACE="Times New Roman, serif"><I>eeprom.bin</I></FONT> > +<FONT FACE="Times New Roman, serif">sollte dabei belassen werden.</FONT><BR>Die > +Datei wird automatisch neu angelegt, wenn sie noch nicht existiert. > +Dann besteht der Inhalt nur aus 0xFF, wie es auch beim > +unintialisierten EEPROM des Atmel der Fall ist.<BR>Damit die > +EEPROM-Funktionen des PC korrekt auf die Datei zugreifen können > +und nur ein Adressraum von 0 bis 1023(2047) entsteht, bedarf es bei > +der PC Implementierung (mit PC ist allgemein der Kode für die > +Simulation gemeint, mag das OS nun Win, Linux oder MacOS heißen) > +eines Tricks. Die Emulation muss wissen welche Speicheradresse die > +erste Variable hat.<BR>Dafür gibt es die beiden Variablen > +<I>_eeprom_start1__</I> und <I>_eeprom_start2_</I><SPAN STYLE="font-style: normal">_ > +in </SPAN><I>ctbot.c</I><SPAN STYLE="font-style: normal">. Diese > +stehen dort, damit sie auf jeden Fall vor der ersten EEPROM Variable > +definiert werden und damit ihre Sections (.</SPAN><I>s1eeprom</I> <SPAN STYLE="font-style: normal">+ > +.</SPAN><I>s2eeprom</I><SPAN STYLE="font-style: normal">) auf jeden > +Fall vor der Section .</SPAN><I>eeprom</I> <SPAN STYLE="font-style: normal">liegen. > +Sie dürfen also auf keine Fall eine EEPROM Variable vor diesen > +definieren. Deshalb sind auch solche Variablen in </SPAN><I><B>command</B></I><SPAN STYLE="font-style: normal"><B>.</B></SPAN><I><B>c</B></I> > +im Moment <SPAN STYLE="font-style: normal">tabu (außer die > +Abarbeitung im Makefile erfolgt nach </SPAN><I>ctbot.c</I><SPAN STYLE="font-style: normal">, > +was im Moment nicht der Fall ist). Sollten einmal eine neue Datei > +hinzugefügt werden, die durch „managed make“ vor > +</SPAN><I>ctbot.c</I> <SPAN STYLE="font-style: normal">landen und > +eeprom Variablen enthalten, muss man wahrscheinlich dieses > +Startvariablen in die neue Datei verlegen, vor deren EEPROM > +Variablen.</SPAN></P> > +<P STYLE="margin-bottom: 0cm; font-style: normal">Durch diesen Trick > +kann die Speicheradresse der ersten EEPROM Variable auch ohne > +Linkerscript ermittelt werden und auch verschiedene > +Section-Alignments (im Moment bei MinGW und Linux unterschiedlich) > +der Linker haben keine Auswirkung.</P> > +<P STYLE="margin-bottom: 0cm; font-style: normal">Auch beim > +Generieren eines neuen ct-bot.exe wird eine EEP mit den > +Initialisierungen der EEPROM-Variablen im post-build angelegt. Diese > +Datei kann die EEPROM-Simulation auch als Initialisierung für > +ihr MCU-Kompatibles EEPROM benutzen oder diese Datei kann direkt als > +EEPROM-Datei benutzt werden, wenn die Simulation im PC-Modus ist, > +gleiches gilt natürlich umgekahr auch für die EEP Datei des > +MCU Exe.</P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><B>Nutzung der EEPROM Simulation</B>.</P> > +<P STYLE="margin-bottom: 0cm">Die EEPROM-Simulation unterscheidet > +sich nur in ein paar Details von den realen Funktionen unter WinAVR > +und ct-bot. Natürlich hat der PC kein EEPROM, dies wird durch > +eine Datei im Binary Format emuliert. Der Dateinamen und der Pfad > +wird über die Konstante EEPROM_FILENAME in <I>eeprom</I>-<I>emu</I>_<I>pc</I>.<I>c</I> > +festgelegt. Ein weiterer Unterschied ist, das beim WinAVR über > +ein DEFINE der Prozessortyp festgelegt wird, entweder ATMega32 oder > +ATMega664. Dieses DEFINE wird normalerweise beim PC Compiler nicht > +übergeben. Standartmäßig wird von einem ATMega32 mit > +1024 Byte EEPROM ausgegangen, der Simulator kennt aber die Konstante > +für den ATMega664 und erhöht den EEPROM Speicher auf 2048 > +Bytes. Sollte schon eine 1K Datei fürs EEPROM bestehen, so muss > +diese gelöscht werden, damit die Größere angelegt > +wird. Wird direkt die erstellte <I>ct-bot.eep</I> Datei genutzt, ist > +dies natürlich nicht notwendig.</P> > +<P STYLE="margin-bottom: 0cm">Alle wichtigen Informationen werden > +beim Start des ct-bot.exe im Log-Fenster angezeigt, dort sieht man > +auch alle eventuellen Fehler und ob die Simulation ordnungsgemäß > +arbeiten kann. Es erfolgt kein beenden des <I>ct-bot.exe</I> bei > +Problemen, ein Funktion des EEPROM ist dann aber nicht gegeben.</P> > +<P STYLE="margin-bottom: 0cm">Generell unterscheidet die Simulation > +zwei Modi:</P> > +<OL> > + <LI><P STYLE="margin-bottom: 0cm">PC-Modus</P> > + <P STYLE="margin-bottom: 0cm">In diesen Modus entspricht die > + eeprom.bin nicht dem EEPROM des realen ct-bot und darf deshalb auch > + nicht auf ihn aufgespielt werden. Dieser Modus wird ohne jedes zu > + tun erreicht. Er benötigt keine weiteren Einträge in Post > + build. > + </P> > + <P STYLE="margin-bottom: 0cm">Wenn eine ct-bot.eep erstellt im > + Binary Format, so kann diese direkt benutzt werden.</P> > + <LI><P STYLE="margin-bottom: 0cm">MCU-Modus</P> > + <P STYLE="margin-bottom: 0cm">Ist dieser Modus erreicht, kann man > + als EEPROM-Datei einen EEPROM Abzug vom ct-bot verwenden. > + Voraussetzung ist natürlich, das der Bot auch mit zuletzt > + erstellten Programm bespielt ist. Natülich kann man auch die > + EEPROM-Datei auf den Bot nutzen.<BR>Der MCU-Modus kann nur erreicht > + werden, wenn sowohl beim avr-ggc als auch unter der PC Oberfläche > + map-Datei erstellt werden, dafür sind im Post Build die > + folgenden Befehle einzutragen:</P> > + <P STYLE="margin-bottom: 0cm">Debug-W32: <B>objcopy -j .eeprom > + --change-section-lma .eeprom=0 -O binary ct-Bot.exe > + ct-Bot.eep;objdump -t ct-bot.exe | grep "(sec 5)" | grep > + "(nx 0)" > eeprom_pc.map</B></P> > + <P STYLE="margin-bottom: 0cm">Debug-MCU-W32: <B>avr-objcopy -O ihex > + -R .eeprom ct-Bot.elf ct-Bot.hex; avr-objcopy -j .eeprom > + --set-section-flags=.eeprom="alloc,load" > + --change-section-lma .eeprom=0 -O binary ct-Bot.elf > + ct-Bot.eep;avr-objdump -t ct-bot.elf | grep "O \.eeprom" > > + eeprom_mcu.map</B></P> > + <P STYLE="margin-bottom: 0cm"><B>(Achtung! Zwischen sec und 5 zwei > + Spaces)</B></P> > + <P STYLE="margin-bottom: 0cm">Diese Befehlssequence des PC gelten > + natürlich auch für MacOS oder Linux. > + </P> > + <P STYLE="margin-bottom: 0cm">Anhand dieser MAP-Datei können > + die Routinen des EEPROM-Manager über eine > + Konvertierungsfunktion die eeprom-Datei bot-kompatible halten. > + Natürlich kann man trotzdem dieses EEPROM mit der EEP-Datei > + initialisieren.</P> > +</OL> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm">Möchte man die vorhandene oder > +noch nicht vorhandene EEPROM-Datei mit den Daten aus der EEP-Datei > +initialisieren, so muss man die ct-bot.exe mit dem Parameter <I>-i > +</I>starten, dabein spielt es keine Rolle in welchen Modus die > +Emulation arbeitet. Der Pfad der EEP-Datei wird in der Konstante > +<FONT COLOR="#000000"><FONT FACE="Courier New, monospace"><FONT SIZE=2>EEP_PC > +</FONT></FONT></FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>eingetragen.</FONT></FONT></FONT></P> > +<P STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Für > +das Debuggen von Zugriffen auf das EEPROM, stehen unter anderen die > +DEFINES LOG_STORE und LOG_LOAD zur Verfügung, die im MCU Modus > +sogar den Variablennamen anzeigen. Andere Variationen sind auch noch > +denkbar.</FONT></FONT></FONT></P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Grenzen der > +Implementierung</B></P> > +<P STYLE="margin-bottom: 0cm; font-style: normal; font-weight: medium"> > +Im Moment erstellen gleiche Compilerversionen (zu Überprüfen > +mit –version) auch (fast) gleiche EEPROM-Sections. Damit es > +auch mit verschiedenen Compiler Version geht (und ich mich auch nicht > +auf die gleichen Versionen verlasssen will) habe ich die > +Adresskonvertierung eingeführt, damit dies kein Problem mehr > +ist.</P> > +<P STYLE="margin-bottom: 0cm; font-style: normal; font-weight: medium"> > +Es gibt aber keine Garantien dafür, das zukünftige Compiler > +Versionen nicht die Reihenfolge der Variablen im Code ändern. > +Ein Einfügen neuer EEPROM Variablen kann auch zu Verschiebungen > +der Adressen führen. Nach solchen Änderungen ist man nur > +auf der sicheren Seite, wenn das EEPROM initialisiert wird (sprich > +Sie Ihre alte eeprom.bin bzw. auf den Atmel das EEPROM löschen). > +Einmal erstellte Werte sind dann natürlich futsch. Wenn man den > +Einfluss von Kodeergänzungen kontrollieren will, kann man dies > +vor und nach der Änderungen mit objdump machen (oder falls Sie > +die Befehle für die MAP-Dateien im Post-Build benutzen, schauen > +Sie in die MAP-Dateien), mit den richtigen Parametern kann man sich > +die Adressverteilung anzeigen lassen. Sie können dann sehen, ob > +die neuen Variablen nun hinten angehängt wurden (dann brauch das > +eeprom nicht gelöscht werden) oder sie dazwischen gelandet sind > +(dann sind die alten Daten unbrauchbar), dafür sollten sie aber > +vorher in eclipse Projekt->clean aufrufen.<BR>Die Implementierung > +des EEPROM auf den PC kontrolliert nicht, ob nicht 1K bzw. 2K an > +Daten überschritten wird. Der EEPROM-Manager meckert dann aber > +im LOG. (Der avg-gcc wird dann aber auch meckern). > +</P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><B>Funktionen</B></P> > +<P STYLE="margin-bottom: 0cm"><B>Nur in eeprom-emu_pc.c sichtbare > +Funktionen</B></P> > +<P STYLE="margin-bottom: 0cm">store_parameter() - Speichern von > +Informationen im simulierten EEPROM</P> > +<P STYLE="margin-bottom: 0cm">load_parameter() - Laden von > +Informationen aus dem simulierten EEPROM</P> > +<P STYLE="margin-bottom: 0cm">init_eeprom() - Erstellt > +Adresskonvertierungstabelle</P> > +<P STYLE="margin-bottom: 0cm">conv_eeaddr() - Wandelt PC Adresse in > +ct-bot Adresse</P> > +<P STYLE="margin-bottom: 0cm">create_ctab() - Erstellt > +Adresskonvertierungstabelle</P> > +<P STYLE="margin-bottom: 0cm">check_eeprom_file() - Erstellt leeres > +EEPROM, wenn nötig und initialisiert es, wenn gewünscht</P> > +<P STYLE="margin-bottom: 0cm">init_eeprom_man() - Initialisiert die > +EEPROM Emulation</P> > +<P STYLE="margin-bottom: 0cm"><B>Zugriffsfunktionen für den PC > +(Identisch zu denen von WinAVR)</B></P> > +<P STYLE="margin-bottom: 0cm">eeprom_read_byte()</P> > +<P STYLE="margin-bottom: 0cm">eeprom_write_byte()</P> > +<P STYLE="margin-bottom: 0cm">eeprom_read_word()</P> > +<P STYLE="margin-bottom: 0cm">eeprom_write_word()</P> > +<P STYLE="margin-bottom: 0cm">eeprom_write_block()</P> > +<P STYLE="margin-bottom: 0cm">eeprom_read_block()</P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Dateien:</B></FONT></P> > +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>eeprom-emu.h Include > +Dateinamen mit Funktionsparameter</FONT></P> > +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>eeprom-emu_pc.c Funktionen > +fuer den ct-Sim</FONT></P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +<P STYLE="margin-bottom: 0cm"><BR> > +</P> > +</BODY> > +</HTML> > \ No newline at end of file > Index: E:/eclipse/ct-bot test/ct-Bot/ct-Bot.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/ct-Bot.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/ct-Bot.c (working copy) > @@ -39,6 +39,7 @@ > #include "bot-2-sim.h" > #include "tcp.h" > #include "tcp-server.h" > + #include "eeprom-emu.h" > #include <pthread.h> > #include <unistd.h> > #include <stdlib.h> > @@ -83,6 +84,12 @@ > #include "gui.h" > #include "ui/available_screens.h" > > +//Moeglichst frueh section erzwingen, damit sie VOR .eeprom liegt!!! > +#ifdef PC > + uint8 __attribute__ ((section (".s1eeprom"))) _eeprom_start1__ = 0; > + uint8 __attribute__ ((section (".s2eeprom"))) _eeprom_start2__ = 0; > +#endif > + > /*! > * Der Mikrocontroller und der PC-Simulator brauchen ein paar Einstellungen, > * bevor wir loslegen koennen. > @@ -93,7 +100,7 @@ > PORTB=0; DDRB=0; > PORTC=0; DDRC=0; > PORTD=0; DDRD=0; > - > + > wdt_disable(); // Watchdog aus! > timer_2_init(); > > @@ -133,6 +140,7 @@ > > #ifdef PC > bot_2_sim_init(); > + init_eeprom_man(); > #endif > > #ifdef DISPLAY_AVAILABLE > @@ -237,6 +245,7 @@ > puts("\t-d \tLoescht eine Mini-Fat-Datei fuer den Sim (emulierte MMC)."); > puts("\t ID \tDie ID aus ASCII-Zeichen"); > puts("\t-l \tKonvertiert eine SpeedLog-Datei in eine txt-Datei"); > + puts("\t-i \t Initialisiert das EEPROM mit den Daten der EEP-Datei"); > puts("\t-h\tZeigt diese Hilfe an"); > exit(1); > } > @@ -271,7 +280,6 @@ > int slog =0; > char *from = NULL; /*!< Speichert den per -M uebergebenen Quellnamen zwischen */ > > - > /* Die Kommandozeilenargumente komplett verarbeiten */ > while ((ch = getopt(argc, argv, "hsTt:M:c:l:e:d:")) != -1) { > switch (ch) { > @@ -348,6 +356,9 @@ > slog=1; > } > break; > + case 'i': > + eeprom_init = 1; > + break; > case 'h': > default: > /* -h oder falscher Parameter, Usage anzeigen */ > Index: E:/eclipse/ct-bot test/ct-Bot/ui/misc.c > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/ui/misc.c (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/ui/misc.c (working copy) > @@ -32,11 +32,11 @@ > #include "timer.h" > #ifdef MCU > #include <avr/eeprom.h> > +#else > + #include "eeprom-emu.h" > #endif > > -#ifdef MCU > - uint8 __attribute__ ((section (".eeprom"))) resetsEEPROM = 0; /*!< Reset-Counter-Wert im EEPROM */ > -#endif > +uint8 EEPROM resetsEEPROM = 0; /*!< Reset-Counter-Wert im EEPROM */ > > #ifdef DISPLAY_AVAILABLE > #ifdef MISC_DISPLAY_AVAILABLE > Index: E:/eclipse/ct-bot test/ct-Bot/ct-Bot.h > =================================================================== > --- E:/eclipse/ct-bot test/ct-Bot/ct-Bot.h (revision 1162) > +++ E:/eclipse/ct-bot test/ct-Bot/ct-Bot.h (working copy) > @@ -31,7 +31,7 @@ > /************************************************************ > * Module switches, to make code smaller if features are not needed > ************************************************************/ > -//#define LOG_CTSIM_AVAILABLE /*!< Logging zum ct-Sim (PC und MCU) */ > +#define LOG_CTSIM_AVAILABLE /*!< Logging zum ct-Sim (PC und MCU) */ > //#define LOG_DISPLAY_AVAILABLE /*!< Logging ueber das LCD-Display (PC und MCU) */ > //#define LOG_UART_AVAILABLE /*!< Logging ueber UART (NUR fuer MCU) */ > //#define LOG_STDOUT_AVAILABLE /*!< Logging auf die Konsole (NUR fuer PC) */ > > > ------------------------------------------------------------------------ > > _______________________________________________ > ct-bot-entwickler Mailingliste > ct-bot-entwickler@xxxxxxxxxxxxxxxxx > http://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler -- Benjamin Benz Heise Zeitschriften Verlag Redaktion c't eMail: bbe@xxxxxxxx WWW : http://www.heise.de Heise Zeitschriften Verlag GmbH & Co. KG Registergericht: Amtsgericht Hannover HRA 26709 Persönlich haftende Gesellschafterin: Heise Zeitschriften Verlag Geschäftsführung GmbH Registergericht: Amtsgericht Hannover, HRB 60405 Geschäftsführer: Ansgar Heise, Steven P. Steinkraus, Dr. Alfons Schräder