Fixed small errors in pipes and pipes factory.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12307 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
parent
f562ee4948
commit
8fa2bcdad9
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
|
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# C specific options here (added to USE_OPT).
|
# C specific options here (added to USE_OPT).
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||||
<stringAttribute key="bad_container_name" value="\RT-STM32L476-DISCOVERY\debug"/>
|
<stringAttribute key="bad_container_name" value="\RT-STM32L476-DISCOVERY\debug"/>
|
||||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
|
<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
|
<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList/>"/>
|
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="r0-(format)" val="4"/></contentList>"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32L476-DISCOVERY"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32L476-DISCOVERY"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.603687198"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.603687198"/>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
<listEntry value="/RT-STM32L476-DISCOVERY"/>
|
<listEntry value="/RT-STM32L476-DISCOVERY"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
<listEntry value="4"/>
|
<listEntry value="4"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|
|
@ -70,7 +70,7 @@ int main(void) {
|
||||||
*/
|
*/
|
||||||
while (true) {
|
while (true) {
|
||||||
if (palReadLine(LINE_JOY_CENTER)) {
|
if (palReadLine(LINE_JOY_CENTER)) {
|
||||||
test_execute((BaseSequentialStream *)&SD2, &rt_test_suite);
|
// test_execute((BaseSequentialStream *)&SD2, &rt_test_suite);
|
||||||
test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
|
test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
|
||||||
}
|
}
|
||||||
chThdSleepMilliseconds(500);
|
chThdSleepMilliseconds(500);
|
||||||
|
|
|
@ -271,6 +271,9 @@ void _factory_init(void) {
|
||||||
#if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
|
#if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
|
||||||
dyn_list_init(&ch_factory.fifo_list);
|
dyn_list_init(&ch_factory.fifo_list);
|
||||||
#endif
|
#endif
|
||||||
|
#if CH_CFG_FACTORY_PIPES == TRUE
|
||||||
|
dyn_list_init(&ch_factory.pipe_list);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||||
|
@ -775,7 +778,7 @@ dyn_pipe_t *chFactoryFindPipe(const char *name) {
|
||||||
|
|
||||||
F_LOCK();
|
F_LOCK();
|
||||||
|
|
||||||
dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.fifo_list);
|
dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.pipe_list);
|
||||||
|
|
||||||
F_UNLOCK();
|
F_UNLOCK();
|
||||||
|
|
||||||
|
|
|
@ -138,8 +138,8 @@ static size_t pipe_read(pipe_t *pp, uint8_t *bp, size_t n) {
|
||||||
size_t s1, s2;
|
size_t s1, s2;
|
||||||
|
|
||||||
/* Number of bytes that can be read in a single atomic operation.*/
|
/* Number of bytes that can be read in a single atomic operation.*/
|
||||||
if (n > chPipeGetFreeCount(pp)) {
|
if (n > chPipeGetUsedCount(pp)) {
|
||||||
n = chPipeGetFreeCount(pp);
|
n = chPipeGetUsedCount(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of bytes before buffer limit.*/
|
/* Number of bytes before buffer limit.*/
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<value>Mailboxes.</value>
|
<value>Mailboxes.</value>
|
||||||
</brief>
|
</brief>
|
||||||
<description>
|
<description>
|
||||||
<value>This sequence tests the ChibiOS libraryfunctionalities related to mailboxes.</value>
|
<value>This sequence tests the ChibiOS library functionalities related to mailboxes.</value>
|
||||||
</description>
|
</description>
|
||||||
<condition>
|
<condition>
|
||||||
<value>CH_CFG_USE_MAILBOXES</value>
|
<value>CH_CFG_USE_MAILBOXES</value>
|
||||||
|
@ -430,6 +430,140 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]></value>
|
||||||
</case>
|
</case>
|
||||||
</cases>
|
</cases>
|
||||||
</sequence>
|
</sequence>
|
||||||
|
<sequence>
|
||||||
|
<type index="0">
|
||||||
|
<value>Internal Tests</value>
|
||||||
|
</type>
|
||||||
|
<brief>
|
||||||
|
<value>Pipes</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>This sequence tests the ChibiOS library functionalities related to pipes.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value>CH_CFG_USE_PIPES</value>
|
||||||
|
</condition>
|
||||||
|
<shared_code>
|
||||||
|
<value><![CDATA[#define PIPE_SIZE 16
|
||||||
|
|
||||||
|
static uint8_t buffer[PIPE_SIZE];
|
||||||
|
static PIPE_DECL(pipe1, buffer, PIPE_SIZE);
|
||||||
|
|
||||||
|
static const uint8_t pipe_pattern[] = "0123456789ABCDEF";]]></value>
|
||||||
|
</shared_code>
|
||||||
|
<cases>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Filling and emptying a pipe, non blocking.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>The pipe functionality is tested by loading and emptying it, all conditions are tested.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value>
|
||||||
|
</value>
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value><![CDATA[chPipeObjectInit(&pipe1, buffer, PIPE_SIZE);]]></value>
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value/>
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[unsigned i;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Filling whole pipe.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[msg_t msg;
|
||||||
|
|
||||||
|
msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE);
|
||||||
|
test_assert(msg == PIPE_SIZE, "wrong size");
|
||||||
|
test_assert((pipe1.rdptr == pipe1.buffer) &&
|
||||||
|
(pipe1.wrptr == pipe1.buffer) &&
|
||||||
|
(pipe1.cnt == PIPE_SIZE),
|
||||||
|
"invalid pipe state");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Emptying pipe.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[msg_t msg;
|
||||||
|
uint8_t buf[PIPE_SIZE];
|
||||||
|
|
||||||
|
msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE);
|
||||||
|
test_assert(msg == PIPE_SIZE, "wrong size");
|
||||||
|
test_assert((pipe1.rdptr == pipe1.buffer) &&
|
||||||
|
(pipe1.wrptr == pipe1.buffer) &&
|
||||||
|
(pipe1.cnt == PIPE_SIZE),
|
||||||
|
"invalid pipe state");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>
|
||||||
|
</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>
|
||||||
|
</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>
|
||||||
|
</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>
|
||||||
|
</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value></value>
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
</cases>
|
||||||
|
</sequence>
|
||||||
<sequence>
|
<sequence>
|
||||||
<type index="0">
|
<type index="0">
|
||||||
<value>Internal Tests</value>
|
<value>Internal Tests</value>
|
||||||
|
@ -438,7 +572,7 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]></value>
|
||||||
<value>Memory Pools.</value>
|
<value>Memory Pools.</value>
|
||||||
</brief>
|
</brief>
|
||||||
<description>
|
<description>
|
||||||
<value>This sequence tests the ChibiOS library functionalities related to memory pools.</value>
|
<value>This sequence tests the ChibiOS library functionalities related to memory pools.</value>
|
||||||
</description>
|
</description>
|
||||||
<condition>
|
<condition>
|
||||||
<value>CH_CFG_USE_MEMPOOLS</value>
|
<value>CH_CFG_USE_MEMPOOLS</value>
|
||||||
|
@ -1681,6 +1815,7 @@ test_assert(dpp == NULL, "found");]]></value>
|
||||||
</case>
|
</case>
|
||||||
</cases>
|
</cases>
|
||||||
</sequence>
|
</sequence>
|
||||||
|
|
||||||
</sequences>
|
</sequences>
|
||||||
</instance>
|
</instance>
|
||||||
</instances>
|
</instances>
|
||||||
|
|
|
@ -3,7 +3,8 @@ TESTSRC += ${CHIBIOS}/test/oslib/source/test/oslib_test_root.c \
|
||||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_001.c \
|
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_001.c \
|
||||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_002.c \
|
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_002.c \
|
||||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_003.c \
|
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_003.c \
|
||||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c
|
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c \
|
||||||
|
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_005.c
|
||||||
|
|
||||||
# Required include directories
|
# Required include directories
|
||||||
TESTINC += ${CHIBIOS}/test/oslib/source/test
|
TESTINC += ${CHIBIOS}/test/oslib/source/test
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
* - @subpage oslib_test_sequence_002
|
* - @subpage oslib_test_sequence_002
|
||||||
* - @subpage oslib_test_sequence_003
|
* - @subpage oslib_test_sequence_003
|
||||||
* - @subpage oslib_test_sequence_004
|
* - @subpage oslib_test_sequence_004
|
||||||
|
* - @subpage oslib_test_sequence_005
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -49,14 +50,17 @@ const testsequence_t * const oslib_test_suite_array[] = {
|
||||||
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||||
&oslib_test_sequence_001,
|
&oslib_test_sequence_001,
|
||||||
#endif
|
#endif
|
||||||
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
|
||||||
&oslib_test_sequence_002,
|
&oslib_test_sequence_002,
|
||||||
#endif
|
#endif
|
||||||
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||||
&oslib_test_sequence_003,
|
&oslib_test_sequence_003,
|
||||||
#endif
|
#endif
|
||||||
#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
&oslib_test_sequence_004,
|
&oslib_test_sequence_004,
|
||||||
|
#endif
|
||||||
|
#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
|
||||||
|
&oslib_test_sequence_005,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "oslib_test_sequence_002.h"
|
#include "oslib_test_sequence_002.h"
|
||||||
#include "oslib_test_sequence_003.h"
|
#include "oslib_test_sequence_003.h"
|
||||||
#include "oslib_test_sequence_004.h"
|
#include "oslib_test_sequence_004.h"
|
||||||
|
#include "oslib_test_sequence_005.h"
|
||||||
|
|
||||||
#if !defined(__DOXYGEN__)
|
#if !defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* File: @ref oslib_test_sequence_001.c
|
* File: @ref oslib_test_sequence_001.c
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This sequence tests the ChibiOS libraryfunctionalities related to
|
* This sequence tests the ChibiOS library functionalities related to
|
||||||
* mailboxes.
|
* mailboxes.
|
||||||
*
|
*
|
||||||
* <h2>Conditions</h2>
|
* <h2>Conditions</h2>
|
||||||
|
|
|
@ -21,259 +21,121 @@
|
||||||
* @file oslib_test_sequence_002.c
|
* @file oslib_test_sequence_002.c
|
||||||
* @brief Test Sequence 002 code.
|
* @brief Test Sequence 002 code.
|
||||||
*
|
*
|
||||||
* @page oslib_test_sequence_002 [2] Memory Pools
|
* @page oslib_test_sequence_002 [2] Pipes
|
||||||
*
|
*
|
||||||
* File: @ref oslib_test_sequence_002.c
|
* File: @ref oslib_test_sequence_002.c
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This sequence tests the ChibiOS library functionalities related to
|
* This sequence tests the ChibiOS library functionalities related to
|
||||||
* memory pools.
|
* pipes.
|
||||||
*
|
*
|
||||||
* <h2>Conditions</h2>
|
* <h2>Conditions</h2>
|
||||||
* This sequence is only executed if the following preprocessor condition
|
* This sequence is only executed if the following preprocessor condition
|
||||||
* evaluates to true:
|
* evaluates to true:
|
||||||
* - CH_CFG_USE_MEMPOOLS
|
* - CH_CFG_USE_PIPES
|
||||||
* .
|
* .
|
||||||
*
|
*
|
||||||
* <h2>Test Cases</h2>
|
* <h2>Test Cases</h2>
|
||||||
* - @subpage oslib_test_002_001
|
* - @subpage oslib_test_002_001
|
||||||
* - @subpage oslib_test_002_002
|
|
||||||
* - @subpage oslib_test_002_003
|
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Shared code.
|
* Shared code.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define MEMORY_POOL_SIZE 4
|
#define PIPE_SIZE 16
|
||||||
|
|
||||||
static uint32_t objects[MEMORY_POOL_SIZE];
|
static uint8_t buffer[PIPE_SIZE];
|
||||||
static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
|
static PIPE_DECL(pipe1, buffer, PIPE_SIZE);
|
||||||
|
|
||||||
#if CH_CFG_USE_SEMAPHORES
|
static const uint8_t pipe_pattern[] = "0123456789ABCDEF";
|
||||||
static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *null_provider(size_t size, unsigned align) {
|
|
||||||
|
|
||||||
(void)size;
|
|
||||||
(void)align;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Test cases.
|
* Test cases.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page oslib_test_002_001 [2.1] Loading and emptying a memory pool
|
* @page oslib_test_002_001 [2.1] Loading and emptying a pipe, non blocking
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* The memory pool functionality is tested by loading and emptying it,
|
* The pipe functionality is tested by loading and emptying it, all
|
||||||
* all conditions are tested.
|
* conditions are tested.
|
||||||
*
|
*
|
||||||
* <h2>Test Steps</h2>
|
* <h2>Test Steps</h2>
|
||||||
* - [2.1.1] Adding the objects to the pool using chPoolLoadArray().
|
* - [2.1.1] Filling whole pipe.
|
||||||
* - [2.1.2] Emptying the pool using chPoolAlloc().
|
* - [2.1.2] Emptying pipe.
|
||||||
* - [2.1.3] Now must be empty.
|
* - [2.1.3].
|
||||||
* - [2.1.4] Adding the objects to the pool using chPoolFree().
|
* - [2.1.4].
|
||||||
* - [2.1.5] Emptying the pool using chPoolAlloc() again.
|
* - [2.1.5].
|
||||||
* - [2.1.6] Now must be empty again.
|
* - [2.1.6].
|
||||||
* - [2.1.7] Covering the case where a provider is unable to return
|
|
||||||
* more memory.
|
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void oslib_test_002_001_setup(void) {
|
static void oslib_test_002_001_setup(void) {
|
||||||
chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
|
chPipeObjectInit(&pipe1, buffer, PIPE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oslib_test_002_001_execute(void) {
|
static void oslib_test_002_001_execute(void) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* [2.1.1] Adding the objects to the pool using chPoolLoadArray().*/
|
/* [2.1.1] Filling whole pipe.*/
|
||||||
test_set_step(1);
|
test_set_step(1);
|
||||||
{
|
{
|
||||||
chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
|
msg_t msg;
|
||||||
|
|
||||||
|
msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE);
|
||||||
|
test_assert(msg == PIPE_SIZE, "wrong size");
|
||||||
|
test_assert((pipe1.rdptr == pipe1.buffer) &&
|
||||||
|
(pipe1.wrptr == pipe1.buffer) &&
|
||||||
|
(pipe1.cnt == PIPE_SIZE),
|
||||||
|
"invalid pipe state");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2.1.2] Emptying the pool using chPoolAlloc().*/
|
/* [2.1.2] Emptying pipe.*/
|
||||||
test_set_step(2);
|
test_set_step(2);
|
||||||
{
|
{
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
msg_t msg;
|
||||||
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
uint8_t buf[PIPE_SIZE];
|
||||||
|
|
||||||
|
msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE);
|
||||||
|
test_assert(msg == PIPE_SIZE, "wrong size");
|
||||||
|
test_assert((pipe1.rdptr == pipe1.buffer) &&
|
||||||
|
(pipe1.wrptr == pipe1.buffer) &&
|
||||||
|
(pipe1.cnt == 0),
|
||||||
|
"invalid pipe state");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2.1.3] Now must be empty.*/
|
/* [2.1.3].*/
|
||||||
test_set_step(3);
|
test_set_step(3);
|
||||||
{
|
{
|
||||||
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2.1.4] Adding the objects to the pool using chPoolFree().*/
|
/* [2.1.4].*/
|
||||||
test_set_step(4);
|
test_set_step(4);
|
||||||
{
|
{
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
|
||||||
chPoolFree(&mp1, &objects[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2.1.5] Emptying the pool using chPoolAlloc() again.*/
|
/* [2.1.5].*/
|
||||||
test_set_step(5);
|
test_set_step(5);
|
||||||
{
|
{
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
|
||||||
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2.1.6] Now must be empty again.*/
|
/* [2.1.6].*/
|
||||||
test_set_step(6);
|
test_set_step(6);
|
||||||
{
|
{
|
||||||
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.1.7] Covering the case where a provider is unable to return
|
|
||||||
more memory.*/
|
|
||||||
test_set_step(7);
|
|
||||||
{
|
|
||||||
chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
|
|
||||||
test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const testcase_t oslib_test_002_001 = {
|
static const testcase_t oslib_test_002_001 = {
|
||||||
"Loading and emptying a memory pool",
|
"Loading and emptying a pipe, non blocking",
|
||||||
oslib_test_002_001_setup,
|
oslib_test_002_001_setup,
|
||||||
NULL,
|
NULL,
|
||||||
oslib_test_002_001_execute
|
oslib_test_002_001_execute
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_002_002 [2.2] Loading and emptying a guarded memory pool without waiting
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* The memory pool functionality is tested by loading and emptying it,
|
|
||||||
* all conditions are tested.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_USE_SEMAPHORES
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [2.2.1] Adding the objects to the pool using
|
|
||||||
* chGuardedPoolLoadArray().
|
|
||||||
* - [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
|
|
||||||
* - [2.2.3] Now must be empty.
|
|
||||||
* - [2.2.4] Adding the objects to the pool using chGuardedPoolFree().
|
|
||||||
* - [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
|
|
||||||
* - [2.2.6] Now must be empty again.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_002_002_setup(void) {
|
|
||||||
chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_002_002_execute(void) {
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
/* [2.2.1] Adding the objects to the pool using
|
|
||||||
chGuardedPoolLoadArray().*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
|
|
||||||
test_set_step(2);
|
|
||||||
{
|
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
|
||||||
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.2.3] Now must be empty.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.2.4] Adding the objects to the pool using
|
|
||||||
chGuardedPoolFree().*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
|
||||||
chGuardedPoolFree(&gmp1, &objects[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
|
|
||||||
again.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
|
||||||
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2.2.6] Now must be empty again.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_002_002 = {
|
|
||||||
"Loading and emptying a guarded memory pool without waiting",
|
|
||||||
oslib_test_002_002_setup,
|
|
||||||
NULL,
|
|
||||||
oslib_test_002_002_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_USE_SEMAPHORES */
|
|
||||||
|
|
||||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_002_003 [2.3] Guarded Memory Pools timeout
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* The timeout features for the Guarded Memory Pools is tested.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_USE_SEMAPHORES
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [2.3.1] Trying to allocate with 100mS timeout, must fail because
|
|
||||||
* the pool is empty.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_002_003_setup(void) {
|
|
||||||
chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_002_003_execute(void) {
|
|
||||||
|
|
||||||
/* [2.3.1] Trying to allocate with 100mS timeout, must fail because
|
|
||||||
the pool is empty.*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_002_003 = {
|
|
||||||
"Guarded Memory Pools timeout",
|
|
||||||
oslib_test_002_003_setup,
|
|
||||||
NULL,
|
|
||||||
oslib_test_002_003_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_USE_SEMAPHORES */
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Exported data.
|
* Exported data.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -283,21 +145,15 @@ static const testcase_t oslib_test_002_003 = {
|
||||||
*/
|
*/
|
||||||
const testcase_t * const oslib_test_sequence_002_array[] = {
|
const testcase_t * const oslib_test_sequence_002_array[] = {
|
||||||
&oslib_test_002_001,
|
&oslib_test_002_001,
|
||||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_002_002,
|
|
||||||
#endif
|
|
||||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_002_003,
|
|
||||||
#endif
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory Pools.
|
* @brief Pipes.
|
||||||
*/
|
*/
|
||||||
const testsequence_t oslib_test_sequence_002 = {
|
const testsequence_t oslib_test_sequence_002 = {
|
||||||
"Memory Pools",
|
"Pipes",
|
||||||
oslib_test_sequence_002_array
|
oslib_test_sequence_002_array
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CH_CFG_USE_MEMPOOLS */
|
#endif /* CH_CFG_USE_PIPES */
|
||||||
|
|
|
@ -21,240 +21,258 @@
|
||||||
* @file oslib_test_sequence_003.c
|
* @file oslib_test_sequence_003.c
|
||||||
* @brief Test Sequence 003 code.
|
* @brief Test Sequence 003 code.
|
||||||
*
|
*
|
||||||
* @page oslib_test_sequence_003 [3] Memory Heaps
|
* @page oslib_test_sequence_003 [3] Memory Pools
|
||||||
*
|
*
|
||||||
* File: @ref oslib_test_sequence_003.c
|
* File: @ref oslib_test_sequence_003.c
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This sequence tests the ChibiOS library functionalities related to
|
* This sequence tests the ChibiOS library functionalities related to
|
||||||
* memory heaps.
|
* memory pools.
|
||||||
*
|
*
|
||||||
* <h2>Conditions</h2>
|
* <h2>Conditions</h2>
|
||||||
* This sequence is only executed if the following preprocessor condition
|
* This sequence is only executed if the following preprocessor condition
|
||||||
* evaluates to true:
|
* evaluates to true:
|
||||||
* - CH_CFG_USE_HEAP
|
* - CH_CFG_USE_MEMPOOLS
|
||||||
* .
|
* .
|
||||||
*
|
*
|
||||||
* <h2>Test Cases</h2>
|
* <h2>Test Cases</h2>
|
||||||
* - @subpage oslib_test_003_001
|
* - @subpage oslib_test_003_001
|
||||||
* - @subpage oslib_test_003_002
|
* - @subpage oslib_test_003_002
|
||||||
|
* - @subpage oslib_test_003_003
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Shared code.
|
* Shared code.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define ALLOC_SIZE 16
|
#define MEMORY_POOL_SIZE 4
|
||||||
#define HEAP_SIZE (ALLOC_SIZE * 8)
|
|
||||||
|
|
||||||
static memory_heap_t test_heap;
|
static uint32_t objects[MEMORY_POOL_SIZE];
|
||||||
static uint8_t test_heap_buffer[HEAP_SIZE];
|
static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
|
||||||
|
|
||||||
|
#if CH_CFG_USE_SEMAPHORES
|
||||||
|
static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void *null_provider(size_t size, unsigned align) {
|
||||||
|
|
||||||
|
(void)size;
|
||||||
|
(void)align;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Test cases.
|
* Test cases.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page oslib_test_003_001 [3.1] Allocation and fragmentation
|
* @page oslib_test_003_001 [3.1] Loading and emptying a memory pool
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* Series of allocations/deallocations are performed in carefully
|
* The memory pool functionality is tested by loading and emptying it,
|
||||||
* designed sequences in order to stimulate all the possible code paths
|
* all conditions are tested.
|
||||||
* inside the allocator. The test expects to find the heap back to the
|
|
||||||
* initial status after each sequence.
|
|
||||||
*
|
*
|
||||||
* <h2>Test Steps</h2>
|
* <h2>Test Steps</h2>
|
||||||
* - [3.1.1] Testing initial conditions, the heap must not be
|
* - [3.1.1] Adding the objects to the pool using chPoolLoadArray().
|
||||||
* fragmented and one free block present.
|
* - [3.1.2] Emptying the pool using chPoolAlloc().
|
||||||
* - [3.1.2] Trying to allocate an block bigger than available space,
|
* - [3.1.3] Now must be empty.
|
||||||
* an error is expected.
|
* - [3.1.4] Adding the objects to the pool using chPoolFree().
|
||||||
* - [3.1.3] Single block allocation using chHeapAlloc() then the block
|
* - [3.1.5] Emptying the pool using chPoolAlloc() again.
|
||||||
* is freed using chHeapFree(), must not fail.
|
* - [3.1.6] Now must be empty again.
|
||||||
* - [3.1.4] Using chHeapStatus() to assess the heap state. There must
|
* - [3.1.7] Covering the case where a provider is unable to return
|
||||||
* be at least one free block of sufficient size.
|
* more memory.
|
||||||
* - [3.1.5] Allocating then freeing in the same order.
|
|
||||||
* - [3.1.6] Allocating then freeing in reverse order.
|
|
||||||
* - [3.1.7] Small fragments handling. Checking the behavior when
|
|
||||||
* allocating blocks with size not multiple of alignment unit.
|
|
||||||
* - [3.1.8] Skipping a fragment, the first fragment in the list is too
|
|
||||||
* small so the allocator must pick the second one.
|
|
||||||
* - [3.1.9] Allocating the whole available space.
|
|
||||||
* - [3.1.10] Testing final conditions. The heap geometry must be the
|
|
||||||
* same than the one registered at beginning.
|
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void oslib_test_003_001_setup(void) {
|
static void oslib_test_003_001_setup(void) {
|
||||||
chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
|
chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oslib_test_003_001_execute(void) {
|
static void oslib_test_003_001_execute(void) {
|
||||||
void *p1, *p2, *p3;
|
unsigned i;
|
||||||
size_t n, sz;
|
|
||||||
|
|
||||||
/* [3.1.1] Testing initial conditions, the heap must not be
|
/* [3.1.1] Adding the objects to the pool using chPoolLoadArray().*/
|
||||||
fragmented and one free block present.*/
|
|
||||||
test_set_step(1);
|
test_set_step(1);
|
||||||
{
|
{
|
||||||
test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
|
chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.2] Trying to allocate an block bigger than available space,
|
/* [3.1.2] Emptying the pool using chPoolAlloc().*/
|
||||||
an error is expected.*/
|
|
||||||
test_set_step(2);
|
test_set_step(2);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
test_assert(p1 == NULL, "allocation not failed");
|
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.3] Single block allocation using chHeapAlloc() then the block
|
/* [3.1.3] Now must be empty.*/
|
||||||
is freed using chHeapFree(), must not fail.*/
|
|
||||||
test_set_step(3);
|
test_set_step(3);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
||||||
test_assert(p1 != NULL, "allocation failed");
|
|
||||||
chHeapFree(p1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.4] Using chHeapStatus() to assess the heap state. There must
|
/* [3.1.4] Adding the objects to the pool using chPoolFree().*/
|
||||||
be at least one free block of sufficient size.*/
|
|
||||||
test_set_step(4);
|
test_set_step(4);
|
||||||
{
|
{
|
||||||
size_t total_size, largest_size;
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
|
chPoolFree(&mp1, &objects[i]);
|
||||||
n = chHeapStatus(&test_heap, &total_size, &largest_size);
|
|
||||||
test_assert(n == 1, "missing free block");
|
|
||||||
test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
|
|
||||||
test_assert(total_size == largest_size, "unexpected heap state");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.5] Allocating then freeing in the same order.*/
|
/* [3.1.5] Emptying the pool using chPoolAlloc() again.*/
|
||||||
test_set_step(5);
|
test_set_step(5);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
||||||
p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
chHeapFree(p1); /* Does not merge.*/
|
|
||||||
chHeapFree(p2); /* Merges backward.*/
|
|
||||||
chHeapFree(p3); /* Merges both sides.*/
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.6] Allocating then freeing in reverse order.*/
|
/* [3.1.6] Now must be empty again.*/
|
||||||
test_set_step(6);
|
test_set_step(6);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
||||||
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
chHeapFree(p3); /* Merges forward.*/
|
|
||||||
chHeapFree(p2); /* Merges forward.*/
|
|
||||||
chHeapFree(p1); /* Merges forward.*/
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.1.7] Small fragments handling. Checking the behavior when
|
/* [3.1.7] Covering the case where a provider is unable to return
|
||||||
allocating blocks with size not multiple of alignment unit.*/
|
more memory.*/
|
||||||
test_set_step(7);
|
test_set_step(7);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
|
chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
|
||||||
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
|
||||||
chHeapFree(p1);
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
|
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
/* Note, the first situation happens when the alignment size is smaller
|
|
||||||
than the header size, the second in the other cases.*/
|
|
||||||
test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
|
|
||||||
(chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
|
|
||||||
chHeapFree(p2);
|
|
||||||
chHeapFree(p1);
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3.1.8] Skipping a fragment, the first fragment in the list is too
|
|
||||||
small so the allocator must pick the second one.*/
|
|
||||||
test_set_step(8);
|
|
||||||
{
|
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
chHeapFree(p1);
|
|
||||||
test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
|
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
|
|
||||||
chHeapFree(p1);
|
|
||||||
chHeapFree(p2);
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3.1.9] Allocating the whole available space.*/
|
|
||||||
test_set_step(9);
|
|
||||||
{
|
|
||||||
(void)chHeapStatus(&test_heap, &n, NULL);
|
|
||||||
p1 = chHeapAlloc(&test_heap, n);
|
|
||||||
test_assert(p1 != NULL, "allocation failed");
|
|
||||||
test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
|
|
||||||
chHeapFree(p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3.1.10] Testing final conditions. The heap geometry must be the
|
|
||||||
same than the one registered at beginning.*/
|
|
||||||
test_set_step(10);
|
|
||||||
{
|
|
||||||
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
|
||||||
test_assert(n == sz, "size changed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const testcase_t oslib_test_003_001 = {
|
static const testcase_t oslib_test_003_001 = {
|
||||||
"Allocation and fragmentation",
|
"Loading and emptying a memory pool",
|
||||||
oslib_test_003_001_setup,
|
oslib_test_003_001_setup,
|
||||||
NULL,
|
NULL,
|
||||||
oslib_test_003_001_execute
|
oslib_test_003_001_execute
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @page oslib_test_003_002 [3.2] Default Heap
|
* @page oslib_test_003_002 [3.2] Loading and emptying a guarded memory pool without waiting
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* The default heap is pre-allocated in the system. We test base
|
* The memory pool functionality is tested by loading and emptying it,
|
||||||
* functionality.
|
* all conditions are tested.
|
||||||
|
*
|
||||||
|
* <h2>Conditions</h2>
|
||||||
|
* This test is only executed if the following preprocessor condition
|
||||||
|
* evaluates to true:
|
||||||
|
* - CH_CFG_USE_SEMAPHORES
|
||||||
|
* .
|
||||||
*
|
*
|
||||||
* <h2>Test Steps</h2>
|
* <h2>Test Steps</h2>
|
||||||
* - [3.2.1] Single block allocation using chHeapAlloc() then the block
|
* - [3.2.1] Adding the objects to the pool using
|
||||||
* is freed using chHeapFree(), must not fail.
|
* chGuardedPoolLoadArray().
|
||||||
* - [3.2.2] Testing allocation failure.
|
* - [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
|
||||||
|
* - [3.2.3] Now must be empty.
|
||||||
|
* - [3.2.4] Adding the objects to the pool using chGuardedPoolFree().
|
||||||
|
* - [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
|
||||||
|
* - [3.2.6] Now must be empty again.
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void oslib_test_003_002_execute(void) {
|
static void oslib_test_003_002_setup(void) {
|
||||||
void *p1;
|
chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
|
||||||
size_t total_size, largest_size;
|
}
|
||||||
|
|
||||||
/* [3.2.1] Single block allocation using chHeapAlloc() then the block
|
static void oslib_test_003_002_execute(void) {
|
||||||
is freed using chHeapFree(), must not fail.*/
|
unsigned i;
|
||||||
|
|
||||||
|
/* [3.2.1] Adding the objects to the pool using
|
||||||
|
chGuardedPoolLoadArray().*/
|
||||||
test_set_step(1);
|
test_set_step(1);
|
||||||
{
|
{
|
||||||
(void)chHeapStatus(NULL, &total_size, &largest_size);
|
chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
|
||||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
|
||||||
test_assert(p1 != NULL, "allocation failed");
|
|
||||||
chHeapFree(p1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3.2.2] Testing allocation failure.*/
|
/* [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
|
||||||
test_set_step(2);
|
test_set_step(2);
|
||||||
{
|
{
|
||||||
p1 = chHeapAlloc(NULL, (size_t)-256);
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
test_assert(p1 == NULL, "allocation not failed");
|
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3.2.3] Now must be empty.*/
|
||||||
|
test_set_step(3);
|
||||||
|
{
|
||||||
|
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3.2.4] Adding the objects to the pool using
|
||||||
|
chGuardedPoolFree().*/
|
||||||
|
test_set_step(4);
|
||||||
|
{
|
||||||
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
|
chGuardedPoolFree(&gmp1, &objects[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
|
||||||
|
again.*/
|
||||||
|
test_set_step(5);
|
||||||
|
{
|
||||||
|
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||||
|
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3.2.6] Now must be empty again.*/
|
||||||
|
test_set_step(6);
|
||||||
|
{
|
||||||
|
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const testcase_t oslib_test_003_002 = {
|
static const testcase_t oslib_test_003_002 = {
|
||||||
"Default Heap",
|
"Loading and emptying a guarded memory pool without waiting",
|
||||||
NULL,
|
oslib_test_003_002_setup,
|
||||||
NULL,
|
NULL,
|
||||||
oslib_test_003_002_execute
|
oslib_test_003_002_execute
|
||||||
};
|
};
|
||||||
|
#endif /* CH_CFG_USE_SEMAPHORES */
|
||||||
|
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @page oslib_test_003_003 [3.3] Guarded Memory Pools timeout
|
||||||
|
*
|
||||||
|
* <h2>Description</h2>
|
||||||
|
* The timeout features for the Guarded Memory Pools is tested.
|
||||||
|
*
|
||||||
|
* <h2>Conditions</h2>
|
||||||
|
* This test is only executed if the following preprocessor condition
|
||||||
|
* evaluates to true:
|
||||||
|
* - CH_CFG_USE_SEMAPHORES
|
||||||
|
* .
|
||||||
|
*
|
||||||
|
* <h2>Test Steps</h2>
|
||||||
|
* - [3.3.1] Trying to allocate with 100mS timeout, must fail because
|
||||||
|
* the pool is empty.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void oslib_test_003_003_setup(void) {
|
||||||
|
chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oslib_test_003_003_execute(void) {
|
||||||
|
|
||||||
|
/* [3.3.1] Trying to allocate with 100mS timeout, must fail because
|
||||||
|
the pool is empty.*/
|
||||||
|
test_set_step(1);
|
||||||
|
{
|
||||||
|
test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const testcase_t oslib_test_003_003 = {
|
||||||
|
"Guarded Memory Pools timeout",
|
||||||
|
oslib_test_003_003_setup,
|
||||||
|
NULL,
|
||||||
|
oslib_test_003_003_execute
|
||||||
|
};
|
||||||
|
#endif /* CH_CFG_USE_SEMAPHORES */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Exported data.
|
* Exported data.
|
||||||
|
@ -265,16 +283,21 @@ static const testcase_t oslib_test_003_002 = {
|
||||||
*/
|
*/
|
||||||
const testcase_t * const oslib_test_sequence_003_array[] = {
|
const testcase_t * const oslib_test_sequence_003_array[] = {
|
||||||
&oslib_test_003_001,
|
&oslib_test_003_001,
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
&oslib_test_003_002,
|
&oslib_test_003_002,
|
||||||
|
#endif
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
&oslib_test_003_003,
|
||||||
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory Heaps.
|
* @brief Memory Pools.
|
||||||
*/
|
*/
|
||||||
const testsequence_t oslib_test_sequence_003 = {
|
const testsequence_t oslib_test_sequence_003 = {
|
||||||
"Memory Heaps",
|
"Memory Pools",
|
||||||
oslib_test_sequence_003_array
|
oslib_test_sequence_003_array
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CH_CFG_USE_HEAP */
|
#endif /* CH_CFG_USE_MEMPOOLS */
|
||||||
|
|
|
@ -21,725 +21,240 @@
|
||||||
* @file oslib_test_sequence_004.c
|
* @file oslib_test_sequence_004.c
|
||||||
* @brief Test Sequence 004 code.
|
* @brief Test Sequence 004 code.
|
||||||
*
|
*
|
||||||
* @page oslib_test_sequence_004 [4] Objects Factory
|
* @page oslib_test_sequence_004 [4] Memory Heaps
|
||||||
*
|
*
|
||||||
* File: @ref oslib_test_sequence_004.c
|
* File: @ref oslib_test_sequence_004.c
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This sequence tests the ChibiOS library functionalities related to
|
* This sequence tests the ChibiOS library functionalities related to
|
||||||
* the object factory.
|
* memory heaps.
|
||||||
*
|
*
|
||||||
* <h2>Conditions</h2>
|
* <h2>Conditions</h2>
|
||||||
* This sequence is only executed if the following preprocessor condition
|
* This sequence is only executed if the following preprocessor condition
|
||||||
* evaluates to true:
|
* evaluates to true:
|
||||||
* - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)
|
* - CH_CFG_USE_HEAP
|
||||||
* .
|
* .
|
||||||
*
|
*
|
||||||
* <h2>Test Cases</h2>
|
* <h2>Test Cases</h2>
|
||||||
* - @subpage oslib_test_004_001
|
* - @subpage oslib_test_004_001
|
||||||
* - @subpage oslib_test_004_002
|
* - @subpage oslib_test_004_002
|
||||||
* - @subpage oslib_test_004_003
|
|
||||||
* - @subpage oslib_test_004_004
|
|
||||||
* - @subpage oslib_test_004_005
|
|
||||||
* - @subpage oslib_test_004_006
|
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Shared code.
|
* Shared code.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ALLOC_SIZE 16
|
||||||
|
#define HEAP_SIZE (ALLOC_SIZE * 8)
|
||||||
|
|
||||||
|
static memory_heap_t test_heap;
|
||||||
|
static uint8_t test_heap_buffer[HEAP_SIZE];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Test cases.
|
* Test cases.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @page oslib_test_004_001 [4.1] Objects Registry
|
* @page oslib_test_004_001 [4.1] Allocation and fragmentation
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This test case verifies the static objects registry.
|
* Series of allocations/deallocations are performed in carefully
|
||||||
*
|
* designed sequences in order to stimulate all the possible code paths
|
||||||
* <h2>Conditions</h2>
|
* inside the allocator. The test expects to find the heap back to the
|
||||||
* This test is only executed if the following preprocessor condition
|
* initial status after each sequence.
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
|
|
||||||
* .
|
|
||||||
*
|
*
|
||||||
* <h2>Test Steps</h2>
|
* <h2>Test Steps</h2>
|
||||||
* - [4.1.1] Retrieving a registered object by name, must not exist.
|
* - [4.1.1] Testing initial conditions, the heap must not be
|
||||||
* - [4.1.2] Registering an object, it must not exists, must succeed.
|
* fragmented and one free block present.
|
||||||
* - [4.1.3] Registering an object with the same name, must fail.
|
* - [4.1.2] Trying to allocate an block bigger than available space,
|
||||||
* - [4.1.4] Retrieving the registered object by name, must exist, then
|
* an error is expected.
|
||||||
* increasing the reference counter, finally releasing both
|
* - [4.1.3] Single block allocation using chHeapAlloc() then the block
|
||||||
* references.
|
* is freed using chHeapFree(), must not fail.
|
||||||
* - [4.1.5] Releasing the first reference to the object, must not
|
* - [4.1.4] Using chHeapStatus() to assess the heap state. There must
|
||||||
* trigger an assertion.
|
* be at least one free block of sufficient size.
|
||||||
* - [4.1.6] Retrieving the registered object by name again, must not
|
* - [4.1.5] Allocating then freeing in the same order.
|
||||||
* exist.
|
* - [4.1.6] Allocating then freeing in reverse order.
|
||||||
|
* - [4.1.7] Small fragments handling. Checking the behavior when
|
||||||
|
* allocating blocks with size not multiple of alignment unit.
|
||||||
|
* - [4.1.8] Skipping a fragment, the first fragment in the list is too
|
||||||
|
* small so the allocator must pick the second one.
|
||||||
|
* - [4.1.9] Allocating the whole available space.
|
||||||
|
* - [4.1.10] Testing final conditions. The heap geometry must be the
|
||||||
|
* same than the one registered at beginning.
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void oslib_test_004_001_teardown(void) {
|
static void oslib_test_004_001_setup(void) {
|
||||||
registered_object_t *rop;
|
chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
|
||||||
|
|
||||||
rop = chFactoryFindObject("myobj");
|
|
||||||
if (rop != NULL) {
|
|
||||||
while (rop->element.refs > 0U) {
|
|
||||||
chFactoryReleaseObject(rop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oslib_test_004_001_execute(void) {
|
static void oslib_test_004_001_execute(void) {
|
||||||
registered_object_t *rop;
|
void *p1, *p2, *p3;
|
||||||
|
size_t n, sz;
|
||||||
|
|
||||||
/* [4.1.1] Retrieving a registered object by name, must not exist.*/
|
/* [4.1.1] Testing initial conditions, the heap must not be
|
||||||
|
fragmented and one free block present.*/
|
||||||
test_set_step(1);
|
test_set_step(1);
|
||||||
{
|
{
|
||||||
rop = chFactoryFindObject("myobj");
|
test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
|
||||||
test_assert(rop == NULL, "found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.1.2] Registering an object, it must not exists, must succeed.*/
|
/* [4.1.2] Trying to allocate an block bigger than available space,
|
||||||
|
an error is expected.*/
|
||||||
test_set_step(2);
|
test_set_step(2);
|
||||||
{
|
{
|
||||||
static uint32_t myobj = 0x55aa;
|
p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
|
||||||
|
test_assert(p1 == NULL, "allocation not failed");
|
||||||
rop = chFactoryRegisterObject("myobj", (void *)&myobj);
|
|
||||||
test_assert(rop != NULL, "cannot register");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.1.3] Registering an object with the same name, must fail.*/
|
/* [4.1.3] Single block allocation using chHeapAlloc() then the block
|
||||||
|
is freed using chHeapFree(), must not fail.*/
|
||||||
test_set_step(3);
|
test_set_step(3);
|
||||||
{
|
{
|
||||||
registered_object_t *rop1;
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
static uint32_t myobj = 0x55aa;
|
test_assert(p1 != NULL, "allocation failed");
|
||||||
|
chHeapFree(p1);
|
||||||
rop1 = chFactoryRegisterObject("myobj", (void *)&myobj);
|
|
||||||
test_assert(rop1 == NULL, "can register");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.1.4] Retrieving the registered object by name, must exist, then
|
/* [4.1.4] Using chHeapStatus() to assess the heap state. There must
|
||||||
increasing the reference counter, finally releasing both
|
be at least one free block of sufficient size.*/
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
test_set_step(4);
|
||||||
{
|
{
|
||||||
registered_object_t *rop1, *rop2;
|
size_t total_size, largest_size;
|
||||||
|
|
||||||
rop1 = chFactoryFindObject("myobj");
|
n = chHeapStatus(&test_heap, &total_size, &largest_size);
|
||||||
test_assert(rop1 != NULL, "not found");
|
test_assert(n == 1, "missing free block");
|
||||||
test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch");
|
test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
|
||||||
test_assert(rop == rop1, "object reference mismatch");
|
test_assert(total_size == largest_size, "unexpected heap state");
|
||||||
test_assert(rop1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element);
|
|
||||||
test_assert(rop1 == rop2, "object reference mismatch");
|
|
||||||
test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch");
|
|
||||||
test_assert(rop2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseObject(rop2);
|
|
||||||
test_assert(rop1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseObject(rop1);
|
|
||||||
test_assert(rop->element.refs == 1, "references mismatch");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.1.5] Releasing the first reference to the object, must not
|
/* [4.1.5] Allocating then freeing in the same order.*/
|
||||||
trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
test_set_step(5);
|
||||||
{
|
{
|
||||||
chFactoryReleaseObject(rop);
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
chHeapFree(p1); /* Does not merge.*/
|
||||||
|
chHeapFree(p2); /* Merges backward.*/
|
||||||
|
chHeapFree(p3); /* Merges both sides.*/
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.1.6] Retrieving the registered object by name again, must not
|
/* [4.1.6] Allocating then freeing in reverse order.*/
|
||||||
exist.*/
|
|
||||||
test_set_step(6);
|
test_set_step(6);
|
||||||
{
|
{
|
||||||
rop = chFactoryFindObject("myobj");
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
test_assert(rop == NULL, "found");
|
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
chHeapFree(p3); /* Merges forward.*/
|
||||||
|
chHeapFree(p2); /* Merges forward.*/
|
||||||
|
chHeapFree(p1); /* Merges forward.*/
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4.1.7] Small fragments handling. Checking the behavior when
|
||||||
|
allocating blocks with size not multiple of alignment unit.*/
|
||||||
|
test_set_step(7);
|
||||||
|
{
|
||||||
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
|
||||||
|
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
chHeapFree(p1);
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
|
||||||
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
/* Note, the first situation happens when the alignment size is smaller
|
||||||
|
than the header size, the second in the other cases.*/
|
||||||
|
test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
|
||||||
|
(chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
|
||||||
|
chHeapFree(p2);
|
||||||
|
chHeapFree(p1);
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4.1.8] Skipping a fragment, the first fragment in the list is too
|
||||||
|
small so the allocator must pick the second one.*/
|
||||||
|
test_set_step(8);
|
||||||
|
{
|
||||||
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
chHeapFree(p1);
|
||||||
|
test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
|
||||||
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
|
||||||
|
chHeapFree(p1);
|
||||||
|
chHeapFree(p2);
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4.1.9] Allocating the whole available space.*/
|
||||||
|
test_set_step(9);
|
||||||
|
{
|
||||||
|
(void)chHeapStatus(&test_heap, &n, NULL);
|
||||||
|
p1 = chHeapAlloc(&test_heap, n);
|
||||||
|
test_assert(p1 != NULL, "allocation failed");
|
||||||
|
test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
|
||||||
|
chHeapFree(p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4.1.10] Testing final conditions. The heap geometry must be the
|
||||||
|
same than the one registered at beginning.*/
|
||||||
|
test_set_step(10);
|
||||||
|
{
|
||||||
|
test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
|
||||||
|
test_assert(n == sz, "size changed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_001 = {
|
static const testcase_t oslib_test_004_001 = {
|
||||||
"Objects Registry",
|
"Allocation and fragmentation",
|
||||||
|
oslib_test_004_001_setup,
|
||||||
NULL,
|
NULL,
|
||||||
oslib_test_004_001_teardown,
|
|
||||||
oslib_test_004_001_execute
|
oslib_test_004_001_execute
|
||||||
};
|
};
|
||||||
#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
|
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @page oslib_test_004_002 [4.2] Dynamic Buffers Factory
|
* @page oslib_test_004_002 [4.2] Default Heap
|
||||||
*
|
*
|
||||||
* <h2>Description</h2>
|
* <h2>Description</h2>
|
||||||
* This test case verifies the dynamic buffers factory.
|
* The default heap is pre-allocated in the system. We test base
|
||||||
*
|
* functionality.
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
|
|
||||||
* .
|
|
||||||
*
|
*
|
||||||
* <h2>Test Steps</h2>
|
* <h2>Test Steps</h2>
|
||||||
* - [4.2.1] Retrieving a dynamic buffer by name, must not exist.
|
* - [4.2.1] Single block allocation using chHeapAlloc() then the block
|
||||||
* - [4.2.2] Creating a dynamic buffer it must not exists, must
|
* is freed using chHeapFree(), must not fail.
|
||||||
* succeed.
|
* - [4.2.2] Testing allocation failure.
|
||||||
* - [4.2.3] Creating a dynamic buffer with the same name, must fail.
|
|
||||||
* - [4.2.4] Retrieving the dynamic buffer by name, must exist, then
|
|
||||||
* increasing the reference counter, finally releasing both
|
|
||||||
* references.
|
|
||||||
* - [4.2.5] Releasing the first reference to the dynamic buffer, must
|
|
||||||
* not trigger an assertion.
|
|
||||||
* - [4.2.6] Retrieving the dynamic buffer by name again, must not
|
|
||||||
* exist.
|
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void oslib_test_004_002_teardown(void) {
|
|
||||||
dyn_buffer_t *dbp;
|
|
||||||
|
|
||||||
dbp = chFactoryFindBuffer("mybuf");
|
|
||||||
if (dbp != NULL) {
|
|
||||||
while (dbp->element.refs > 0U) {
|
|
||||||
chFactoryReleaseBuffer(dbp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_004_002_execute(void) {
|
static void oslib_test_004_002_execute(void) {
|
||||||
dyn_buffer_t *dbp;
|
void *p1;
|
||||||
|
size_t total_size, largest_size;
|
||||||
|
|
||||||
/* [4.2.1] Retrieving a dynamic buffer by name, must not exist.*/
|
/* [4.2.1] Single block allocation using chHeapAlloc() then the block
|
||||||
|
is freed using chHeapFree(), must not fail.*/
|
||||||
test_set_step(1);
|
test_set_step(1);
|
||||||
{
|
{
|
||||||
dbp = chFactoryFindBuffer("mybuf");
|
(void)chHeapStatus(NULL, &total_size, &largest_size);
|
||||||
test_assert(dbp == NULL, "found");
|
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||||
|
test_assert(p1 != NULL, "allocation failed");
|
||||||
|
chHeapFree(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4.2.2] Creating a dynamic buffer it must not exists, must
|
/* [4.2.2] Testing allocation failure.*/
|
||||||
succeed.*/
|
|
||||||
test_set_step(2);
|
test_set_step(2);
|
||||||
{
|
{
|
||||||
dbp = chFactoryCreateBuffer("mybuf", 128U);
|
p1 = chHeapAlloc(NULL, (size_t)-256);
|
||||||
test_assert(dbp != NULL, "cannot create");
|
test_assert(p1 == NULL, "allocation not failed");
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.2.3] Creating a dynamic buffer with the same name, must fail.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
dyn_buffer_t *dbp1;
|
|
||||||
|
|
||||||
dbp1 = chFactoryCreateBuffer("mybuf", 128U);
|
|
||||||
test_assert(dbp1 == NULL, "can create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.2.4] Retrieving the dynamic buffer by name, must exist, then
|
|
||||||
increasing the reference counter, finally releasing both
|
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
dyn_buffer_t *dbp1, *dbp2;
|
|
||||||
|
|
||||||
dbp1 = chFactoryFindBuffer("mybuf");
|
|
||||||
test_assert(dbp1 != NULL, "not found");
|
|
||||||
test_assert(dbp == dbp1, "object reference mismatch");
|
|
||||||
test_assert(dbp1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element);
|
|
||||||
test_assert(dbp1 == dbp2, "object reference mismatch");
|
|
||||||
test_assert(dbp2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseBuffer(dbp2);
|
|
||||||
test_assert(dbp1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseBuffer(dbp1);
|
|
||||||
test_assert(dbp->element.refs == 1, "references mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.2.5] Releasing the first reference to the dynamic buffer, must
|
|
||||||
not trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
chFactoryReleaseBuffer(dbp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.2.6] Retrieving the dynamic buffer by name again, must not
|
|
||||||
exist.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
dbp = chFactoryFindBuffer("mybuf");
|
|
||||||
test_assert(dbp == NULL, "found");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_002 = {
|
static const testcase_t oslib_test_004_002 = {
|
||||||
"Dynamic Buffers Factory",
|
"Default Heap",
|
||||||
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
oslib_test_004_002_teardown,
|
|
||||||
oslib_test_004_002_execute
|
oslib_test_004_002_execute
|
||||||
};
|
};
|
||||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
|
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_004_003 [4.3] Dynamic Semaphores Factory
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* This test case verifies the dynamic semaphores factory.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_SEMAPHORES == TRUE
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [4.3.1] Retrieving a dynamic semaphore by name, must not exist.
|
|
||||||
* - [4.3.2] Creating a dynamic semaphore it must not exists, must
|
|
||||||
* succeed.
|
|
||||||
* - [4.3.3] Creating a dynamic semaphore with the same name, must
|
|
||||||
* fail.
|
|
||||||
* - [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
|
|
||||||
* increasing the reference counter, finally releasing both
|
|
||||||
* references.
|
|
||||||
* - [4.3.5] Releasing the first reference to the dynamic semaphore
|
|
||||||
* must not trigger an assertion.
|
|
||||||
* - [4.3.6] Retrieving the dynamic semaphore by name again, must not
|
|
||||||
* exist.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_004_003_teardown(void) {
|
|
||||||
dyn_semaphore_t *dsp;
|
|
||||||
|
|
||||||
dsp = chFactoryFindSemaphore("mysem");
|
|
||||||
if (dsp != NULL) {
|
|
||||||
while (dsp->element.refs > 0U) {
|
|
||||||
chFactoryReleaseSemaphore(dsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_004_003_execute(void) {
|
|
||||||
dyn_semaphore_t *dsp;
|
|
||||||
|
|
||||||
/* [4.3.1] Retrieving a dynamic semaphore by name, must not exist.*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
dsp = chFactoryFindSemaphore("mysem");
|
|
||||||
test_assert(dsp == NULL, "found");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.3.2] Creating a dynamic semaphore it must not exists, must
|
|
||||||
succeed.*/
|
|
||||||
test_set_step(2);
|
|
||||||
{
|
|
||||||
dsp = chFactoryCreateSemaphore("mysem", 0);
|
|
||||||
test_assert(dsp != NULL, "cannot create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.3.3] Creating a dynamic semaphore with the same name, must
|
|
||||||
fail.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
dyn_semaphore_t *dsp1;
|
|
||||||
|
|
||||||
dsp1 = chFactoryCreateSemaphore("mysem", 0);
|
|
||||||
test_assert(dsp1 == NULL, "can create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
|
|
||||||
increasing the reference counter, finally releasing both
|
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
dyn_semaphore_t *dsp1, *dsp2;
|
|
||||||
|
|
||||||
dsp1 = chFactoryFindSemaphore("mysem");
|
|
||||||
test_assert(dsp1 != NULL, "not found");
|
|
||||||
test_assert(dsp == dsp1, "object reference mismatch");
|
|
||||||
test_assert(dsp1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element);
|
|
||||||
test_assert(dsp1 == dsp2, "object reference mismatch");
|
|
||||||
test_assert(dsp2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseSemaphore(dsp2);
|
|
||||||
test_assert(dsp1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseSemaphore(dsp1);
|
|
||||||
test_assert(dsp->element.refs == 1, "references mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.3.5] Releasing the first reference to the dynamic semaphore
|
|
||||||
must not trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
chFactoryReleaseSemaphore(dsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.3.6] Retrieving the dynamic semaphore by name again, must not
|
|
||||||
exist.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
dsp = chFactoryFindSemaphore("mysem");
|
|
||||||
test_assert(dsp == NULL, "found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_003 = {
|
|
||||||
"Dynamic Semaphores Factory",
|
|
||||||
NULL,
|
|
||||||
oslib_test_004_003_teardown,
|
|
||||||
oslib_test_004_003_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
|
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_004_004 [4.4] Dynamic Mailboxes Factory
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* This test case verifies the dynamic mailboxes factory.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_MAILBOXES == TRUE
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [4.4.1] Retrieving a dynamic mailbox by name, must not exist.
|
|
||||||
* - [4.4.2] Creating a dynamic mailbox it must not exists, must
|
|
||||||
* succeed.
|
|
||||||
* - [4.4.3] Creating a dynamic mailbox with the same name, must fail.
|
|
||||||
* - [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
|
|
||||||
* increasing the reference counter, finally releasing both
|
|
||||||
* references.
|
|
||||||
* - [4.4.5] Releasing the first reference to the dynamic mailbox must
|
|
||||||
* not trigger an assertion.
|
|
||||||
* - [4.4.6] Retrieving the dynamic mailbox by name again, must not
|
|
||||||
* exist.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_004_004_teardown(void) {
|
|
||||||
dyn_mailbox_t *dmp;
|
|
||||||
|
|
||||||
dmp = chFactoryFindMailbox("mymbx");
|
|
||||||
if (dmp != NULL) {
|
|
||||||
while (dmp->element.refs > 0U) {
|
|
||||||
chFactoryReleaseMailbox(dmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_004_004_execute(void) {
|
|
||||||
dyn_mailbox_t *dmp;
|
|
||||||
|
|
||||||
/* [4.4.1] Retrieving a dynamic mailbox by name, must not exist.*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
dmp = chFactoryFindMailbox("mymbx");
|
|
||||||
test_assert(dmp == NULL, "found");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.4.2] Creating a dynamic mailbox it must not exists, must
|
|
||||||
succeed.*/
|
|
||||||
test_set_step(2);
|
|
||||||
{
|
|
||||||
dmp = chFactoryCreateMailbox("mymbx", 16U);
|
|
||||||
test_assert(dmp != NULL, "cannot create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.4.3] Creating a dynamic mailbox with the same name, must
|
|
||||||
fail.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
dyn_mailbox_t *dmp1;
|
|
||||||
|
|
||||||
dmp1 = chFactoryCreateMailbox("mymbx", 16U);
|
|
||||||
test_assert(dmp1 == NULL, "can create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
|
|
||||||
increasing the reference counter, finally releasing both
|
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
dyn_mailbox_t *dmp1, *dmp2;
|
|
||||||
|
|
||||||
dmp1 = chFactoryFindMailbox("mymbx");
|
|
||||||
test_assert(dmp1 != NULL, "not found");
|
|
||||||
test_assert(dmp == dmp1, "object reference mismatch");
|
|
||||||
test_assert(dmp1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element);
|
|
||||||
test_assert(dmp1 == dmp2, "object reference mismatch");
|
|
||||||
test_assert(dmp2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseMailbox(dmp2);
|
|
||||||
test_assert(dmp1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseMailbox(dmp1);
|
|
||||||
test_assert(dmp->element.refs == 1, "references mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.4.5] Releasing the first reference to the dynamic mailbox must
|
|
||||||
not trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
chFactoryReleaseMailbox(dmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.4.6] Retrieving the dynamic mailbox by name again, must not
|
|
||||||
exist.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
dmp = chFactoryFindMailbox("mymbx");
|
|
||||||
test_assert(dmp == NULL, "found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_004 = {
|
|
||||||
"Dynamic Mailboxes Factory",
|
|
||||||
NULL,
|
|
||||||
oslib_test_004_004_teardown,
|
|
||||||
oslib_test_004_004_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
|
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_004_005 [4.5] Dynamic Objects FIFOs Factory
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* This test case verifies the dynamic objects FIFOs factory.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_OBJ_FIFOS == TRUE
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [4.5.1] Retrieving a dynamic objects FIFO by name, must not exist.
|
|
||||||
* - [4.5.2] Creating a dynamic objects FIFO it must not exists, must
|
|
||||||
* succeed.
|
|
||||||
* - [4.5.3] Creating a dynamic objects FIFO with the same name, must
|
|
||||||
* fail.
|
|
||||||
* - [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
|
|
||||||
* then increasing the reference counter, finally releasing both
|
|
||||||
* references.
|
|
||||||
* - [4.5.5] Releasing the first reference to the dynamic objects FIFO
|
|
||||||
* must not trigger an assertion.
|
|
||||||
* - [4.5.6] Retrieving the dynamic objects FIFO by name again, must
|
|
||||||
* not exist.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_004_005_teardown(void) {
|
|
||||||
dyn_objects_fifo_t *dofp;
|
|
||||||
|
|
||||||
dofp = chFactoryFindObjectsFIFO("myfifo");
|
|
||||||
if (dofp != NULL) {
|
|
||||||
while (dofp->element.refs > 0U) {
|
|
||||||
chFactoryReleaseObjectsFIFO(dofp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_004_005_execute(void) {
|
|
||||||
dyn_objects_fifo_t *dofp;
|
|
||||||
|
|
||||||
/* [4.5.1] Retrieving a dynamic objects FIFO by name, must not
|
|
||||||
exist.*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
dofp = chFactoryFindObjectsFIFO("myfifo");
|
|
||||||
test_assert(dofp == NULL, "found");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.5.2] Creating a dynamic objects FIFO it must not exists, must
|
|
||||||
succeed.*/
|
|
||||||
test_set_step(2);
|
|
||||||
{
|
|
||||||
dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
|
|
||||||
test_assert(dofp != NULL, "cannot create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.5.3] Creating a dynamic objects FIFO with the same name, must
|
|
||||||
fail.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
dyn_objects_fifo_t *dofp1;
|
|
||||||
|
|
||||||
dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
|
|
||||||
test_assert(dofp1 == NULL, "can create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
|
|
||||||
then increasing the reference counter, finally releasing both
|
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
dyn_objects_fifo_t *dofp1, *dofp2;
|
|
||||||
|
|
||||||
dofp1 = chFactoryFindObjectsFIFO("myfifo");
|
|
||||||
test_assert(dofp1 != NULL, "not found");
|
|
||||||
test_assert(dofp == dofp1, "object reference mismatch");
|
|
||||||
test_assert(dofp1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element);
|
|
||||||
test_assert(dofp1 == dofp2, "object reference mismatch");
|
|
||||||
test_assert(dofp2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseObjectsFIFO(dofp2);
|
|
||||||
test_assert(dofp1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleaseObjectsFIFO(dofp1);
|
|
||||||
test_assert(dofp->element.refs == 1, "references mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.5.5] Releasing the first reference to the dynamic objects FIFO
|
|
||||||
must not trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
chFactoryReleaseObjectsFIFO(dofp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.5.6] Retrieving the dynamic objects FIFO by name again, must
|
|
||||||
not exist.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
dofp = chFactoryFindObjectsFIFO("myfifo");
|
|
||||||
test_assert(dofp == NULL, "found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_005 = {
|
|
||||||
"Dynamic Objects FIFOs Factory",
|
|
||||||
NULL,
|
|
||||||
oslib_test_004_005_teardown,
|
|
||||||
oslib_test_004_005_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
|
|
||||||
|
|
||||||
#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @page oslib_test_004_006 [4.6] Dynamic Pipes Factory
|
|
||||||
*
|
|
||||||
* <h2>Description</h2>
|
|
||||||
* This test case verifies the dynamic pipes factory.
|
|
||||||
*
|
|
||||||
* <h2>Conditions</h2>
|
|
||||||
* This test is only executed if the following preprocessor condition
|
|
||||||
* evaluates to true:
|
|
||||||
* - CH_CFG_FACTORY_PIPES == TRUE
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* <h2>Test Steps</h2>
|
|
||||||
* - [4.6.1] Retrieving a dynamic pipe by name, must not exist.
|
|
||||||
* - [4.6.2] Creating a dynamic pipe it must not exists, must succeed.
|
|
||||||
* - [4.6.3] Creating a dynamic pipe with the same name, must fail.
|
|
||||||
* - [4.6.4] Retrieving the dynamic pipe by name, must exist, then
|
|
||||||
* increasing the reference counter, finally releasing both
|
|
||||||
* references.
|
|
||||||
* - [4.6.5] Releasing the first reference to the dynamic pipe must not
|
|
||||||
* trigger an assertion.
|
|
||||||
* - [4.6.6] Retrieving the dynamic pipe by name again, must not exist.
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void oslib_test_004_006_teardown(void) {
|
|
||||||
dyn_pipe_t *dpp;
|
|
||||||
|
|
||||||
dpp = chFactoryFindPipe("mypipe");
|
|
||||||
if (dpp != NULL) {
|
|
||||||
while (dpp->element.refs > 0U) {
|
|
||||||
chFactoryReleasePipe(dpp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oslib_test_004_006_execute(void) {
|
|
||||||
dyn_pipe_t *dpp;
|
|
||||||
|
|
||||||
/* [4.6.1] Retrieving a dynamic pipe by name, must not exist.*/
|
|
||||||
test_set_step(1);
|
|
||||||
{
|
|
||||||
dpp = chFactoryFindPipe("mypipe");
|
|
||||||
test_assert(dpp == NULL, "found");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.6.2] Creating a dynamic pipe it must not exists, must
|
|
||||||
succeed.*/
|
|
||||||
test_set_step(2);
|
|
||||||
{
|
|
||||||
dpp = chFactoryCreatePipe("mypipe", 16U);
|
|
||||||
test_assert(dpp != NULL, "cannot create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.6.3] Creating a dynamic pipe with the same name, must fail.*/
|
|
||||||
test_set_step(3);
|
|
||||||
{
|
|
||||||
dyn_pipe_t *dpp1;
|
|
||||||
|
|
||||||
dpp1 = chFactoryCreatePipe("mypipe", 16U);
|
|
||||||
test_assert(dpp1 == NULL, "can create");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.6.4] Retrieving the dynamic pipe by name, must exist, then
|
|
||||||
increasing the reference counter, finally releasing both
|
|
||||||
references.*/
|
|
||||||
test_set_step(4);
|
|
||||||
{
|
|
||||||
dyn_pipe_t *dpp1, *dpp2;
|
|
||||||
|
|
||||||
dpp1 = chFactoryFindPipe("mypipe");
|
|
||||||
test_assert(dpp1 != NULL, "not found");
|
|
||||||
test_assert(dpp == dpp1, "object reference mismatch");
|
|
||||||
test_assert(dpp1->element.refs == 2, "object reference mismatch");
|
|
||||||
|
|
||||||
dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element);
|
|
||||||
test_assert(dpp1 == dpp2, "object reference mismatch");
|
|
||||||
test_assert(dpp2->element.refs == 3, "object reference mismatch");
|
|
||||||
|
|
||||||
chFactoryReleasePipe(dpp2);
|
|
||||||
test_assert(dpp1->element.refs == 2, "references mismatch");
|
|
||||||
|
|
||||||
chFactoryReleasePipe(dpp1);
|
|
||||||
test_assert(dpp->element.refs == 1, "references mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.6.5] Releasing the first reference to the dynamic pipe must not
|
|
||||||
trigger an assertion.*/
|
|
||||||
test_set_step(5);
|
|
||||||
{
|
|
||||||
chFactoryReleasePipe(dpp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [4.6.6] Retrieving the dynamic pipe by name again, must not
|
|
||||||
exist.*/
|
|
||||||
test_set_step(6);
|
|
||||||
{
|
|
||||||
dpp = chFactoryFindPipe("mypipe");
|
|
||||||
test_assert(dpp == NULL, "found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const testcase_t oslib_test_004_006 = {
|
|
||||||
"Dynamic Pipes Factory",
|
|
||||||
NULL,
|
|
||||||
oslib_test_004_006_teardown,
|
|
||||||
oslib_test_004_006_execute
|
|
||||||
};
|
|
||||||
#endif /* CH_CFG_FACTORY_PIPES == TRUE */
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Exported data.
|
* Exported data.
|
||||||
|
@ -749,33 +264,17 @@ static const testcase_t oslib_test_004_006 = {
|
||||||
* @brief Array of test cases.
|
* @brief Array of test cases.
|
||||||
*/
|
*/
|
||||||
const testcase_t * const oslib_test_sequence_004_array[] = {
|
const testcase_t * const oslib_test_sequence_004_array[] = {
|
||||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_001,
|
&oslib_test_004_001,
|
||||||
#endif
|
|
||||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_002,
|
&oslib_test_004_002,
|
||||||
#endif
|
|
||||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_003,
|
|
||||||
#endif
|
|
||||||
#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_004,
|
|
||||||
#endif
|
|
||||||
#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_005,
|
|
||||||
#endif
|
|
||||||
#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
&oslib_test_004_006,
|
|
||||||
#endif
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Objects Factory.
|
* @brief Memory Heaps.
|
||||||
*/
|
*/
|
||||||
const testsequence_t oslib_test_sequence_004 = {
|
const testsequence_t oslib_test_sequence_004 = {
|
||||||
"Objects Factory",
|
"Memory Heaps",
|
||||||
oslib_test_sequence_004_array
|
oslib_test_sequence_004_array
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */
|
#endif /* CH_CFG_USE_HEAP */
|
||||||
|
|
Loading…
Reference in New Issue