Sauraen Posted January 24, 2016 Report Share Posted January 24, 2016 The application code for MIDIbox Quad Genesis absolutely needs C++: pieces of VGM files have to be edited, which means dynamic memory allocation (and freeing). Even the playback engine, where one VGM file can be played by multiple "play heads" at different positions corresponding to different channels, is inherently object-oriented. So I started making the core VGM player in MIOS32 in a new C++ application. Just testing the MBHP_Genesis driver with a C++ project (app.cpp) works fine, no compilation issues, and I was able to get the driver mostly working. But I then added some more complicated object-oriented source files, and after they compile, they fail to link: /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-abort.o): In function `abort': abort.c:(.text.abort+0xa): undefined reference to `_exit' /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk' /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-signalr.o): In function `_kill_r': signalr.c:(.text._kill_r+0xe): undefined reference to `_kill' and so on. Do you have any idea what could be going on? The application includes a number of C++ source files, one C source file, and of course a number of drivers and MIOS32 components in C. Does this have to do with the 'extern "C"' thing? Not exactly sure where I need that, but all my code compiled, so the C and C++ source files seemed to have found each other's headers. The only reason I needed a C source file in the first place was to manipulate the timers (higher resolution than those provided in MIOS32_Timer), and putting things like TIM5->CNT in a C++ source file didn't work. So I wrapped all the timer accesses in C functions and then had the original C++ source file call them. Again, this compiles, and this part doesn't seem to fail to link, just those OS things above. Quote Link to comment Share on other sites More sharing options...
Sauraen Posted January 24, 2016 Author Report Share Posted January 24, 2016 I committed this code so you can take a look if you want. I also created a test project in apps/troubleshooting that has the same overall structure as my project, but which doesn't have the linker issues. This leads me to believe that my code is at fault (of course it is!), but I still don't know what I could have messed up that would lead to this kind of linker issue. Quote Link to comment Share on other sites More sharing options...
Sauraen Posted January 24, 2016 Author Report Share Posted January 24, 2016 Never mind, it's me not understanding polymorphism and virtual functions. Still a dumb error message to get in response to those kind of issues. Quote Link to comment Share on other sites More sharing options...
lis0r Posted January 24, 2016 Report Share Posted January 24, 2016 (edited) Those error messages are related to memory allocation (sbrk_r) and clean up on termination, so don't be entirely surprised if they show up again later, because it looks like a library mismatch. You can write object oriented code with dynamic memory usage in C, you know. Just pass a structure in as the first parameter, and use malloc/free. C++ is mostly just a load of cruft and baggage to hide doing the same thing. Given you've had worries about performance for this project, you should keep a close eye on the overheads C++ will be introducing into your code base. Profiling, metrics, and some good test code will save you a lot of headaches later on. Edited January 24, 2016 by lis0r Quote Link to comment Share on other sites More sharing options...
Sauraen Posted January 26, 2016 Author Report Share Posted January 26, 2016 I may do that, as the core object-oriented part which really needed that had to be changed anyway. We'll see. The one thing is that I don't think I can use malloc and free. I looked at the OS source and there's a pvPortMalloc function, but I'm not sure if I can use that. And in the documentation of those functions, it mentions not being able to free memory after allocating it. But new and delete work fine (if less quickly). I would think they would actually call the C functions malloc and free, but there's a lot about low-level embedded stuff I don't know. Maybe TK can weigh in on this? Has anyone else done a big MIDIbox project in C++? Quote Link to comment Share on other sites More sharing options...
TK. Posted January 26, 2016 Report Share Posted January 26, 2016 malloc/free overlays are part of the programming model: http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fprogramming_models%2Ftraditional%2Ffreertos_heap.cpp Big C++ based MIDIbox application: http://svnmios.midibox.org/listing.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Fprocessing%2Fmidibox_cv_v2%2Fsrc%2F (major object orientied code located in src/components) I don't use dynamic object allocation, but prefer static instead for deterministic behaviour. Btw.: please move your cpp_issues program to a different location, e.g. /playground. The apps/troubleshooting directory is intended to collect troubleshooting applications for the users, and not to discuss programming problems. Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Sauraen Posted January 27, 2016 Author Report Share Posted January 27, 2016 Thanks TK. In previous projects I used all static allocation, but this one involves users editing these VGM files on the synth, and this requires arrays to change size and other dynamic stuff. I deleted the cpp_issues directory as per your request. I would have made it in playground in the first place, but I didn't know if I would be able to get the project to build, due to it not being in a valid position in the mios32 directory tree. Quote Link to comment Share on other sites More sharing options...
lis0r Posted January 27, 2016 Report Share Posted January 27, 2016 The static approach would be to declare oversized arrays, and only use as much as you need. This has the advantage that you never have to worry about allocation overheads, heap fragmentation, or running out of memory. An alternative approach is to couple this idea with a pool (e.g. static array and usage bitmap) of fixed memory blocks. As well as eliminating the danger of fragmentation, you can conceptually reset the pool on mode change, removing dangling pointers. A lot of these concepts are similar between embedded work and video games, so if you google for "memory allocation in games", you'll find some useful articles. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.