Ein Roboter mit bürstenlosem Antrieb, differenzial und NRF24L01 Funk. Großflächig gebaut um ein großes Solarpanel aufzunehmen. https://gitlab.informatik.hs-fulda.de/fdai5253/roboter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
5.3 KiB

  1. /*
  2. Interrupts functions extruded from wiringPi library by Oitzu.
  3. wiringPi Copyright (c) 2012 Gordon Henderson
  4. https://projects.drogon.net/raspberry-pi/wiringpi
  5. wiringPi is free software: GNU Lesser General Public License
  6. see <http://www.gnu.org/licenses/>
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <stdint.h>
  14. #include <string.h>
  15. #include <sys/wait.h>
  16. #include <sys/ioctl.h>
  17. #include <poll.h>
  18. #include <sys/stat.h>
  19. #include "interrupt.h"
  20. #include <pthread.h>
  21. #define delay(x) bcm2835_delay(x)
  22. static pthread_mutex_t pinMutex = PTHREAD_MUTEX_INITIALIZER;
  23. static volatile int pinPass = -1 ;
  24. pthread_t threadId [64];
  25. // sysFds:
  26. // Map a file descriptor from the /sys/class/gpio/gpioX/value
  27. static int sysFds [64] =
  28. {
  29. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  30. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  31. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  32. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  33. } ;
  34. // ISR Data
  35. static void (*isrFunctions [64])(void) ;
  36. int waitForInterrupt (int pin, int mS)
  37. {
  38. int fd, x ;
  39. uint8_t c ;
  40. struct pollfd polls ;
  41. if ((fd = sysFds [pin]) == -1)
  42. return -2 ;
  43. // Setup poll structure
  44. polls.fd = fd ;
  45. polls.events = POLLPRI ; // Urgent data!
  46. // Wait for it ...
  47. x = poll (&polls, 1, mS) ;
  48. // Do a dummy read to clear the interrupt
  49. // A one character read appars to be enough.
  50. // Followed by a seek to reset it.
  51. (void)read (fd, &c, 1) ;
  52. lseek (fd, 0, SEEK_SET) ;
  53. return x ;
  54. }
  55. int piHiPri (const int pri)
  56. {
  57. struct sched_param sched ;
  58. memset (&sched, 0, sizeof(sched)) ;
  59. if (pri > sched_get_priority_max (SCHED_RR))
  60. sched.sched_priority = sched_get_priority_max (SCHED_RR) ;
  61. else
  62. sched.sched_priority = pri ;
  63. return sched_setscheduler (0, SCHED_RR, &sched) ;
  64. }
  65. void *interruptHandler (void *arg)
  66. {
  67. int myPin ;
  68. (void)piHiPri (55) ; // Only effective if we run as root
  69. myPin = pinPass ;
  70. pinPass = -1 ;
  71. for (;;)
  72. if (waitForInterrupt (myPin, -1) > 0){
  73. pthread_mutex_lock (&pinMutex) ;
  74. isrFunctions [myPin] () ;
  75. pthread_mutex_unlock (&pinMutex) ;
  76. pthread_testcancel(); //Cancel at this point if we have an cancellation request.
  77. }
  78. return NULL ;
  79. }
  80. int attachInterrupt (int pin, int mode, void (*function)(void))
  81. {
  82. const char *modeS ;
  83. char fName [64] ;
  84. char pinS [8] ;
  85. pid_t pid ;
  86. int count, i ;
  87. char c ;
  88. int bcmGpioPin ;
  89. bcmGpioPin = pin ;
  90. if (mode != INT_EDGE_SETUP)
  91. {
  92. /**/ if (mode == INT_EDGE_FALLING)
  93. modeS = "falling" ;
  94. else if (mode == INT_EDGE_RISING)
  95. modeS = "rising" ;
  96. else
  97. modeS = "both" ;
  98. sprintf (pinS, "%d", bcmGpioPin) ;
  99. if ((pid = fork ()) < 0) // Fail
  100. return printf("wiringPiISR: fork failed: %s\n", strerror (errno)) ;
  101. if (pid == 0) // Child, exec
  102. {
  103. /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0)
  104. {
  105. execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
  106. return printf ("wiringPiISR: execl failed: %s\n", strerror (errno)) ;
  107. }
  108. else if (access ("/usr/bin/gpio", X_OK) == 0)
  109. {
  110. execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
  111. return printf ("wiringPiISR: execl failed: %s\n", strerror (errno)) ;
  112. }
  113. else
  114. return printf ("wiringPiISR: Can't find gpio program\n") ;
  115. }
  116. else // Parent, wait
  117. wait (NULL) ;
  118. }
  119. if (sysFds [bcmGpioPin] == -1)
  120. {
  121. sprintf (fName, "/sys/class/gpio/gpio%d/value",bcmGpioPin);
  122. if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
  123. return printf ("wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ;
  124. }
  125. ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ;
  126. for (i = 0 ; i < count ; ++i)
  127. read (sysFds [bcmGpioPin], &c, 1) ;
  128. isrFunctions [pin] = function ;
  129. pthread_mutex_lock (&pinMutex) ;
  130. pinPass = pin ;
  131. pthread_create (&threadId[bcmGpioPin], NULL, interruptHandler, NULL) ;
  132. while (pinPass != -1)
  133. delay (1) ;
  134. pthread_mutex_unlock (&pinMutex) ;
  135. return 0 ;
  136. }
  137. int detachInterrupt (int pin)
  138. {
  139. char pinS [8];
  140. const char *modeS = "none";
  141. pid_t pid ;
  142. if (pthread_cancel(threadId[pin]) != 0) //Cancel the thread
  143. {
  144. return 0;
  145. }
  146. if (close(sysFds[pin]) != 0) //Close filehandle
  147. {
  148. return 0;
  149. }
  150. /* Set wiringPi to 'none' interrupt mode */
  151. sprintf (pinS, "%d", pin) ;
  152. if ((pid = fork ()) < 0) // Fail
  153. return printf("wiringPiISR: fork failed: %s\n", strerror (errno)) ;
  154. if (pid == 0) // Child, exec
  155. {
  156. /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0)
  157. {
  158. execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
  159. return printf ("wiringPiISR: execl failed: %s\n", strerror (errno)) ;
  160. }
  161. else if (access ("/usr/bin/gpio", X_OK) == 0)
  162. {
  163. execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
  164. return printf ("wiringPiISR: execl failed: %s\n", strerror (errno)) ;
  165. }
  166. else
  167. return printf ("wiringPiISR: Can't find gpio program\n") ;
  168. }
  169. else // Parent, wait
  170. wait (NULL) ;
  171. return 1;
  172. }
  173. void rfNoInterrupts(){
  174. pthread_mutex_lock (&pinMutex) ;
  175. }
  176. void rfInterrupts(){
  177. pthread_mutex_unlock (&pinMutex) ;
  178. }