mirror of https://github.com/rusefi/ChibiOS.git
OS library test suite, not finished.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10840 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
ca77bbc7ba
commit
a202724fea
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="com.st.tools.spc5.configuration.default">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.tools.spc5.configuration.default" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="com.st.tools.spc5.configuration.default" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="com.st.tools.spc5.configuration.default." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1601604545" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1601604545.979430051" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1252703125" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder">
|
||||
<outputEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
|
||||
</outputEntries>
|
||||
</builder>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.758143064" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.466800556" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.276542087" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1590093401" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1021209563" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1880457386" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1710576459" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="OS Library Tests Generator.null.1740439042" name="OS Library Tests Generator"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="com.st.tools.spc5.configuration.default">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
</cproject>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>OS Library Tests Generator</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.st.tools.spc5.spc5StudioPatchBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>com.st.tools.spc5.spc5StudioNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SPC5StudioProject>
|
||||
<Properties />
|
||||
</SPC5StudioProject>
|
|
@ -0,0 +1,15 @@
|
|||
sourceRoot: ../../tools/ftl/processors/unittest
|
||||
outputRoot: source
|
||||
dataRoot: .
|
||||
|
||||
freemarkerLinks: {
|
||||
ftllibs: ../../tools/ftl/libs
|
||||
}
|
||||
|
||||
data : {
|
||||
conf:xml (
|
||||
configuration.xml
|
||||
{
|
||||
}
|
||||
)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,9 @@
|
|||
# List of all the ChibiOS OS Library test files.
|
||||
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_002.c \
|
||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_003.c \
|
||||
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c
|
||||
|
||||
# Required include directories
|
||||
TESTINC += ${CHIBIOS}/test/oslib/source/test
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SPC5-Patch version="1.0.0">
|
||||
<!--It is your patch repository, do not break your XML File.-->
|
||||
<files />
|
||||
</SPC5-Patch>
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage Test Suite Specification
|
||||
* Test suite for ChibiOS OS Library. The purpose of this suite is to
|
||||
* perform unit tests on the library modules and to converge to 100%
|
||||
* code coverage through successive improvements.
|
||||
*
|
||||
* <h2>Test Sequences</h2>
|
||||
* - @subpage oslib_test_sequence_001
|
||||
* - @subpage oslib_test_sequence_002
|
||||
* - @subpage oslib_test_sequence_003
|
||||
* - @subpage oslib_test_sequence_004
|
||||
* .
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_root.c
|
||||
* @brief Test Suite root structures code.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Array of test sequences.
|
||||
*/
|
||||
const testsequence_t * const oslib_test_suite_array[] = {
|
||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
&oslib_test_sequence_001,
|
||||
#endif
|
||||
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||
&oslib_test_sequence_002,
|
||||
#endif
|
||||
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||
&oslib_test_sequence_003,
|
||||
#endif
|
||||
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
||||
&oslib_test_sequence_004,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Test suite root structure.
|
||||
*/
|
||||
const testsuite_t oslib_test_suite = {
|
||||
NULL,
|
||||
oslib_test_suite_array
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Shared code. */
|
||||
/*===========================================================================*/
|
||||
|
||||
void test_print_port_info(void) {
|
||||
|
||||
#ifdef PORT_COMPILER_NAME
|
||||
test_print("*** Compiler: ");
|
||||
test_println(PORT_COMPILER_NAME);
|
||||
#endif
|
||||
test_print("*** Architecture: ");
|
||||
test_println(PORT_ARCHITECTURE_NAME);
|
||||
#ifdef PORT_CORE_VARIANT_NAME
|
||||
test_print("*** Core Variant: ");
|
||||
test_println(PORT_CORE_VARIANT_NAME);
|
||||
#endif
|
||||
#ifdef PORT_INFO
|
||||
test_print("*** Port Info: ");
|
||||
test_println(PORT_INFO);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Global test buffer holding 5 working areas.
|
||||
*/
|
||||
ALIGNED_VAR(PORT_WORKING_AREA_ALIGN) uint8_t test_buffer[WA_SIZE * 5];
|
||||
|
||||
/*
|
||||
* Pointers to the spawned threads.
|
||||
*/
|
||||
thread_t *threads[MAX_THREADS];
|
||||
|
||||
/*
|
||||
* Pointers to the working areas.
|
||||
*/
|
||||
void * ROMCONST wa[5] = {test_buffer + (WA_SIZE * 0),
|
||||
test_buffer + (WA_SIZE * 1),
|
||||
test_buffer + (WA_SIZE * 2),
|
||||
test_buffer + (WA_SIZE * 3),
|
||||
test_buffer + (WA_SIZE * 4)};
|
||||
|
||||
/*
|
||||
* Sets a termination request in all the test-spawned threads.
|
||||
*/
|
||||
void test_terminate_threads(void) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < MAX_THREADS; i++)
|
||||
if (threads[i])
|
||||
chThdTerminate(threads[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Waits for the completion of all the test-spawned threads.
|
||||
*/
|
||||
void test_wait_threads(void) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < MAX_THREADS; i++)
|
||||
if (threads[i] != NULL) {
|
||||
chThdWait(threads[i]);
|
||||
threads[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delays execution until next system time tick.
|
||||
*/
|
||||
systime_t test_wait_tick(void) {
|
||||
|
||||
chThdSleep(1);
|
||||
return chVTGetSystemTime();
|
||||
}
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_root.h
|
||||
* @brief Test Suite root structures header.
|
||||
*/
|
||||
|
||||
#ifndef OSLIB_TEST_ROOT_H
|
||||
#define OSLIB_TEST_ROOT_H
|
||||
|
||||
#include "ch_test.h"
|
||||
|
||||
#include "oslib_test_sequence_001.h"
|
||||
#include "oslib_test_sequence_002.h"
|
||||
#include "oslib_test_sequence_003.h"
|
||||
#include "oslib_test_sequence_004.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
extern const testsuite_t oslib_test_suite;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Shared definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define TEST_SUITE_NAME "ChibiOS/RT Test Suite"
|
||||
|
||||
/*
|
||||
* Allowed delay in timeout checks.
|
||||
*/
|
||||
#define ALLOWED_DELAY TIME_MS2I(2)
|
||||
|
||||
/*
|
||||
* Maximum number of test threads.
|
||||
*/
|
||||
#define MAX_THREADS 5
|
||||
|
||||
/*
|
||||
* Stack size of test threads.
|
||||
*/
|
||||
#if defined(CH_ARCHITECTURE_AVR) || defined(CH_ARCHITECTURE_MSP430)
|
||||
#define THREADS_STACK_SIZE 48
|
||||
#elif defined(CH_ARCHITECTURE_STM8)
|
||||
#define THREADS_STACK_SIZE 64
|
||||
#elif defined(CH_ARCHITECTURE_SIMIA32)
|
||||
#define THREADS_STACK_SIZE 512
|
||||
#else
|
||||
#define THREADS_STACK_SIZE 128
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Working Area size of test threads.
|
||||
*/
|
||||
#define WA_SIZE MEM_ALIGN_NEXT(THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), \
|
||||
PORT_WORKING_AREA_ALIGN)
|
||||
|
||||
#define TEST_REPORT_HOOK_HEADER test_print_port_info();
|
||||
|
||||
extern uint8_t test_buffer[WA_SIZE * 5];
|
||||
extern thread_t *threads[MAX_THREADS];
|
||||
extern void * ROMCONST wa[5];
|
||||
|
||||
void test_print_port_info(void);
|
||||
void test_terminate_threads(void);
|
||||
void test_wait_threads(void);
|
||||
systime_t test_wait_tick(void);
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
#endif /* OSLIB_TEST_ROOT_H */
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_001.c
|
||||
* @brief Test Sequence 001 code.
|
||||
*
|
||||
* @page oslib_test_sequence_001 [1] Binary Semaphores
|
||||
*
|
||||
* File: @ref oslib_test_sequence_001.c
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This sequence tests the ChibiOS library functionalities related to
|
||||
* binary semaphores.
|
||||
*
|
||||
* <h2>Conditions</h2>
|
||||
* This sequence is only executed if the following preprocessor condition
|
||||
* evaluates to true:
|
||||
* - CH_CFG_USE_SEMAPHORES
|
||||
* .
|
||||
*
|
||||
* <h2>Test Cases</h2>
|
||||
* - @subpage oslib_test_001_001
|
||||
* - @subpage oslib_test_001_002
|
||||
* - @subpage oslib_test_001_003
|
||||
* - @subpage oslib_test_001_004
|
||||
* - @subpage oslib_test_001_005
|
||||
* - @subpage oslib_test_001_006
|
||||
* .
|
||||
*/
|
||||
|
||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
|
||||
/****************************************************************************
|
||||
* Shared code.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
static semaphore_t sem1;
|
||||
|
||||
static THD_FUNCTION(thread1, p) {
|
||||
|
||||
chSemWait(&sem1);
|
||||
test_emit_token(*(char *)p);
|
||||
}
|
||||
|
||||
static THD_FUNCTION(thread2, p) {
|
||||
|
||||
(void)p;
|
||||
chThdSleepMilliseconds(50);
|
||||
chSysLock();
|
||||
chSemSignalI(&sem1); /* For coverage reasons */
|
||||
chSchRescheduleS();
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
static THD_FUNCTION(thread3, p) {
|
||||
|
||||
(void)p;
|
||||
chSemWait(&sem1);
|
||||
chSemSignal(&sem1);
|
||||
}
|
||||
|
||||
static THD_FUNCTION(thread4, p) {
|
||||
|
||||
chBSemSignal((binary_semaphore_t *)p);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Test cases.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_001 [1.1] Semaphore primitives, no state change
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* Wait, Signal and Reset primitives are tested. The testing thread
|
||||
* does not trigger a state change.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.1.1] The function chSemWait() is invoked, after return the
|
||||
* counter and the returned message are tested.
|
||||
* - [1.1.2] The function chSemSignal() is invoked, after return the
|
||||
* counter is tested.
|
||||
* - [1.1.3] The function chSemReset() is invoked, after return the
|
||||
* counter is tested.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_001_setup(void) {
|
||||
chSemObjectInit(&sem1, 1);
|
||||
}
|
||||
|
||||
static void oslib_test_001_001_teardown(void) {
|
||||
chSemReset(&sem1, 0);
|
||||
}
|
||||
|
||||
static void oslib_test_001_001_execute(void) {
|
||||
|
||||
/* [1.1.1] The function chSemWait() is invoked, after return the
|
||||
counter and the returned message are tested.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
msg_t msg;
|
||||
|
||||
msg = chSemWait(&sem1);
|
||||
test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
|
||||
test_assert(MSG_OK == msg, "wrong returned message");
|
||||
}
|
||||
|
||||
/* [1.1.2] The function chSemSignal() is invoked, after return the
|
||||
counter is tested.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chSemSignal(&sem1);
|
||||
test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value");
|
||||
}
|
||||
|
||||
/* [1.1.3] The function chSemReset() is invoked, after return the
|
||||
counter is tested.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
chSemReset(&sem1, 2);
|
||||
test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_001 = {
|
||||
"Semaphore primitives, no state change",
|
||||
oslib_test_001_001_setup,
|
||||
oslib_test_001_001_teardown,
|
||||
oslib_test_001_001_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_002 [1.2] Semaphore enqueuing test
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* Five threads with randomized priorities are enqueued to a semaphore
|
||||
* then awakened one at time. The test expects that the threads reach
|
||||
* their goal in FIFO order or priority order depending on the @p
|
||||
* CH_CFG_USE_SEMAPHORES_PRIORITY configuration setting.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.2.1] Five threads are created with mixed priority levels (not
|
||||
* increasing nor decreasing). Threads enqueue on a semaphore
|
||||
* initialized to zero.
|
||||
* - [1.2.2] The semaphore is signaled 5 times. The thread activation
|
||||
* sequence is tested.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_002_setup(void) {
|
||||
chSemObjectInit(&sem1, 0);
|
||||
}
|
||||
|
||||
static void oslib_test_001_002_execute(void) {
|
||||
|
||||
/* [1.2.1] Five threads are created with mixed priority levels (not
|
||||
increasing nor decreasing). Threads enqueue on a semaphore
|
||||
initialized to zero.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
|
||||
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
|
||||
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
|
||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
|
||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
|
||||
}
|
||||
|
||||
/* [1.2.2] The semaphore is signaled 5 times. The thread activation
|
||||
sequence is tested.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chSemSignal(&sem1);
|
||||
chSemSignal(&sem1);
|
||||
chSemSignal(&sem1);
|
||||
chSemSignal(&sem1);
|
||||
chSemSignal(&sem1);
|
||||
test_wait_threads();
|
||||
#if CH_CFG_USE_SEMAPHORES_PRIORITY
|
||||
test_assert_sequence("ADCEB", "invalid sequence");
|
||||
#else
|
||||
test_assert_sequence("ABCDE", "invalid sequence");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_002 = {
|
||||
"Semaphore enqueuing test",
|
||||
oslib_test_001_002_setup,
|
||||
NULL,
|
||||
oslib_test_001_002_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_003 [1.3] Semaphore timeout test
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The three possible semaphore waiting modes (do not wait, wait with
|
||||
* timeout, wait without timeout) are explored. The test expects that
|
||||
* the semaphore wait function returns the correct value in each of the
|
||||
* above scenario and that the semaphore structure status is correct
|
||||
* after each operation.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.3.1] Testing special case TIME_IMMEDIATE.
|
||||
* - [1.3.2] Testing non-timeout condition.
|
||||
* - [1.3.3] Testing timeout condition.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_003_setup(void) {
|
||||
chSemObjectInit(&sem1, 0);
|
||||
}
|
||||
|
||||
static void oslib_test_001_003_execute(void) {
|
||||
unsigned i;
|
||||
systime_t target_time;
|
||||
msg_t msg;
|
||||
|
||||
/* [1.3.1] Testing special case TIME_IMMEDIATE.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
|
||||
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
|
||||
test_assert(queue_isempty(&sem1.queue), "queue not empty");
|
||||
test_assert(sem1.cnt == 0, "counter not zero");
|
||||
}
|
||||
|
||||
/* [1.3.2] Testing non-timeout condition.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
||||
thread2, 0);
|
||||
msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
|
||||
test_wait_threads();
|
||||
test_assert(msg == MSG_OK, "wrong wake-up message");
|
||||
test_assert(queue_isempty(&sem1.queue), "queue not empty");
|
||||
test_assert(sem1.cnt == 0, "counter not zero");
|
||||
}
|
||||
|
||||
/* [1.3.3] Testing timeout condition.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
target_time = test_wait_tick() + TIME_MS2I(5 * 50);
|
||||
for (i = 0; i < 5; i++) {
|
||||
test_emit_token('A' + i);
|
||||
msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
|
||||
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
|
||||
test_assert(queue_isempty(&sem1.queue), "queue not empty");
|
||||
test_assert(sem1.cnt == 0, "counter not zero");
|
||||
}
|
||||
test_assert_sequence("ABCDE", "invalid sequence");
|
||||
test_assert_time_window(target_time, target_time + ALLOWED_DELAY,
|
||||
"out of time window");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_003 = {
|
||||
"Semaphore timeout test",
|
||||
oslib_test_001_003_setup,
|
||||
NULL,
|
||||
oslib_test_001_003_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_004 [1.4] Testing chSemAddCounterI() functionality
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The functon is tested by waking up a thread then the semaphore
|
||||
* counter value is tested.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.4.1] A thread is created, it goes to wait on the semaphore.
|
||||
* - [1.4.2] The semaphore counter is increased by two, it is then
|
||||
* tested to be one, the thread must have completed.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_004_setup(void) {
|
||||
chSemObjectInit(&sem1, 0);
|
||||
}
|
||||
|
||||
static void oslib_test_001_004_execute(void) {
|
||||
|
||||
/* [1.4.1] A thread is created, it goes to wait on the semaphore.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
|
||||
}
|
||||
|
||||
/* [1.4.2] The semaphore counter is increased by two, it is then
|
||||
tested to be one, the thread must have completed.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chSysLock();
|
||||
chSemAddCounterI(&sem1, 2);
|
||||
chSchRescheduleS();
|
||||
chSysUnlock();
|
||||
test_wait_threads();
|
||||
test_assert_lock(chSemGetCounterI(&sem1) == 1, "invalid counter");
|
||||
test_assert_sequence("A", "invalid sequence");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_004 = {
|
||||
"Testing chSemAddCounterI() functionality",
|
||||
oslib_test_001_004_setup,
|
||||
NULL,
|
||||
oslib_test_001_004_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_005 [1.5] Testing chSemWaitSignal() functionality
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This test case explicitly addresses the @p chSemWaitSignal()
|
||||
* function. A thread is created that performs a wait and a signal
|
||||
* operations. The tester thread is awakened from an atomic wait/signal
|
||||
* operation. The test expects that the semaphore wait function returns
|
||||
* the correct value in each of the above scenario and that the
|
||||
* semaphore structure status is correct after each operation.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.5.1] An higher priority thread is created that performs
|
||||
* non-atomical wait and signal operations on a semaphore.
|
||||
* - [1.5.2] The function chSemSignalWait() is invoked by specifying
|
||||
* the same semaphore for the wait and signal phases. The counter
|
||||
* value must be one on exit.
|
||||
* - [1.5.3] The function chSemSignalWait() is invoked again by
|
||||
* specifying the same semaphore for the wait and signal phases. The
|
||||
* counter value must be one on exit.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_005_setup(void) {
|
||||
chSemObjectInit(&sem1, 0);
|
||||
}
|
||||
|
||||
static void oslib_test_001_005_teardown(void) {
|
||||
test_wait_threads();
|
||||
}
|
||||
|
||||
static void oslib_test_001_005_execute(void) {
|
||||
|
||||
/* [1.5.1] An higher priority thread is created that performs
|
||||
non-atomical wait and signal operations on a semaphore.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
|
||||
}
|
||||
|
||||
/* [1.5.2] The function chSemSignalWait() is invoked by specifying
|
||||
the same semaphore for the wait and signal phases. The counter
|
||||
value must be one on exit.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chSemSignalWait(&sem1, &sem1);
|
||||
test_assert(queue_isempty(&sem1.queue), "queue not empty");
|
||||
test_assert(sem1.cnt == 0, "counter not zero");
|
||||
}
|
||||
|
||||
/* [1.5.3] The function chSemSignalWait() is invoked again by
|
||||
specifying the same semaphore for the wait and signal phases. The
|
||||
counter value must be one on exit.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
chSemSignalWait(&sem1, &sem1);
|
||||
test_assert(queue_isempty(&sem1.queue), "queue not empty");
|
||||
test_assert(sem1.cnt == 0, "counter not zero");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_005 = {
|
||||
"Testing chSemWaitSignal() functionality",
|
||||
oslib_test_001_005_setup,
|
||||
oslib_test_001_005_teardown,
|
||||
oslib_test_001_005_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_001_006 [1.6] Testing Binary Semaphores special case
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This test case tests the binary semaphores functionality. The test
|
||||
* both checks the binary semaphore status and the expected status of
|
||||
* the underlying counting semaphore.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [1.6.1] Creating a binary semaphore in "taken" state, the state is
|
||||
* checked.
|
||||
* - [1.6.2] Resetting the binary semaphore in "taken" state, the state
|
||||
* must not change.
|
||||
* - [1.6.3] Starting a signaler thread at a lower priority.
|
||||
* - [1.6.4] Waiting for the binary semaphore to be signaled, the
|
||||
* semaphore is expected to be taken.
|
||||
* - [1.6.5] Signaling the binary semaphore, checking the binary
|
||||
* semaphore state to be "not taken" and the underlying counter
|
||||
* semaphore counter to be one.
|
||||
* - [1.6.6] Signaling the binary semaphore again, the internal state
|
||||
* must not change from "not taken".
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_001_006_teardown(void) {
|
||||
test_wait_threads();
|
||||
}
|
||||
|
||||
static void oslib_test_001_006_execute(void) {
|
||||
binary_semaphore_t bsem;
|
||||
msg_t msg;
|
||||
|
||||
/* [1.6.1] Creating a binary semaphore in "taken" state, the state is
|
||||
checked.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
chBSemObjectInit(&bsem, true);
|
||||
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
|
||||
}
|
||||
|
||||
/* [1.6.2] Resetting the binary semaphore in "taken" state, the state
|
||||
must not change.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chBSemReset(&bsem, true);
|
||||
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
|
||||
}
|
||||
|
||||
/* [1.6.3] Starting a signaler thread at a lower priority.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE,
|
||||
chThdGetPriorityX()-1, thread4, &bsem);
|
||||
}
|
||||
|
||||
/* [1.6.4] Waiting for the binary semaphore to be signaled, the
|
||||
semaphore is expected to be taken.*/
|
||||
test_set_step(4);
|
||||
{
|
||||
msg = chBSemWait(&bsem);
|
||||
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
|
||||
test_assert(msg == MSG_OK, "unexpected message");
|
||||
}
|
||||
|
||||
/* [1.6.5] Signaling the binary semaphore, checking the binary
|
||||
semaphore state to be "not taken" and the underlying counter
|
||||
semaphore counter to be one.*/
|
||||
test_set_step(5);
|
||||
{
|
||||
chBSemSignal(&bsem);
|
||||
test_assert_lock(chBSemGetStateI(&bsem) ==false, "still taken");
|
||||
test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");
|
||||
}
|
||||
|
||||
/* [1.6.6] Signaling the binary semaphore again, the internal state
|
||||
must not change from "not taken".*/
|
||||
test_set_step(6);
|
||||
{
|
||||
chBSemSignal(&bsem);
|
||||
test_assert_lock(chBSemGetStateI(&bsem) == false, "taken");
|
||||
test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_001_006 = {
|
||||
"Testing Binary Semaphores special case",
|
||||
NULL,
|
||||
oslib_test_001_006_teardown,
|
||||
oslib_test_001_006_execute
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Exported data.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Array of test cases.
|
||||
*/
|
||||
const testcase_t * const oslib_test_sequence_001_array[] = {
|
||||
&oslib_test_001_001,
|
||||
&oslib_test_001_002,
|
||||
&oslib_test_001_003,
|
||||
&oslib_test_001_004,
|
||||
&oslib_test_001_005,
|
||||
&oslib_test_001_006,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Binary Semaphores.
|
||||
*/
|
||||
const testsequence_t oslib_test_sequence_001 = {
|
||||
NULL,
|
||||
oslib_test_sequence_001_array
|
||||
};
|
||||
|
||||
#endif /* CH_CFG_USE_SEMAPHORES */
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_001.h
|
||||
* @brief Test Sequence 001 header.
|
||||
*/
|
||||
|
||||
#ifndef OSLIB_TEST_SEQUENCE_001_H
|
||||
#define OSLIB_TEST_SEQUENCE_001_H
|
||||
|
||||
extern const testsequence_t oslib_test_sequence_001;
|
||||
|
||||
#endif /* OSLIB_TEST_SEQUENCE_001_H */
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_002.c
|
||||
* @brief Test Sequence 002 code.
|
||||
*
|
||||
* @page oslib_test_sequence_002 [2] Mailboxes
|
||||
*
|
||||
* File: @ref oslib_test_sequence_002.c
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This sequence tests the ChibiOS libraryfunctionalities related to
|
||||
* mailboxes.
|
||||
*
|
||||
* <h2>Conditions</h2>
|
||||
* This sequence is only executed if the following preprocessor condition
|
||||
* evaluates to true:
|
||||
* - CH_CFG_USE_MAILBOXES
|
||||
* .
|
||||
*
|
||||
* <h2>Test Cases</h2>
|
||||
* - @subpage oslib_test_002_001
|
||||
* - @subpage oslib_test_002_002
|
||||
* - @subpage oslib_test_002_003
|
||||
* .
|
||||
*/
|
||||
|
||||
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||
|
||||
/****************************************************************************
|
||||
* Shared code.
|
||||
****************************************************************************/
|
||||
|
||||
#define MB_SIZE 4
|
||||
|
||||
static msg_t mb_buffer[MB_SIZE];
|
||||
static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
|
||||
|
||||
/****************************************************************************
|
||||
* Test cases.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @page oslib_test_002_001 [2.1] Mailbox normal API, non-blocking tests
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The mailbox normal API is tested without triggering blocking
|
||||
* conditions.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [2.1.1] Testing the mailbox size.
|
||||
* - [2.1.2] Resetting the mailbox, conditions are checked, no errors
|
||||
* expected.
|
||||
* - [2.1.3] Testing the behavior of API when the mailbox is in reset
|
||||
* state then return in active state.
|
||||
* - [2.1.4] Filling the mailbox using chMBPostTimeout() and
|
||||
* chMBPostAheadTimeout() once, no errors expected.
|
||||
* - [2.1.5] Testing intermediate conditions. Data pointers must be
|
||||
* aligned, semaphore counters are checked.
|
||||
* - [2.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
|
||||
* expected.
|
||||
* - [2.1.7] Posting and then fetching one more message, no errors
|
||||
* expected.
|
||||
* - [2.1.8] Testing final conditions. Data pointers must be aligned to
|
||||
* buffer start, semaphore counters are checked.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_002_001_setup(void) {
|
||||
chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
|
||||
}
|
||||
|
||||
static void oslib_test_002_001_teardown(void) {
|
||||
chMBReset(&mb1);
|
||||
}
|
||||
|
||||
static void oslib_test_002_001_execute(void) {
|
||||
msg_t msg1, msg2;
|
||||
unsigned i;
|
||||
|
||||
/* [2.1.1] Testing the mailbox size.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
|
||||
}
|
||||
|
||||
/* [2.1.2] Resetting the mailbox, conditions are checked, no errors
|
||||
expected.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chMBReset(&mb1);
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
|
||||
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
|
||||
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
|
||||
}
|
||||
|
||||
/* [2.1.3] Testing the behavior of API when the mailbox is in reset
|
||||
state then return in active state.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
msg1 = chMBPostTimeout(&mb1, (msg_t)0, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_RESET, "not in reset state");
|
||||
msg1 = chMBPostAheadTimeout(&mb1, (msg_t)0, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_RESET, "not in reset state");
|
||||
msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_RESET, "not in reset state");
|
||||
chMBResumeX(&mb1);
|
||||
}
|
||||
|
||||
/* [2.1.4] Filling the mailbox using chMBPostTimeout() and
|
||||
chMBPostAheadTimeout() once, no errors expected.*/
|
||||
test_set_step(4);
|
||||
{
|
||||
for (i = 0; i < MB_SIZE - 1; i++) {
|
||||
msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
msg1 = chMBPostAheadTimeout(&mb1, 'A', TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
|
||||
/* [2.1.5] Testing intermediate conditions. Data pointers must be
|
||||
aligned, semaphore counters are checked.*/
|
||||
test_set_step(5);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
|
||||
test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
|
||||
}
|
||||
|
||||
/* [2.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
|
||||
expected.*/
|
||||
test_set_step(6);
|
||||
{
|
||||
for (i = 0; i < MB_SIZE; i++) {
|
||||
msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
test_emit_token(msg2);
|
||||
}
|
||||
test_assert_sequence("ABCD", "wrong get sequence");
|
||||
}
|
||||
|
||||
/* [2.1.7] Posting and then fetching one more message, no errors
|
||||
expected.*/
|
||||
test_set_step(7);
|
||||
{
|
||||
msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
|
||||
/* [2.1.8] Testing final conditions. Data pointers must be aligned to
|
||||
buffer start, semaphore counters are checked.*/
|
||||
test_set_step(8);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
|
||||
test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
|
||||
test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_002_001 = {
|
||||
"Mailbox normal API, non-blocking tests",
|
||||
oslib_test_002_001_setup,
|
||||
oslib_test_002_001_teardown,
|
||||
oslib_test_002_001_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_002_002 [2.2] Mailbox I-Class API, non-blocking tests
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The mailbox I-Class API is tested without triggering blocking
|
||||
* conditions.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [2.2.1] Testing the mailbox size.
|
||||
* - [2.2.2] Resetting the mailbox, conditions are checked, no errors
|
||||
* expected. The mailbox is then returned in active state.
|
||||
* - [2.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
|
||||
* once, no errors expected.
|
||||
* - [2.2.4] Testing intermediate conditions. Data pointers must be
|
||||
* aligned, semaphore counters are checked.
|
||||
* - [2.2.5] Emptying the mailbox using chMBFetchI(), no errors
|
||||
* expected.
|
||||
* - [2.2.6] Posting and then fetching one more message, no errors
|
||||
* expected.
|
||||
* - [2.2.7] Testing final conditions. Data pointers must be aligned to
|
||||
* buffer start, semaphore counters are checked.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_002_002_setup(void) {
|
||||
chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
|
||||
}
|
||||
|
||||
static void oslib_test_002_002_teardown(void) {
|
||||
chMBReset(&mb1);
|
||||
}
|
||||
|
||||
static void oslib_test_002_002_execute(void) {
|
||||
msg_t msg1, msg2;
|
||||
unsigned i;
|
||||
|
||||
/* [2.2.1] Testing the mailbox size.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
|
||||
}
|
||||
|
||||
/* [2.2.2] Resetting the mailbox, conditions are checked, no errors
|
||||
expected. The mailbox is then returned in active state.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
chSysLock();
|
||||
chMBResetI(&mb1);
|
||||
chSysUnlock();
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
|
||||
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
|
||||
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
|
||||
chMBResumeX(&mb1);
|
||||
}
|
||||
|
||||
/* [2.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
|
||||
once, no errors expected.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
for (i = 0; i < MB_SIZE - 1; i++) {
|
||||
chSysLock();
|
||||
msg1 = chMBPostI(&mb1, 'B' + i);
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
chSysLock();
|
||||
msg1 = chMBPostAheadI(&mb1, 'A');
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
|
||||
/* [2.2.4] Testing intermediate conditions. Data pointers must be
|
||||
aligned, semaphore counters are checked.*/
|
||||
test_set_step(4);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
|
||||
test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
|
||||
}
|
||||
|
||||
/* [2.2.5] Emptying the mailbox using chMBFetchI(), no errors
|
||||
expected.*/
|
||||
test_set_step(5);
|
||||
{
|
||||
for (i = 0; i < MB_SIZE; i++) {
|
||||
chSysLock();
|
||||
msg1 = chMBFetchI(&mb1, &msg2);
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
test_emit_token(msg2);
|
||||
}
|
||||
test_assert_sequence("ABCD", "wrong get sequence");
|
||||
}
|
||||
|
||||
/* [2.2.6] Posting and then fetching one more message, no errors
|
||||
expected.*/
|
||||
test_set_step(6);
|
||||
{
|
||||
msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
|
||||
/* [2.2.7] Testing final conditions. Data pointers must be aligned to
|
||||
buffer start, semaphore counters are checked.*/
|
||||
test_set_step(7);
|
||||
{
|
||||
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
|
||||
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
|
||||
test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
|
||||
test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_002_002 = {
|
||||
"Mailbox I-Class API, non-blocking tests",
|
||||
oslib_test_002_002_setup,
|
||||
oslib_test_002_002_teardown,
|
||||
oslib_test_002_002_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_002_003 [2.3] Mailbox timeouts
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The mailbox API is tested for timeouts.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [2.3.1] Filling the mailbox.
|
||||
* - [2.3.2] Testing chMBPostTimeout(), chMBPostI(),
|
||||
* chMBPostAheadTimeout() and chMBPostAheadI() timeout.
|
||||
* - [2.3.3] Resetting the mailbox. The mailbox is then returned in
|
||||
* active state.
|
||||
* - [2.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_002_003_setup(void) {
|
||||
chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
|
||||
}
|
||||
|
||||
static void oslib_test_002_003_teardown(void) {
|
||||
chMBReset(&mb1);
|
||||
}
|
||||
|
||||
static void oslib_test_002_003_execute(void) {
|
||||
msg_t msg1, msg2;
|
||||
unsigned i;
|
||||
|
||||
/* [2.3.1] Filling the mailbox.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
for (i = 0; i < MB_SIZE; i++) {
|
||||
msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
|
||||
test_assert(msg1 == MSG_OK, "wrong wake-up message");
|
||||
}
|
||||
}
|
||||
|
||||
/* [2.3.2] Testing chMBPostTimeout(), chMBPostI(),
|
||||
chMBPostAheadTimeout() and chMBPostAheadI() timeout.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
msg1 = chMBPostTimeout(&mb1, 'X', 1);
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
chSysLock();
|
||||
msg1 = chMBPostI(&mb1, 'X');
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
msg1 = chMBPostAheadTimeout(&mb1, 'X', 1);
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
chSysLock();
|
||||
msg1 = chMBPostAheadI(&mb1, 'X');
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
}
|
||||
|
||||
/* [2.3.3] Resetting the mailbox. The mailbox is then returned in
|
||||
active state.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
chMBReset(&mb1);
|
||||
chMBResumeX(&mb1);
|
||||
}
|
||||
|
||||
/* [2.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.*/
|
||||
test_set_step(4);
|
||||
{
|
||||
msg1 = chMBFetchTimeout(&mb1, &msg2, 1);
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
chSysLock();
|
||||
msg1 = chMBFetchI(&mb1, &msg2);
|
||||
chSysUnlock();
|
||||
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_002_003 = {
|
||||
"Mailbox timeouts",
|
||||
oslib_test_002_003_setup,
|
||||
oslib_test_002_003_teardown,
|
||||
oslib_test_002_003_execute
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Exported data.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Array of test cases.
|
||||
*/
|
||||
const testcase_t * const oslib_test_sequence_002_array[] = {
|
||||
&oslib_test_002_001,
|
||||
&oslib_test_002_002,
|
||||
&oslib_test_002_003,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Mailboxes.
|
||||
*/
|
||||
const testsequence_t oslib_test_sequence_002 = {
|
||||
NULL,
|
||||
oslib_test_sequence_002_array
|
||||
};
|
||||
|
||||
#endif /* CH_CFG_USE_MAILBOXES */
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_002.h
|
||||
* @brief Test Sequence 002 header.
|
||||
*/
|
||||
|
||||
#ifndef OSLIB_TEST_SEQUENCE_002_H
|
||||
#define OSLIB_TEST_SEQUENCE_002_H
|
||||
|
||||
extern const testsequence_t oslib_test_sequence_002;
|
||||
|
||||
#endif /* OSLIB_TEST_SEQUENCE_002_H */
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_003.c
|
||||
* @brief Test Sequence 003 code.
|
||||
*
|
||||
* @page oslib_test_sequence_003 [3] Memory Pools
|
||||
*
|
||||
* File: @ref oslib_test_sequence_003.c
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This sequence tests the ChibiOS library functionalities related to
|
||||
* memory pools.
|
||||
*
|
||||
* <h2>Conditions</h2>
|
||||
* This sequence is only executed if the following preprocessor condition
|
||||
* evaluates to true:
|
||||
* - CH_CFG_USE_MEMPOOLS
|
||||
* .
|
||||
*
|
||||
* <h2>Test Cases</h2>
|
||||
* - @subpage oslib_test_003_001
|
||||
* - @subpage oslib_test_003_002
|
||||
* - @subpage oslib_test_003_003
|
||||
* .
|
||||
*/
|
||||
|
||||
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||
|
||||
/****************************************************************************
|
||||
* Shared code.
|
||||
****************************************************************************/
|
||||
|
||||
#define MEMORY_POOL_SIZE 4
|
||||
|
||||
static uint32_t objects[MEMORY_POOL_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.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @page oslib_test_003_001 [3.1] Loading and emptying a memory pool
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The memory pool functionality is tested by loading and emptying it,
|
||||
* all conditions are tested.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [3.1.1] Adding the objects to the pool using chPoolLoadArray().
|
||||
* - [3.1.2] Emptying the pool using chPoolAlloc().
|
||||
* - [3.1.3] Now must be empty.
|
||||
* - [3.1.4] Adding the objects to the pool using chPoolFree().
|
||||
* - [3.1.5] Emptying the pool using chPoolAlloc() again.
|
||||
* - [3.1.6] Now must be empty again.
|
||||
* - [3.1.7] Covering the case where a provider is unable to return
|
||||
* more memory.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_003_001_setup(void) {
|
||||
chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
|
||||
}
|
||||
|
||||
static void oslib_test_003_001_execute(void) {
|
||||
unsigned i;
|
||||
|
||||
/* [3.1.1] Adding the objects to the pool using chPoolLoadArray().*/
|
||||
test_set_step(1);
|
||||
{
|
||||
chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
|
||||
}
|
||||
|
||||
/* [3.1.2] Emptying the pool using chPoolAlloc().*/
|
||||
test_set_step(2);
|
||||
{
|
||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
||||
}
|
||||
|
||||
/* [3.1.3] Now must be empty.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
||||
}
|
||||
|
||||
/* [3.1.4] Adding the objects to the pool using chPoolFree().*/
|
||||
test_set_step(4);
|
||||
{
|
||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||
chPoolFree(&mp1, &objects[i]);
|
||||
}
|
||||
|
||||
/* [3.1.5] Emptying the pool using chPoolAlloc() again.*/
|
||||
test_set_step(5);
|
||||
{
|
||||
for (i = 0; i < MEMORY_POOL_SIZE; i++)
|
||||
test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
|
||||
}
|
||||
|
||||
/* [3.1.6] Now must be empty again.*/
|
||||
test_set_step(6);
|
||||
{
|
||||
test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
|
||||
}
|
||||
|
||||
/* [3.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_003_001 = {
|
||||
"Loading and emptying a memory pool",
|
||||
oslib_test_003_001_setup,
|
||||
NULL,
|
||||
oslib_test_003_001_execute
|
||||
};
|
||||
|
||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @page oslib_test_003_002 [3.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>
|
||||
* - [3.2.1] Adding the objects to the pool using
|
||||
* chGuardedPoolLoadArray().
|
||||
* - [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_setup(void) {
|
||||
chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
|
||||
}
|
||||
|
||||
static void oslib_test_003_002_execute(void) {
|
||||
unsigned i;
|
||||
|
||||
/* [3.2.1] Adding the objects to the pool using
|
||||
chGuardedPoolLoadArray().*/
|
||||
test_set_step(1);
|
||||
{
|
||||
chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
|
||||
}
|
||||
|
||||
/* [3.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");
|
||||
}
|
||||
|
||||
/* [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 = {
|
||||
"Loading and emptying a guarded memory pool without waiting",
|
||||
oslib_test_003_002_setup,
|
||||
NULL,
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Array of test cases.
|
||||
*/
|
||||
const testcase_t * const oslib_test_sequence_003_array[] = {
|
||||
&oslib_test_003_001,
|
||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
&oslib_test_003_002,
|
||||
#endif
|
||||
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
&oslib_test_003_003,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory Pools.
|
||||
*/
|
||||
const testsequence_t oslib_test_sequence_003 = {
|
||||
NULL,
|
||||
oslib_test_sequence_003_array
|
||||
};
|
||||
|
||||
#endif /* CH_CFG_USE_MEMPOOLS */
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_003.h
|
||||
* @brief Test Sequence 003 header.
|
||||
*/
|
||||
|
||||
#ifndef OSLIB_TEST_SEQUENCE_003_H
|
||||
#define OSLIB_TEST_SEQUENCE_003_H
|
||||
|
||||
extern const testsequence_t oslib_test_sequence_003;
|
||||
|
||||
#endif /* OSLIB_TEST_SEQUENCE_003_H */
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_004.c
|
||||
* @brief Test Sequence 004 code.
|
||||
*
|
||||
* @page oslib_test_sequence_004 [4] Memory Heaps
|
||||
*
|
||||
* File: @ref oslib_test_sequence_004.c
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* This sequence tests the ChibiOS library functionalities related to
|
||||
* memory heaps.
|
||||
*
|
||||
* <h2>Conditions</h2>
|
||||
* This sequence is only executed if the following preprocessor condition
|
||||
* evaluates to true:
|
||||
* - CH_CFG_USE_HEAP
|
||||
* .
|
||||
*
|
||||
* <h2>Test Cases</h2>
|
||||
* - @subpage oslib_test_004_001
|
||||
* - @subpage oslib_test_004_002
|
||||
* .
|
||||
*/
|
||||
|
||||
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
|
||||
|
||||
/****************************************************************************
|
||||
* Shared code.
|
||||
****************************************************************************/
|
||||
|
||||
#define ALLOC_SIZE 16
|
||||
#define HEAP_SIZE (ALLOC_SIZE * 8)
|
||||
|
||||
memory_heap_t test_heap;
|
||||
|
||||
/****************************************************************************
|
||||
* Test cases.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @page oslib_test_004_001 [4.1] Allocation and fragmentation
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* Series of allocations/deallocations are performed in carefully
|
||||
* designed sequences in order to stimulate all the possible code paths
|
||||
* inside the allocator. The test expects to find the heap back to the
|
||||
* initial status after each sequence.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [4.1.1] Testing initial conditions, the heap must not be
|
||||
* fragmented and one free block present.
|
||||
* - [4.1.2] Trying to allocate an block bigger than available space,
|
||||
* an error is expected.
|
||||
* - [4.1.3] Single block allocation using chHeapAlloc() then the block
|
||||
* is freed using chHeapFree(), must not fail.
|
||||
* - [4.1.4] Using chHeapStatus() to assess the heap state. There must
|
||||
* be at least one free block of sufficient size.
|
||||
* - [4.1.5] Allocating then freeing in the same order.
|
||||
* - [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_setup(void) {
|
||||
chHeapObjectInit(&test_heap, test_buffer, sizeof(test_buffer));
|
||||
}
|
||||
|
||||
static void oslib_test_004_001_execute(void) {
|
||||
void *p1, *p2, *p3;
|
||||
size_t n, sz;
|
||||
|
||||
/* [4.1.1] Testing initial conditions, the heap must not be
|
||||
fragmented and one free block present.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
|
||||
}
|
||||
|
||||
/* [4.1.2] Trying to allocate an block bigger than available space,
|
||||
an error is expected.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
p1 = chHeapAlloc(&test_heap, sizeof test_buffer * 2);
|
||||
test_assert(p1 == NULL, "allocation not failed");
|
||||
}
|
||||
|
||||
/* [4.1.3] Single block allocation using chHeapAlloc() then the block
|
||||
is freed using chHeapFree(), must not fail.*/
|
||||
test_set_step(3);
|
||||
{
|
||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||
test_assert(p1 != NULL, "allocation failed");
|
||||
chHeapFree(p1);
|
||||
}
|
||||
|
||||
/* [4.1.4] Using chHeapStatus() to assess the heap state. There must
|
||||
be at least one free block of sufficient size.*/
|
||||
test_set_step(4);
|
||||
{
|
||||
size_t total_size, largest_size;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* [4.1.5] Allocating then freeing in the same order.*/
|
||||
test_set_step(5);
|
||||
{
|
||||
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] Allocating then freeing in reverse order.*/
|
||||
test_set_step(6);
|
||||
{
|
||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||
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 = {
|
||||
"Allocation and fragmentation",
|
||||
oslib_test_004_001_setup,
|
||||
NULL,
|
||||
oslib_test_004_001_execute
|
||||
};
|
||||
|
||||
/**
|
||||
* @page oslib_test_004_002 [4.2] Default Heap
|
||||
*
|
||||
* <h2>Description</h2>
|
||||
* The default heap is pre-allocated in the system. We test base
|
||||
* functionality.
|
||||
*
|
||||
* <h2>Test Steps</h2>
|
||||
* - [4.2.1] Single block allocation using chHeapAlloc() then the block
|
||||
* is freed using chHeapFree(), must not fail.
|
||||
* - [4.2.2] Testing allocation failure.
|
||||
* .
|
||||
*/
|
||||
|
||||
static void oslib_test_004_002_execute(void) {
|
||||
void *p1;
|
||||
size_t total_size, largest_size;
|
||||
|
||||
/* [4.2.1] Single block allocation using chHeapAlloc() then the block
|
||||
is freed using chHeapFree(), must not fail.*/
|
||||
test_set_step(1);
|
||||
{
|
||||
(void)chHeapStatus(NULL, &total_size, &largest_size);
|
||||
p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
|
||||
test_assert(p1 != NULL, "allocation failed");
|
||||
chHeapFree(p1);
|
||||
}
|
||||
|
||||
/* [4.2.2] Testing allocation failure.*/
|
||||
test_set_step(2);
|
||||
{
|
||||
p1 = chHeapAlloc(NULL, (size_t)-256);
|
||||
test_assert(p1 == NULL, "allocation not failed");
|
||||
}
|
||||
}
|
||||
|
||||
static const testcase_t oslib_test_004_002 = {
|
||||
"Default Heap",
|
||||
NULL,
|
||||
NULL,
|
||||
oslib_test_004_002_execute
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Exported data.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Array of test cases.
|
||||
*/
|
||||
const testcase_t * const oslib_test_sequence_004_array[] = {
|
||||
&oslib_test_004_001,
|
||||
&oslib_test_004_002,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory Heaps.
|
||||
*/
|
||||
const testsequence_t oslib_test_sequence_004 = {
|
||||
NULL,
|
||||
oslib_test_sequence_004_array
|
||||
};
|
||||
|
||||
#endif /* CH_CFG_USE_HEAP */
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file oslib_test_sequence_004.h
|
||||
* @brief Test Sequence 004 header.
|
||||
*/
|
||||
|
||||
#ifndef OSLIB_TEST_SEQUENCE_004_H
|
||||
#define OSLIB_TEST_SEQUENCE_004_H
|
||||
|
||||
extern const testsequence_t oslib_test_sequence_004;
|
||||
|
||||
#endif /* OSLIB_TEST_SEQUENCE_004_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
del html\*.* /Q
|
||||
Doxygen Doxyfile
|
||||
del html\*.md5
|
||||
del html\*.map
|
||||
pause
|
|
@ -0,0 +1,800 @@
|
|||
/* The standard CSS for doxygen */
|
||||
|
||||
body, table, div, p, dl {
|
||||
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* @group Heading Levels */
|
||||
|
||||
h1 {
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.multicol {
|
||||
-moz-column-gap: 1em;
|
||||
-webkit-column-gap: 1em;
|
||||
-moz-column-count: 3;
|
||||
-webkit-column-count: 3;
|
||||
}
|
||||
|
||||
p.startli, p.startdd, p.starttd {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
p.endli {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
p.enddd {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
p.endtd {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
caption {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.legend {
|
||||
font-size: 70%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3.version {
|
||||
font-size: 90%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.qindex, div.navtab{
|
||||
background-color: #EBEFF6;
|
||||
border: 1px solid #A3B4D7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
div.qindex, div.navpath {
|
||||
width: 100%;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
div.navtab {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* @group Link Styling */
|
||||
|
||||
a {
|
||||
color: #3D578C;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.contents a:visited {
|
||||
color: #4665A2;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a.qindex {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.qindexHL {
|
||||
font-weight: bold;
|
||||
background-color: #9CAFD4;
|
||||
color: #ffffff;
|
||||
border: 1px double #869DCA;
|
||||
}
|
||||
|
||||
.contents a.qindexHL:visited {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
a.el {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.elRef {
|
||||
}
|
||||
|
||||
a.code {
|
||||
color: #4665A2;
|
||||
}
|
||||
|
||||
a.codeRef {
|
||||
color: #4665A2;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
dl.el {
|
||||
margin-left: -1cm;
|
||||
}
|
||||
|
||||
.fragment {
|
||||
font-family: monospace, fixed;
|
||||
font-size: 105%;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border: 1px solid #C4CFE5;
|
||||
background-color: #FBFCFD;
|
||||
padding: 4px 6px;
|
||||
margin: 4px 8px 4px 2px;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
font-size: 9pt;
|
||||
line-height: 125%;
|
||||
}
|
||||
|
||||
div.ah {
|
||||
background-color: black;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px;
|
||||
padding: 0.2em;
|
||||
border: solid thin #333;
|
||||
border-radius: 0.5em;
|
||||
-webkit-border-radius: .5em;
|
||||
-moz-border-radius: .5em;
|
||||
box-shadow: 2px 2px 3px #999;
|
||||
-webkit-box-shadow: 2px 2px 3px #999;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
|
||||
background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
|
||||
}
|
||||
|
||||
div.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.contents {
|
||||
margin-top: 10px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
td.indexkey {
|
||||
background-color: #EBEFF6;
|
||||
font-weight: bold;
|
||||
border: 1px solid #C4CFE5;
|
||||
margin: 2px 0px 2px 0;
|
||||
padding: 2px 10px;
|
||||
}
|
||||
|
||||
td.indexvalue {
|
||||
background-color: #EBEFF6;
|
||||
border: 1px solid #C4CFE5;
|
||||
padding: 2px 10px;
|
||||
margin: 2px 0px;
|
||||
}
|
||||
|
||||
tr.memlist {
|
||||
background-color: #EEF1F7;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.formulaDsp {
|
||||
|
||||
}
|
||||
|
||||
img.formulaInl {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.center {
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div.center img {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
address.footer {
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
img.footer {
|
||||
border: 0px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* @group Code Colorization */
|
||||
|
||||
span.keyword {
|
||||
color: #008000
|
||||
}
|
||||
|
||||
span.keywordtype {
|
||||
color: #604020
|
||||
}
|
||||
|
||||
span.keywordflow {
|
||||
color: #e08000
|
||||
}
|
||||
|
||||
span.comment {
|
||||
color: #800000
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #806020
|
||||
}
|
||||
|
||||
span.stringliteral {
|
||||
color: #002080
|
||||
}
|
||||
|
||||
span.charliteral {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
span.vhdldigit {
|
||||
color: #ff00ff
|
||||
}
|
||||
|
||||
span.vhdlchar {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
span.vhdlkeyword {
|
||||
color: #700070
|
||||
}
|
||||
|
||||
span.vhdllogic {
|
||||
color: #ff0000
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/*
|
||||
.search {
|
||||
color: #003399;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
form.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
input.search {
|
||||
font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #e8eef2;
|
||||
}
|
||||
*/
|
||||
|
||||
td.tiny {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.dirtab {
|
||||
padding: 4px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #A3B4D7;
|
||||
}
|
||||
|
||||
th.dirtab {
|
||||
background: #EBEFF6;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 0px;
|
||||
border: none;
|
||||
border-top: 1px solid #4A6AAA;
|
||||
}
|
||||
|
||||
hr.footer {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
/* @group Member Descriptions */
|
||||
|
||||
table.memberdecls {
|
||||
border-spacing: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.mdescLeft, .mdescRight,
|
||||
.memItemLeft, .memItemRight,
|
||||
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
|
||||
background-color: #F9FAFC;
|
||||
border: none;
|
||||
margin: 4px;
|
||||
padding: 1px 0 0 8px;
|
||||
}
|
||||
|
||||
.mdescLeft, .mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.memItemLeft, .memItemRight, .memTemplParams {
|
||||
border-top: 1px solid #C4CFE5;
|
||||
}
|
||||
|
||||
.memItemLeft, .memTemplItemLeft {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.memTemplParams {
|
||||
color: #4665A2;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Member Details */
|
||||
|
||||
/* Styles for detailed member documentation */
|
||||
|
||||
.memtemplate {
|
||||
font-size: 80%;
|
||||
color: #4665A2;
|
||||
font-weight: normal;
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.memnav {
|
||||
background-color: #EBEFF6;
|
||||
border: 1px solid #A3B4D7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.memitem {
|
||||
padding: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
border-top: 1px solid #A8B8D9;
|
||||
border-left: 1px solid #A8B8D9;
|
||||
border-right: 1px solid #A8B8D9;
|
||||
padding: 6px 0px 6px 0px;
|
||||
color: #253555;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
|
||||
/* opera specific markup */
|
||||
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
border-top-right-radius: 8px;
|
||||
border-top-left-radius: 8px;
|
||||
/* firefox specific markup */
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
|
||||
-moz-border-radius-topright: 8px;
|
||||
-moz-border-radius-topleft: 8px;
|
||||
/* webkit specific markup */
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
-webkit-border-top-right-radius: 8px;
|
||||
-webkit-border-top-left-radius: 8px;
|
||||
background-image:url('nav_f.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color: #E2E8F2;
|
||||
|
||||
}
|
||||
|
||||
.memdoc {
|
||||
border-bottom: 1px solid #A8B8D9;
|
||||
border-left: 1px solid #A8B8D9;
|
||||
border-right: 1px solid #A8B8D9;
|
||||
padding: 2px 5px;
|
||||
background-color: #FBFCFD;
|
||||
border-top-width: 0;
|
||||
/* opera specific markup */
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
/* firefox specific markup */
|
||||
-moz-border-radius-bottomleft: 8px;
|
||||
-moz-border-radius-bottomright: 8px;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
|
||||
background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
|
||||
/* webkit specific markup */
|
||||
-webkit-border-bottom-left-radius: 8px;
|
||||
-webkit-border-bottom-right-radius: 8px;
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
|
||||
}
|
||||
|
||||
.paramkey {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.paramtype {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.paramname {
|
||||
color: #602020;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.paramname em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.params, .retval, .exception, .tparams {
|
||||
border-spacing: 6px 2px;
|
||||
}
|
||||
|
||||
.params .paramname, .retval .paramname {
|
||||
font-weight: bold;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.params .paramtype {
|
||||
font-style: italic;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.params .paramdir {
|
||||
font-family: "courier new",courier,monospace;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Directory (tree) */
|
||||
|
||||
/* for the tree view */
|
||||
|
||||
.ftvtree {
|
||||
font-family: sans-serif;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/* these are for tree view when used as main index */
|
||||
|
||||
.directory {
|
||||
font-size: 9pt;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.directory h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
/*
|
||||
The following two styles can be used to replace the root node title
|
||||
with an image of your choice. Simply uncomment the next two styles,
|
||||
specify the name of your image and be sure to set 'height' to the
|
||||
proper pixel height of your image.
|
||||
*/
|
||||
|
||||
/*
|
||||
.directory h3.swap {
|
||||
height: 61px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("yourimage.gif");
|
||||
}
|
||||
.directory h3.swap span {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
.directory > h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.directory p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.directory div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.directory img {
|
||||
vertical-align: -30%;
|
||||
}
|
||||
|
||||
/* these are for tree view when not used as main index */
|
||||
|
||||
.directory-alt {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.directory-alt h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
.directory-alt > h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.directory-alt p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.directory-alt div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.directory-alt img {
|
||||
vertical-align: -30%;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
div.dynheader {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
color: #2A3D61;
|
||||
}
|
||||
|
||||
table.doxtable {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
table.doxtable td, table.doxtable th {
|
||||
border: 1px solid #2D4068;
|
||||
padding: 3px 7px 2px;
|
||||
}
|
||||
|
||||
table.doxtable th {
|
||||
background-color: #374F7F;
|
||||
color: #FFFFFF;
|
||||
font-size: 110%;
|
||||
padding-bottom: 4px;
|
||||
padding-top: 5px;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
.tabsearch {
|
||||
top: 0px;
|
||||
left: 10px;
|
||||
height: 36px;
|
||||
background-image: url('tab_b.png');
|
||||
z-index: 101;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.navpath ul
|
||||
{
|
||||
font-size: 11px;
|
||||
background-image:url('tab_b.png');
|
||||
background-repeat:repeat-x;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
color:#8AA0CC;
|
||||
border:solid 1px #C2CDE4;
|
||||
overflow:hidden;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.navpath li
|
||||
{
|
||||
list-style-type:none;
|
||||
float:left;
|
||||
padding-left:10px;
|
||||
padding-right:15px;
|
||||
background-image:url('bc_s.png');
|
||||
background-repeat:no-repeat;
|
||||
background-position:right;
|
||||
color:#364D7C;
|
||||
}
|
||||
|
||||
.navpath li.navelem a
|
||||
{
|
||||
height:32px;
|
||||
display:block;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navpath li.navelem a:hover
|
||||
{
|
||||
color:#6884BD;
|
||||
}
|
||||
|
||||
.navpath li.footer
|
||||
{
|
||||
list-style-type:none;
|
||||
float:right;
|
||||
padding-left:10px;
|
||||
padding-right:15px;
|
||||
background-image:none;
|
||||
background-repeat:no-repeat;
|
||||
background-position:right;
|
||||
color:#364D7C;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
|
||||
div.summary
|
||||
{
|
||||
float: right;
|
||||
font-size: 8pt;
|
||||
padding-right: 5px;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.summary a
|
||||
{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.ingroups
|
||||
{
|
||||
font-size: 8pt;
|
||||
padding-left: 5px;
|
||||
width: 50%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.ingroups a
|
||||
{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.header
|
||||
{
|
||||
background-image:url('nav_h.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color: #F9FAFC;
|
||||
margin: 0px;
|
||||
border-bottom: 1px solid #C4CFE5;
|
||||
}
|
||||
|
||||
div.headertitle
|
||||
{
|
||||
padding: 5px 5px 5px 10px;
|
||||
}
|
||||
|
||||
dl
|
||||
{
|
||||
padding: 0 0 0 10px;
|
||||
}
|
||||
|
||||
dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
|
||||
{
|
||||
border-left:4px solid;
|
||||
padding: 0 0 0 6px;
|
||||
}
|
||||
|
||||
dl.note
|
||||
{
|
||||
border-color: #D0D000;
|
||||
}
|
||||
|
||||
dl.warning, dl.attention
|
||||
{
|
||||
border-color: #FF0000;
|
||||
}
|
||||
|
||||
dl.pre, dl.post, dl.invariant
|
||||
{
|
||||
border-color: #00D000;
|
||||
}
|
||||
|
||||
dl.deprecated
|
||||
{
|
||||
border-color: #505050;
|
||||
}
|
||||
|
||||
dl.todo
|
||||
{
|
||||
border-color: #00C0E0;
|
||||
}
|
||||
|
||||
dl.test
|
||||
{
|
||||
border-color: #3030E0;
|
||||
}
|
||||
|
||||
dl.bug
|
||||
{
|
||||
border-color: #C08050;
|
||||
}
|
||||
|
||||
#projectlogo
|
||||
{
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
#projectlogo img
|
||||
{
|
||||
border: 0px none;
|
||||
}
|
||||
|
||||
#projectname
|
||||
{
|
||||
font: 300% arial,sans-serif;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#projectbrief
|
||||
{
|
||||
font: 120% arial,sans-serif;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#projectnumber
|
||||
{
|
||||
font: 50% arial,sans-serif;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#titlearea
|
||||
{
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #5373B4;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated on $datetime for $projectname by <a href="http://www.doxygen.org/index.html"><img class="footer" src="$relpath$doxygen.png" alt="doxygen"/></a> $doxygenversion</small></address>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<title>$title</title>
|
||||
<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectname">ChibiOS/NIL <span id="projectnumber">$projectnumber</span></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
Loading…
Reference in New Issue