jgaeddert / liquid-dsp

digital signal processing library for software-defined radios
http://liquidsdr.org
MIT License
1.87k stars 439 forks source link

compiling for microcontroller environments #277

Closed jcw closed 2 years ago

jcw commented 2 years ago

I'd like to have a go at making liquid-dsp work on ARM Cortex microcontrollers, e.g. STM32. It's exquisitely well-written, modular, and truly lightweight, IMNSHO. I'm not trying to flatter, just expressing my delight at finding this package ...

The source code structure appears to fit in quite nicely with the PlatformIO build environment I use, but I'm running into a first snag - I don't understand how the naming system is working, i.e. things like AGC(_s). I can see that it's a concatenating macro, and that the intention is no doubt to produce something like agc_s once expanded by the C preprocessor, but I can't seem to find the place where this is set up.

More concretely, while doing a very first build, I'm running into compilation errors such as:

lib/liquid-dsp/src/agc/src/agc.c:37:32: error: unknown type name 'AGC'
 void AGC(_squelch_update_mode)(AGC() _q);
                                ^~~
lib/liquid-dsp/src/agc/src/agc.c:40:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
 struct AGC(_s) {

Is there some documantation I've missed, or could you please give me a hint on where to dig further? I'm very familiar with C and C++, no need to explain #define or the use of ## :)

Update - It looks like this issue overlaps with #252, but that doesn't resolve the problem described above.

This build step works fine: arm-none-eabi-gcc -o .pio/build/liquid/libe9a/liquid-dsp/agc/src/agc.o -c -Wno-format -Wall -Wno-deprecated-declarations -Os -ffunction-sections -fdata-sections -Wall -mthumb -mcpu=cortex-m7 -DPLATFORMIO=50300 -DSTM32F723xx -DSTM32F7 -DXTAL=25 -DF_CPU=216000000L -Ilib/liquid-dsp/include -Ilib/liquid-dsp/src -Isrc -I. -I/Users/jcw/.platformio/packages/framework-cmsis@2.50501.200527/CMSIS/Include -I/Users/jcw/.platformio/packages/framework-cmsis-stm32f7/Include lib/liquid-dsp/src/agc/src/agc.c

But the next one fails, same error as above: arm-none-eabi-gcc -o .pio/build/liquid/libe9a/liquid-dsp/agc/src/agc_crcf.o -c -Wno-format -Wall -Wno-deprecated-declarations -Os -ffunction-sections -fdata-sections -Wall -mthumb -mcpu=cortex-m7 -DPLATFORMIO=50300 -DSTM32F723xx -DSTM32F7 -DXTAL=25 -DF_CPU=216000000L -Ilib/liquid-dsp/include -Ilib/liquid-dsp/src -Isrc -I. -I/Users/jcw/.platformio/packages/framework-cmsis@2.50501.200527/CMSIS/Include -I/Users/jcw/.platformio/packages/framework-cmsis-stm32f7/Include lib/liquid-dsp/src/agc/src/agc_crcf.c

(This is on latest MacOS)

jcw commented 2 years ago

To follow up - I think I found the problem: some .c files are not meant to be compiled by themselves, but are included by other small wrappers to vary the compiled type they get built for. This conflicts with PlatformIO's convention of including every .c file it sees in the src/*/src/ areas.

jcw commented 2 years ago

Second follow-up: it can be made to work, as the output below shows. Since PlatformIO supports many µC brands, this may well work on not just a wide range of ARM Cortex µCs, but also things like ESP32 and RiscV - I haven't tried that.

The change I had to make was minimal, but impacts the names of many source files: every source code file which is not compiled on its own needs to be renamed, i.e. blah.c to blah.inc.c. With this change, it's very easy to configure PlatformIO to avoid compiling these source files.

I can finish up these renames (currently *.inc, but *.inc.c is better) and can submit a pull request, if there is interest.

Here is a sample run, compiling liquid-dsp as a separate library, building the FFT demo for an STM32F723 µC, uploading it, and viewing the results:

$ pio run -e liquid -t upload -t monitor
Processing liquid (platform: ststm32; framework: cmsis; board: disco_f723ie)
-------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/disco_f723ie.html
PLATFORM: ST STM32 (15.2.0) > 32F723EDISCOVERY
HARDWARE: STM32F723IEK6 216MHz, 192KB RAM, 512KB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, cmsis-dap, jlink)
PACKAGES:
 - framework-cmsis 2.50501.200527 (5.5.1)
 - framework-cmsis-stm32f7 1.2.5
 - tool-dfuutil 1.9.211020
 - tool-ldscripts-ststm32 0.2.0
 - tool-openocd 2.1100.211028 (11.0)
 - tool-stm32duino 1.0.1
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 2 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <JeeH> 1.28
|-- <liquid-dsp>
Building in release mode
Checking size .pio/build/liquid/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.9% (used 1708 bytes from 196608 bytes)
Flash: [=         ]   8.3% (used 43256 bytes from 524288 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, jlink, stlink
CURRENT: upload_protocol = stlink
Uploading .pio/build/liquid/firmware.elf
xPack OpenOCD x86_64 Open On-Chip Debugger 0.11.0+dev (2021-10-17-00:18)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

srst_only separate srst_nogate srst_open_drain connect_deassert_srst

target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08001b84 msp: 0x20040000
** Programming Started **
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
============================ [SUCCESS] Took 2.62 seconds ============================
--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Miniterm on /dev/cu.usbmodem1103  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
fft plan [forward], n=16, DFT
16, DFT
original signal, x[n]:
  x[  0] =   0.0000 + j  0.0000
  x[  1] =   1.0000 + j -1.0000
  x[  2] =   2.0000 + j -2.0000
  x[  3] =   3.0000 + j -3.0000
  x[  4] =   4.0000 + j -4.0000
  x[  5] =   5.0000 + j -5.0000
  x[  6] =   6.0000 + j -6.0000
  x[  7] =   7.0000 + j -7.0000
  x[  8] =   8.0000 + j -8.0000
  x[  9] =   9.0000 + j -9.0000
  x[ 10] =  10.0000 + j-10.0000
  x[ 11] =  11.0000 + j-11.0000
  x[ 12] =  12.0000 + j-12.0000
  x[ 13] =  13.0000 + j-13.0000
  x[ 14] =  14.0000 + j-14.0000
  x[ 15] =  15.0000 + j-15.0000
y[n] = fft( x[n] ):
  y[  0] = 120.0000 + j-120.0000
  y[  1] =  32.2187 + j 48.2187
  y[  2] =  11.3137 + j 27.3137
  y[  3] =   3.9728 + j 19.9728
  y[  4] =   0.0000 + j 16.0000
  y[  5] =  -2.6546 + j 13.3454
  y[  6] =  -4.6863 + j 11.3137
  y[  7] =  -6.4087 + j  9.5913
  y[  8] =  -8.0000 + j  8.0000
  y[  9] =  -9.5913 + j  6.4087
  y[ 10] = -11.3137 + j  4.6863
  y[ 11] = -13.3454 + j  2.6546
  y[ 12] = -16.0000 + j  0.0000
  y[ 13] = -19.9728 + j -3.9728
  y[ 14] = -27.3137 + j-11.3137
  y[ 15] = -48.2187 + j-32.2187
z[n] = ifft( y[n] ):
  z[  0] =   0.0000 + j  0.0000
  z[  1] =   1.0000 + j -1.0000
  z[  2] =   2.0000 + j -2.0000
  z[  3] =   3.0000 + j -3.0000
  z[  4] =   4.0000 + j -4.0000
  z[  5] =   5.0000 + j -5.0000
  z[  6] =   6.0000 + j -6.0000
  z[  7] =   7.0000 + j -7.0000
  z[  8] =   8.0000 + j -8.0000
  z[  9] =   9.0000 + j -9.0000
  z[ 10] =  10.0000 + j-10.0000
  z[ 11] =  11.0000 + j-11.0000
  z[ 12] =  12.0000 + j-12.0000
  z[ 13] =  13.0000 + j-13.0000
  z[ 14] =  14.0000 + j-14.0000
  z[ 15] =  15.0000 + j-15.0000
rmse =   2.1491e-07
done.

Update - The following lines are needed to use Liquid-DSP in my own (C++) projects:

#include <complex>
#undef _B
#undef _L
#undef _N
#undef _P
#undef _U
#undef _X
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <liquid.h>
jgaeddert commented 2 years ago

Ah, yes. Sorry for the confusion. liquid uses a lot of pre-processor macros to avoid code duplication. I realize this isn't the most elegant solution.

majkrzak commented 2 years ago

Identifiers which starts with underscore followed by capital letter are reserved in C++ https://en.cppreference.com/w/cpp/language/identifiers

jcw commented 2 years ago

Thanks for pointing to the precise rules - to summarise:

That ought to be fairly easy to fix in the source code, @jgaeddert. (I understand that the mass-file-rename I propose may be more involved)

jgaeddert commented 2 years ago

I would love to set up a test environment for this. I do use variables prefixed with underscores to indicate function inputs (e.g. _As for stop-band attenuation in filters) which can be a problem with point 2 from @jcw above.

jcw commented 2 years ago

I can give you a snapshot of the setup I tried, for starters here's my (messy) main app code. This was tried on a "Disco-F723" board from STM, which includes good audio codec hardware, but it would not be hard to target another uC board - do you actually want to build for embedded, and perhaps also try it on real hardware? Basic trials with sample data would not be hard, tying into actual audio ADC & DAC hardware would be more work (and can be addictive ...).

jcw commented 2 years ago

As for underscore variables: one option would be to convert them to underscore + lowercase 1st char. Or place the underscore at the end ...

majkrzak commented 2 years ago

I think running tool like clang-tidy may help, as there is a check for this issue https://clang.llvm.org/extra/clang-tidy/checks/bugprone-reserved-identifier.html It may detect some other issues.

jgaeddert commented 2 years ago

As for underscore variables: one option would be to convert them to underscore + lowercase 1st char.

That should be an easy fix, although it will touch a LOT of files!

jgaeddert commented 2 years ago

I think running tool like clang-tidy may help, as there is a check for this issue https://clang.llvm.org/extra/clang-tidy/checks/bugprone-reserved-identifier.html It may detect some other issues.

That's a great suggestion! Any idea how to run clang-tidy without CMake? aking for a friend...

majkrzak commented 2 years ago

Tell the friend to stay tunnend and to look to my coming on the first day of the next day (or a bit later). I think I'll manage to run it.

jgaeddert commented 2 years ago

@jcw I'm very interested in getting this running on embedded microcontrollers. I'm embarrassed to admit I only just recently realized who you are. I've played around with JeeNodes for years, and only just now put two-and-two together!

I've started digging into PlatformIO and some of the tidy efforts to keep the compiler happy. There are certainly a lot of instances of _<upper-case-letter>. A quick-and-dirty search is showing more than 1,000 instances:

git grep " _[A-B,D-Z]" | wc
1100    7071   87371

I can start making changes in a branch before pulling into master, but I'll need to avoid doing a blind regex search/replace to avoid certain conflicts.

Having an integrated test, though, as a separate GitHub action would be invaluable.

jcw commented 2 years ago

Cool. I just realised that there's probably an easy way to set up a test in PIO for the "native" target, i.e. running on a desktop OS. After that, switching to an embedded build target should then also work - and since PIO can be run from the command line, GiHub actions (or any other CI setup) will be easy.

I'll look into setting up a test project in the next few days. Stay tuned :)

majkrzak commented 2 years ago

Getting back to the friend:

./bootstrap.sh
./configure
bear make
run-clang-tidy -checks=-\*,bugprone-reserved-identifier
jgaeddert commented 2 years ago

Thanks, @majkrzak ! The specific commands I... I mean she ran:

./bootstrap.sh
./configure
bear -- make
clang-tidy --checks=-\*,bugprone-reserved-identifier include/liquid.h
jcw commented 2 years ago

My apologies for taking so long to follow up. I had to dig up my modifications from a backup, as I'm currently working on other projects. There are two changes needed to build with PIO:

The library.json file is as follows:

{
    "build": {
        "flags": ["-I.", "-Wno-deprecated-declarations"],
        "srcFilter": "+<*> -<.git/> -<*/bench/> -<*/tests/> -<*/src/*.av.c> -<*/src/*.mmx.c> -<*/src/*.neon.c> -<*/src/*.sse4.c> -<*/src/*.x86.s>"
    }
}

Attached is a list of all the affected files, as compared to this checkout which I used at the time:

commit 2e9d1316299327772e101a8d8ae56be8fca9a4b7 (HEAD -> master, origin/master, origin/HEAD)
Author: Joseph D. Gaeddert <joseph@liquidsdr.org>
Date:   Sun Mar 6 09:11:35 2022 -0500

    eqlms/autotest: adjusting parameters of tests for better consistency

gitstat.txt

That second change will also affect your Makefile-based build, since source file names have changed.

But I'm not terribly happy with this approach, due to all the funny *.inc.c file names and the trickery needed in library.json to make it work. I can think of two alternatives:

  1. in all the src/*/src/ subdirs, move the included files to say src/*/include/
  2. ... and perhaps rename them to use a .h suffix (they are included, after all)
  3. or leave them as .c, but place them in src/*/cinc/ for example, to highlight their special treatment

Either way, the #include directives do not need to be adjusted w.r.t path, by adding -I ... to CFLAGS.

It's all a bit of a toss-up, if you ask me. In C, there is not really a file naming convention when including large swaths of code, AFAIK. In C++, with much more emphasis on headers and templates, it all ends up in files named.h or .hpp, usually.

I could have another go at this and start from scratch, perhaps from a dedicated git branch, if you let me know which approach you'd prefer. The basic issue is that right now, PIO feeds all the .c it finds in src/ to the compiler - so we either need to tell it to make exceptions based on some naming convention (as I did above), or the source files need to be split out into separate areas, so that PIO won't try compiling files it shouldn't.

jcw commented 2 years ago

Just a thought: you could name the new branch "main", while getting these fairly invasive changes going, and then switch the default branch from "master" to "main" once the transition is ready. That would fit in with what seems to be the new trend of moving to "main" as standard branch on GitHub.

jgaeddert commented 2 years ago

Just now getting back to this as I was on travel the better part of the week. These are all great points. I will point out that while these files are indeed included (e.g. filter_crcf.c includes firfilt.c) they're not function declarations but rather definitions, so giving them a .h extension makes less sense than .inc.c or putting them in a separate directory. My initial reaction is to give them a .proto.c to indicate they are prototype source files. It's a bit unfortunate that PlatformIO is trying to infer the build rules from a set of source files rather than allowing them to be stated explicitly, but I admit that its ease of use makes it really attractive for embedded development.

jgaeddert commented 2 years ago

Attached is a list of all the affected files, as compared to this checkout which I used at the time:

Besides renaming files with the .inc extension, there are lots of modifications on individual files. Were those mostly to avoid reserved identifiers for C++, e.g. _M variables? Could you provide a diff on, say, src/agc/src/agc_crcf.c?

jcw commented 2 years ago

I'm not at my desk right now, but I'm pretty sure all the other changes were just included-filename changes.

jgaeddert commented 2 years ago

I took a crack at updating the include files by giving them explicit .proto.c extension. I'm pretty new to platformio, but I'm at least getting it to compile with the following config:

[env:ststm32]
platform = ststm32
framework = cmsis
build_flags = -DSTM32F7 -DXTAL=25 -std=c++17 -Wno-format -Wall -I. -Wno-deprecated-declarations
monitor_speed = 115200
board = disco_f723ie
src_filter = +<*/src/*.c> -<.git/> -<*/src/*.proto.c> -<*/src/*.av.c> -<*/src/*.mmx.c> -<*/src/*.neon.c> -<*/src/*.sse4.c> -<*/src/*.x86.s>

Alas, I don't have a board to test it on, but hopefully this helps. I've tried compiling for a few other boards, but without luck (mostly hitting errors along the lines of cannot find complex.h)

jcw commented 2 years ago

Good progress! You can build for "platform = native" (and remove the "framework = ..." and "board = ..." lines). That will give you an executable which can be launched on your host system as `.pio/build/ststm32/program". Different boards may be using different toolchains, with their own idiosyncracies.

jgaeddert commented 2 years ago

I actually developed in a branch, but then "merged" (actually just a fast-forward) into master. Looks like there are some issues with implicit declarations with some of the polynomial routines which I can probably fix soon.

jgaeddert commented 2 years ago

Ok. Should be resolved now (had some old files lingering that pio was trying to compile, unsuccessfully). Works now with the following platformio.ini:

[env:native]
platform = native
build_flags = -DLIQUID_FFTOVERRIDE -std=c++17 -Wno-format -Wall -I. -Wno-deprecated-declarations
src_filter = +<*/src/*.c> +<*.c> -<.git/> -<*/src/*.proto.c> -<*/src/*.av.c> -<*/src/*.mmx.c> -<*/src/*.neon.c> -<*/src/*.sse4.c> -<*/src/*.x86.s>

and with an example program with main as src/platformio.c:

#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include "liquid.h"

int main()
{
    // create mod/demod objects
    modulation_scheme ms = LIQUID_MODEM_QAM16;

    // create the modem objects
    modemcf mod   = modemcf_create(ms);
    modemcf demod = modemcf_create(ms);

    // ensure bits/symbol matches modem description (only
    // applicable to certain specific modems)
    unsigned int bps = modemcf_get_bps(mod);
    modemcf_print(mod);

    unsigned int i; // modulated symbol
    unsigned int s; // demodulated symbol
    unsigned int num_symbols = 1<<bps;
    float complex x;
    unsigned int num_sym_errors = 0;
    unsigned int num_bit_errors = 0;
    for (i=0; i<num_symbols; i++) {
        modemcf_modulate(mod, i, &x);
        modemcf_demodulate(demod, x, &s);

        printf("%4u : %12.8f + j*%12.8f\n", i, crealf(x), cimagf(x));

        num_sym_errors += i == s ? 0 : 1;
        num_bit_errors += count_bit_errors(i,s);
    }
    printf("num sym errors: %4u / %4u\n", num_sym_errors, num_symbols);
    printf("num bit errors: %4u / %4u\n", num_bit_errors, num_symbols*bps);

    modemcf_destroy(mod);
    modemcf_destroy(demod);
    return 0;
}

Compile and run:

Processing native (platform: native)
--------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/native/src/agc/src/agc_crcf.o
...
Linking .pio/build/native/program
================================== [SUCCESS] Took 3.96 seconds ==================================
linear modem:
    scheme:         qam16
    bits/symbol:    4
   0 :  -0.94868326 + j* -0.94868326
   1 :  -0.94868326 + j* -0.31622776
   2 :  -0.94868326 + j*  0.94868326
   3 :  -0.94868326 + j*  0.31622776
   4 :  -0.31622776 + j* -0.94868326
   5 :  -0.31622776 + j* -0.31622776
   6 :  -0.31622776 + j*  0.94868326
   7 :  -0.31622776 + j*  0.31622776
   8 :   0.94868326 + j* -0.94868326
   9 :   0.94868326 + j* -0.31622776
  10 :   0.94868326 + j*  0.94868326
  11 :   0.94868326 + j*  0.31622776
  12 :   0.31622776 + j* -0.94868326
  13 :   0.31622776 + j* -0.31622776
  14 :   0.31622776 + j*  0.94868326
  15 :   0.31622776 + j*  0.31622776
num sym errors:    0 /   16
num bit errors:    0 /   64

I suppose the last thing would be setting up an appropriate library.json file and registering it?

jcw commented 2 years ago

Ah, nice. I was also trying to build - with your latest check-in, it now works here as well. Yes, library.json will let you make it available via say lib_deps = liquid-dsp. I'm attaching the version which works for me. The platformio.ini file is not used when building as a library, the equivalent settings are now in JSON:

{
    "build": {
        "flags": [
            "-std=c11",
            "-Iexample-pio",
            "-Wno-deprecated-declarations",
            "-Wno-implicit-function-declaration"
        ],
        "srcFilter": [
            "+<*>",
            "-<.git/>",
            "-<*/bench/>",
            "-<*/tests/>",
            "-<*/src/*.proto.c>",
            "-<*/src/*.av.c>",
            "-<*/src/*.mmx.c>",
            "-<*/src/*.neon.c>",
            "-<*/src/*.sse4.c>",
            "-<*/src/*.x86.s>"
        ]
    }
}

There's one issue with this: there needs to be a config.h file somewhere for PIO to pick up, I placed it in example-pio/. I also have a complete project there which illustrates the build for native, very similar to what you have:

example-pio.zip

You can unzip at the top level, place library.json at the top level, then cd example-pio; pio test to build and run.

Update - just to be clear: the example project is optional (but config.h will have to be present, somewhere), but it's a nice extra. The code I have is very rough, perhaps not quite what you'll want to have in there, and I didn't add a README.md in there yet. Just wanted to illustrate how a subdir can contain a PIO project which uses the parent dir as library.

Update 2 - the pio test is a trick to build and run in one step on native. It's probably a bad idea for an example, as it assumes some knowledge of pio test (and brings in the "Unity" test framework, which isn't even being used).

jcw commented 2 years ago

To be able to register, you need to add a name, version, repo url, etc - see the library docs. FWIW, here's an example of a library I have registered: https://git.jeelabs.org/jeeh/tree/library.json.

jcw commented 2 years ago

And just to follow up: you don't have to submit your library to the registry, see this info. IOW, your library will be usable as soon as it has a proper library.json file in git, by adding a line such as this to the PIO project which wants to use it:

lib_deps = https://github.com/jgaeddert/liquid-dsp.git
jgaeddert commented 2 years ago

I think I'm close. Just trying to find an appropriate way to test this locally before I push.

jgaeddert commented 2 years ago

I pushed to platformio-dev branch. Still some work to do, of course

jgaeddert commented 2 years ago

Are these changes sufficient to close this issue? I've been able to cross-compile an example program for STM32 but as I don't have a board to test it on I cannot confirm that it works.

jcw commented 2 years ago

I'll check it out later today. Been traveling, sorry for the late response.

jgaeddert commented 2 years ago

Oh, no rush! Just wanted to see if I was on the right track. Once you give me the go-ahead, I'll merge into master.

jcw commented 2 years ago

I've checked out your branch and placed it in lib/ in the same project as at the top of this issue thread. It looks like I still need the same lines before I can make the liquid.h header compile (in C++, maybe that's the issue?). IOW, I need:

#include <complex>
#undef _B
#undef _L
#undef _N
#undef _P
#undef _U
#undef _X
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <liquid.h>

Attached is a complete project, which fetches your library from github, builds, and - with a "Disco-F723" board attached, produces the expected output on its serial USB console port:

fft plan [forward], n=16, DFT
16, DFT
original signal, x[n]:
  x[  0] =   0.0000 + j  0.0000
  x[  1] =   1.0000 + j -1.0000
  x[  2] =   2.0000 + j -2.0000
[...]
  z[ 13] =  13.0000 + j-13.0000
  z[ 14] =  14.0000 + j-14.0000
  z[ 15] =  15.0000 + j-15.0000
rmse =   2.1491e-07
done.

liqembed.zip

It's still C++ code (probably easy to adapt to C), but I've removed my own library and added a basic UART interface. You should be able to replicate at least the build step using pio run.

jgaeddert commented 2 years ago

Ah, right. I was trying to tidy up the code in a separate branch. I'll try using your project as a litmus test.

jgaeddert commented 2 years ago

Alright, I've cleaned up many of the reserved identifiers. Some still exist, but I've tested the current branch on platformio-dev (fe9f75021e8dcff96c9da209bdea3e068703fe57) with your example, @jcw, and it builds fine.

jcw commented 2 years ago

Confirmed, it now builds and runs perfectly out of the box with this code (just to avoid some warnings):

#include <complex>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <liquid.h>

I think you've nailed it: Liquid-DSP can now be used on embedded µCs ... \o/ Congratulations, and thanks!

jgaeddert commented 2 years ago

Thanks @jcw! I'll be working on a workflow for testing before I close this out.

jcw commented 2 years ago

Ok - in the PIO world, there is this (but note that the testing setup is about change in the upcoming v6 release).

It's quite sophisticated: you can have an embedded board tied to say a Raspberry Pi, and register it for remote testing. After that, any continuous integration setup (incl GitHub actions, I expect) can test on that board, given proper access. Just mentioning this if you want to test on real hardware. Else, there's always the platform = native option, of course.

errikosmes commented 2 years ago

Hi,

I'm getting a similar error while trying to build the latest master for an embedded ARM processor using the ARM v8 gcc compiler inside Vitis IDE.

../libs/liquid-dsp-master/src/vector/src/vector_add.proto.c:36:19: error: unknown type name 'T'
   36 | void VECTOR(_add)(T *          _x,
      |                   ^

../libs/liquid-dsp-master/src/vector/src/vector_add.proto.c:37:19: error: unknown type name 'T'
   37 |                   T *          _y,
      |                   ^

Do you know if this fix will work for me too?

jgaeddert commented 2 years ago

It's quite sophisticated: you can have an embedded board tied to say a Raspberry Pi, and register it for remote testing. After that, any continuous integration setup (incl GitHub actions, I expect) can test on that board, given proper access. Just mentioning this if you want to test on real hardware. Else, there's always the platform = native option, of course.

Thanks for the reference! I've set up similar configurations at work (but using gitlab runners) to test on target hardware, but not using platformio. I'll give it a try.

jgaeddert commented 2 years ago

I'm getting a similar error while trying to build the latest master for an embedded ARM processor using the ARM v8 gcc compiler inside Vitis IDE.

@errikosmes Are you running this on a microblaze core? or something like a zynq? Unfortunately I don't have access to a setup like that. You might try the platformio-dev branch instead of master.

errikosmes commented 2 years ago

No it's a Zync UltraScale+ Cortex-a53 core.

Sure, I'll give that branch a go. Thanks!

errikosmes commented 2 years ago

The problem is still there, but to start with I think that I need to exclude every *.proto.c file from the build. I'll see if it compiles fine after that.

Just in general if you could give me some advice, what I've done to compile for my platform is:

I haven't messed with any config scripts as I'm trying to cross compile using Vitis IDE. Am I doing something wrong? Is there a recommended way to cross-compile I haven't found?

Thanks

jcw commented 2 years ago

I think that I need to exclude every *.proto.c file from the build

Oh yes, definitely. That's what started this issue, and that's what the platformio-dev branch fixes. And some more excludes, see https://github.com/jgaeddert/liquid-dsp/blob/platformio-dev/library.json#L40

errikosmes commented 2 years ago

Thanks jcw, that's what I needed. It compiles fine now and I can start testing the library

jgaeddert commented 2 years ago

Well, it seems I don't have a great board for testing locally. I have a lot of AVR microprocessors but I can't seem to find a math library that supports complex types in a consistent way.

jgaeddert commented 2 years ago

Well, it's fairly rudimentary but I have a platformio CI workflow set up and passing. Should probably expand beyond just the pico board.

jgaeddert commented 2 years ago

I merged into master; can link with the following:

lib_deps = https://github.com/jgaeddert/liquid-dsp.git

Closing this one out, but we can open new issues for specific boards as needed.