source: multiio/pcmmio/original/poll.c @ da59d43

Last change on this file since da59d43 was 2bae2aa, checked in by Joel Sherrill <joel.sherrill@…>, on 06/08/09 at 14:52:43

Initial import.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/* Poll.c Demonstration program for WinSystems PCM-MIO Driver */
2
3/*
4*
5* $Header$
6*
7* $Id$
8*
9* $Log$
10*
11*/
12
13/* This program demonstrates one manner in which an unprivledged
14   application running in user space can sychronize to hardware events
15   handled by a device driver running in Kernel space.
16*/
17
18
19#include "mio_io.h"   
20
21#include <stdio.h>
22#include <fcntl.h>      /* open */
23#include <unistd.h>     /* exit */
24#include <sys/ioctl.h>  /* ioctl */
25#include <stdlib.h>
26#include <pthread.h>
27
28
29/* This function will be a sub-processe using the Posix threads
30   capability of Linux. This thread will simulate a type of
31   Interrupt service routine in that it will start up and then suspend
32   until an interrupt occurs and the driver awakens it.
33*/
34
35void *thread_function(void *arg);
36
37/* Event count, counts the number of events we've handled */
38
39volatile int event_count;
40volatile int exit_flag = 0;
41
42char line[80];
43
44main(int argc, char *argv[])
45{
46int res, res1;
47pthread_t a_thread;
48int c;
49int x;
50
51                /* Do a read_bit to test for port/driver availability */
52
53          c = dio_read_bit(1);
54          if(mio_error_code)
55          {
56                  printf("%s\n",mio_error_string);
57                  exit(1);
58          }
59
60
61        /* Here, we'll enable all 24 bits for falling edge interrupts on both
62     chips. We'll also make sure that they're ready and armed by
63     explicitly calling the clr_int() function.
64        */
65
66    for(x=1; x < 25; x++)
67    {
68        dio_enab_bit_int(x,FALLING);
69                dio_clr_int(x);
70    }
71
72
73    /* We'll also clear out any events that are queued up within the
74       driver and clear any pending interrupts
75    */
76
77        enable_dio_interrupt();
78       
79        if(mio_error_code)
80        {
81                printf("%s\n",mio_error_string);
82                exit(1);
83        }
84
85    while((x= dio_get_int()))
86    {
87                printf("Clearing interrupt on Chip 1 bit %d\n",x);
88                dio_clr_int(x);
89    }
90
91
92    /* Now the sub-thread will be started */
93
94    printf("Splitting off polling process\n");
95
96    res = pthread_create(&a_thread,NULL,thread_function,NULL);
97
98    if(res != 0)
99    {
100                perror("Thread creation failed");
101                exit(EXIT_FAILURE);
102    }
103
104
105    /* The thread is now running in the background. It will execute up
106      to the point were there are no interrupts and suspend. We as its
107      parent continue on. The nice thing about POSIX threads is that we're
108      all in the same data space the parent and the children so we can
109      share data directly. In this program we share the event_count
110      variable.
111   */
112
113
114    /* We'll continue on in this loop until we're terminated */
115
116    while(1)
117    {
118        /* Print Something so we know the foreground is alive */
119
120                printf("**");
121
122
123        /* The foreground will now wait for an input from the console
124           We could actually go on and do anything we wanted to at this
125           point.
126        */
127
128                fgets(line,75,stdin);
129
130                if(line[0] == 'q' || line[0] == 'Q')
131                        break;
132
133        /* Here's the actual exit. If we hit 'Q' and Enter. The program
134           terminates.
135        */
136
137    }
138
139
140    /* This flag is a shared variable that the children can look at to
141        know we're finished and they can exit too.
142    */
143
144    exit_flag = 1;
145
146        disable_dio_interrupt();
147
148    /* Display our event count total */
149
150    printf("Event count = %05d\r",event_count);
151
152    printf("\n\nAttempting to cancel subthread\n");
153   
154    /* If out children are not in a position to see the exit_flag, we
155       will use a more forceful technique to make sure they terminate with
156       us. If we leave them hanging and we try to re-run the program or
157       if another program wants to talk to the device they may be locked
158       out. This way everything cleans up much nicer.
159    */
160
161    pthread_cancel(a_thread);
162    printf("\nExiting Now\n");
163
164    fflush(NULL);
165
166}
167
168    /* This is the the sub-procesc. For the purpose of this
169       example, it does nothing but wait for an interrupt to be active on
170       chip 1 and then reports that fact via the console. It also
171       increments the shared data variable event_count.
172    */
173
174void *thread_function(void *arg)
175{
176int c;
177
178        while(1)
179        {
180                /* Test for a thread cancellation signal */
181
182            pthread_testcancel();
183
184                /* Test the exit_flag also for exit */
185
186            if(exit_flag)
187                        break;
188
189            /* This call will put THIS process to sleep until either an
190               interrupt occurs or a terminating signal is sent by the
191               parent or the system.
192            */
193            c = wait_dio_int();
194
195            /* We check to see if it was a real interrupt instead of a
196               termination request.
197            */
198           
199                if(c > 0)
200            {
201                    printf("Event sense occured on bit %d\n",c);
202                    ++event_count;
203            }
204            else
205                break;
206        }
207}
208
Note: See TracBrowser for help on using the repository browser.