Porting AVR Software/Debugging on Nano ARM

Post Reply
jBrisbin
Posts: 8
Joined: Thu Jul 20, 2017 6:10 pm

Porting AVR Software/Debugging on Nano ARM

Post by jBrisbin » Sun Aug 06, 2017 10:10 pm

Issues noted:
1. Nothing prints on the console.

Diagnosis: AVR boards always print to the console through the Serial object, as in Serial.println("Hello World")
Arduino ARM boards print to console through SerialUSB, as in SerialUSB.println("Hello World"). (technically this applies only the the Native USB port, which is the only one on Nano ARM)
Solution: So either change all the Serial to SerialUSB in your Nano ARM sketches (and switch back to use the sketch with an AVR),
or do something like this in a common header:
#ifndef DebugSerial
#if defined(__AVR__)
#define DebugSerial Serial
#elif defined(__SAMD21G18A__)
#define DebugSerial SerialUSB
#endif
#endif
Then change all the Serial references that go the the console to DebugSerial. Be aware that similar changes may be necessary in libraries you use.
(Other non-AVR processosr than the Zero version used on the Nano ARM (DUE, for example) would require a change to the above macro.)

The ill considered change from Serial to SerialUSB was brought to you by Arduino headquarters, not Protoneer.

2. Even after fixing item 1, the first few lines of console output may be missing. They appear when run on an original Nano.

Diagnosis: There was enough startup delay with the AVR processor at 16MHz for the USB serial connection to be setup before you got a chance to print anything to it. With faster AVR processors and all ARMs, the delay is too short to reliably catch the first few lines output.
Solution: Where you once wrote:
Serial.begin(115200);
Write:
while (!DebugSerial && (millis() < 2000)) ;
DebugSerial.begin(115200);

This waits a maximum of 2 seconds for the serial port to become ready (either ARM or AVR) the configures the serial output and begins normal operation. Without the millis check, you may hang when booted without a USB serial connection present.

3. After a failed test of new software, I can't upload anymore. The IDE upload can't find the port, etc.

Diagnosis: Arduino ARM based boards seem to be more prone to lockup in places that the uploader cannot break through than AVR devices. Memory faults of the kind than cannot occur on an AVR are an example of this. Accesses out of bounds or with bad alignment for the object size will cause this failure.
Solution: Wait until lines beginning with
PORTS {
appear repeatedly in the uploading pane of the IDE. When it does, double click the reset button on the Nana Arm to force it into upload mode. The upload should start after a few more PORT lines are printed. (If you double click too soon, it won't work either.)

4. My old working code hangs and after adding a lot of serial debug statements, I traced it to a statement like this:
if (*((unsigned long*) dip) == 0xFFFFFFFF) <dosomething>;

Diagnosis: A read of a 4 byte object is being forced by the cast to unsigned long*, but it is not a native 4 byte object, probably a pointer to bytes or 16 bit values. The ARM M0 processor does not handle misaligned accesses (such as trying to retrieve a 32 bit long from an address that is not a multiple of 4).
Solution: Don't do that. It is bad practice to assume that you can access values through a byte pointer as if it was a pointer to something bigger.
Or, if there are a number of such instances and it is so natural to use a long to reference them, like IPV4 addresses, then force them into long alignment with an attribute command like:
uint8_t dip[] __attribute__((aligned(4))) = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
This can cause as much as 3 bytes wasted space, and the __attribute__((aligned(4))) can be omitted for AVR devices, so some more macro magic is possible but not implemented here to eliminate unnecessary loss of RAM space.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest