Hi,
I am moving from Eclipse / GCC to Keil ARM-MDK / uVision4 (the "lite" version at present). I can compile, download and run simple C programs OK. But I wish to be able use C++ classes (objects), typically a few "static" objects that are instantiated as my code starts-up and then remain in existance and accessible to the rest of the program "forever".
However, it seems no matter how simple my classes, my code hangs as soon as I attempt to instantiate a class. I have prepared some simple code that demonstrates my problem, see below.
I am working with AT91SAM7X256 CPUs on Olimex SAM7-EX256 development boards and on custom boards. I have "told" uVision4 I am using a AT91SAM7X256 and it has copied the "SAM7.s" file into my project (the startup code).
I suspect my problem has to do with the Keil provided statup code - I think somehow it does not allow for object instantiation during program start-up ? Perhaps I need to tweak it to allow this, but I haven't found any explanation of how to do this. So any advice would be appreciated.
My sample code below compiles, downloads and runs on my hardware fine as long as I do not instantiate or reference the TestCounter class (that is, if I comment out lines 46 and 55). But with the instantiation enabled (line 46) the code compiles and downloads without error but the target system appears to hang at power on / does not start-up.
I would appeciate any assistance anyone can offer on this - perhaps a pointer to an article expaining how to make this work, or some working sample code, or an appropriately "tweaked" startup file.
Thanking you,
Martin.
#include ".\AT91SAM7X256.h" void SetLcdBacklightOn(void); void SetLcdBacklightOff(void); class clsCounter // Simple class to demonstrate / test class instantiation problem { private: int Count; public: clsCounter(); // Class Constructor ~clsCounter(); // Class Destructor void Reset(void); void Increment(void); int GetCount(void); }; clsCounter::clsCounter() // Class Constructor - Initializes the internal count value to 0 { Count = 0; } clsCounter::~clsCounter() // Class Destructor - No code is required { } void clsCounter::Reset(void) // Reset method - Resets the intenal count value back to 0 { Count = 0; } void clsCounter::Increment(void) // Increment method - Increments the internal count value by 1 { Count++; } int clsCounter::GetCount(void) // GetCount method - Returns the current internal count value { return Count; } clsCounter TestCounter; // Instantiate an instance of the Counter Class int main(void) { *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS; // Disable the Watchdog Timer *AT91C_PMC_PCER = 0xFFFFFFFF; // Enable All Peripheral Clocks TestCounter.Increment(); // Make use of the class int i; while(1) // Endless Loop to Flash LCD Backlight at about 1Hz { SetLcdBacklightOn(); // Turn the Backlight On for (i = 0; i < 5000; i++); // Wait about half a second SetLcdBacklightOff(); // Turn the Backlight Off for (i = 0; i < 5000; i++); // Wait about half a second } } void SetLcdBacklightOn(void) { *AT91C_PIOB_PER = 0x00100000; // Allocate I/O Pin PB20 to PIOB *AT91C_PIOB_OER = 0x00100000; // Configure it as an output to drive the LCD Backlight enable signal *AT91C_PIOB_SODR = 0x00100000; // Drive it High to Enable the LCD Backlight } void SetLcdBacklightOff(void) { *AT91C_PIOB_PER = 0x00100000; // Allocate I/O Pin PB20 to PIOB *AT91C_PIOB_OER = 0x00100000; // Configure it as an output to drive the LCD Backlight enable signal *AT91C_PIOB_CODR = 0x00100000; // Drive it Low to Disable the LCD Backlight }