MCP3208 Build Failing (undefined reference to 'MCP3208_Entry'
Trezitorul
Posts: 68
Hi guys I figured I would start learning C and C++ and I am trying to interface to the MCP3208 but my build keeps failing with the following errors:
(.text+0x24): undefined reference to `MCP3208_Entry'
/tmp/cckxDf1w.o: In function `_main':
(.text+0x88): undefined reference to `__load_start_mcp3208_cog'
As far as I can tell its because of the mcp3208.s file is not being picked up properly by the simpleIde compiler...however, I am very new with C and C++ so it could also just be gross incompetence on my part.
I copied the mcp3208.h, mcp3208.test.h, and mcp3208.s file into the same folder as my project as suggested by the libpropeller readme. The code that I wrote to try to interface with the MCP is below:
-Trezitorul
(.text+0x24): undefined reference to `MCP3208_Entry'
/tmp/cckxDf1w.o: In function `_main':
(.text+0x88): undefined reference to `__load_start_mcp3208_cog'
As far as I can tell its because of the mcp3208.s file is not being picked up properly by the simpleIde compiler...however, I am very new with C and C++ so it could also just be gross incompetence on my part.
I copied the mcp3208.h, mcp3208.test.h, and mcp3208.s file into the same folder as my project as suggested by the libpropeller readme. The code that I wrote to try to interface with the MCP is below:
#include "simpletools.h" // Include simple tools #include "mcp3208.h" //using namespace libpropeller; int main() // Main function { libpropeller::MCP3208 mcp; print("Hello from the PropStick"); mcp.Start(31,29,30,0xFF,-1,-1); int in=-1; while(1) { in=mcp.In(0); print("The ADC Value is: %d \n",in); } }Thanks for the help!
-Trezitorul
Comments
Second, it may help if you post a zip of your project. Under "Project" choose the "Zip" option and the post the resulting file.
In the libpropeller instructions it states:
"Some objects (that take a seperate cog, usually) have an associated .S file that you'll have to include in your make file or on the command line."
They do not, however, elaborate on exactly how one would include them in your make file or on the command line. How would I go about doing that since just adding it to the SimpleIDE project does not seem to work successfully? I did notice that I can add command line arguments to both the compiler and the linker in the simpleIDE, is there a way I can add the .S file there?
Thanks!
-Trezitorul
P.S. I have attached my projects zipfile before and after attempting to add mcp3208.S to the project.
PullTester1.zip <- Without trying to add mcp3208.S to project
PullTester1(Added.S).zip <- After trying to add mcp3208.S to the project
dgately
C++ code not as the assembly file it is? Is that what is happening or is it something else and what might I do about it?
Error output when I try to compile project.
Current project included below:
PullTester1(Added.S).zip
Thanks for the help!
-Trezitorul
Is your .S file a GAS-compatible source file?
dgately
the output it produces when run is in my previous post.
Thanks for the help!
-Trezitorul
dgately
As dgately pointed out that comments were the wrong type and fixing those almost let the object compile. However, there is another error at the bottom of the file. The .res1 should be .res 1 .
e.g.
should be
Once that if corrected everything seems to be in order and the assembler produces mcp3208.o files as would be expected with a successful build of the .S file. However, the overall build fails with the following message:
Then I found a really sketchy work around by going to the lmm folder and taking the mcp3208.o file and renaming it mcp3208.S.o as is expected by the compiler for some reason. Is there a more elegant/proper solution to this that I don't know about? (Sorry the documentation for dealing with .S files with simpleIDE is nonexistant as far as I can tell).
Once all of this is done all is well and my project builds...however, there is another error that pops up. For some reason the way the MCP driver is written right now it seems to overwrite the serial buffer. For example my code is suppose to say "The ADC Value is: %d \n" to the serial port. However, if I start up the MCP driver it outputs strange characters in the middle of the output such as:
This happens even if you output a message such as "Hello World" after starting up the MCP. Any ideas why such a thing would happen?
I am just now learning how to use propgcc but I would be interested in working through the bugs together. Should I start a new thread for debugging the MCP driver in libpropeller?
-Trezitorul
The first place to look when you're having trouble is the repository. In particular, the Makefile and the unit tests (source). I just ran them for MCP3208.h and they run fine under propgcc version (propellergcc-alpha_v1_9_0_2408) 4.6.1. So we know that it works with one setup. I'm not sure where I can get a propgcc version history, so I can't tell if you have an earlier or later version of propgcc.
First off, I'm not having any problem with double slash // comments versus apostrophe ' comments. The double slash is compiling just fine.
Second, the "T1 .res1" that you mentioned at the end appears to be a copy error on your end. If you look at the source you can see that there is a tab in there.
I think I read somewhere that SimpleIDE doesn't support .S files, although I could be wrong about that. My recommendation is to try compiling from the command line, getting that working, then trying to integrate with SimpleIDE.
Can you post your current code?
ps: if you (or any readers) are ever having trouble with libpropeller code please PM me or open an issue on Github so that I don't miss it.
PropWare binary: http://david.zemon.name/downloads/PropWare_Binaries/PropWare_current.zip
The first thing I did was use the assembler to generate the mcp3208.o file from the mcp3208.S and the commenting errors showed up again and were gone when I changed the "//" to " ' ". I am using propgcc version: "propeller-elf-gcc -v GCC 4.6.1 (propellergcc_v1_0_0_2411)". The problem does not occur if I run the makefile included with the mcp3208.h file...is there a flag of some kind in the make file telling it to read the assembly comments as "//" instead of " ' ".
The other thing that SRLM mentioned was that there was a copy error, and with that I concur I did make copy error so ... disregard my previous comment about the RES 1 spacing error.
Finally, I did manage to get SimpleIDE to compile and build the whole project. However, I believe there is a bug in simpleIDE in which instead of searching for mcp3208.o which it does assemble correctly it searches for mcp3208.S.o which is incorrect. I went to the lmm and cmm folders of the project and simply renamed my mcp3208.o files to mcp3208.S.o and the project builds and compiles now. I have other issues but that solved the build issues. Does anyone know where I should report the bug in simpleIDE? Or ...if it is a bug at all? Oh and just in case it helps my simpleIDE version is: 1.0.1 (RC1) the latest version as far as I can tell.
I have gone ahead and just zipped up the whole project directory to show the renaming of the mcp files. I have another issue which I described in my previous post regarding the serial output getting trashed by the mcp3208 being started...I honestly have no idea what could be causing that since theoretically the mcp code and the serial output are running on entirely different cogs. Is it possible that the i2c driver which is being used to communicate with the MCP is interfering with the serial output?
And thank you everyone for your help! The mud is beginning to clear!
Pull Tester.zip
You're starting the MCP3208 on pins 29,30, and 31. That's not allowed. Those pins are reserved for I2C (28 and 29) and USB host serial (30 and 31). You'll need to put the MCP3208 on another set of 3 pins (any are fine).
The MCP3208 is not I2C. It's an SPI device.
For compiling I much prefer to use a makefile and Netbeans or (my new favorite) CLion. So, I can't provide much support for SimpleIDE usage except to say that since you got it working with the rename you might as well continue with that. The ASM file shouldn't ever change, so you don't really need to have it in your build system.
Also keep in mind that libpropeller (and PropWare?) is designed for a single step compilation and linking (a single translation unit) to fully optimize the result binary. So you'll get slightly smaller binaries by using a makefile similar to what's in the libpropeller library.
I am curious if you could elucidate a bit further what you mean by single step linking and compilation. Also how does one use the make files in the libpropeller library, do I just copy them and modify them to add my source files to them for a new project or is there a better way to do this?
Thanks for all the help everyone!
-Trezitorul
This is different from pretty much every other example has you do. Those other examples would prefer that you compile .cpp source files into a .o object file, then link those together to build the final program.
My approach is to give the entire program (all *.cpp, *.h, and *.S files) to a single call of the GCC. This has two benefits:
1. Saves a few hundred bytes or so, due to increased optimization opportunities
2. Makes the most of inline headers, whose justification I set out here.
C++ tutorials recommend against this approach with a passion bordering on vehemence. But there's pretty much one reason why they want to do that: because compiling a big program takes time. But large PropGCC programs are physically impossible, and hence compilation times are always short. So, it makes more sense to get the most out of every byte, and that's what libpropeller was designed for from the ground up.
As a side benefit, makefiles get really simple. It's easy to just pass `*.cpp *.h *.S` to your compilation command and let GCC work out the details. No more dealing with writing all the rules for your makefile.
The libpropeller makefile is a good place to start. Just strip out the unit testing relevant stuff (the UNIT_TEST and ruby stuff), and set it up to pull the sources of your project. It has all the compilation flags that I've found to work best with PropGCC for the smallest binary size.
Anyway, other than the building and liking approach the same general structure of a makefile applies. Rules, variable replacements, and tabs for indentation, etc. Any makefile tutorial would be a good place to start to get up to speed on that aspect.
I did not try to do that when PropWare moved to CMake.
Glad to hear we have another CLion fan!