rtdm.h
1 /** 2 * @file 3 * Real-Time Driver Model for RTAI, user API header 4 * 5 * @note Copyright (C) 2005, 2006 Jan Kiszka <jan.kiszka@web.de> 6 * @note Copyright (C) 2005 Joerg Langenberg <joerg.langenberg@gmx.net> 7 * @note Copyright (C) 2005-2010 Paolo Mantegazza <mantegazza@aero.polimi.it> 8 * 9 * RTAI is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * RTAI is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with RTAI; if not, write to the Free Software Foundation, 21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 * 23 * @ingroup userapi 24 */ 25 26 /*! 27 * @defgroup rtdm Real-Time Driver Model 28 * 29 * The Real-Time Driver Model (RTDM) provides a unified interface to 30 * both users and developers of real-time device 31 * drivers. Specifically, it addresses the constraints of mixed 32 * RT/non-RT systems like RTAI. RTDM conforms to POSIX 33 * semantics (IEEE Std 1003.1) where available and applicable. 34 * 35 * @b API @b Revision: 8 36 */ 37 38 /*! 39 * @ingroup rtdm 40 * @defgroup userapi User API 41 * 42 * This is the upper interface of RTDM provided to application programs both 43 * in kernel and user space. Note that certain functions may not be 44 * implemented by every device. Refer to the @ref profiles "Device Profiles" 45 * for precise information. 46 */ 47 48 #ifndef _RTDM_H 49 #define _RTDM_H 50 51 #define RTDM_INDX 15 52 53 #define __rtdm_fdcount 0 54 #define __rtdm_open 1 55 #define __rtdm_socket 2 56 #define __rtdm_close 3 57 #define __rtdm_ioctl 4 58 #define __rtdm_read 5 59 #define __rtdm_write 6 60 #define __rtdm_recvmsg 7 61 #define __rtdm_sendmsg 8 62 #define __rtdm_select 9 63 64 #ifdef __KERNEL__ 65 66 #include <linux/fcntl.h> 67 #include <linux/ioctl.h> 68 #include <linux/sched.h> 69 #include <linux/socket.h> 70 71 typedef u32 socklen_t; 72 typedef struct task_struct rtdm_user_info_t; 73 74 #else /* !__KERNEL__ */ 75 76 #include <fcntl.h> 77 #include <stdint.h> 78 #include <sys/ioctl.h> 79 #include <sys/socket.h> 80 81 #endif /* !__KERNEL__ */ 82 83 /*! 84 * @addtogroup rtdm 85 * @{ 86 */ 87 88 /*! 89 * @anchor api_versioning @name API Versioning 90 * @{ */ 91 /** Common user and driver API version */ 92 #define RTDM_API_VER 8 93 94 /** Minimum API revision compatible with the current release */ 95 #define RTDM_API_MIN_COMPAT_VER 6 96 /** @} API Versioning */ 97 98 /** RTDM type for representing absolute dates. Its base type is a 64 bit 99 * unsigned integer. The unit is 1 nanosecond. */ 100 typedef int64_t nanosecs_abs_t; 101 102 /** RTDM type for representing relative intervals. Its base type is a 64 bit 103 * signed integer. The unit is 1 nanosecond. Relative intervals can also 104 * encode the special timeouts "infinite" and "non-blocking", see 105 * @ref RTDM_TIMEOUT_xxx. */ 106 typedef int64_t nanosecs_rel_t; 107 108 /*! 109 * @anchor RTDM_TIMEOUT_xxx @name RTDM_TIMEOUT_xxx 110 * Special timeout values 111 * @{ */ 112 /** Block forever. */ 113 #define RTDM_TIMEOUT_INFINITE 0 114 115 /** Any negative timeout means non-blocking. */ 116 #define RTDM_TIMEOUT_NONE (-1) 117 /** @} RTDM_TIMEOUT_xxx */ 118 /** @} rtdm */ 119 120 /*! 121 * @addtogroup profiles 122 * @{ 123 */ 124 125 /*! 126 * @anchor RTDM_CLASS_xxx @name RTDM_CLASS_xxx 127 * Device classes 128 * @{ */ 129 #define RTDM_CLASS_PARPORT 1 130 #define RTDM_CLASS_SERIAL 2 131 #define RTDM_CLASS_CAN 3 132 #define RTDM_CLASS_NETWORK 4 133 #define RTDM_CLASS_RTMAC 5 134 #define RTDM_CLASS_TESTING 6 135 #define RTDM_CLASS_RTIPC 7 136 /* 137 #define RTDM_CLASS_USB ? 138 #define RTDM_CLASS_FIREWIRE ? 139 #define RTDM_CLASS_INTERBUS ? 140 #define RTDM_CLASS_PROFIBUS ? 141 #define ... 142 */ 143 #define RTDM_CLASS_EXPERIMENTAL 224 144 #define RTDM_CLASS_MAX 255 145 /** @} RTDM_CLASS_xxx */ 146 147 #define RTDM_SUBCLASS_GENERIC (-1) 148 149 #define RTIOC_TYPE_COMMON 0 150 151 /*! 152 * @anchor device_naming @name Device Naming 153 * Maximum length of device names (excluding the final null character) 154 * @{ 155 */ 156 #define RTDM_MAX_DEVNAME_LEN 31 157 /** @} Device Naming */ 158 159 /** 160 * Device information 161 */ 162 typedef struct rtdm_device_info { 163 /** Device flags, see @ref dev_flags "Device Flags" for details */ 164 int device_flags; 165 166 /** Device class ID, see @ref RTDM_CLASS_xxx */ 167 int device_class; 168 169 /** Device sub-class, either RTDM_SUBCLASS_GENERIC or a 170 * RTDM_SUBCLASS_xxx definition of the related @ref profiles 171 * "Device Profile" */ 172 int device_sub_class; 173 174 /** Supported device profile version */ 175 int profile_version; 176 } rtdm_device_info_t; 177 178 /*! 179 * @anchor RTDM_PURGE_xxx_BUFFER @name RTDM_PURGE_xxx_BUFFER 180 * Flags selecting buffers to be purged 181 * @{ */ 182 #define RTDM_PURGE_RX_BUFFER 0x0001 183 #define RTDM_PURGE_TX_BUFFER 0x0002 184 /** @} RTDM_PURGE_xxx_BUFFER*/ 185 186 /*! 187 * @anchor common_IOCTLs @name Common IOCTLs 188 * The following IOCTLs are common to all device profiles. 189 * @{ 190 */ 191 192 /** 193 * Retrieve information about a device or socket. 194 * @param[out] arg Pointer to information buffer (struct rtdm_device_info) 195 */ 196 #define RTIOC_DEVICE_INFO \ 197 _IOR(RTIOC_TYPE_COMMON, 0x00, struct rtdm_device_info) 198 199 /** 200 * Purge internal device or socket buffers. 201 * @param[in] arg Purge mask, see @ref RTDM_PURGE_xxx_BUFFER 202 */ 203 #define RTIOC_PURGE _IOW(RTIOC_TYPE_COMMON, 0x10, int) 204 /** @} Common IOCTLs */ 205 /** @} rtdm */ 206 207 /* Internally used for mapping socket functions on IOCTLs */ 208 struct _rtdm_getsockopt_args { 209 int level; 210 int optname; 211 void *optval; 212 socklen_t *optlen; 213 }; 214 215 struct _rtdm_setsockopt_args { 216 int level; 217 int optname; 218 const void *optval; 219 socklen_t optlen; 220 }; 221 222 struct _rtdm_getsockaddr_args { 223 struct sockaddr *addr; 224 socklen_t *addrlen; 225 }; 226 227 struct _rtdm_setsockaddr_args { 228 const struct sockaddr *addr; 229 socklen_t addrlen; 230 }; 231 232 #define _RTIOC_GETSOCKOPT _IOW(RTIOC_TYPE_COMMON, 0x20, \ 233 struct _rtdm_getsockopt_args) 234 #define _RTIOC_SETSOCKOPT _IOW(RTIOC_TYPE_COMMON, 0x21, \ 235 struct _rtdm_setsockopt_args) 236 #define _RTIOC_BIND _IOW(RTIOC_TYPE_COMMON, 0x22, \ 237 struct _rtdm_setsockaddr_args) 238 #define _RTIOC_CONNECT _IOW(RTIOC_TYPE_COMMON, 0x23, \ 239 struct _rtdm_setsockaddr_args) 240 #define _RTIOC_LISTEN _IOW(RTIOC_TYPE_COMMON, 0x24, \ 241 int) 242 #define _RTIOC_ACCEPT _IOW(RTIOC_TYPE_COMMON, 0x25, \ 243 struct _rtdm_getsockaddr_args) 244 #define _RTIOC_GETSOCKNAME _IOW(RTIOC_TYPE_COMMON, 0x26, \ 245 struct _rtdm_getsockaddr_args) 246 #define _RTIOC_GETPEERNAME _IOW(RTIOC_TYPE_COMMON, 0x27, \ 247 struct _rtdm_getsockaddr_args) 248 #define _RTIOC_SHUTDOWN _IOW(RTIOC_TYPE_COMMON, 0x28, \ 249 int) 250 251 #ifdef __KERNEL__ 252 int __rt_dev_open(rtdm_user_info_t *user_info, const char *path, int oflag); 253 int __rt_dev_socket(rtdm_user_info_t *user_info, int protocol_family, 254 int socket_type, int protocol); 255 int __rt_dev_close(rtdm_user_info_t *user_info, int fd); 256 int __rt_dev_ioctl(rtdm_user_info_t *user_info, int fd, int request, ...); 257 ssize_t __rt_dev_read(rtdm_user_info_t *user_info, int fd, void *buf, 258 size_t nbyte); 259 ssize_t __rt_dev_write(rtdm_user_info_t *user_info, int fd, const void *buf, 260 size_t nbyte); 261 ssize_t __rt_dev_recvmsg(rtdm_user_info_t *user_info, int fd, 262 struct msghdr *msg, int flags); 263 ssize_t __rt_dev_sendmsg(rtdm_user_info_t *user_info, int fd, 264 const struct msghdr *msg, int flags); 265 #include "select.h" 266 int __rt_dev_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, nanosecs_rel_t timeout, struct xnselector *selector, int space); 267 #endif /* __KERNEL__ */ 268 269 /* Define RTDM_NO_DEFAULT_USER_API to switch off the default rt_dev_xxx 270 * interface when providing a customised user API */ 271 #ifndef RTDM_NO_DEFAULT_USER_API 272 273 #ifdef __KERNEL__ 274 275 #define rt_dev_open(path, oflag, ...) \ 276 __rt_dev_open(NULL, path, oflag) 277 278 #define rt_dev_socket(protocol_family, socket_type, protocol) \ 279 __rt_dev_socket(NULL, protocol_family, socket_type, protocol) 280 281 #define rt_dev_close(fd) \ 282 __rt_dev_close(NULL, fd) 283 284 #define rt_dev_ioctl(fd, request, ...) \ 285 __rt_dev_ioctl(NULL, fd, request, __VA_ARGS__) 286 287 #define rt_dev_read(fd, buf, nbyte) \ 288 __rt_dev_read(NULL, fd, buf, nbyte) 289 290 #define rt_dev_write(fd, buf, nbyte) \ 291 __rt_dev_write(NULL, fd, buf, nbyte) 292 293 #define rt_dev_recvmsg(fd, msg, flags) \ 294 __rt_dev_recvmsg(NULL, fd, msg, flags) 295 296 #define rt_dev_sendmsg(fd, msg, flags) \ 297 __rt_dev_sendmsg(NULL, fd, msg, flags) 298 299 static inline ssize_t rt_dev_recvfrom(int fd, void *buf, size_t len, int flags, 300 struct sockaddr *from, 301 socklen_t *fromlen) 302 { 303 struct iovec iov; 304 struct msghdr msg; 305 int ret; 306 307 iov.iov_base = buf; 308 iov.iov_len = len; 309 310 msg.msg_name = from; 311 msg.msg_namelen = from ? *fromlen : 0; 312 msg.msg_iov = &iov; 313 msg.msg_iovlen = 1; 314 msg.msg_control = NULL; 315 msg.msg_controllen = 0; 316 317 ret = rt_dev_recvmsg(fd, &msg, flags); 318 if (ret >= 0 && from) 319 *fromlen = msg.msg_namelen; 320 return ret; 321 } 322 323 324 static inline int rt_dev_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, nanosecs_rel_t timeout) 325 { 326 #ifdef CONFIG_RTAI_RTDM_SELECT 327 struct xnselector *selector; 328 int ret; 329 selector = rt_malloc(sizeof(struct xnselector)); 330 xnselector_init(selector); 331 ret = __rt_dev_select(nfds, rfds, wfds, efds, timeout, selector, 1); 332 xnselector_destroy(selector); 333 return ret; 334 #else 335 return -ENOSYS; 336 #endif 337 } 338 339 #else /* !__KERNEL__ */ 340 341 #ifdef __cplusplus 342 extern "C" { 343 #endif 344 345 #ifndef _RTAI_FUSION_LXRT_H 346 #include <rtai_lxrt.h> 347 #endif 348 #include <stdarg.h> 349 350 //#define RTAI_LXRT(ext, lsize, srq, arg) rtai_lxrt(ext, lsize, srq, arg).i[LOW] 351 352 #ifndef RTDM_RTAI_LXRT 353 static inline int RTDM_RTAI_LXRT(int ext, int lsize, int srq, void *arg) 354 { 355 int r; 356 if ((r = rtai_lxrt(ext, lsize, srq, arg).i[LOW]) == -ENOSYS && rt_is_hard_real_time(NULL)) { 357 rt_make_soft_real_time(); 358 r = rtai_lxrt(ext, lsize, srq, arg).i[LOW]; 359 rt_make_hard_real_time(); 360 } 361 return r; 362 } 363 #endif 364 365 static inline int rt_dev_fdcount(void) 366 { 367 struct { long dummy; } arg = { 0 }; 368 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_fdcount, &arg); 369 } 370 371 static inline int rt_dev_open(const char *path, int oflag, ...) 372 { 373 struct { const char *path; long oflag; } arg = { path, oflag }; 374 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_open, &arg); 375 } 376 377 static inline int rt_dev_socket(int protocol_family, int socket_type, int protocol) 378 { 379 struct { long protocol_family; long socket_type; long protocol; } arg = { protocol_family, socket_type, protocol }; 380 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_socket, &arg); 381 } 382 383 static inline int rt_dev_close(int fd) 384 { 385 struct { long fd; } arg = { fd }; 386 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_close, &arg); 387 } 388 389 static inline int rt_dev_ioctl(int fd, int request, ...) 390 { 391 struct { long fd; long request; void *arg; } arg = { fd, request, NULL }; 392 va_list ap; 393 va_start(ap, request); 394 arg.arg = va_arg(ap, void *); 395 va_end(ap); 396 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_ioctl, &arg); 397 } 398 399 static inline ssize_t rt_dev_read(int fd, void *buf, size_t nbytes) 400 { 401 struct { long fd; void *buf; long nbytes; } arg = { fd, buf, nbytes }; 402 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_read, &arg); 403 } 404 405 static inline ssize_t rt_dev_write(int fd, const void *buf, size_t nbytes) 406 { 407 struct { long fd; const void *buf; long nbytes; } arg = { fd, buf, nbytes }; 408 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_write, &arg); 409 } 410 411 static inline ssize_t rt_dev_recvmsg(int fd, struct msghdr *msg, int flags) 412 { 413 struct { long fd; struct msghdr *msg; long flags; } arg = { fd, msg, flags }; 414 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_recvmsg, &arg); 415 } 416 417 static inline ssize_t rt_dev_sendmsg(int fd, const struct msghdr *msg, int flags) 418 { 419 struct { long fd; const struct msghdr *msg; long flags; } arg = { fd, msg, flags }; 420 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_sendmsg, &arg); 421 } 422 423 static inline ssize_t rt_dev_recvfrom(int fd, void *buf, size_t len, int flags, 424 struct sockaddr *from, socklen_t *fromlen) 425 { 426 struct iovec iov; 427 struct msghdr msg; 428 int ret; 429 430 iov.iov_base = buf; 431 iov.iov_len = len; 432 433 msg.msg_name = from; 434 msg.msg_namelen = from ? *fromlen : 0; 435 msg.msg_iov = &iov; 436 msg.msg_iovlen = 1; 437 msg.msg_control = NULL; 438 msg.msg_controllen = 0; 439 440 ret = rt_dev_recvmsg(fd, &msg, flags); 441 if (ret >= 0 && from) 442 *fromlen = msg.msg_namelen; 443 return ret; 444 } 445 446 static inline int rt_dev_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, nanosecs_rel_t timeout) 447 { 448 #ifdef CONFIG_RTAI_RTDM_SELECT 449 struct { long nfds; fd_set *rfds; fd_set *wfds; fd_set *efds; nanosecs_rel_t timeout; } arg = { nfds, rfds, wfds, efds, timeout }; 450 return RTDM_RTAI_LXRT(RTDM_INDX, SIZARG, __rtdm_select, &arg); 451 #else 452 return -ENOSYS; 453 #endif 454 } 455 456 #ifdef __cplusplus 457 } 458 #endif 459 460 #endif /* !__KERNEL__ */ 461 462 #ifdef __cplusplus 463 extern "C" { 464 #endif 465 466 static inline ssize_t rt_dev_recv(int fd, void *buf, size_t len, int flags) 467 { 468 return rt_dev_recvfrom(fd, buf, len, flags, NULL, NULL); 469 } 470 471 static inline ssize_t rt_dev_sendto(int fd, const void *buf, size_t len, 472 int flags, const struct sockaddr *to, 473 socklen_t tolen) 474 { 475 struct iovec iov; 476 struct msghdr msg; 477 478 iov.iov_base = (void *)buf; 479 iov.iov_len = len; 480 481 msg.msg_name = (struct sockaddr *)to; 482 msg.msg_namelen = tolen; 483 msg.msg_iov = &iov; 484 msg.msg_iovlen = 1; 485 msg.msg_control = NULL; 486 msg.msg_controllen = 0; 487 488 return rt_dev_sendmsg(fd, &msg, flags); 489 } 490 491 static inline ssize_t rt_dev_send(int fd, const void *buf, size_t len, 492 int flags) 493 { 494 return rt_dev_sendto(fd, buf, len, flags, NULL, 0); 495 } 496 497 static inline int rt_dev_getsockopt(int fd, int level, int optname, 498 void *optval, socklen_t *optlen) 499 { 500 struct _rtdm_getsockopt_args args = 501 { level, optname, optval, optlen }; 502 503 return rt_dev_ioctl(fd, _RTIOC_GETSOCKOPT, &args); 504 } 505 506 static inline int rt_dev_setsockopt(int fd, int level, int optname, 507 const void *optval, socklen_t optlen) 508 { 509 struct _rtdm_setsockopt_args args = 510 { level, optname, (void *)optval, optlen }; 511 512 return rt_dev_ioctl(fd, _RTIOC_SETSOCKOPT, &args); 513 } 514 515 static inline int rt_dev_bind(int fd, const struct sockaddr *my_addr, 516 socklen_t addrlen) 517 { 518 struct _rtdm_setsockaddr_args args = { my_addr, addrlen }; 519 520 return rt_dev_ioctl(fd, _RTIOC_BIND, &args); 521 } 522 523 static inline int rt_dev_connect(int fd, const struct sockaddr *serv_addr, 524 socklen_t addrlen) 525 { 526 struct _rtdm_setsockaddr_args args = { serv_addr, addrlen }; 527 528 return rt_dev_ioctl(fd, _RTIOC_CONNECT, &args); 529 } 530 531 static inline int rt_dev_listen(int fd, int backlog) 532 { 533 return rt_dev_ioctl(fd, _RTIOC_LISTEN, backlog); 534 } 535 536 static inline int rt_dev_accept(int fd, struct sockaddr *addr, 537 socklen_t *addrlen) 538 { 539 struct _rtdm_getsockaddr_args args = { addr, addrlen }; 540 541 return rt_dev_ioctl(fd, _RTIOC_ACCEPT, &args); 542 } 543 544 static inline int rt_dev_getsockname(int fd, struct sockaddr *name, 545 socklen_t *namelen) 546 { 547 struct _rtdm_getsockaddr_args args = { name, namelen }; 548 549 return rt_dev_ioctl(fd, _RTIOC_GETSOCKNAME, &args); 550 } 551 552 static inline int rt_dev_getpeername(int fd, struct sockaddr *name, 553 socklen_t *namelen) 554 { 555 struct _rtdm_getsockaddr_args args = { name, namelen }; 556 557 return rt_dev_ioctl(fd, _RTIOC_GETPEERNAME, &args); 558 } 559 560 static inline int rt_dev_shutdown(int fd, int how) 561 { 562 return rt_dev_ioctl(fd, _RTIOC_SHUTDOWN, how); 563 } 564 565 #ifdef __cplusplus 566 } 567 #endif 568 569 #endif /* RTDM_NO_DEFAULT_USER_API */ 570 571 #endif /* _RTDM_H */