Union supported by compiler?

I am working on porting code from arduino to Spark. When I compile, I get errors regarding a variable not being declared in the scope. This variable is clearly defined at the top of the file, after the #defines but uses a “union” of two items. Is “union” support in the Web IDE compiler?

Hi @peekay123,

We added multiple file support on Friday, I’m guessing if you added your new types to a library, this would probably fix the issue! (Based on your other posts, I’m not sure if you posted this before / after trying multiple-file stuff)

I’m guessing the pre-processor is trying to add missing function declarations at the top of your file (above the union), so it’s getting confused. If they were in another file however, it shouldn’t have this problem.

If it doesn’t work in multiple files, if you posted a breaking example I would be very grateful! :slight_smile:

Thanks!
David

Dave, I am trying to port the 4D Systems VisiGenie library over to the Spark. I split the files up into demo, .h and .cpp. The .h file has the supposed missing declaration but the Web IDE may be shuffling things in ways I am not aware of. I posted the three file on my github.

Hmm.

I’m thinking maybe I should have the pre-processor ignore .h and .cpp files in order to reduce any potential issues or messing with those files. I grabbed that source and tried to build it, and it wasn’t compiling, but I added “#define SPARK_NO_PREPROCESSOR” to the top of both the .h and .cpp files just to see if it was causing problems (it had the same errors). Maybe adding that to your source files would help with porting in the meantime?

edit: oops! should be pragma, not define!

#pragma SPARK_NO_PREPROCESSOR

Thanks,
David

Thanks Dave! I will give it a try shot and let you know how it goes :slight_smile:

1 Like

Dave, I added the “#define SPARK_NO_PREPROCESSOR” at the top of all the files with no affect. I still get the same errors. The first error reported is related to a “union” still. Any thoughts? :frowning:

Can you send the full text of the error, and the code snippet that causes the error?

Zach,

The error text is as follows:

genieSpark.cpp:5:29: error: 'genieFrame' was not declared in this scope
genieSpark.cpp:5:42: error: 'e' was not declared in this scope
genieSpark.cpp:6:19: error: 'genieFrame' was not declared in this scope
genieSpark.cpp:6:32: error: 'e' was not declared in this scope
genieSpark.cpp:6:43: error: expected primary-expression before 'cmd'
genieSpark.cpp:6:56: error: expected primary-expression before 'object'
genieSpark.cpp:6:72: error: expected primary-expression before 'index'
genieSpark.cpp:6:77: error: expression list treated as compound expression in initializer [-fpermissive]
genieSpark.cpp:18:24: error: 'genieFrame' was not declared in this scope
genieSpark.cpp:18:37: error: 'buff' was not declared in this scope
genieSpark.cpp:27:31: error: variable or field 'genieAttachEventHandler' declared void
genieSpark.cpp:27:31: error: 'genieUserEventHandlerPtr' was not declared in this scope
In file included from genieSpark.cpp:36:0:
genieSpark.h:164:89: error: 'bool genieEventIs(genieFrame*, uint8_t, uint8_t, uint8_t)' redeclared as different kind of symbol
genieSpark.cpp:6:6: error: previous declaration of 'bool genieEventIs'
In file included from genieSpark.cpp:36:0:
genieSpark.h:165:52: error: 'uint16_t genieGetEventData(genieFrame*)' redeclared as different kind of symbol
genieSpark.cpp:5:10: error: previous declaration of 'uint16_t genieGetEventData'
In file included from genieSpark.cpp:36:0:
genieSpark.h:168:52: error: 'bool genieDequeueEvent(genieFrame*)' redeclared as different kind of symbol
genieSpark.cpp:18:6: error: previous declaration of 'bool genieDequeueEvent'
genieSpark.cpp: In function 'uint16_t genieGetEventData(genieFrame*)':
genieSpark.cpp:119:43: error: 'uint16_t genieGetEventData(genieFrame*)' redeclared as different kind of symbol
genieSpark.cpp:5:10: error: previous declaration of 'uint16_t genieGetEventData'
genieSpark.cpp: In function 'bool genieEventIs(genieFrame*, uint8_t, uint8_t, uint8_t)':
genieSpark.cpp:131:77: error: 'bool genieEventIs(genieFrame*, uint8_t, uint8_t, uint8_t)' redeclared as different kind of symbol
genieSpark.cpp:6:6: error: previous declaration of 'bool genieEventIs'
genieSpark.cpp: In function 'void _genieWaitForIdle()':
genieSpark.cpp:148:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
genieSpark.cpp: In function 'uint8_t _genieGetchar()':
genieSpark.cpp:342:11: warning: unused variable 'result' [-Wunused-variable]
genieSpark.cpp: In function 'uint16_t _genieGetchar_Serial()':
genieSpark.cpp:362:1: warning: no return statement in function returning non-void [-Wreturn-type]
genieSpark.cpp: In function 'void genieResync()':
genieSpark.cpp:396:60: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
genieSpark.cpp:401:41: warning: value computed is not used [-Wunused-value]
genieSpark.cpp: In function 'bool genieDequeueEvent(genieFrame*)':
genieSpark.cpp:435:41: error: 'bool genieDequeueEvent(genieFrame*)' redeclared as different kind of symbol
genieSpark.cpp:18:6: error: previous declaration of 'bool genieDequeueEvent'
genieSpark.cpp: In function 'uint16_t genieWriteObject(uint16_t, uint16_t, uint16_t)':
genieSpark.cpp:544:20: error: 'lowByte' was not declared in this scope
genieSpark.cpp:545:21: error: 'highByte' was not declared in this scope
genieSpark.cpp:563:1: warning: no return statement in function returning non-void [-Wreturn-type]
genieSpark.cpp: In function 'uint16_t genieDoEvents()':
genieSpark.cpp:329:1: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [genieSpark.o] Error 1

The code snippet is not at the listed line number but later at line 119:

uint16_t genieGetEventData (genieFrame * e) {
	return  (e->reportObject.data_msb << 8) + e->reportObject.data_lsb;
}

The declaration in digoleSpark.h is:

#define		GENIE_FRAME_SIZE	6

struct genieFrameReportObj {
	uint8_t		cmd;
	uint8_t		object;
	uint8_t		index;
	uint8_t		data_msb;
	uint8_t		data_lsb;
};

/////////////////////////////////////////////////////////////////////
// The Genie frame definition
//
// The union allows the data to be referenced as an array of uint8_t
// or a structure of type genieFrameReportObj, eg
//
//	genieFrame f;
//	f.bytes[4];
//	f.reportObject.data_lsb
//
//	both methods get the same byte
//
union genieFrame {
	uint8_t				bytes[GENIE_FRAME_SIZE];
	genieFrameReportObj	reportObject;
};

I need to point out that on a local compile, I don’t get this error, though I do get others which appear valid.

:smile:

Sorry, my mistake! It should be:

#pragma SPARK_NO_PREPROCESSOR

DOH!! When I run with the new line, I get:

genieSpark.cpp:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
In file included from genieSpark.cpp:36:0:
genieSpark.h:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
In file included from genieSpark.cpp:36:0:

I don’t get the union error but I do get a list of errors which I need to validate. Thanks!

:smile:

1 Like

Dave, everything is moving forward but I had to add this to the .h file for stream and Serial references to work:

#include <spark_wiring_usartserial.h>
#include <spark_wiring_usbserial.h>

After I fixed the errors and only get warning, the compile fails with:

genieSpark.cpp:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
In file included from genieSpark.cpp:36:0:
genieSpark.h:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
genieSpark.cpp: In function 'void genieResync()':
genieSpark.cpp:403:41: warning: value computed is not used [-Wunused-value]
genieSpark.cpp: In function 'uint16_t genieDoEvents()':
genieSpark.cpp:329:1: warning: control reaches end of non-void function [-Wreturn-type]
In file included from the_user_app.cpp:4:0:
genieSpark.h:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
the_user_app.cpp: In function 'void setup()':
the_user_app.cpp:43:33: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/bin/ld: 96804317fb6d284e14e31ad1156de5c38e0f706bd2e07c944d0577616fc7.elf section `.text' will not fit in region `FLASH'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 29648 bytes
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
make: *** [96804317fb6d284e14e31ad1156de5c38e0f706bd2e07c944d0577616fc7.elf] Error 1

Not sure where to go from here.

Dave, while I am trying to resolve the Web IDE compile issue, I am also compile the same code locally. I noticed that the definition for NULL is commented out in spark_wiring.h! Not sure why that is. Second, I am getting a memcpy error indicating “invalid arguments” but this code compiles fine on arduino IDE.

bool genieDequeueEvent(genieFrame * buff) {

	if (_genieEventQueue.n_events > 0) {
		memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
				GENIE_FRAME_SIZE);
		_genieEventQueue.rd_index++;
		_genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
		_genieEventQueue.n_events--;
		return TRUE;
	}
	return FALSE;
}

You could try adding the following pragmas:

#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wreturn-type" 
#pragma GCC diagnostic ignored "-Wswitch"

@Kitard reports that these help lower the noise and you definitely have the writeable string one in the output above. You have another one of these -Wunused-value that is new.

This part about overflowed region FLASH is interesting:

1 Like

Dave, I added the pragmas and little changed. Only a couple of warning went away. Here are the results:

genieSpark.cpp:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
In file included from genieSpark.cpp:39:0:
genieSpark.h:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
genieSpark.cpp: In function 'void genieResync()':
genieSpark.cpp:406:41: warning: value computed is not used [-Wunused-value]
In file included from the_user_app.cpp:4:0:
genieSpark.h:1:0: warning: ignoring #pragma SPARK_NO_PREPROCESSOR [-Wunknown-pragmas]
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/bin/ld: 544c874829549cb06d262899ef2dd31c686d20bdf8277b5cce1687a26fff.elf section `.text' will not fit in region `FLASH'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 29648 bytes
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/opt/gcc_arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
make: *** [544c874829549cb06d262899ef2dd31c686d20bdf8277b5cce1687a26fff.elf] Error 1

Compiling this code on Arduino for Teensy3 shows about 14K of code taken and 3600 bytes of RAM. The Spark should compile near that so not sure about that FLASH message.

Hi @peekay123,

I seemed to remember you sent / posted code for this, but I’m having trouble tracking it down. Any chance you could re-send? Sorry!

edit: I think @bko is right, there is something going on in there that is allocating something big. Sometimes just including a particular library can cause a binary to expand like this when it doesn’t need to.

Thanks,
David

Dave,

I posted the code on github: https://github.com/pkourany/VisiGenieSpark

Thanks for helping! :smiley:

1 Like

Hi @peekay123,

I added the pragmas, and got some compiling errors – I’m guessing I caught you between modifications :slight_smile:

  • genieBegin overloads a function on return type (I think that’s not allowed?)
    http://stackoverflow.com/questions/9568852/overloading-by-return-type

  • without the pre-processor you need an include for application.h, or spark_wiring_stream.h: #include "application.h"

  • lowByte, and highByte weren’t defined when I compiled?

    genieSpark.cpp: In function ‘uint16_t genieWriteObject(uint16_t, uint16_t, uint16_t)’:
    genieSpark.cpp:545:20: error: ‘lowByte’ was not declared in this scope
    genieSpark.cpp:546:21: error: ‘highByte’ was not declared in this scope

Happy to help debug compiling issues, lemme know when I should take another look :smile:

Thanks,
David

Dave,

The github source was pulled from the Web IDE files I setup. I am still figuring out how to not affect the source files when I compile via Eclipse cause I suck at makefiles. I’m trying to figure out why my code on github does not match the one I have in the Web IDE!

I don’t see an overload error on the Web IDE but from looking at the code, the genieBegin is defined twice which is a normal overload definition which is allowed since each takes a different number of arguments. I will get the code to compile on eclipse or the command line and see where its at and report back. :koala:

Dave, I managed to setup my local compile with the latest git pull and the genieSpark files. With or without the pragmas, I don’t get the overloaded function error. In fact I only get a couple of warnings but the linker fails with:

e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe:
core-firmware.elf section `.text' will not fit in region `FLASH'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe:
region `FLASH' overflowed by 7812 bytes
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
e:/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\
libg.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2.exe: error: ld returned 1 exit status
make: *** [core-firmware.elf] Error 1

On the Web IDE, the FLASH overflow is by 29648 bytes while locally, it is 7812. Not sure what that means.

Anyway, there is something wrong and I am not sure where to look. I will look for large var allocations to start. Any thoughts?

It seems to be complaining about a bunch of missing symbols for standard Unix filesystem helpers.

write, close, isatty, lseek, and read are all in unistd.h
fstat is in sys/stat.h

None of these would seem to apply to :spark: core development.

Maybe libg.a is not built right? I think you need a gcc wizard for this one.