2

I am trying to use Eigen C++ library on STM32F4 Discovery embedded board to perform some matrix operations in the future, specifically to do some kalman filtering on sensor data.

I tried linking against the standard c++ library and even tried to compile the program using g++ arm compiler.

typedef Eigen::Matrix<float, 10, 10> Matrix10d;
Matrix10d mat1 = Matrix10d::Constant(10, 10, 1);
Matrix10d mat2 = Matrix10d::Constant(10, 10, 2);
Matrix10d result;
result = mat1 * mat2;

I can compile the same code if the matrix size as been set to 7. If I cross that then the code wont compile and the eigen gives me a warning that

warning: argument 1 value '4294967295' exceeds maximum object size 2147483647

These are the partial error messages I am getting

n function 'throw_std_bad_alloc,
    inlined from 'check_size_for_overflow at bla/bla/Eigen/src/Core/util/Memory.h:289:24

Here is the memory allocation in Linker script I am using

/*
 * STM32F407xG memory setup.
 * Note: Use of ram1 and ram2 is mutually exclusive with use of ram0.
 */
MEMORY
{
    flash0  : org = 0x08000000, len = 1M
    flash1  : org = 0x00000000, len = 0
    flash2  : org = 0x00000000, len = 0
    flash3  : org = 0x00000000, len = 0
    flash4  : org = 0x00000000, len = 0
    flash5  : org = 0x00000000, len = 0
    flash6  : org = 0x00000000, len = 0
    flash7  : org = 0x00000000, len = 0
    ram0    : org = 0x20000000, len = 128k      /* SRAM1 + SRAM2 */
    ram1    : org = 0x20000000, len = 112k      /* SRAM1 */
    ram2    : org = 0x2001C000, len = 16k       /* SRAM2 */
    ram3    : org = 0x00000000, len = 0
    ram4    : org = 0x10000000, len = 64k       /* CCM SRAM */
    ram5    : org = 0x40024000, len = 4k        /* BCKP SRAM */
    ram6    : org = 0x00000000, len = 0
    ram7    : org = 0x00000000, len = 0
}

I am just running STM32F4 discovery board with unchanged Chibios configuration

# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
  USE_PROCESS_STACKSIZE = 0x400
endif

Update

I was not able to reproduce this error anymore. The sad thing is that I didn't do anything to solve the issue.

arm-none-eabi-gcc -c -mcpu=cortex-m4 -O3 -Os -ggdb -fomit-frame-pointer -falign-functions=16 -ffunction-sections -fdata-sections -fno-common -flto -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -Wall -Wextra -Wundef -Wstrict-prototypes -Wa,-alms=build/lst/ -DCORTEX_USE_FPU=TRUE -DCHPRINTF_USE_FLOAT=TRUE -DTHUMB_PRESENT -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -MD -MP -MF .dep/build.d -I.

The above are the compiler options that I am using if anyone is interested.

Now I can multiply even 20x20 matrices with out any problem.

Matrix20d mat1 = Matrix20d::Constant(20, 20, 2);
// Multiply the matrix with a vector.
Vector20d vec = Vector20d::Constant(20, 1, 2);
Vector20d result;
systime_t startTime = chVTGetSystemTimeX();
result = mat1 * vec;
// Calculate the timedifference
systime_t endTime = chVTGetSystemTimeX();
systime_t timeDifference = chTimeDiffX(startTime, endTime);
chprintf(chp,"Time taken for the multiplication in milliseconds : %d\n", (int)timeDifference);
chprintf(chp, "System time : %d \n", startTime);
chprintf(chp, "Systime end : %d \n", endTime);
chprintf(chp, "Values in the vector : \n [");
for(Eigen::Index i=0; i < result.size();i++)
{
    chprintf(chp, "%0.3f, ", result(i));
}
chprintf(chp, "] \n");
chThdSleepMilliseconds(1000);

It took about ~1ms to do the above computation.

I thought that there might be some problem with my compiler. So I tried with two versions of compilers

Version - 1

arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Version-2

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
the_parzival
  • 354
  • 3
  • 19
  • Can you specify which exact MCU you are using? It seems you are over allocating your memory as 10*10*4 = 400, that times 2 gets you 800 bytes translates to 0x320 and that is probably more than your heap. So please also include your linker file and chibios memory area allocations. – Tarick Welling Jul 01 '19 at 20:51
  • @TarickWelling Thank you. I am using STM32F4 Discovery board for this project. – the_parzival Jul 01 '19 at 21:08
  • @the_parzival That does not answer Tarick's question. He asked about the MCU, not the board. Even then there are multiple STM32F4 Discovery boards in any case. – Clifford Jul 01 '19 at 21:47
  • It is not clear which line of code the warning refers to. It does not appear to be either of the lines in the fragment you have posted. – Clifford Jul 01 '19 at 21:50
  • sorry its the `STM32F407VG` – the_parzival Jul 01 '19 at 21:50
  • Yeah, its not emanating from those lines but somewhere within Eigen or most probably GCC where it checks whether the processor has enough memory to hold the matrices. – the_parzival Jul 01 '19 at 21:52
  • 1
    @the_parzival _All_ the information issued in the diagnostic is important. The warning would have included the filename and the line number of the code it refers to, but for reasons that are beyond me you have chosen to omit that information. Moreover you have elided and truncated other diagnostics by posting "partial" error messages. Why would you do that!? – Clifford Jul 01 '19 at 21:57
  • 1
    Probably a duplicate of https://stackoverflow.com/questions/53933092/eigen-with-o3-warning-argument-1-value-x-exceeds-maximum-object-size-y. What compiler options are you using? What version of Eigen are you using? And what version of GCC? Note how that question posts the _whole_ diagnostic, where you have elided it, hiding important diagnostic information. In this case I found it by Googling the text of the warning _fragment_ you posted - always worth a try for unusual like this one. – Clifford Jul 01 '19 at 22:28
  • @Clifford seems like a dup **but** this is an embedded device and as such has most likely an outdated compiler. As such the workaround/fix might be different and in my opinion constitutes an original question. – Tarick Welling Jul 02 '19 at 07:40
  • @op what compiler and IDE are you using? What version is your compiler? – Tarick Welling Jul 02 '19 at 07:40
  • @TarickWelling About your first comment: `Eigen::Matrix` will actually be allocated on the stack, not the heap. And the code-snippet requires 4 matrices of that size (one temporary could be avoided). 1600 bytes on the stack probably is too much for that device. – chtz Jul 02 '19 at 08:06
  • @chtz : Its a fair point, although that is not what the warning refers to - the stack overflow would not be detected at compile time. I am not sure where you see four matrices or determine 1600 bytes. I see 3 at 300 bytes each - still large though. – Clifford Jul 02 '19 at 08:15
  • @Clifford how did you get 300 bytes each? Float is 4 bytes right? – Tarick Welling Jul 02 '19 at 08:16
  • @chtz it was a quick guess but luckily doesn't matter as it is still too big for either as ST normally allocates about `0x200` for either. – Tarick Welling Jul 02 '19 at 08:17
  • @TarickWelling : The work-around in the other question is applied to the Eigen library rather then the compiler I think. – Clifford Jul 02 '19 at 08:17
  • @chtz : Doh! yes 400! – Clifford Jul 02 '19 at 08:18
  • @TarickWelling ; The ARM maintained GNU toolchain for Cortex-M is currently GCC 8, 20 December 2018 - so it is by far a given that the toolchain is outdated because it is embedded. https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads – Clifford Jul 02 '19 at 10:36

0 Answers0