diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-10-12 10:19:44 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-10-13 09:55:54 +0200 |
commit | 6146398a1794bc2aa3f8c8e93fd9783e02c27b0b (patch) | |
tree | 77cd1e2a8cb49f39bd2b5df923c31741d69d4298 | |
parent | spec: Fix rate monotonic statistics (diff) | |
download | rtems-central-6146398a1794bc2aa3f8c8e93fd9783e02c27b0b.tar.bz2 |
spec: Specify and test timecounters
29 files changed, 1942 insertions, 158 deletions
diff --git a/spec/req/clocks.yml b/spec/req/clocks.yml new file mode 100644 index 00000000..53799319 --- /dev/null +++ b/spec/req/clocks.yml @@ -0,0 +1,14 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: root +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The system shall provide clocks. +type: requirement diff --git a/spec/rtems/clock/req/get-boot-time.yml b/spec/rtems/clock/req/get-boot-time.yml new file mode 100644 index 00000000..da47774f --- /dev/null +++ b/spec/rtems/clock/req/get-boot-time.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: interface-function + uid: ../if/get-boot-time +- role: interface-function + uid: ../if/get-boot-time-bintime +- role: interface-function + uid: ../if/get-boot-time-timeval +- role: function-implementation + uid: /score/timecounter/req/get-coarse +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directive shall return a time point during system initialization which is + used by ${/glossary/clock-realtime:/term}. +type: requirement diff --git a/spec/rtems/clock/req/get-monotonic-coarse.yml b/spec/rtems/clock/req/get-monotonic-coarse.yml new file mode 100644 index 00000000..ef3956c2 --- /dev/null +++ b/spec/rtems/clock/req/get-monotonic-coarse.yml @@ -0,0 +1,22 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: interface-function + uid: ../if/get-monotonic-coarse +- role: interface-function + uid: ../if/get-monotonic-coarse-bintime +- role: interface-function + uid: ../if/get-monotonic-coarse-timeval +- role: function-implementation + uid: /score/timecounter/req/get-coarse +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directive shall return the time elapsed since some fixed time point in + the past measured using the ${/glossary/clock-monotonic:/term} at some time + point close to the directive call. +type: requirement diff --git a/spec/rtems/clock/req/get-monotonic.yml b/spec/rtems/clock/req/get-monotonic.yml new file mode 100644 index 00000000..33a257e0 --- /dev/null +++ b/spec/rtems/clock/req/get-monotonic.yml @@ -0,0 +1,24 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: interface-function + uid: ../if/get-monotonic +- role: interface-function + uid: ../if/get-monotonic-bintime +- role: interface-function + uid: ../if/get-monotonic-sbintime +- role: interface-function + uid: ../if/get-monotonic-timeval +- role: function-implementation + uid: /score/timecounter/req/get +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directive shall return the time elapsed since some fixed time point in + the past measured using the ${/glossary/clock-monotonic:/term} at some time + point during the directive call. +type: requirement diff --git a/spec/rtems/clock/req/get-realtime-coarse.yml b/spec/rtems/clock/req/get-realtime-coarse.yml new file mode 100644 index 00000000..9d685f26 --- /dev/null +++ b/spec/rtems/clock/req/get-realtime-coarse.yml @@ -0,0 +1,23 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: interface-function + uid: ../if/get-realtime-coarse +- role: interface-function + uid: ../if/get-realtime-coarse-bintime +- role: interface-function + uid: ../if/get-realtime-coarse-timeval +- role: function-implementation + uid: /score/timecounter/req/get-coarse +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directive shall return the time elapsed since the + ${/glossary/unix-epoch:/term} measured using the + ${/glossary/clock-realtime:/term} at some time point close to the directive + call. +type: requirement diff --git a/spec/rtems/clock/req/get-realtime.yml b/spec/rtems/clock/req/get-realtime.yml new file mode 100644 index 00000000..20e2608c --- /dev/null +++ b/spec/rtems/clock/req/get-realtime.yml @@ -0,0 +1,23 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: interface-function + uid: ../if/get-realtime +- role: interface-function + uid: ../if/get-realtime-bintime +- role: interface-function + uid: ../if/get-realtime-timeval +- role: function-implementation + uid: /score/timecounter/req/get +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directive shall return the time elapsed since the + ${/glossary/unix-epoch:/term} measured using the + ${/glossary/clock-realtime:/term} at some time point during the directive + call. +type: requirement diff --git a/spec/score/timecounter/req/clock-monotonic-initial-frozen.yml b/spec/score/timecounter/req/clock-monotonic-initial-frozen.yml new file mode 100644 index 00000000..5429d222 --- /dev/null +++ b/spec/score/timecounter/req/clock-monotonic-initial-frozen.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: clock-monotonic +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + While no timecounter is installed, the ${/glossary/clock-monotonic:/term} + shall remain at the initial value. +type: requirement diff --git a/spec/score/timecounter/req/clock-monotonic-initial.yml b/spec/score/timecounter/req/clock-monotonic-initial.yml new file mode 100644 index 00000000..81321d97 --- /dev/null +++ b/spec/score/timecounter/req/clock-monotonic-initial.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: clock-monotonic +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The initial value of the ${/glossary/clock-monotonic:/term} shall be + 0000-00-00T00:00:01.000000000. +type: requirement diff --git a/spec/score/timecounter/req/clock-monotonic.yml b/spec/score/timecounter/req/clock-monotonic.yml new file mode 100644 index 00000000..12f119c7 --- /dev/null +++ b/spec/score/timecounter/req/clock-monotonic.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: group +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The timecounter component shall provide the + ${/glossary/clock-monotonic:/term}. +type: requirement diff --git a/spec/score/timecounter/req/clock-realtime-initial-frozen.yml b/spec/score/timecounter/req/clock-realtime-initial-frozen.yml new file mode 100644 index 00000000..d87265bb --- /dev/null +++ b/spec/score/timecounter/req/clock-realtime-initial-frozen.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: clock-realtime +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + While no timecounter is installed, the ${/glossary/clock-realtime:/term} + shall remain at the initial value. +type: requirement diff --git a/spec/score/timecounter/req/clock-realtime-initial.yml b/spec/score/timecounter/req/clock-realtime-initial.yml new file mode 100644 index 00000000..278fa362 --- /dev/null +++ b/spec/score/timecounter/req/clock-realtime-initial.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: clock-realtime +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The initial value of the ${/glossary/clock-realtime:/term} shall be + 1988-01-01T00:00:00.000000000. +type: requirement diff --git a/spec/score/timecounter/req/clock-realtime.yml b/spec/score/timecounter/req/clock-realtime.yml new file mode 100644 index 00000000..7c911452 --- /dev/null +++ b/spec/score/timecounter/req/clock-realtime.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: group +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The timecounter component shall provide the + ${/glossary/clock-realtime:/term}. +type: requirement diff --git a/spec/score/timecounter/req/get-coarse-no-device.yml b/spec/score/timecounter/req/get-coarse-no-device.yml new file mode 100644 index 00000000..752ee27a --- /dev/null +++ b/spec/score/timecounter/req/get-coarse-no-device.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: get-coarse +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directives to get time values in a coarse precision shall not use the + currently installed timecounter. +type: requirement diff --git a/spec/score/timecounter/req/get-coarse.yml b/spec/score/timecounter/req/get-coarse.yml new file mode 100644 index 00000000..875d4550 --- /dev/null +++ b/spec/score/timecounter/req/get-coarse.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: group +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The timecounter component shall implement directives to get time values in a + coarse precision. +type: requirement diff --git a/spec/score/timecounter/req/get-device.yml b/spec/score/timecounter/req/get-device.yml new file mode 100644 index 00000000..27219ebc --- /dev/null +++ b/spec/score/timecounter/req/get-device.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: get +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + The directives to get time values in the highest precision shall use the + currently installed timecounter to get a clock snapshot. +type: requirement diff --git a/spec/score/timecounter/req/get-large-delta.yml b/spec/score/timecounter/req/get-large-delta.yml new file mode 100644 index 00000000..1b7770b3 --- /dev/null +++ b/spec/score/timecounter/req/get-large-delta.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: get +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + While the timehand used to get the time was not updated for one second or + more, while the timecounter of the timehand did not overflow, the directives + to get time values in the highest precision shall return the correct time. +type: requirement diff --git a/spec/score/timecounter/req/get-non-blocking.yml b/spec/score/timecounter/req/get-non-blocking.yml new file mode 100644 index 00000000..c3eb2b95 --- /dev/null +++ b/spec/score/timecounter/req/get-non-blocking.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: get +- role: requirement-refinement + uid: get-coarse +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The directives to get time values shall use a sequence lock to synchronize + the reader with exactly one writer. +type: requirement diff --git a/spec/score/timecounter/req/get.yml b/spec/score/timecounter/req/get.yml new file mode 100644 index 00000000..fa8234e6 --- /dev/null +++ b/spec/score/timecounter/req/get.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: group +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The timecounter component shall implement directives to get time values in + the highest precision available to the system. +type: requirement diff --git a/spec/score/timecounter/req/group.yml b/spec/score/timecounter/req/group.yml new file mode 100644 index 00000000..7a2e0ff9 --- /dev/null +++ b/spec/score/timecounter/req/group.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +identifier: RTEMSScoreTimecounter +links: +- role: interface-ingroup + uid: ../../if/group +non-functional-type: design-group +rationale: null +references: [] +requirement-type: non-functional +text: | + The super core shall have a component containing the clock implementation. +type: requirement diff --git a/spec/score/timecounter/req/install-frequency.yml b/spec/score/timecounter/req/install-frequency.yml new file mode 100644 index 00000000..d88401f8 --- /dev/null +++ b/spec/score/timecounter/req/install-frequency.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: install +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + While the timecounter to install has a quality level equal to the quality + level of the currently installed timecounter, while the timecounter to + install has a higher frequancy greater than the frequency of the currently + installed timecounter, the timecounter to install shall be installed. +type: requirement diff --git a/spec/score/timecounter/req/install-quality.yml b/spec/score/timecounter/req/install-quality.yml new file mode 100644 index 00000000..8e83424a --- /dev/null +++ b/spec/score/timecounter/req/install-quality.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: install +functional-type: function +rationale: null +references: [] +requirement-type: functional +text: | + While the timecounter to install has a quality level greater than the quality + level of the currently installed timecounter, the timecounter to install + shall be installed. +type: requirement diff --git a/spec/score/timecounter/req/install.yml b/spec/score/timecounter/req/install.yml new file mode 100644 index 00000000..1356890e --- /dev/null +++ b/spec/score/timecounter/req/install.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: group +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The timecounter component shall implement a directive to install a + timecounter. +type: requirement diff --git a/spec/score/timecounter/unit/kern-tc.yml b/spec/score/timecounter/unit/kern-tc.yml index 3e4dcd3b..fb1cdca2 100644 --- a/spec/score/timecounter/unit/kern-tc.yml +++ b/spec/score/timecounter/unit/kern-tc.yml @@ -5,158 +5,6 @@ enabled-by: true links: [] test-actions: -#### _Timecounter_Getbintime() ################################################ - -- action-brief: | - Call function _Timecounter_Getbintime(). - action-code: | - struct bintime bt; - _Timecounter_Getbintime( &bt ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( bt.sec, TOD_SECONDS_1970_THROUGH_1988 ); - T_eq_long( bt.frac, 0 ); - links: [] - links: - - name: _Timecounter_Getbintime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Getbinuptime() ############################################## - -- action-brief: | - Call function _Timecounter_Getbinuptime(). - action-code: | - struct bintime bt; - _Timecounter_Getbinuptime( &bt ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( bt.sec, 1 ); - T_eq_long( bt.frac, 0 ); - links: [] - links: - - name: _Timecounter_Getbinuptime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Getboottime() ##############$$$############################## - -- action-brief: | - Call function _Timecounter_Getboottime(). - action-code: | - struct timeval tv; - _Timecounter_Getboottime( &tv ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( tv.tv_sec, TOD_SECONDS_1970_THROUGH_1988 - 1 ); - T_eq_long( tv.tv_usec, 0 ); - links: [] - links: - - name: _Timecounter_Getboottime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Getboottimebin() ############################################ - -- action-brief: | - Call function _Timecounter_Getboottimebin(). - action-code: | - struct bintime bt; - _Timecounter_Getboottimebin( &bt ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( bt.sec, TOD_SECONDS_1970_THROUGH_1988 - 1 ); - T_eq_long( bt.frac, 0 ); - links: [] - links: - - name: _Timecounter_Getboottimebin - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Getmicrotime() ############################################## - -- action-brief: | - Call function _Timecounter_Getmicrotime(). - action-code: | - struct timeval tv; - _Timecounter_Getmicrotime( &tv ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( tv.tv_sec, TOD_SECONDS_1970_THROUGH_1988 ); - T_eq_long( tv.tv_usec, 0 ); - links: [] - links: - - name: _Timecounter_Getmicrotime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Getmicrouptime() ############################################ - -- action-brief: | - Call function _Timecounter_Getmicrouptime(). - action-code: | - struct timeval tv; - _Timecounter_Getmicrouptime( &tv ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( tv.tv_sec, 1 ); - T_eq_long( tv.tv_usec, 0 ); - links: [] - links: - - name: _Timecounter_Getmicrouptime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Microuptime() ############################################## - -- action-brief: | - Call function _Timecounter_Microuptime(). - action-code: | - struct timeval tv; - _Timecounter_Microuptime( &tv ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( tv.tv_sec, 1 ); - /* T_eq_long( tv.tv_usec, 0 ); is increased by other sources */ - links: [] - links: - - name: _Timecounter_Microuptime - role: unit-test - uid: ../../if/domain - -#### _Timecounter_Nanotime() ################################################# - -- action-brief: | - Call function _Timecounter_Nanotime(). - action-code: | - struct timespec ts; - _Timecounter_Nanotime( &ts ); - checks: - - brief: | - Check value returned by function call. - code: | - T_eq_u64( ts.tv_sec, TOD_SECONDS_1970_THROUGH_1988 ); - /* T_eq_long( ts.tv_nsec, 0 ); is increased by other sources */ - links: [] - links: - - name: _Timecounter_Nanotime - role: unit-test - uid: ../../if/domain - #### _Timecounter_Tick_simple() ############################################### - action-brief: | @@ -178,15 +26,13 @@ test-brief: | test-context: [] test-context-support: null test-description: | - Parts of the file ``cpukit/score/src/kern_tc.c`` - are only executed by the POSIX API and certain device driver code. The - space qualified code subset does not contain those features. This test - exercises the code parts otherwise not reached in order to achieve full - code coverage. + Parts of the file ``cpukit/score/src/kern_tc.c`` are only executed by certain + device driver code. The space qualified code subset does not contain those + features. This test exercises the code parts otherwise not reached in order + to achieve full code coverage. test-header: null test-includes: - rtems/score/timecounter.h -- rtems/score/todimpl.h test-local-includes: [] test-setup: null test-stop: null diff --git a/spec/score/timecounter/val/get-smp.yml b/spec/score/timecounter/val/get-smp.yml new file mode 100644 index 00000000..d3257d7a --- /dev/null +++ b/spec/score/timecounter/val/get-smp.yml @@ -0,0 +1,161 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: [] +test-actions: +- action-brief: | + Install timecounter of different quality levels and frequencies. + action-code: | + Timecounter *tc; + rtems_id worker_id; + Per_CPU_Control *cpu_self; + + tc = &test_timecounter; + _SMP_barrier_Control_initialize( &tc->barrier ); + _SMP_barrier_State_initialize( &tc->barrier_state[ 0 ] ); + _SMP_barrier_State_initialize( &tc->barrier_state[ 1 ] ); + + worker_id = CreateTask( "WORK", PRIO_NORMAL ); + SetScheduler( worker_id, SCHEDULER_B_ID, PRIO_NORMAL ); + StartTask( worker_id, Worker, tc ); + + tc->base.tc_get_timecount = GetTimecount; + tc->base.tc_counter_mask = 0xffffffff; + tc->base.tc_frequency = 0x10000000; + tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install( &tc->base ); + + /* A */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + checks: + - brief: | + Install a timecounter with a high quality level and normal frequency. + Check that it was installed. + code: | + /* B0 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + /* B1 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + cpu_self = _Thread_Dispatch_disable(); + tc->delay = false; + rtems_timecounter_tick(); + tc->delay = true; + rtems_timecounter_tick(); + _Thread_Dispatch_enable( cpu_self ); + + /* B4 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + /* B5 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + tc->base.tc_get_timecount = GetTimecountDummy; + DeleteTask( worker_id ); + links: + - role: validation + uid: ../req/install-quality + links: [] +test-brief: | + Tests directives to get a time value. +test-context: [] +test-context-support: null +test-description: null +test-header: null +test-includes: +- rtems.h +- rtems/timecounter.h +- rtems/score/threaddispatch.h +- rtems/score/smpbarrier.h +test-local-includes: +- tx-support.h +test-setup: null +test-stop: null +test-support: | + typedef struct { + struct timecounter base; + bool delay; + uint32_t counter; + SMP_barrier_Control barrier; + SMP_barrier_State barrier_state[ 2 ]; + } Timecounter; + + static Timecounter test_timecounter; + + static uint32_t GetTimecount( struct timecounter *base ) + { + Timecounter *tc; + + tc = (Timecounter *) base; + + if ( rtems_scheduler_get_processor() == 0 ) { + if ( !tc->delay ) { + return 0; + } + + /* B2 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + /* B3 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 ); + + return 0; + } + + if ( tc->counter == 0 ) { + /* Do nothing */ + } else if ( tc->counter == 1 ) { + tc->counter = 2; + + /* B1 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + + /* B2 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + } else if ( tc->counter == 2 ) { + tc->counter = 3; + + /* B3 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + + /* B4 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + } + + return 0; + } + + static uint32_t GetTimecountDummy( struct timecounter *base ) + { + (void) base; + + return 0; + } + + static void Worker( rtems_task_argument arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + + /* A */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + + tc->counter = 1; + + /* B0 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + + rtems_clock_get_realtime_bintime( &bt ); + + /* B5 */ + _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 ); + + ReceiveAnyEvents(); + } +test-target: testsuites/validation/tc-timecounter-get-smp.c +test-teardown: null +type: test-case diff --git a/spec/score/timecounter/val/get.yml b/spec/score/timecounter/val/get.yml new file mode 100644 index 00000000..a09072f3 --- /dev/null +++ b/spec/score/timecounter/val/get.yml @@ -0,0 +1,518 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: [] +test-actions: +- action-brief: | + Install a timecounter which can be used to perform interrut tests for the + get time directives. + action-code: | + T_interrupt_test_config config = { + .prepare = InterruptPrepare, + .interrupt = Interrupt, + .max_iteration_count = 10000 + }; + Timecounter *tc; + + tc = &test_timecounter; + tc->base.tc_get_timecount = GetTimecount; + tc->base.tc_counter_mask = 0xffffffff; + tc->base.tc_frequency = rtems_counter_frequency(); + tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1; + tc->busy = T_get_one_clock_tick_busy() / 10; + rtems_clock_get_realtime_bintime( &tc->tod ); + rtems_timecounter_install( &tc->base ); + checks: + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime:/name} directive to + provoke a change in the timehand generation number. + code: | + config.action = ActionRealtime; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime-bintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionRealtimeBintime; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime-timeval:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionRealtimeTimeval; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic:/name} directive to + provoke a change in the timehand generation number. + code: | + config.action = ActionMonotonic; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-bintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionMonotonicBintime; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-sbintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionMonotonicSbintime; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-timeval:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionMonotonicTimeval; + InterruptTest( &config, tc, 1 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Prepare for the coarse get time directives. + code: | + config.interrupt = InterruptCoarse; + links: [] + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime-coarse:/name} directive to + provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseRealtime; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime-coarse-bintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseRealtimeBintime; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-realtime-coarse-timeval:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseRealtimeTimeval; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-coarse:/name} directive to + provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseMonotonic; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-coarse-bintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseMonotonicBintime; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-monotonic-coarse-timeval:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionCoarseMonotonicTimeval; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Try to interrupt the ${/rtems/clock/if/get-boot-time:/name} directive to + provoke a change in the timehand generation number. + code: | + config.action = ActionBootTime; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Try to interrupt the ${/rtems/clock/if/get-boot-time-bintime:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionBootTimeBintime; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Try to interrupt the ${/rtems/clock/if/get-boot-time-timeval:/name} + directive to provoke a change in the timehand generation number. + code: | + config.action = ActionBootTimeTimeval; + InterruptTest( &config, tc, 10 ); + links: + - role: validation + uid: ../req/get-non-blocking + - role: validation + uid: /rtems/clock/req/get-boot-time + links: [] +test-brief: | + Tests directives to get a time value. +test-context: [] +test-context-support: | +test-description: null +test-header: null +test-includes: +- rtems.h +- rtems/counter.h +- rtems/timecounter.h +- rtems/score/timecounterimpl.h +test-local-includes: +- tx-support.h +test-setup: null +test-stop: null +test-support: | + typedef enum { + STATE_EARLY, + STATE_GET_TIMECOUNT_BEFORE, + STATE_GET_TIMECOUNT_BUSY, + STATE_GET_TIMECOUNT_DONE, + STATE_GET_TIMECOUNT_AFTER + } State; + + typedef struct { + struct timecounter base; + State state; + uint_fast32_t busy; + struct bintime tod; + } Timecounter; + + static Timecounter test_timecounter; + + static uint32_t GetTimecount( struct timecounter *base ) + { + Timecounter *tc; + + tc = (Timecounter *) base; + + if ( + tc->state == STATE_GET_TIMECOUNT_BEFORE && + !rtems_interrupt_is_in_progress() + ) { + tc->state = STATE_GET_TIMECOUNT_BUSY; + T_busy( tc->busy ); + tc->state = STATE_GET_TIMECOUNT_DONE; + } + + return rtems_counter_read(); + } + + static void InterruptPrepare( void *arg ) + { + Timecounter *tc; + + tc = (Timecounter *) arg; + tc->state = STATE_EARLY; + } + + static void ActionRealtime( void *arg ) + { + Timecounter *tc; + struct timespec ts; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime( &ts ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionRealtimeBintime( void *arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime_bintime( &bt ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionRealtimeTimeval( void *arg ) + { + Timecounter *tc; + struct timeval tv; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime_timeval( &tv ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionMonotonic( void *arg ) + { + Timecounter *tc; + struct timespec ts; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic( &ts ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionMonotonicBintime( void *arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic_bintime( &bt ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionMonotonicSbintime( void *arg ) + { + Timecounter *tc; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + (void) rtems_clock_get_monotonic_sbintime(); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionMonotonicTimeval( void *arg ) + { + Timecounter *tc; + struct timeval tv; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic_timeval( &tv ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseRealtime( void *arg ) + { + Timecounter *tc; + struct timespec ts; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime_coarse( &ts ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseRealtimeBintime( void *arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime_coarse_bintime( &bt ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseRealtimeTimeval( void *arg ) + { + Timecounter *tc; + struct timeval tv; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_realtime_coarse_timeval( &tv ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseMonotonic( void *arg ) + { + Timecounter *tc; + struct timespec ts; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic_coarse( &ts ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseMonotonicBintime( void *arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic_coarse_bintime( &bt ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionCoarseMonotonicTimeval( void *arg ) + { + Timecounter *tc; + struct timeval tv; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_monotonic_coarse_timeval( &tv ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionBootTime( void *arg ) + { + Timecounter *tc; + struct timespec ts; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_boot_time( &ts ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionBootTimeBintime( void *arg ) + { + Timecounter *tc; + struct bintime bt; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_boot_time_bintime( &bt ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void ActionBootTimeTimeval( void *arg ) + { + Timecounter *tc; + struct timeval tv; + + tc = (Timecounter *) arg; + tc->state = STATE_GET_TIMECOUNT_BEFORE; + rtems_clock_get_boot_time_timeval( &tv ); + tc->state = STATE_GET_TIMECOUNT_AFTER; + } + + static void CallTimcounterWindupTwice( const Timecounter *tc ) + { + ISR_lock_Context lock_context; + + /* + * Make sure that tc_windup() was called at least twice to increment the + * generation number for * both timehands. + */ + + _Timecounter_Acquire( &lock_context ); + _Timecounter_Set_clock( &tc->tod, &lock_context ); + + _Timecounter_Acquire( &lock_context ); + _Timecounter_Set_clock( &tc->tod, &lock_context ); + } + + static T_interrupt_test_state Interrupt( void *arg ) + { + Timecounter *tc; + State state; + + tc = (Timecounter *) arg; + state = tc->state; + + if ( state == STATE_EARLY || state == STATE_GET_TIMECOUNT_BEFORE ) { + return T_INTERRUPT_TEST_EARLY; + } + + if ( state == STATE_GET_TIMECOUNT_BUSY ) { + CallTimcounterWindupTwice( tc ); + + return T_INTERRUPT_TEST_DONE; + } + + return T_INTERRUPT_TEST_LATE; + } + + static T_interrupt_test_state InterruptCoarse( void *arg ) + { + Timecounter *tc; + State state; + + tc = (Timecounter *) arg; + state = tc->state; + + if ( state == STATE_EARLY ) { + return T_INTERRUPT_TEST_EARLY; + } + + if ( state == STATE_GET_TIMECOUNT_BEFORE ) { + CallTimcounterWindupTwice( tc ); + + return T_INTERRUPT_TEST_DONE; + } + + return T_INTERRUPT_TEST_LATE; + } + + static void InterruptTest( + const T_interrupt_test_config *config, + void *arg, + uint32_t iterations + ) + { + uint32_t i; + + for ( i = 0; i < iterations; ++i ) { + T_interrupt_test_state test_state; + + test_state = T_interrupt_test( config, arg ); + T_eq_int( test_state, T_INTERRUPT_TEST_DONE ); + } + } +test-target: testsuites/validation/tc-timecounter-get.c +test-teardown: null +type: test-case diff --git a/spec/score/timecounter/val/install.yml b/spec/score/timecounter/val/install.yml new file mode 100644 index 00000000..82684e72 --- /dev/null +++ b/spec/score/timecounter/val/install.yml @@ -0,0 +1,816 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: [] +test-actions: +- action-brief: | + Call the directives to get the initial value of + ${/glossary/clock-realtime:/term} and the initial boot time. + action-code: | + struct bintime bt; + struct timespec ts; + struct timeval tv; + checks: + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in seconds and + nanoseconds format. + code: | + rtems_clock_get_realtime( &ts ); + T_eq_i64( ts.tv_sec, 567993600 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in seconds and + nanoseconds format. + code: | + rtems_clock_get_realtime( &ts ); + T_eq_i64( ts.tv_sec, 567993600 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in coarse precision + in seconds and nanoseconds format. + code: | + rtems_clock_get_realtime_coarse( &ts ); + T_eq_i64( ts.tv_sec, 567993600 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in coarse + precision in seconds and nanoseconds format. + code: | + rtems_clock_get_realtime_coarse( &ts ); + T_eq_i64( ts.tv_sec, 567993600 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in binary time + format. + code: | + rtems_clock_get_realtime_bintime( &bt ); + T_eq_i64( bt.sec, 567993600 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in binary time + format. + code: | + rtems_clock_get_realtime_bintime( &bt ); + T_eq_i64( bt.sec, 567993600 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in coarse precision + in binary time format. + code: | + rtems_clock_get_realtime_coarse_bintime( &bt ); + T_eq_i64( bt.sec, 567993600 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in coarse + precision in binary time format. + code: | + rtems_clock_get_realtime_coarse_bintime( &bt ); + T_eq_i64( bt.sec, 567993600 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in seconds and + microseconds format. + code: | + rtems_clock_get_realtime_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993600 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in seconds and + microseconds format. + code: | + rtems_clock_get_realtime_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993600 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial ${/glossary/clock-realtime:/term} in coarse precision + in seconds and microseconds format. + code: | + rtems_clock_get_realtime_coarse_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993600 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that ${/glossary/clock-realtime:/term} is frozen in coarse + precision in seconds and microseconds format. + code: | + rtems_clock_get_realtime_coarse_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993600 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial-frozen + - brief: | + Check the initial boot time in seconds and nanoseconds format. + code: | + rtems_clock_get_boot_time( &ts ); + T_eq_i64( ts.tv_sec, 567993599 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Check the initial boot time in binary time format. + code: | + rtems_clock_get_boot_time_bintime( &bt ); + T_eq_i64( bt.sec, 567993599 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Check the initial boot time in seconds and microseconds format. + code: | + rtems_clock_get_boot_time_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993599 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-realtime-initial + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-boot-time + links: [] +- action-brief: | + Call the directives to get the initial value of + ${/glossary/clock-monotonic:/term} and the initial boot time. + action-code: | + struct bintime bt; + sbintime_t sb; + struct timespec ts; + struct timeval tv; + checks: + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in seconds and + nanoseconds format. + code: | + rtems_clock_get_monotonic( &ts ); + T_eq_i64( ts.tv_sec, 1 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in seconds and + nanoseconds format. + code: | + rtems_clock_get_monotonic( &ts ); + T_eq_i64( ts.tv_sec, 1 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in coarse precision + in seconds and nanoseconds format. + code: | + rtems_clock_get_monotonic_coarse( &ts ); + T_eq_i64( ts.tv_sec, 1 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in coarse + precision in seconds and nanoseconds format. + code: | + rtems_clock_get_monotonic_coarse( &ts ); + T_eq_i64( ts.tv_sec, 1 ); + T_eq_u64( ts.tv_nsec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in binary time + format. + code: | + rtems_clock_get_monotonic_bintime( &bt ); + T_eq_i64( bt.sec, 1 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in binary time + format. + code: | + rtems_clock_get_monotonic_bintime( &bt ); + T_eq_i64( bt.sec, 1 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in coarse precision + in binary time format. + code: | + rtems_clock_get_monotonic_coarse_bintime( &bt ); + T_eq_i64( bt.sec, 1 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in coarse + precision in binary time format. + code: | + rtems_clock_get_monotonic_coarse_bintime( &bt ); + T_eq_i64( bt.sec, 1 ); + T_eq_u64( bt.frac, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in signed binary + time format. + code: | + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_i64( sb, SBT_1S ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in signed binary + time format. + code: | + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_i64( sb, SBT_1S ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in seconds and + microseconds format. + code: | + rtems_clock_get_monotonic_timeval( &tv ); + T_eq_i64( tv.tv_sec, 1 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in seconds and + microseconds format. + code: | + rtems_clock_get_monotonic_timeval( &tv ); + T_eq_i64( tv.tv_sec, 1 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + - brief: | + Check the initial ${/glossary/clock-monotonic:/term} in coarse precision + in seconds and microseconds format. + code: | + rtems_clock_get_monotonic_coarse_timeval( &tv ); + T_eq_i64( tv.tv_sec, 1 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that ${/glossary/clock-monotonic:/term} is frozen in coarse + precision in seconds and microseconds format. + code: | + rtems_clock_get_monotonic_coarse_timeval( &tv ); + T_eq_i64( tv.tv_sec, 1 ); + T_eq_long( tv.tv_usec, 0 ); + links: + - role: validation + uid: ../req/clock-monotonic-initial-frozen + links: [] +- action-brief: | + Install timecounter of different quality levels and frequencies. + action-code: | + Timecounter *hqlf; + Timecounter *hqnf; + Timecounter *hqhf; + Timecounter *lq; + sbintime_t sb; + + hqlf = &high_quality_low_frequency; + hqnf = &high_quality_normal_frequency; + hqhf = &high_quality_high_frequency; + lq = &low_quality; + checks: + - brief: | + Install a timecounter with a high quality level and normal frequency. + Check that it was installed. + code: | + hqnf->base.tc_get_timecount = GetTimecount; + hqnf->base.tc_counter_mask = 0xffffffff; + hqnf->base.tc_frequency = 0x20000000; + hqnf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1; + rtems_timecounter_install( &hqnf->base ); + + T_eq_u32( GetCounter( hqnf ), 1 ); + + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_u32( GetCounter( hqnf ), 2 ); + T_eq_i64( sb, SBT_1S + 8 ); + links: + - role: validation + uid: ../req/install-quality + - brief: | + Install a timecounter with a high quality level and low frequency. + Check that it was not installed. + code: | + hqlf->base.tc_get_timecount = GetTimecount; + hqlf->base.tc_counter_mask = 0xffffffff; + hqlf->base.tc_frequency = 0x10000000; + hqlf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1; + rtems_timecounter_install( &hqlf->base ); + + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 2 ); + + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 3 ); + T_eq_i64( sb, SBT_1S + 16 ); + links: + - role: validation + uid: ../req/install-frequency + - brief: | + Install a timecounter with a high quality level and high frequency. + Check that it was installed. + code: | + hqhf->base.tc_get_timecount = GetTimecount; + hqhf->base.tc_counter_mask = 0xffffffff; + hqhf->base.tc_frequency = 0x40000000; + hqhf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1; + rtems_timecounter_install( &hqhf->base ); + + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 4 ); + T_eq_u32( GetCounter( hqhf ), 1 ); + + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 4 ); + T_eq_u32( GetCounter( hqhf ), 2 ); + T_eq_i64( sb, SBT_1S + 28 ); + links: + - role: validation + uid: ../req/install-frequency + - brief: | + Install a timecounter with a low quality level. Check that it was not + installed. + code: | + lq->base.tc_get_timecount = GetTimecount; + lq->base.tc_counter_mask = 0xffffffff; + lq->base.tc_frequency = 0x80000000; + lq->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install( &lq->base ); + + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 4 ); + T_eq_u32( GetCounter( hqhf ), 2 ); + T_eq_u32( GetCounter( lq ), 0 ); + + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_u32( GetCounter( hqlf ), 0 ); + T_eq_u32( GetCounter( hqnf ), 4 ); + T_eq_u32( GetCounter( hqhf ), 3 ); + T_eq_u32( GetCounter( lq ), 0 ); + T_eq_i64( sb, SBT_1S + 32 ); + links: + - role: validation + uid: ../req/install-quality + links: [] +- action-brief: | + Call the directives to get the time in the highest precision available to + the system. + action-code: | + Timecounter *tc; + uint32_t counter; + struct bintime bt; + struct timespec ts; + struct timeval tv; + + tc = &high_quality_high_frequency; + counter = GetCounter( tc ); + checks: + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-realtime:/name}. + code: | + rtems_clock_get_realtime( &ts ); + T_eq_u32( GetCounter( tc ), counter + 1 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-realtime-bintime:/name}. + code: | + rtems_clock_get_realtime_bintime( &bt ); + T_eq_u32( GetCounter( tc ), counter + 2 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-realtime-timeval:/name}. + code: | + rtems_clock_get_realtime_timeval( &tv ); + T_eq_u32( GetCounter( tc ), counter + 3 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-monotonic:/name}. + code: | + rtems_clock_get_monotonic( &ts ); + T_eq_u32( GetCounter( tc ), counter + 4 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-monotonic-bintime:/name}. + code: | + rtems_clock_get_monotonic_bintime( &bt ); + T_eq_u32( GetCounter( tc ), counter + 5 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-monotonic-sbintime:/name}. + code: | + (void) rtems_clock_get_monotonic_sbintime(); + T_eq_u32( GetCounter( tc ), counter + 6 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Check that the timecounter was used by + ${/rtems/clock/if/get-monotonic-timeval:/name}. + code: | + rtems_clock_get_monotonic_timeval( &tv ); + T_eq_u32( GetCounter( tc ), counter + 7 ); + links: + - role: validation + uid: ../req/get-device + - role: validation + uid: /rtems/clock/req/get-monotonic + links: [] +- action-brief: | + Call the directives to get the time in a coarse precision. + action-code: | + Timecounter *tc; + uint32_t counter; + struct bintime bt; + struct timespec ts; + struct timeval tv; + + tc = &high_quality_high_frequency; + counter = GetCounter( tc ); + checks: + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-realtime-coarse:/name}. + code: | + rtems_clock_get_realtime_coarse( &ts ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-realtime-coarse-bintime:/name}. + code: | + rtems_clock_get_realtime_coarse_bintime( &bt ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-realtime-coarse-timeval:/name}. + code: | + rtems_clock_get_realtime_coarse_timeval( &tv ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-realtime-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-monotonic-coarse:/name}. + code: | + rtems_clock_get_monotonic_coarse( &ts ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-monotonic-coarse-bintime:/name}. + code: | + rtems_clock_get_monotonic_coarse_bintime( &bt ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-monotonic-coarse-timeval:/name}. + code: | + rtems_clock_get_monotonic_coarse_timeval( &tv ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-monotonic-coarse + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-boot-time:/name}. + code: | + rtems_clock_get_boot_time( &ts ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-boot-time-bintime:/name}. + code: | + rtems_clock_get_boot_time_bintime( &bt ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-boot-time + - brief: | + Check that the timecounter was not used by + ${/rtems/clock/if/get-boot-time-timeval:/name}. + code: | + rtems_clock_get_boot_time_timeval( &tv ); + T_eq_u32( GetCounter( tc ), counter ); + links: + - role: validation + uid: ../req/get-coarse-no-device + - role: validation + uid: /rtems/clock/req/get-boot-time + links: [] +- action-brief: | + Call the directives to get the time in the highest precision available to + the system. + action-code: | + Timecounter *tc; + uint32_t counter; + struct bintime bt; + sbintime_t sb; + struct timespec ts; + struct timeval tv; + + tc = &high_quality_high_frequency; + counter = 3 * tc->base.tc_frequency + 123456789; + checks: + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-realtime:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_realtime( &ts ); + T_eq_i64( ts.tv_sec, 567993603 ); + T_eq_u64( ts.tv_nsec, 114978100 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-realtime-bintime:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_realtime_bintime( &bt ); + T_eq_i64( bt.sec, 567993603 ); + T_eq_u64( bt.frac, 2120971587975905280 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-realtime-timeval:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_realtime_timeval( &tv ); + T_eq_i64( tv.tv_sec, 567993603 ); + T_eq_long( tv.tv_usec, 114978 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-realtime + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-monotonic:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_monotonic( &ts ); + T_eq_i64( ts.tv_sec, 4 ); + T_eq_u64( ts.tv_nsec, 114978100 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-monotonic-bintime:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_monotonic_bintime( &bt ); + T_eq_i64( bt.sec, 4 ); + T_eq_u64( bt.frac, 2120971587975905280 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-monotonic-sbintime:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + sb = rtems_clock_get_monotonic_sbintime(); + T_eq_i64( sb, 17673696364 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-monotonic + - brief: | + Prepare the timecounter to get a large time difference. Check that + ${/rtems/clock/if/get-monotonic-timeval:/name} returns the correct time. + code: | + SetCounter( tc, counter ); + rtems_clock_get_monotonic_timeval( &tv ); + T_eq_i64( tv.tv_sec, 4 ); + T_eq_long( tv.tv_usec, 114978 ); + links: + - role: validation + uid: ../req/get-large-delta + - role: validation + uid: /rtems/clock/req/get-monotonic + links: [] +test-brief: | + Tests timecounter installation related functions and directives of the Clock + Manager. +test-context: [] +test-context-support: null +test-description: null +test-header: null +test-includes: +- rtems.h +- rtems/timecounter.h +- rtems/score/atomic.h +test-local-includes: +- tx-support.h +test-setup: null +test-stop: null +test-support: | + typedef struct { + struct timecounter base; + Atomic_Ulong counter; + } Timecounter; + + static Timecounter high_quality_low_frequency; + + static Timecounter high_quality_normal_frequency; + + static Timecounter high_quality_high_frequency; + + static Timecounter low_quality; + + static uint32_t GetTimecount( struct timecounter *base ) + { + Timecounter *tc; + + tc = (Timecounter *) base; + + return (uint32_t) _Atomic_Fetch_add_ulong( + &tc->counter, + 1, + ATOMIC_ORDER_RELAXED + ); + } + + static uint32_t GetCounter( const Timecounter *tc ) + { + return (uint32_t) _Atomic_Load_ulong( + &tc->counter, + ATOMIC_ORDER_RELAXED + ); + } + + static void SetCounter( Timecounter *tc, uint32_t counter ) + { + _Atomic_Store_ulong( + &tc->counter, + counter, + ATOMIC_ORDER_RELAXED + ); + } +test-target: testsuites/validation/tc-timecounter-install.c +test-teardown: null +type: test-case diff --git a/spec/testsuites/validation-timecounter-0.yml b/spec/testsuites/validation-timecounter-0.yml new file mode 100644 index 00000000..8fdd3262 --- /dev/null +++ b/spec/testsuites/validation-timecounter-0.yml @@ -0,0 +1,24 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: /req/test-suites +test-brief: | + This validation test suite is intended test cases related to the installation + of timecouters. The ${/glossary/clock-driver:/term} is disabled. +test-code: | + const char rtems_test_name[] = "${.:/test-suite-name}"; + + #define CONFIGURE_MAXIMUM_PROCESSORS 1 + + #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + + #include "ts-default.h" +test-description: null +test-includes: [] +test-local-includes: [] +test-suite-name: ValidationTimecounter0 +test-target: testsuites/validation/ts-validation-timecounter-0.c +type: test-suite diff --git a/spec/testsuites/validation-timecounter-1.yml b/spec/testsuites/validation-timecounter-1.yml new file mode 100644 index 00000000..8324feab --- /dev/null +++ b/spec/testsuites/validation-timecounter-1.yml @@ -0,0 +1,22 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: /req/test-suites +test-brief: | + This validation test suite is intended test cases related to the use of + timecouters. The ${/glossary/clock-driver:/term} is enabled. +test-code: | + const char rtems_test_name[] = "${.:/test-suite-name}"; + + #define CONFIGURE_MAXIMUM_PROCESSORS 4 + + #include "ts-default.h" +test-description: null +test-includes: [] +test-local-includes: [] +test-suite-name: ValidationTimecounter1 +test-target: testsuites/validation/ts-validation-timecounter-1.c +type: test-suite diff --git a/spec/testsuites/validation-timecounter-smp-0.yml b/spec/testsuites/validation-timecounter-smp-0.yml new file mode 100644 index 00000000..dc420a6d --- /dev/null +++ b/spec/testsuites/validation-timecounter-smp-0.yml @@ -0,0 +1,24 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +links: +- role: requirement-refinement + uid: /req/test-suites +test-brief: | + This validation test suite is intended test cases related to the use of + timecouters. The ${/glossary/clock-driver:/term} is disabled. +test-code: | + const char rtems_test_name[] = "${.:/test-suite-name}"; + + #define CONFIGURE_MAXIMUM_PROCESSORS 4 + + #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + + #include "ts-default.h" +test-description: null +test-includes: [] +test-local-includes: [] +test-suite-name: ValidationTimecounterSmp0 +test-target: testsuites/validation/ts-validation-timecounter-smp-0.c +type: test-suite |