source: rtems/testsuites/sptests/sppps01/init.c @ 34ba0e5a

Last change on this file since 34ba0e5a was 34ba0e5a, checked in by Gabriel Moyano <gabriel.moyano@…>, on 05/25/22 at 12:19:11

sppps01: Improve default handler test

Update #2349.

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2022 German Aerospace Center (DLR)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <errno.h>
33#include <rtems/test.h>
34#include <rtems/test-info.h>
35#include <rtems/timespec.h>
36#include <rtems/rtems/event.h>
37#define _KERNEL
38#include <sys/timepps.h>
39
40const char rtems_test_name[] = "SPPPS 1";
41
42#define PPS_EVENT RTEMS_EVENT_0
43#define TASK_WAITING RTEMS_EVENT_1
44#define PPS_EVENT_RECEIVED RTEMS_EVENT_2
45
46struct test_pps_device {
47  struct pps_state pps;
48  rtems_id task_waiting;
49};
50
51typedef struct {
52  rtems_id main_task;
53  struct test_pps_device *pps_dev;
54} test_context;
55
56T_TEST_CASE( WaitPPSEventDefaultHandler )
57{
58  int status;
59  struct test_pps_device pps_dev;
60  struct pps_fetch_args fetch;
61
62  pps_dev.task_waiting = RTEMS_INVALID_ID;
63
64  memset( &pps_dev.pps, 0, sizeof( pps_dev.pps ) );
65  pps_dev.pps.ppscap = PPS_CAPTUREBOTH;
66  pps_init_abi( &pps_dev.pps );
67  pps_dev.pps.ppsparam.mode = PPS_CAPTUREASSERT;
68
69  /* If no timeout is requested, pps_fetch() doesn't call the default handler */
70  memset( &fetch, 0, sizeof( fetch ) );
71  status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &pps_dev.pps );
72  T_eq_int( status, 0 );
73
74  fetch.timeout.tv_sec = 1;
75  status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &pps_dev.pps );
76  T_eq_int( status, ETIMEDOUT );
77}
78
79static void wakeup(struct pps_state *pps)
80{
81  struct test_pps_device *pps_dev;
82
83  pps_dev = RTEMS_CONTAINER_OF( pps, struct test_pps_device, pps );
84  if (pps_dev->task_waiting != RTEMS_INVALID_ID)
85    rtems_event_send( pps_dev->task_waiting, PPS_EVENT );
86}
87
88static int wait(struct pps_state *pps, struct timespec timeout)
89{
90  rtems_status_code sc;
91  rtems_event_set out;
92  uint32_t timeoutticks;
93  struct test_pps_device *pps_dev;
94
95  pps_dev = RTEMS_CONTAINER_OF( pps, struct test_pps_device, pps );
96  pps_dev->task_waiting = rtems_task_self();
97
98  timeoutticks = rtems_timespec_to_ticks(&timeout);
99  sc = rtems_event_receive( PPS_EVENT, RTEMS_DEFAULT_OPTIONS, timeoutticks, &out );
100  return rtems_status_code_to_errno(sc);
101}
102
103static void pps_task(rtems_task_argument arg)
104{
105  int status;
106  rtems_status_code sc;
107  struct pps_fetch_args fetch;
108  test_context *ctx;
109
110  ctx = (test_context *) arg;
111
112  fetch.tsformat = PPS_TSFMT_TSPEC;
113  fetch.timeout.tv_sec = 1;
114  fetch.timeout.tv_nsec = 0;
115
116  sc = rtems_event_send( ctx->main_task, TASK_WAITING );
117  T_rsc_success( sc );
118  status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &ctx->pps_dev->pps );
119  T_eq_int( status, 0 );
120  sc = rtems_event_send( ctx->main_task, PPS_EVENT_RECEIVED );
121  T_rsc_success( sc );
122
123  rtems_task_delete(rtems_task_self());
124}
125
126T_TEST_CASE( WakeupTaskWithPPSEvent )
127{
128  int status;
129  rtems_status_code sc;
130  struct test_pps_device pps_dev;
131  struct pps_kcbind_args kcbind;
132  test_context ctx;
133  rtems_id pps_task_id;
134  rtems_task_priority pps_task_prio = 1;
135  rtems_event_set out;
136
137  pps_dev.task_waiting = RTEMS_INVALID_ID;
138  ctx.pps_dev = &pps_dev;
139  ctx.main_task = rtems_task_self();
140
141  memset( &pps_dev.pps, 0, sizeof( pps_dev.pps ) );
142  pps_dev.pps.ppscap = PPS_CAPTUREBOTH;
143  pps_init_abi( &pps_dev.pps );
144  pps_dev.pps.wait = wait;
145  pps_dev.pps.wakeup = wakeup;
146  pps_dev.pps.ppsparam.mode = PPS_CAPTUREASSERT;
147
148  kcbind.kernel_consumer = PPS_KC_HARDPPS;
149  kcbind.edge = PPS_CAPTUREASSERT;
150  kcbind.tsformat = PPS_TSFMT_TSPEC;
151  status = pps_ioctl( PPS_IOC_KCBIND, (caddr_t)&kcbind, &pps_dev.pps );
152  T_eq_int( status, 0 );
153
154  /* Save current timecounter in pps_state object */
155  pps_capture( &pps_dev.pps );
156  pps_event( &pps_dev.pps, PPS_CAPTUREASSERT );
157
158  sc = rtems_task_create(
159    rtems_build_name('P', 'P', 'S', 'E'),
160    pps_task_prio,
161    RTEMS_MINIMUM_STACK_SIZE,
162    RTEMS_DEFAULT_MODES,
163    RTEMS_DEFAULT_ATTRIBUTES,
164    &pps_task_id
165  );
166  T_rsc_success( sc );
167  sc = rtems_task_start( pps_task_id, pps_task, (rtems_task_argument) &ctx );
168  T_rsc_success( sc );
169
170  sc = rtems_event_receive( TASK_WAITING, RTEMS_DEFAULT_OPTIONS, RTEMS_MILLISECONDS_TO_TICKS(100), &out );
171  T_rsc_success( sc );
172
173  /* Capture event and send wake-up */
174  pps_capture( &pps_dev.pps );
175  pps_event( &pps_dev.pps, PPS_CAPTUREASSERT );
176
177  sc = rtems_event_receive( PPS_EVENT_RECEIVED, RTEMS_DEFAULT_OPTIONS, RTEMS_MILLISECONDS_TO_TICKS(100), &out );
178  T_rsc_success( sc );
179}
180
181static rtems_task Init( rtems_task_argument argument )
182{
183  rtems_test_run( argument, TEST_STATE );
184}
185
186#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
187#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
188
189#define CONFIGURE_MAXIMUM_TASKS 2
190
191#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
192
193#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
194
195#define CONFIGURE_INIT
196
197#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.