iio_generic_buffer.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /* Industrialio buffer test code.
  2. *
  3. * Copyright (c) 2008 Jonathan Cameron
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 as published by
  7. * the Free Software Foundation.
  8. *
  9. * This program is primarily intended as an example application.
  10. * Reads the current buffer setup from sysfs and starts a short capture
  11. * from the specified device, pretty printing the result after appropriate
  12. * conversion.
  13. *
  14. * Command line parameters
  15. * generic_buffer -n <device_name> -t <trigger_name>
  16. * If trigger name is not specified the program assumes you want a dataready
  17. * trigger associated with the device and goes looking for it.
  18. *
  19. */
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <dirent.h>
  23. #include <fcntl.h>
  24. #include <stdio.h>
  25. #include <errno.h>
  26. #include <sys/stat.h>
  27. #include <sys/dir.h>
  28. #include <linux/types.h>
  29. #include <string.h>
  30. #include <poll.h>
  31. #include <endian.h>
  32. #include <getopt.h>
  33. #include <inttypes.h>
  34. #include <stdbool.h>
  35. #include <signal.h>
  36. #include "iio_utils.h"
  37. /**
  38. * enum autochan - state for the automatic channel enabling mechanism
  39. */
  40. enum autochan {
  41. AUTOCHANNELS_DISABLED,
  42. AUTOCHANNELS_ENABLED,
  43. AUTOCHANNELS_ACTIVE,
  44. };
  45. /**
  46. * size_from_channelarray() - calculate the storage size of a scan
  47. * @channels: the channel info array
  48. * @num_channels: number of channels
  49. *
  50. * Has the side effect of filling the channels[i].location values used
  51. * in processing the buffer output.
  52. **/
  53. int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
  54. {
  55. int bytes = 0;
  56. int i = 0;
  57. while (i < num_channels) {
  58. if (bytes % channels[i].bytes == 0)
  59. channels[i].location = bytes;
  60. else
  61. channels[i].location = bytes - bytes % channels[i].bytes
  62. + channels[i].bytes;
  63. bytes = channels[i].location + channels[i].bytes;
  64. i++;
  65. }
  66. return bytes;
  67. }
  68. void print1byte(uint8_t input, struct iio_channel_info *info)
  69. {
  70. /*
  71. * Shift before conversion to avoid sign extension
  72. * of left aligned data
  73. */
  74. input >>= info->shift;
  75. input &= info->mask;
  76. if (info->is_signed) {
  77. int8_t val = (int8_t)(input << (8 - info->bits_used)) >>
  78. (8 - info->bits_used);
  79. printf("%05f ", ((float)val + info->offset) * info->scale);
  80. } else {
  81. printf("%05f ", ((float)input + info->offset) * info->scale);
  82. }
  83. }
  84. void print2byte(uint16_t input, struct iio_channel_info *info)
  85. {
  86. /* First swap if incorrect endian */
  87. if (info->be)
  88. input = be16toh(input);
  89. else
  90. input = le16toh(input);
  91. /*
  92. * Shift before conversion to avoid sign extension
  93. * of left aligned data
  94. */
  95. input >>= info->shift;
  96. input &= info->mask;
  97. if (info->is_signed) {
  98. int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
  99. (16 - info->bits_used);
  100. printf("%05f ", ((float)val + info->offset) * info->scale);
  101. } else {
  102. printf("%05f ", ((float)input + info->offset) * info->scale);
  103. }
  104. }
  105. void print4byte(uint32_t input, struct iio_channel_info *info)
  106. {
  107. /* First swap if incorrect endian */
  108. if (info->be)
  109. input = be32toh(input);
  110. else
  111. input = le32toh(input);
  112. /*
  113. * Shift before conversion to avoid sign extension
  114. * of left aligned data
  115. */
  116. input >>= info->shift;
  117. input &= info->mask;
  118. if (info->is_signed) {
  119. int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
  120. (32 - info->bits_used);
  121. printf("%05f ", ((float)val + info->offset) * info->scale);
  122. } else {
  123. printf("%05f ", ((float)input + info->offset) * info->scale);
  124. }
  125. }
  126. void print8byte(uint64_t input, struct iio_channel_info *info)
  127. {
  128. /* First swap if incorrect endian */
  129. if (info->be)
  130. input = be64toh(input);
  131. else
  132. input = le64toh(input);
  133. /*
  134. * Shift before conversion to avoid sign extension
  135. * of left aligned data
  136. */
  137. input >>= info->shift;
  138. input &= info->mask;
  139. if (info->is_signed) {
  140. int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
  141. (64 - info->bits_used);
  142. /* special case for timestamp */
  143. if (info->scale == 1.0f && info->offset == 0.0f)
  144. printf("%" PRId64 " ", val);
  145. else
  146. printf("%05f ",
  147. ((float)val + info->offset) * info->scale);
  148. } else {
  149. printf("%05f ", ((float)input + info->offset) * info->scale);
  150. }
  151. }
  152. /**
  153. * process_scan() - print out the values in SI units
  154. * @data: pointer to the start of the scan
  155. * @channels: information about the channels.
  156. * Note: size_from_channelarray must have been called first
  157. * to fill the location offsets.
  158. * @num_channels: number of channels
  159. **/
  160. void process_scan(char *data,
  161. struct iio_channel_info *channels,
  162. int num_channels)
  163. {
  164. int k;
  165. for (k = 0; k < num_channels; k++)
  166. switch (channels[k].bytes) {
  167. /* only a few cases implemented so far */
  168. case 1:
  169. print1byte(*(uint8_t *)(data + channels[k].location),
  170. &channels[k]);
  171. break;
  172. case 2:
  173. print2byte(*(uint16_t *)(data + channels[k].location),
  174. &channels[k]);
  175. break;
  176. case 4:
  177. print4byte(*(uint32_t *)(data + channels[k].location),
  178. &channels[k]);
  179. break;
  180. case 8:
  181. print8byte(*(uint64_t *)(data + channels[k].location),
  182. &channels[k]);
  183. break;
  184. default:
  185. break;
  186. }
  187. printf("\n");
  188. }
  189. static int enable_disable_all_channels(char *dev_dir_name, int enable)
  190. {
  191. const struct dirent *ent;
  192. char scanelemdir[256];
  193. DIR *dp;
  194. int ret;
  195. snprintf(scanelemdir, sizeof(scanelemdir),
  196. FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
  197. scanelemdir[sizeof(scanelemdir)-1] = '\0';
  198. dp = opendir(scanelemdir);
  199. if (!dp) {
  200. fprintf(stderr, "Enabling/disabling channels: can't open %s\n",
  201. scanelemdir);
  202. return -EIO;
  203. }
  204. ret = -ENOENT;
  205. while (ent = readdir(dp), ent) {
  206. if (iioutils_check_suffix(ent->d_name, "_en")) {
  207. printf("%sabling: %s\n",
  208. enable ? "En" : "Dis",
  209. ent->d_name);
  210. ret = write_sysfs_int(ent->d_name, scanelemdir,
  211. enable);
  212. if (ret < 0)
  213. fprintf(stderr, "Failed to enable/disable %s\n",
  214. ent->d_name);
  215. }
  216. }
  217. if (closedir(dp) == -1) {
  218. perror("Enabling/disabling channels: "
  219. "Failed to close directory");
  220. return -errno;
  221. }
  222. return 0;
  223. }
  224. void print_usage(void)
  225. {
  226. fprintf(stderr, "Usage: generic_buffer [options]...\n"
  227. "Capture, convert and output data from IIO device buffer\n"
  228. " -a Auto-activate all available channels\n"
  229. " -c <n> Do n conversions\n"
  230. " -e Disable wait for event (new data)\n"
  231. " -g Use trigger-less mode\n"
  232. " -l <n> Set buffer length to n samples\n"
  233. " --device-name -n <name>\n"
  234. " --device-num -N <num>\n"
  235. " Set device by name or number (mandatory)\n"
  236. " --trigger-name -t <name>\n"
  237. " --trigger-num -T <num>\n"
  238. " Set trigger by name or number\n"
  239. " -w <n> Set delay between reads in us (event-less mode)\n");
  240. }
  241. enum autochan autochannels = AUTOCHANNELS_DISABLED;
  242. char *dev_dir_name = NULL;
  243. char *buf_dir_name = NULL;
  244. bool current_trigger_set = false;
  245. void cleanup(void)
  246. {
  247. int ret;
  248. /* Disable trigger */
  249. if (dev_dir_name && current_trigger_set) {
  250. /* Disconnect the trigger - just write a dummy name. */
  251. ret = write_sysfs_string("trigger/current_trigger",
  252. dev_dir_name, "NULL");
  253. if (ret < 0)
  254. fprintf(stderr, "Failed to disable trigger: %s\n",
  255. strerror(-ret));
  256. current_trigger_set = false;
  257. }
  258. /* Disable buffer */
  259. if (buf_dir_name) {
  260. ret = write_sysfs_int("enable", buf_dir_name, 0);
  261. if (ret < 0)
  262. fprintf(stderr, "Failed to disable buffer: %s\n",
  263. strerror(-ret));
  264. }
  265. /* Disable channels if auto-enabled */
  266. if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
  267. ret = enable_disable_all_channels(dev_dir_name, 0);
  268. if (ret)
  269. fprintf(stderr, "Failed to disable all channels\n");
  270. autochannels = AUTOCHANNELS_DISABLED;
  271. }
  272. }
  273. void sig_handler(int signum)
  274. {
  275. fprintf(stderr, "Caught signal %d\n", signum);
  276. cleanup();
  277. exit(-signum);
  278. }
  279. void register_cleanup(void)
  280. {
  281. struct sigaction sa = { .sa_handler = sig_handler };
  282. const int signums[] = { SIGINT, SIGTERM, SIGABRT };
  283. int ret, i;
  284. for (i = 0; i < ARRAY_SIZE(signums); ++i) {
  285. ret = sigaction(signums[i], &sa, NULL);
  286. if (ret) {
  287. perror("Failed to register signal handler");
  288. exit(-1);
  289. }
  290. }
  291. }
  292. static const struct option longopts[] = {
  293. { "device-name", 1, 0, 'n' },
  294. { "device-num", 1, 0, 'N' },
  295. { "trigger-name", 1, 0, 't' },
  296. { "trigger-num", 1, 0, 'T' },
  297. { },
  298. };
  299. int main(int argc, char **argv)
  300. {
  301. unsigned long num_loops = 2;
  302. unsigned long timedelay = 1000000;
  303. unsigned long buf_len = 128;
  304. int ret, c, i, j, toread;
  305. int fp = -1;
  306. int num_channels = 0;
  307. char *trigger_name = NULL, *device_name = NULL;
  308. char *data = NULL;
  309. ssize_t read_size;
  310. int dev_num = -1, trig_num = -1;
  311. char *buffer_access = NULL;
  312. int scan_size;
  313. int noevents = 0;
  314. int notrigger = 0;
  315. char *dummy;
  316. struct iio_channel_info *channels = NULL;
  317. register_cleanup();
  318. while ((c = getopt_long(argc, argv, "ac:egl:n:N:t:T:w:", longopts, NULL)) != -1) {
  319. switch (c) {
  320. case 'a':
  321. autochannels = AUTOCHANNELS_ENABLED;
  322. break;
  323. case 'c':
  324. errno = 0;
  325. num_loops = strtoul(optarg, &dummy, 10);
  326. if (errno) {
  327. ret = -errno;
  328. goto error;
  329. }
  330. break;
  331. case 'e':
  332. noevents = 1;
  333. break;
  334. case 'g':
  335. notrigger = 1;
  336. break;
  337. case 'l':
  338. errno = 0;
  339. buf_len = strtoul(optarg, &dummy, 10);
  340. if (errno) {
  341. ret = -errno;
  342. goto error;
  343. }
  344. break;
  345. case 'n':
  346. device_name = strdup(optarg);
  347. break;
  348. case 'N':
  349. errno = 0;
  350. dev_num = strtoul(optarg, &dummy, 10);
  351. if (errno) {
  352. ret = -errno;
  353. goto error;
  354. }
  355. break;
  356. case 't':
  357. trigger_name = strdup(optarg);
  358. break;
  359. case 'T':
  360. errno = 0;
  361. trig_num = strtoul(optarg, &dummy, 10);
  362. if (errno)
  363. return -errno;
  364. break;
  365. case 'w':
  366. errno = 0;
  367. timedelay = strtoul(optarg, &dummy, 10);
  368. if (errno) {
  369. ret = -errno;
  370. goto error;
  371. }
  372. break;
  373. case '?':
  374. print_usage();
  375. ret = -1;
  376. goto error;
  377. }
  378. }
  379. /* Find the device requested */
  380. if (dev_num < 0 && !device_name) {
  381. fprintf(stderr, "Device not set\n");
  382. print_usage();
  383. ret = -1;
  384. goto error;
  385. } else if (dev_num >= 0 && device_name) {
  386. fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
  387. print_usage();
  388. ret = -1;
  389. goto error;
  390. } else if (dev_num < 0) {
  391. dev_num = find_type_by_name(device_name, "iio:device");
  392. if (dev_num < 0) {
  393. fprintf(stderr, "Failed to find the %s\n", device_name);
  394. ret = dev_num;
  395. goto error;
  396. }
  397. }
  398. printf("iio device number being used is %d\n", dev_num);
  399. ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
  400. if (ret < 0)
  401. return -ENOMEM;
  402. /* Fetch device_name if specified by number */
  403. if (!device_name) {
  404. device_name = malloc(IIO_MAX_NAME_LENGTH);
  405. if (!device_name) {
  406. ret = -ENOMEM;
  407. goto error;
  408. }
  409. ret = read_sysfs_string("name", dev_dir_name, device_name);
  410. if (ret < 0) {
  411. fprintf(stderr, "Failed to read name of device %d\n", dev_num);
  412. goto error;
  413. }
  414. }
  415. if (notrigger) {
  416. printf("trigger-less mode selected\n");
  417. } else if (trig_num >= 0) {
  418. char *trig_dev_name;
  419. ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
  420. if (ret < 0) {
  421. return -ENOMEM;
  422. }
  423. trigger_name = malloc(IIO_MAX_NAME_LENGTH);
  424. ret = read_sysfs_string("name", trig_dev_name, trigger_name);
  425. free(trig_dev_name);
  426. if (ret < 0) {
  427. fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
  428. return ret;
  429. }
  430. printf("iio trigger number being used is %d\n", trig_num);
  431. } else {
  432. if (!trigger_name) {
  433. /*
  434. * Build the trigger name. If it is device associated
  435. * its name is <device_name>_dev[n] where n matches
  436. * the device number found above.
  437. */
  438. ret = asprintf(&trigger_name,
  439. "%s-dev%d", device_name, dev_num);
  440. if (ret < 0) {
  441. ret = -ENOMEM;
  442. goto error;
  443. }
  444. }
  445. /* Look for this "-devN" trigger */
  446. trig_num = find_type_by_name(trigger_name, "trigger");
  447. if (trig_num < 0) {
  448. /* OK try the simpler "-trigger" suffix instead */
  449. free(trigger_name);
  450. ret = asprintf(&trigger_name,
  451. "%s-trigger", device_name);
  452. if (ret < 0) {
  453. ret = -ENOMEM;
  454. goto error;
  455. }
  456. }
  457. trig_num = find_type_by_name(trigger_name, "trigger");
  458. if (trig_num < 0) {
  459. fprintf(stderr, "Failed to find the trigger %s\n",
  460. trigger_name);
  461. ret = trig_num;
  462. goto error;
  463. }
  464. printf("iio trigger number being used is %d\n", trig_num);
  465. }
  466. /*
  467. * Parse the files in scan_elements to identify what channels are
  468. * present
  469. */
  470. ret = build_channel_array(dev_dir_name, &channels, &num_channels);
  471. if (ret) {
  472. fprintf(stderr, "Problem reading scan element information\n"
  473. "diag %s\n", dev_dir_name);
  474. goto error;
  475. }
  476. if (num_channels && autochannels == AUTOCHANNELS_ENABLED) {
  477. fprintf(stderr, "Auto-channels selected but some channels "
  478. "are already activated in sysfs\n");
  479. fprintf(stderr, "Proceeding without activating any channels\n");
  480. }
  481. if (!num_channels && autochannels == AUTOCHANNELS_ENABLED) {
  482. fprintf(stderr,
  483. "No channels are enabled, enabling all channels\n");
  484. ret = enable_disable_all_channels(dev_dir_name, 1);
  485. if (ret) {
  486. fprintf(stderr, "Failed to enable all channels\n");
  487. goto error;
  488. }
  489. /* This flags that we need to disable the channels again */
  490. autochannels = AUTOCHANNELS_ACTIVE;
  491. ret = build_channel_array(dev_dir_name, &channels,
  492. &num_channels);
  493. if (ret) {
  494. fprintf(stderr, "Problem reading scan element "
  495. "information\n"
  496. "diag %s\n", dev_dir_name);
  497. goto error;
  498. }
  499. if (!num_channels) {
  500. fprintf(stderr, "Still no channels after "
  501. "auto-enabling, giving up\n");
  502. goto error;
  503. }
  504. }
  505. if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) {
  506. fprintf(stderr,
  507. "No channels are enabled, we have nothing to scan.\n");
  508. fprintf(stderr, "Enable channels manually in "
  509. FORMAT_SCAN_ELEMENTS_DIR
  510. "/*_en or pass -a to autoenable channels and "
  511. "try again.\n", dev_dir_name);
  512. ret = -ENOENT;
  513. goto error;
  514. }
  515. /*
  516. * Construct the directory name for the associated buffer.
  517. * As we know that the lis3l02dq has only one buffer this may
  518. * be built rather than found.
  519. */
  520. ret = asprintf(&buf_dir_name,
  521. "%siio:device%d/buffer", iio_dir, dev_num);
  522. if (ret < 0) {
  523. ret = -ENOMEM;
  524. goto error;
  525. }
  526. if (!notrigger) {
  527. printf("%s %s\n", dev_dir_name, trigger_name);
  528. /*
  529. * Set the device trigger to be the data ready trigger found
  530. * above
  531. */
  532. ret = write_sysfs_string_and_verify("trigger/current_trigger",
  533. dev_dir_name,
  534. trigger_name);
  535. if (ret < 0) {
  536. fprintf(stderr,
  537. "Failed to write current_trigger file\n");
  538. goto error;
  539. }
  540. }
  541. /* Setup ring buffer parameters */
  542. ret = write_sysfs_int("length", buf_dir_name, buf_len);
  543. if (ret < 0)
  544. goto error;
  545. /* Enable the buffer */
  546. ret = write_sysfs_int("enable", buf_dir_name, 1);
  547. if (ret < 0) {
  548. fprintf(stderr,
  549. "Failed to enable buffer: %s\n", strerror(-ret));
  550. goto error;
  551. }
  552. scan_size = size_from_channelarray(channels, num_channels);
  553. data = malloc(scan_size * buf_len);
  554. if (!data) {
  555. ret = -ENOMEM;
  556. goto error;
  557. }
  558. ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
  559. if (ret < 0) {
  560. ret = -ENOMEM;
  561. goto error;
  562. }
  563. /* Attempt to open non blocking the access dev */
  564. fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
  565. if (fp == -1) { /* TODO: If it isn't there make the node */
  566. ret = -errno;
  567. fprintf(stderr, "Failed to open %s\n", buffer_access);
  568. goto error;
  569. }
  570. for (j = 0; j < num_loops; j++) {
  571. if (!noevents) {
  572. struct pollfd pfd = {
  573. .fd = fp,
  574. .events = POLLIN,
  575. };
  576. ret = poll(&pfd, 1, -1);
  577. if (ret < 0) {
  578. ret = -errno;
  579. goto error;
  580. } else if (ret == 0) {
  581. continue;
  582. }
  583. toread = buf_len;
  584. } else {
  585. usleep(timedelay);
  586. toread = 64;
  587. }
  588. read_size = read(fp, data, toread * scan_size);
  589. if (read_size < 0) {
  590. if (errno == EAGAIN) {
  591. fprintf(stderr, "nothing available\n");
  592. continue;
  593. } else {
  594. break;
  595. }
  596. }
  597. for (i = 0; i < read_size / scan_size; i++)
  598. process_scan(data + scan_size * i, channels,
  599. num_channels);
  600. }
  601. error:
  602. cleanup();
  603. if (fp >= 0 && close(fp) == -1)
  604. perror("Failed to close buffer");
  605. free(buffer_access);
  606. free(data);
  607. free(buf_dir_name);
  608. for (i = num_channels - 1; i >= 0; i--) {
  609. free(channels[i].name);
  610. free(channels[i].generic_name);
  611. }
  612. free(channels);
  613. free(trigger_name);
  614. free(device_name);
  615. free(dev_dir_name);
  616. return ret;
  617. }