File indexing completed on 2025-05-11 08:24:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <errno.h>
0033 #include <rtems/test.h>
0034 #include <rtems/test-info.h>
0035 #include <rtems/timespec.h>
0036 #include <rtems/rtems/event.h>
0037 #define _KERNEL
0038 #include <sys/timepps.h>
0039
0040 const char rtems_test_name[] = "SPPPS 1";
0041
0042 #define PPS_EVENT RTEMS_EVENT_0
0043 #define TASK_WAITING RTEMS_EVENT_1
0044 #define PPS_EVENT_RECEIVED RTEMS_EVENT_2
0045
0046 struct test_pps_device {
0047 struct pps_state pps;
0048 rtems_id task_waiting;
0049 int wokenup;
0050 };
0051
0052 typedef struct {
0053 rtems_id main_task;
0054 struct test_pps_device *pps_dev;
0055 } test_context;
0056
0057 T_TEST_CASE( WaitPPSEventDefaultHandler )
0058 {
0059 int status;
0060 struct test_pps_device pps_dev;
0061 struct pps_fetch_args fetch;
0062
0063 memset( &pps_dev, 0, sizeof( pps_dev ) );
0064 pps_dev.task_waiting = RTEMS_INVALID_ID;
0065
0066 pps_dev.pps.ppscap = PPS_CAPTUREBOTH;
0067 pps_init_abi( &pps_dev.pps );
0068 pps_dev.pps.ppsparam.mode = PPS_CAPTUREASSERT;
0069
0070
0071 memset( &fetch, 0, sizeof( fetch ) );
0072 status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &pps_dev.pps );
0073 T_eq_int( status, 0 );
0074
0075 fetch.timeout.tv_sec = 1;
0076 status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &pps_dev.pps );
0077 T_eq_int( status, ETIMEDOUT );
0078 }
0079
0080 static void fake_wakeup(struct pps_state *pps)
0081 {
0082 struct test_pps_device *pps_dev;
0083
0084 pps_dev = RTEMS_CONTAINER_OF( pps, struct test_pps_device, pps );
0085 pps_dev->wokenup++;
0086 }
0087
0088 T_TEST_CASE( PPSEventEarlyReturns )
0089 {
0090 struct test_pps_device pps_dev;
0091
0092 memset( &pps_dev, 0, sizeof( pps_dev ) );
0093 pps_dev.task_waiting = RTEMS_INVALID_ID;
0094
0095 pps_dev.pps.ppscap = PPS_CAPTUREBOTH;
0096 pps_init_abi( &pps_dev.pps );
0097 pps_dev.pps.wakeup = fake_wakeup;
0098 pps_dev.pps.ppsparam.mode = PPS_CAPTUREASSERT;
0099
0100 pps_capture( &pps_dev.pps );
0101
0102 pps_event( &pps_dev.pps, PPS_CAPTURECLEAR );
0103 T_eq_int( pps_dev.wokenup, 0 );
0104
0105 pps_dev.pps.ppsparam.mode = PPS_CAPTURECLEAR;
0106
0107
0108 rtems_task_wake_after( 2 );
0109 pps_event( &pps_dev.pps, PPS_CAPTURECLEAR );
0110 T_eq_int( pps_dev.wokenup, 0 );
0111
0112
0113 pps_capture( &pps_dev.pps );
0114 pps_event( &pps_dev.pps, PPS_CAPTURECLEAR );
0115 T_eq_int( pps_dev.wokenup, 0 );
0116
0117 pps_capture( &pps_dev.pps );
0118 pps_event( &pps_dev.pps, PPS_CAPTURECLEAR );
0119 T_eq_int( pps_dev.wokenup, 1 );
0120 }
0121
0122 static void wakeup(struct pps_state *pps)
0123 {
0124 struct test_pps_device *pps_dev;
0125
0126 pps_dev = RTEMS_CONTAINER_OF( pps, struct test_pps_device, pps );
0127 if (pps_dev->task_waiting != RTEMS_INVALID_ID)
0128 rtems_event_send( pps_dev->task_waiting, PPS_EVENT );
0129 }
0130
0131 static int wait(struct pps_state *pps, struct timespec timeout)
0132 {
0133 rtems_status_code sc;
0134 rtems_event_set out;
0135 uint32_t timeoutticks;
0136 struct test_pps_device *pps_dev;
0137
0138 pps_dev = RTEMS_CONTAINER_OF( pps, struct test_pps_device, pps );
0139 pps_dev->task_waiting = rtems_task_self();
0140
0141 timeoutticks = rtems_timespec_to_ticks(&timeout);
0142 sc = rtems_event_receive( PPS_EVENT, RTEMS_DEFAULT_OPTIONS, timeoutticks, &out );
0143 return rtems_status_code_to_errno(sc);
0144 }
0145
0146 static void pps_task(rtems_task_argument arg)
0147 {
0148 int status;
0149 rtems_status_code sc;
0150 struct pps_fetch_args fetch;
0151 test_context *ctx;
0152
0153 ctx = (test_context *) arg;
0154
0155 fetch.tsformat = PPS_TSFMT_TSPEC;
0156 fetch.timeout.tv_sec = 1;
0157 fetch.timeout.tv_nsec = 0;
0158
0159 sc = rtems_event_send( ctx->main_task, TASK_WAITING );
0160 T_rsc_success( sc );
0161 status = pps_ioctl( PPS_IOC_FETCH, (caddr_t)&fetch, &ctx->pps_dev->pps );
0162 T_eq_int( status, 0 );
0163 sc = rtems_event_send( ctx->main_task, PPS_EVENT_RECEIVED );
0164 T_rsc_success( sc );
0165
0166 rtems_task_exit();
0167 }
0168
0169 T_TEST_CASE( WakeupTaskWithPPSEvent )
0170 {
0171 int status;
0172 rtems_status_code sc;
0173 struct test_pps_device pps_dev;
0174 struct pps_kcbind_args kcbind;
0175 test_context ctx;
0176 rtems_id pps_task_id;
0177 rtems_task_priority pps_task_prio = 1;
0178 rtems_event_set out;
0179
0180 memset( &pps_dev, 0, sizeof( pps_dev ) );
0181 pps_dev.task_waiting = RTEMS_INVALID_ID;
0182 ctx.pps_dev = &pps_dev;
0183 ctx.main_task = rtems_task_self();
0184
0185 pps_dev.pps.ppscap = PPS_CAPTUREBOTH;
0186 pps_init_abi( &pps_dev.pps );
0187 pps_dev.pps.wait = wait;
0188 pps_dev.pps.wakeup = wakeup;
0189 pps_dev.pps.ppsparam.mode = PPS_CAPTUREASSERT;
0190
0191 kcbind.kernel_consumer = PPS_KC_HARDPPS;
0192 kcbind.edge = PPS_CAPTUREASSERT;
0193 kcbind.tsformat = PPS_TSFMT_TSPEC;
0194 status = pps_ioctl( PPS_IOC_KCBIND, (caddr_t)&kcbind, &pps_dev.pps );
0195 T_eq_int( status, 0 );
0196
0197
0198 pps_capture( &pps_dev.pps );
0199 pps_event( &pps_dev.pps, PPS_CAPTUREASSERT );
0200
0201 sc = rtems_task_create(
0202 rtems_build_name('P', 'P', 'S', 'E'),
0203 pps_task_prio,
0204 RTEMS_MINIMUM_STACK_SIZE,
0205 RTEMS_DEFAULT_MODES,
0206 RTEMS_DEFAULT_ATTRIBUTES,
0207 &pps_task_id
0208 );
0209 T_rsc_success( sc );
0210 sc = rtems_task_start( pps_task_id, pps_task, (rtems_task_argument) &ctx );
0211 T_rsc_success( sc );
0212
0213 sc = rtems_event_receive( TASK_WAITING, RTEMS_DEFAULT_OPTIONS, RTEMS_MILLISECONDS_TO_TICKS(100), &out );
0214 T_rsc_success( sc );
0215
0216
0217 pps_capture( &pps_dev.pps );
0218 pps_event( &pps_dev.pps, PPS_CAPTUREASSERT );
0219
0220 sc = rtems_event_receive( PPS_EVENT_RECEIVED, RTEMS_DEFAULT_OPTIONS, RTEMS_MILLISECONDS_TO_TICKS(100), &out );
0221 T_rsc_success( sc );
0222 }
0223
0224 static rtems_task Init( rtems_task_argument argument )
0225 {
0226 rtems_test_run( argument, TEST_STATE );
0227 }
0228
0229 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0230 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0231
0232 #define CONFIGURE_MAXIMUM_TASKS 2
0233
0234 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0235
0236 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0237
0238 #define CONFIGURE_INIT
0239
0240 #include <rtems/confdefs.h>