2020-08-12 09:13 AM
I've tried __attribute__((constructor)) on STM32F030R8T6 for running tests like Gtest framework by user-defined test. The code is shown as below:
#define TEST(name) \
void Test##name(void); \
__attribute__((constructor)) void LoadTest##name(){ \
RegisterTestFunction(Test##name); \
g_Signal++; \
} \
\
void Test##name(void) \
void RegisterTestFunction(TestFunctionProto pTf)
{
if(pTf == NULL)
{
return APPO_ERROR;
}
else if(StackGetSize(&g_TestFunctions) >= TEST_FUNCTIONS_MAX_NUM)
{
TestPrintf("Test Functions overflow!");
return APPO_ERROR;
}
return StackPush(&g_TestFunctions, pTf);
}
void RunAllTests(void)
{
TestFunctionProto tmp = NULL;
DebugPrintf("g_Signal = %d", g_Signal);
while(FALSE == StackIsEmpty(&g_TestFunctions))
{
tmp = (TestFunctionProto) StackPop(&g_TestFunctions);
tmp();
}
}
Then I use TEST(***) to test my function like this:
TEST(Stack)
{
/*My test code*/
}
In the main() function , I run the "RunAllTests()", I could see the Test function results by UART printing :
But when I use the same code on the STM32L073RZ chip , I can't run my tests!
The LoadTest##name() function cannot run before main() even if I use "__attribute__((constructor))" !!!!:persevering_face:
Anybody can help me?
2020-08-12 09:44 AM
The startup code provided in the ST library is minimal and it does not run constructors.
You can add the needed code into the startup, or just call your tests from your main() as normal functions.
-- pa
2020-08-12 12:42 PM
No. It works for me (STMCubeIDE 1.4.1)
The usual newlib mechanism is used. See the sources: https://github.com/bminor/newlib/blob/master/newlib/libc/misc/init.c
For
__attribute__((constructor)) void LoadTest()
{
__asm("nop");
}
the call stack is:
LoadTest() at main.c:61 0x8000224
__libc_init_array() at 0x8001b6c
Reset_Handler() at startup_stm32f042k6tx.s:119 0x800055e
and, in a C++ project, for
class Klass {
public:
Klass() {
__asm("nop");
}
};
Klass klass;
Klass::Klass() at maincpp.cpp:6 0x800037e
__static_initialization_and_destruction_0() at maincpp.cpp:10 0x80003c0
_GLOBAL__sub_I_klass() at maincpp.cpp:20 0x80003de
__libc_init_array() at 0x8001b60
Reset_Handler() at startup_stm32f042k6tx.s:119 0x8000552
hth
KnarfB
2020-08-12 01:06 PM
Would have to be sure startup.s calls __libc_init_array
And that the linker script handled constructors
Not saying it doesn't work out-of-the-box these days, but they've shipped decades worth of broken code...
2020-08-12 04:33 PM
My bad ;( somehow in my projects call to __libc_init_array is removed.
In ST provided package for GCC toolchain it is in place and works.
-- pa