"new" seems to not run constructors?


(Pharap) #6

In fairness it’s not a “never use new or delete because they’re evil”, it’s more of a “don’t use them unless you know what you’re doing and you’re certain they’re the right option”, which I say as standard because I know some people come from C# or Java and think new is the standard way of creating objects (i.e. they don’t know about the stack and the heap and Obj o = Obj(); vs Obj * o = new Obj()), or at least aren’t aware of the overhead involved in heap allocation or the dangers of heap fragmentation.

In this case I think @ulfben probably knows what he’s doing.


I have some insight into this case because I’ve actually successfully implemented a templated class based state machine system that uses new and delete to allocate states.
I created it for my unpublished minesweeper game and I’m re-using it for my jam entry if I can get it finished in time.
(I didn’t use the constructor and destructor to do resetting though, I used the activate() and deactivate() functions (akin to enter() and exit()).)


(Felipe Manga) #7

Sure, “never say never”… but on these processors using the heap is a non-deterministic minefield that blows up on run-time with no warnings from the compiler or exceptions. Just unexpected behavior because the stack overwrote something.


(Ulf Benjaminsson) #8

Yeah - I really want to (have a few gameplay bugs left before the game is “done” and then I can go back and check out the constructor issue again). However, it seems my environment (I am using the vMicro visual studio extension for my development) can’t handle the serial port well. Whenever I bring Serial.begin(9600); into my setup(), the IDE turns into an unreliable and frustrating mess.

Some of the symptoms I’m getting:

  • frequently failing to upload new builds. The project is at Program size: 16 582 bytes (used 58%) and
    Minimum Memory Usage: 1781 bytes (70%) - but it acts as if it’s already interfering with the boot loader magic value? (but even when booting into “safe mode”, uploads often fail so perhaps I’m miss-attributing the failed flashing)

  • the IDE doesn’t auto-connect to the port, and sometimes just refuse to connect all together. For the past couple of hours I haven’t been able to see any output from the first 5-10 seconds of the application life time simply because the vMicro terminal isn’t capturing properly

  • way too frequently vMicro just won’t connect to the port properly no matter what I do. Hard-resetting or unplug-replugging the Arduboy often kicks the terminal back to life.

… all that to say: the Serial output seem to make my IDE very unhappy, the IDE interface is not at all clear enough to work this out sensibly (like; I still don’t know how to get the terminal window back after accidentally closing it).

Just wanted to vent for a bit.

I’ll create a new empty default project tomorrow and compile something entirely paired down, like your example. Perhaps it’s something about my project settings that’s broken.

EDIT. no. this is just absurd. stale code keeps running on the device, despite the IDE reporting successful builds and uploads. I get prints that hasn’t been in the code since hours ago, and I’ve cleaned, rebuilt and re-uploaded fresh build several times. I’m going to bed.


(Simon) #9

I am using the VSCode IDE from Microsoft. My machine also has Visual Studio and they are (not surprisingly) remarkably similar. VSCode has no issues with the serial port.


(Pharap) #10

Are you against getting a copy of the Arduino IDE or are you willing to try getting a copy to use Serial printing? If so that could be an answer.

Or as @filmote suggests, VSCode, which is essentially a text editor where compilers and other features are plugins.

Sounds like you’re probably trying to allocate more than you can afford.
That 70% doesn’t include the stack or the heap as far as I’m aware.

Have you tried using the while(!Serial); idiom in your code?
It prevents the program going further until it detects a serial connection.

Also note that serial works a bit differently to other communication techniques, it’s generally difficult to know if something’s listening.


If you know any .Net languages you could use the SerialPort class to fashion your own serial reader.

I think I have the right settings written down somewhere.


(Ulf Benjaminsson) #11

The problem right now is that I can’t even upload a new build. The uploader (both Aruduino IDE and vMicro) simply spin for several minutes before reporting “The uploader returned an error”.

The currently running build does call safeMode() so I can hold up to halt execution during boot, but it seems to make no difference - the red LED glows for ten seconds or so, and then the game starts up as usual. A minute or so later the uploader reports the same error.

I’m currently using the Arduino IDE to try and push the included “HelloWorld” sample code onto the board, but it’s not having any of it. I’ll try another USB-cable for good measure.

I haven’t tried the reset-button yet. Might it help?

EDIT:
Different cables: no change.
Reset button: just a reboot with a different name?


(Scott) #12

safeMode() doesn’t exit. If the game itself starts after invoking safe mode, then something’s wrong.


(Ulf Benjaminsson) #13

I double checked and you are correct. The game does not spontaneously break out of safemode.

What actually happens is that my Arduboy breaks out of safemode (and starts my game) the moment the uploader tries to connect.

Not sure what you mean. The source code seem to disagree:


(Scott) #14

while (true) { } is an infinite loop. When you start the upload, the loader causes an interrupt, which jumps into the bootloader.

It sounds like you may have connection problems or a corrupted bootloader. Setting “Show verbose output on upload” in the IDE preferences may tell you something.


(Ulf Benjaminsson) #15

Thanks. Here’s what I get:

Sketch uses 7138 bytes (24%) of program storage space. Maximum is 28672 bytes.
Global variables use 1224 bytes (47%) of dynamic memory, leaving 1336 bytes for local variables. Maximum is 2560 bytes.
Forcing reset using 1200bps open/close on port COM6
PORTS {COM6, } / {} => {}
PORTS {} / {COM6, } => {COM6, }
Found upload port: COM6
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega32u4 -cavr109 -PCOM6 -b57600 -D -Uflash:w:C:\Users\ulfbe\AppData\Local\Temp\arduino_build_537969/HelloWorld.ino.hex:i 

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
Copyright © 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright © 2007-2014 Joerg Wunsch

     System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

     Using Port                    : COM6
     Using Programmer              : avr109
     Overriding Baud Rate          : 57600
     AVR Part                      : ATmega32U4
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PA0
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
       lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : butterfly
     Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding


(Ulf Benjaminsson) #16

So to pick this up again (and taking the thread further off topic - I’ll come back to the constructors once I can upload new code on my Arduboy again).

The situation is:

  1. I have a sketch on the Arduboy. It runs well, but I can’t upload a new sketch to overwrite it.
  2. I have tried uploading the sample Hello World sketch, and an empty sketch.
  3. I have tried uploading via the Arduino IDE, vsMicro in Visual Studio and ArduBoyManager
  4. I have tested different cables and different ports
  5. The uploader(s) all connects and triggers the interrupt correctly (see post above) but instead of rebooting into USB-mode and taking commands from the computer, the Arduboy just reboots the sketch.
  6. Making me suspect that my sketch inadvertently overwrites the magic value during the USB interrupt watchdog interval. Somehow.

Is there anything I can do to regain write-access to the Arduboy now?

I’ve shared my game source over on github. It’s a heavily refactored version of Filmote’s tutorial in Arduboy Magazine (vol 10), the dino runner game.

The entry point and high level execution flow is:

GameEngine _engine;
void setup(){	
	arduboy.boot();
	arduboy.blank();
	arduboy.safeMode(); //hold UP at boot to unfuck a locked bootloader 
#ifdef DEBUG
	Serial.begin(9600);
	while(!Serial);
	Serial.println("Tracing ON");
#endif
};
void loop(){
	if(!arduboy.nextFrame()){ return; } //idles the CPU 1ms at a time
	_engine.input();
	_engine.update();
	_engine.render();
};

The _engine instance will do four things at creation:

  1. it creates all game objects up front (they are static instances, re-used throughout the game life-cycle),
  2. it calls arduboy.initRandomSeed(),
  3. it creates the StartMenuState,
  4. which in turn calls setFrameRate() (lower framerate when not in-game = improved battery life)

But otherwise the sketch executes no code and registers no timeouts, interrupts or such, until the loop() is entered. Eg. if I’m touching the magic value, it should happen during the creation of all those static objects.Not that any of this matters - what I need right now is not a code review, but a solution for uploading a new sketch.

So: have I locked myself out permanently, or can my Arduboy be rescued?

(thinking back, the Serial object (eg the “#DEBUG”-section) is not in the running code on the arduboy. that was a later edition)


(Felipe Manga) #17

Have you tried uploading any other game, to make sure you’re actually unable to upload?

Your current source crashes:

  • In the GameEngine constructor. You can’t call initRandomSeed before boot(). The ADC hasn’t been configured yet.
  • In GameEngine::changeState. It calls new, which calls malloc, which hasn’t been initialized before setup().

I commented both lines in the constructor and changed setup to this:

void setup(){	
    arduboy.begin();
    _engine.changeState(GameState::StartMenu);
};

I removed the #DEBUG as ProjectABE doesn’t do serial yet. Runs OK now.

Edit: just saw you tried “Hello World” and it reboots without flashing. I get this behaviour on my Pro Micro. flashlight mode seems to help, a bit. Might be placebo. I generally have to try flashing more than once for it to work. Using the emulator instead of testing on hardware keeps me from going bald.


(Ulf Benjaminsson) #18

Thanks a ton! I implemented your fixes.

Just to be clear; the repo represents a bit of a schroedingers code base since I haven’t been able to upload any builds since forever (this thread is basically my drawn-out realization that uploads haven’t been working).

Yeah. I have tried many, many times with safe mode, reset-button, varying timing (visavi the build+upload). This is not shaking loose.


(Felipe Manga) #19

Now that I think of it, your Arduboy is crashing before it gets to setup, so safe mode / flashlight / begin won’t help at all.

What I’d do on the Pro Micro:
After the IDE does a software reset, there’s a short time window where I need to press the reset button and it goes into bootloader mode for a few seconds. Too early and I get an error, too late and it boots the old sketch.
No idea why this weird trick works, but since you’ve got a brick, might as well try it about 20 times. :stuck_out_tongue:


(Ulf Benjaminsson) #20

Sounds promising. Do I understand you correctly?

  1. start upload from Arduino IDE
  2. once Arduboy blinks and reset
  3. … hit the reset-button (within the 120ms watchdog window, presumably?)

Got a paperclip ready, I’ll report back after a couple of tries :slight_smile:

EDIT. and again just to confirm I understand your process, my first try (failed) yielded

avrdude: ser_send(): write error: sorry no info avail
avrdude: ser_recv(): read error: The device does not recognize the command.
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_recv(): read error: The device does not recognize the command.

I assume that’s similar to what you get on failed attempts?


(Ulf Benjaminsson) #21

YEAH BUDDY!

I never thought I’d be so happy to see that painfully slow logo crawl again. :smiley:

EDIT: seriously. What a relief! I tried breaking it again by uploading my game, and my current code base seems to fit better with the device! I had no problems uploading new sketches afterwards.

But now I’m left with the question: what actually broke? I mean obviously my sketch was crashing (thanks again @FManga! I would never have discovered those bugs), but how did that ruin the bootloader, specifically?


(Felipe Manga) #22

I do get the butterfly_recv line, I don’t remember the others. I think the window has something to do with the programmer trying to access the port, not the watchdog. Again, no idea why this works.

Glad you got it booting again! :slight_smile:

Edit:
Honestly not trying to plug, but, due to a bug, that logo is REALLY quick in the emulator. :stuck_out_tongue:


(Pharap) #23

If I’ve been following the conversation right then it was probably the attempt to allocate dynamic memory before the dynamic memory system had been initialised.


I’m not entirely sure though, since I had a similar thing happen to me when working on the early stages of Dark & Under, and we weren’t doing any dynamic allocation.


(Ulf Benjaminsson) #24

Your browser based emulator is amazeballs! (esp. with both disassembly and ram view being so easily accessible). But is there any way to dump a directory / zip of source code on it or do I have to manually re-create every single file?

(I guess, what I’m really saying is: some documentation on the front page would be good. :))

Anyway; a browser based emulator (no installs!) is absolutely genius and would absolutely become part of my workflow if the uploads were quicker (and preferably pushed straight from the conventional IDEs).


(Felipe Manga) #25

If you’re using Chrome, you can drop a ZIP into the IDE.

Otherwise, you can point it to github:
https://felipemanga.github.io/ProjectABE/?url=https://github.com/ulfben/DinoRun/

Also, you can use the offline builds (without the debugger, for now) for integration with your IDE like @Schuemi does here:

I’ve been using it like this with Emacs a lot, lately.

Yeah, I do need to get some documentation done. I’m not really good at that. :stuck_out_tongue: