Well, my bug is back, this time after ~12 hours of run time.
Code: Select all
-------------------Trap information-----------------------------
Exception Frame/A7 =0210F814
Trap Vector =Access Error (2)
Format =04
Status register SR =2000
Fault Status =08
Faulted PC =0206C812
-------------------Register information-------------------------
A0=00000000 A1=200009C4 A2=0210F89E A3=0210F974
A4=02114C4A A5=020690E6 A6=0210F824 A7=0210F814
D0=00000000 D1=00002000 D2=003FFFE3 D3=00000000
D4=0210F89E D5=02114C4A D6=0210F8E8 D7=0210F99C
SR=2000 PC=0206C812
-------------------RTOS information-----------------------------
The OSTCBCur current task control block = 20000A9C
This looks like a valid TCB
The current running task is: HTTP#2D
-------------------Task information-----------------------------
Task | State |Wait| Call Stack
Idle#3F|Ready | |0200C64C,0200C530,0
Main#32|Ready | |0200E2F2,0200276C,0200C530,0
TCPD#28|Semaphore |00BD|0200DF22,0201C6C6,0200C530,0
IP#27|Fifo |000D|0200D3F8,02011194,0200C530,0
Enet#26|Fifo |0024|0200D3F8,0202E4B8,0200C530,0
FTPD#30|Semaphore |0000|0200DF22,0201F754,02017948,0200C530,0
TELNET#37|Semaphore |0000|0200DF22,0201C27C,02002BAC,0200C530,0
HTTP#2D|Running | |0206C812,0
QUADSERIAL#2A|Semaphore |0001|0200DF22,0201F754,0200574C,0200C530,0
-------------------End of Trap Diagnostics----------------------
WinAddr2Line says 0206C812 is this again:
Code: Select all
std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&)
??:0
Code in the web.cpp file now looks like this:
Code: Select all
#include <startnet.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <math.h>
#include <autoupdate.h>
using namespace std;
//Define External Variables
extern const char* AppName;
extern unsigned long g_UptimeSeconds;
extern bool g_USUnits;
extern int g_DirectionTTL;
extern bool g_DirectionForward;
extern string g_IOCardVersion;
extern bool g_MaxOfflineDistanceOverrideActive;
extern int g_ReceiverTTL[];
extern double g_ReceiverDistance[2][2];
extern double g_ReceiverHeading[];
extern string g_ReceiverFields[2][12];
extern double g_Distances[2][2];
extern double g_WayPointHeading[];
extern double g_WayPointDistance[];
extern bool g_WayPointStraight[];
extern int g_WayPointCount;
extern int g_ActiveWayPointSegment;
extern double g_ActiveWayPointHeading;
template<typename T>
static std::pair<bool,T> ValueFromString(std::string const& theString) {
T value;
std::istringstream iss (theString);
if ((iss >> value).fail() ) return std::make_pair(false, 0);
return std::make_pair(true, value);
}
// Functions called from a web page must be declared extern C
extern "C" {
void DisplayFirmwareVersion(int sock, PCSTR url);
void DisplayIOCardVersion(int sock, PCSTR url);
void getAJAXSystemStatus(int sock, PCSTR url);
void getAJAXPathList(int sock, PCSTR url);
void RebootSystem();
void ReadUserSettings();
void WriteUserSettings();
void DisplayUnitsDropDown(int sock, PCSTR url);
}
// Structure for storing and retieving from user Flash
#define VERIFY_VALUE (0x48666050) //A random value picked from the phone book....
struct MyOwnDataStore {
DWORD verify_key;
bool USUnits;
};
void ReadUserSettings() { //Read the stored data
MyOwnDataStore *pData = (MyOwnDataStore*) GetUserParameters();
//Verify it has the right key value. In a "Real" application, a checksum would be more robust.
if (pData->verify_key == VERIFY_VALUE) { //Data is ok
if (pData->USUnits) {
g_USUnits = true;
iprintf("Loading System Settings: Using US units (feet).\r\n");
} else {
g_USUnits = false;
iprintf("Loading System Settings: Using metric units (meters).\r\n");
}
} else {
iprintf("System settings could not be read from NVRAM.\r\n");
}
}
void WriteUserSettings() {
MyOwnDataStore mds;
mds.USUnits = g_USUnits;
mds.verify_key = VERIFY_VALUE;
if (SaveUserParameters( &mds, sizeof(mds)) != 0) {
iprintf("Parameters saved in User Parameter area.\r\n");
} else {
iprintf("Programming failed \r\n");
}
}
int MyDoPost(int sock, char *url, char *pData, char *rxBuffer) {
iprintf("----- Processing Post -----\r\n");
iprintf("Post URL: %s\r\n", url);
iprintf("Post Data: %s\r\n", pData);
if (httpstricmp(url+1, "REBOOTSYSTEM")) {
//ExtractPostData("textForm1", pData, textForm1, MAX_BUF_LEN);
//iprintf("textForm1 set to: \"%s\"\r\n", textForm1 );
RebootSystem();
// Tell the web browser to issue a GET request for the next page
RedirectResponse(sock, "advanced.htm");
} else if (httpstricmp(url+1, "SETUNITS")) {
char newunits[20];
if (ExtractPostData("units", pData, newunits, 20) != -1) {
if (!strcmp(newunits, "metric")) {
g_USUnits = false;
iprintf("Setting units to Metric.\r\n");
} else if (!strcmp(newunits, "us")) {
g_USUnits = true;
iprintf("Setting units to Feet.\r\n");
} else {
iprintf("Specified units were not recognized.\r\n");
}
WriteUserSettings();
}
RedirectResponse(sock, "advanced.htm");
} else {
NotFoundResponse(sock, url);
iprintf("HTTP Post Form Processor: We did not match any page\r\n");
}
return 1;
}
void RegisterPost() {
SetNewPostHandler(MyDoPost);
}
void DisplayFirmwareVersion(int sock, PCSTR url) {
writestring(sock, AppName);
}
void DisplayIOCardVersion(int sock, PCSTR url) {
ostringstream output;
output << g_IOCardVersion;
writestring(sock, output.str().c_str());
}
void DisplayUnitsDropDown(int sock, PCSTR url) {
ostringstream output;
output << "<select name=\"units\">";
if (g_USUnits) {
output << "<option value=\"metric\">Metric (Meters)</option>";
output << "<option value=\"us\" SELECTED>US (Feet)</option>";
} else {
output << "<option value=\"metric\" SELECTED>Metric (Meters)</option>";
output << "<option value=\"us\">US (Feet)</option>";
}
output << "</select>";
writestring(sock, output.str().c_str());
}
void getAJAXSystemStatus(int sock, PCSTR url) {
ostringstream output;
output << fixed; //Needed for setprecision
unsigned long secs = g_UptimeSeconds;
unsigned int days = secs/86400; secs -= days*86400;
unsigned int hours = secs/3600; secs -= hours*3600;
unsigned int mins = secs/60; secs -= mins*60;
output << "<table border=1 cellspacing=0 cellpadding=5>";
output << "<tr><td colspan=3>System Uptime: " << days << " Day";
if (days != 1) output << "s";
output << ", " << hours << " Hour";
if (hours != 1) output << "s";
output << ", " << mins << " Minute";
if (mins != 1) output << "s";
output << ", " << secs << " Second";
if (secs != 1) output << "s";
output << "<br><br></td></tr>";
output << "<tr><td>Travel Direction:</td><td colspan=2";
if (g_DirectionTTL == 0) {
output << " bgcolor=#FF6666>I/O Card Not Available";
} else {
if (g_DirectionForward) {
output << ">Forward";
} else {
output << ">Reverse";
}
}
output << "</td></tr>";
output << "<tr><td>-</td><td><b>Receiver 1</b></td><td><b>Receiver 2</b></td></tr>";
output << "<tr><td><b>Receiving Data</b></td>";
if (g_ReceiverTTL[0] == 0) {
output << "<td bgcolor=#FF6666>No</td>";
} else {
output << "<td bgcolor=#00FF00>Yes</td>";
}
if (g_ReceiverTTL[1] == 0) {
output << "<td bgcolor=#FF6666>No</td>";
} else {
output << "<td bgcolor=#00FF00>Yes</td>";
}
output << "</tr>";
output << "<tr><td><b>GPS Solution Status</b></td><td>" << g_ReceiverFields[0][0] << "</td><td>" << g_ReceiverFields[1][0] << "</td></tr>";
output << "<tr><td><b>GPS Position Type</b></td><td>" << g_ReceiverFields[0][1] << "</td><td>" << g_ReceiverFields[1][1] << "</td></tr>";
output << "<tr><td><b>Satellites Tracked</b></td><td>" << g_ReceiverFields[0][9] << "</td><td>" << g_ReceiverFields[1][9] << "</td></tr>";
output << "<tr><td><b>Satellites Used</b></td><td>" << g_ReceiverFields[0][10] << "</td><td>" << g_ReceiverFields[1][10] << "</td></tr>";
output << "<tr><td><b>Vector Length</b></td><td>";
if (g_USUnits) { //*3.28084
std::pair<bool,double> rf02 = ValueFromString<double>(g_ReceiverFields[0][2]);
std::pair<bool,double> rf12 = ValueFromString<double>(g_ReceiverFields[1][2]);
if (rf02.first == true) {
output << setprecision(2) << rf02.second * 3.28084;
} else {
output << "Error: Not Numeric";
}
output << " ft</td><td>";
if (rf12.first == true) {
output << setprecision(2) << rf12.second * 3.28084;
} else {
output << "Error: Not Numeric";
}
output << " ft";
} else {
output << g_ReceiverFields[0][2] << " m</td><td>" << g_ReceiverFields[1][2] << " m";
}
output << "</td></tr>";
output << "<tr><td><b>Vector Heading</b></td><td>" << g_ReceiverFields[0][3] << "°</td><td>" << g_ReceiverFields[1][3] << "°</td></tr>";
output << "<tr><td><b>Vector Pitch</b></td><td>" << g_ReceiverFields[0][4] << "°</td><td>" << g_ReceiverFields[1][4] << "°</td></tr>";
output << "<tr><td><b>Heading Accuracy</b></td><td>" << g_ReceiverFields[0][6] << "°</td><td>" << g_ReceiverFields[1][6] << "°</td></tr>";
output << "<tr><td><b>Pitch Accuracy</b></td><td>" << g_ReceiverFields[0][7] << "°</td><td>" << g_ReceiverFields[1][7] << "°</td></tr>";
output << "<tr><td><BR><BR><b>Current Distance</b></td><td><BR><BR>";
if (g_USUnits) {
output << setprecision(2) << g_ReceiverDistance[0][0] * 3.28084 << " ft";
} else {
output << setprecision(2) << g_ReceiverDistance[0][0] << " m";
}
output << "</td><td><BR><BR>";
if (g_USUnits) {
output << setprecision(2) << g_ReceiverDistance[1][0] * 3.28084 << " ft";
} else {
output << setprecision(2) << g_ReceiverDistance[1][0] << " m";
}
output << "</td></tr>";
output << "<tr><td><b>Offline Distance</b></td><td";
double dbl_od = fabs(g_ReceiverDistance[0][1]);
if (dbl_od > 0.5) {
if (dbl_od > 1) { //Red
output << " bgcolor=#FF6666";
} else { //Yellow
output << " bgcolor=#FFFF00";
}
}
if (g_USUnits) {
dbl_od *= 3.28084 * 12; //to feet, to inches
output << ">" << setprecision(1) << dbl_od << " in";
} else {
output << ">" << setprecision(2) << dbl_od << " m";
}
output << "</td><td";
dbl_od = fabs(g_ReceiverDistance[1][1]);
if (dbl_od > 0.5) {
if (dbl_od > 1) { //Red
output << " bgcolor=#FF6666";
} else { //Yellow
output << " bgcolor=#FFFF00";
}
}
if (g_USUnits) {
dbl_od *= 3.28084 * 12; //to feet, to inches
output << ">" << setprecision(1) << dbl_od << " in";
} else {
output << ">" << setprecision(2) << dbl_od << " m";
}
output << "</td></tr>";
if (g_MaxOfflineDistanceOverrideActive) {
output << "<tr><td colspan=3 bgcolor=#FFFF00><b>Override of Maximum Offline Distance is Enabled</b></td><tr>";
}
output << "</table>";
writestring(sock, output.str().c_str());
}
void getAJAXPathList(int sock, PCSTR url) {
ostringstream output;
output << fixed; //Needed for setprecision
if (g_WayPointCount == 0) {
output << "There are no waypoints defined.<BR><BR>";
} else {
output << "<table border=1 cellspacing=0 cellpadding=5>";
output << "<tr><td>Heading<BR>(in Degrees)</td><td>Distance<BR>(in ";
if (g_USUnits) {
output << "Feet";
} else {
output << "Meters";
}
output << ")</td><td>Path</td></tr>";
if (g_WayPointCount > 0) {
for (int i = 0; i < g_WayPointCount; i++) { //-1
if (i > 0 && i == g_ActiveWayPointSegment) { //Add the row showing current location
output << "<tr><td bgcolor=#CCCCCC><b>";
output << setprecision(4) << g_ActiveWayPointHeading;
output << "</b></td><td bgcolor=#CCCCCC><b>";
if (g_USUnits) {
output << setprecision(2) << g_ReceiverDistance[1][0] * 3.28084;
} else {
output << setprecision(2) << g_ReceiverDistance[1][0];
}
output << "</b></td><td bgcolor=#CCCCCC><b>Current Location";
output << "</b></td></tr>";
}
output << "<tr><td>";
output << setprecision(4) << g_WayPointHeading[i];
output << "</td><td>";
if (g_USUnits) {
output << setprecision(2) << g_WayPointDistance[i] * 3.28084;
} else {
output << setprecision(2) << g_WayPointDistance[i];
}
output << "</td><td>";
if (i == 0) {
output << "-";
} else {
if (g_WayPointStraight[i]) {
output << "Straight";
} else {
output << "Arc";
}
}
output << "</td></tr>";
}
}
output << "</table>";
}
writestring(sock, output.str().c_str());
}
I'm pretty sure it was executing either getAJAXSystemStatus() or getAJAXPathList().