iio_generic_buffer.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  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. " -A Force-activate ALL channels\n"
  230. " -c <n> Do n conversions, or loop forever if n < 0\n"
  231. " -e Disable wait for event (new data)\n"
  232. " -g Use trigger-less mode\n"
  233. " -l <n> Set buffer length to n samples\n"
  234. " --device-name -n <name>\n"
  235. " --device-num -N <num>\n"
  236. " Set device by name or number (mandatory)\n"
  237. " --trigger-name -t <name>\n"
  238. " --trigger-num -T <num>\n"
  239. " Set trigger by name or number\n"
  240. " -w <n> Set delay between reads in us (event-less mode)\n");
  241. }
  242. enum autochan autochannels = AUTOCHANNELS_DISABLED;
  243. char *dev_dir_name = NULL;
  244. char *buf_dir_name = NULL;
  245. bool current_trigger_set = false;
  246. void cleanup(void)
  247. {
  248. int ret;
  249. /* Disable trigger */
  250. if (dev_dir_name && current_trigger_set) {
  251. /* Disconnect the trigger - just write a dummy name. */
  252. ret = write_sysfs_string("trigger/current_trigger",
  253. dev_dir_name, "NULL");
  254. if (ret < 0)
  255. fprintf(stderr, "Failed to disable trigger: %s\n",
  256. strerror(-ret));
  257. current_trigger_set = false;
  258. }
  259. /* Disable buffer */
  260. if (buf_dir_name) {
  261. ret = write_sysfs_int("enable", buf_dir_name, 0);
  262. if (ret < 0)
  263. fprintf(stderr, "Failed to disable buffer: %s\n",
  264. strerror(-ret));
  265. }
  266. /* Disable channels if auto-enabled */
  267. if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
  268. ret = enable_disable_all_channels(dev_dir_name, 0);
  269. if (ret)
  270. fprintf(stderr, "Failed to disable all channels\n");
  271. autochannels = AUTOCHANNELS_DISABLED;
  272. }
  273. }
  274. void sig_handler(int signum)
  275. {
  276. fprintf(stderr, "Caught signal %d\n", signum);
  277. cleanup();
  278. exit(-signum);
  279. }
  280. void register_cleanup(void)
  281. {
  282. struct sigaction sa = { .sa_handler = sig_handler };
  283. const int signums[] = { SIGINT, SIGTERM, SIGABRT };
  284. int ret, i;
  285. for (i = 0; i < ARRAY_SIZE(signums); ++i) {
  286. ret = sigaction(signums[i], &sa, NULL);
  287. if (ret) {
  288. perror("Failed to register signal handler");
  289. exit(-1);
  290. }
  291. }
  292. }
  293. static const struct option longopts[] = {
  294. { "device-name", 1, 0, 'n' },
  295. { "device-num", 1, 0, 'N' },
  296. { "trigger-name", 1, 0, 't' },
  297. { "trigger-num", 1, 0, 'T' },
  298. { },
  299. };
  300. int main(int argc, char **argv)
  301. {
  302. long long num_loops = 2;
  303. unsigned long timedelay = 1000000;
  304. unsigned long buf_len = 128;
  305. ssize_t i;
  306. unsigned long long j;
  307. unsigned long toread;
  308. int ret, c;
  309. int fp = -1;
  310. int num_channels = 0;
  311. char *trigger_name = NULL, *device_name = NULL;
  312. char *data = NULL;
  313. ssize_t read_size;
  314. int dev_num = -1, trig_num = -1;
  315. char *buffer_access = NULL;
  316. int scan_size;
  317. int noevents = 0;
  318. int notrigger = 0;
  319. char *dummy;
  320. bool force_autochannels = false;
  321. struct iio_channel_info *channels = NULL;
  322. register_cleanup();
  323. while ((c = getopt_long(argc, argv, "aAc:egl:n:N:t:T:w:?", longopts,
  324. NULL)) != -1) {
  325. switch (c) {
  326. case 'a':
  327. autochannels = AUTOCHANNELS_ENABLED;
  328. break;
  329. case 'A':
  330. autochannels = AUTOCHANNELS_ENABLED;
  331. force_autochannels = true;
  332. break;
  333. case 'c':
  334. errno = 0;
  335. num_loops = strtoll(optarg, &dummy, 10);
  336. if (errno) {
  337. ret = -errno;
  338. goto error;
  339. }
  340. break;
  341. case 'e':
  342. noevents = 1;
  343. break;
  344. case 'g':
  345. notrigger = 1;
  346. break;
  347. case 'l':
  348. errno = 0;
  349. buf_len = strtoul(optarg, &dummy, 10);
  350. if (errno) {
  351. ret = -errno;
  352. goto error;
  353. }
  354. break;
  355. case 'n':
  356. device_name = strdup(optarg);
  357. break;
  358. case 'N':
  359. errno = 0;
  360. dev_num = strtoul(optarg, &dummy, 10);
  361. if (errno) {
  362. ret = -errno;
  363. goto error;
  364. }
  365. break;
  366. case 't':
  367. trigger_name = strdup(optarg);
  368. break;
  369. case 'T':
  370. errno = 0;
  371. trig_num = strtoul(optarg, &dummy, 10);
  372. if (errno)
  373. return -errno;
  374. break;
  375. case 'w':
  376. errno = 0;
  377. timedelay = strtoul(optarg, &dummy, 10);
  378. if (errno) {
  379. ret = -errno;
  380. goto error;
  381. }
  382. break;
  383. case '?':
  384. print_usage();
  385. ret = -1;
  386. goto error;
  387. }
  388. }
  389. /* Find the device requested */
  390. if (dev_num < 0 && !device_name) {
  391. fprintf(stderr, "Device not set\n");
  392. print_usage();
  393. ret = -1;
  394. goto error;
  395. } else if (dev_num >= 0 && device_name) {
  396. fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
  397. print_usage();
  398. ret = -1;
  399. goto error;
  400. } else if (dev_num < 0) {
  401. dev_num = find_type_by_name(device_name, "iio:device");
  402. if (dev_num < 0) {
  403. fprintf(stderr, "Failed to find the %s\n", device_name);
  404. ret = dev_num;
  405. goto error;
  406. }
  407. }
  408. printf("iio device number being used is %d\n", dev_num);
  409. ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
  410. if (ret < 0)
  411. return -ENOMEM;
  412. /* Fetch device_name if specified by number */
  413. if (!device_name) {
  414. device_name = malloc(IIO_MAX_NAME_LENGTH);
  415. if (!device_name) {
  416. ret = -ENOMEM;
  417. goto error;
  418. }
  419. ret = read_sysfs_string("name", dev_dir_name, device_name);
  420. if (ret < 0) {
  421. fprintf(stderr, "Failed to read name of device %d\n", dev_num);
  422. goto error;
  423. }
  424. }
  425. if (notrigger) {
  426. printf("trigger-less mode selected\n");
  427. } else if (trig_num >= 0) {
  428. char *trig_dev_name;
  429. ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
  430. if (ret < 0) {
  431. return -ENOMEM;
  432. }
  433. trigger_name = malloc(IIO_MAX_NAME_LENGTH);
  434. ret = read_sysfs_string("name", trig_dev_name, trigger_name);
  435. free(trig_dev_name);
  436. if (ret < 0) {
  437. fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
  438. return ret;
  439. }
  440. printf("iio trigger number being used is %d\n", trig_num);
  441. } else {
  442. if (!trigger_name) {
  443. /*
  444. * Build the trigger name. If it is device associated
  445. * its name is <device_name>_dev[n] where n matches
  446. * the device number found above.
  447. */
  448. ret = asprintf(&trigger_name,
  449. "%s-dev%d", device_name, dev_num);
  450. if (ret < 0) {
  451. ret = -ENOMEM;
  452. goto error;
  453. }
  454. }
  455. /* Look for this "-devN" trigger */
  456. trig_num = find_type_by_name(trigger_name, "trigger");
  457. if (trig_num < 0) {
  458. /* OK try the simpler "-trigger" suffix instead */
  459. free(trigger_name);
  460. ret = asprintf(&trigger_name,
  461. "%s-trigger", device_name);
  462. if (ret < 0) {
  463. ret = -ENOMEM;
  464. goto error;
  465. }
  466. }
  467. trig_num = find_type_by_name(trigger_name, "trigger");
  468. if (trig_num < 0) {
  469. fprintf(stderr, "Failed to find the trigger %s\n",
  470. trigger_name);
  471. ret = trig_num;
  472. goto error;
  473. }
  474. printf("iio trigger number being used is %d\n", trig_num);
  475. }
  476. /*
  477. * Parse the files in scan_elements to identify what channels are
  478. * present
  479. */
  480. ret = build_channel_array(dev_dir_name, &channels, &num_channels);
  481. if (ret) {
  482. fprintf(stderr, "Problem reading scan element information\n"
  483. "diag %s\n", dev_dir_name);
  484. goto error;
  485. }
  486. if (num_channels && autochannels == AUTOCHANNELS_ENABLED &&
  487. !force_autochannels) {
  488. fprintf(stderr, "Auto-channels selected but some channels "
  489. "are already activated in sysfs\n");
  490. fprintf(stderr, "Proceeding without activating any channels\n");
  491. }
  492. if ((!num_channels && autochannels == AUTOCHANNELS_ENABLED) ||
  493. (autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) {
  494. fprintf(stderr, "Enabling all channels\n");
  495. ret = enable_disable_all_channels(dev_dir_name, 1);
  496. if (ret) {
  497. fprintf(stderr, "Failed to enable all channels\n");
  498. goto error;
  499. }
  500. /* This flags that we need to disable the channels again */
  501. autochannels = AUTOCHANNELS_ACTIVE;
  502. ret = build_channel_array(dev_dir_name, &channels,
  503. &num_channels);
  504. if (ret) {
  505. fprintf(stderr, "Problem reading scan element "
  506. "information\n"
  507. "diag %s\n", dev_dir_name);
  508. goto error;
  509. }
  510. if (!num_channels) {
  511. fprintf(stderr, "Still no channels after "
  512. "auto-enabling, giving up\n");
  513. goto error;
  514. }
  515. }
  516. if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) {
  517. fprintf(stderr,
  518. "No channels are enabled, we have nothing to scan.\n");
  519. fprintf(stderr, "Enable channels manually in "
  520. FORMAT_SCAN_ELEMENTS_DIR
  521. "/*_en or pass -a to autoenable channels and "
  522. "try again.\n", dev_dir_name);
  523. ret = -ENOENT;
  524. goto error;
  525. }
  526. /*
  527. * Construct the directory name for the associated buffer.
  528. * As we know that the lis3l02dq has only one buffer this may
  529. * be built rather than found.
  530. */
  531. ret = asprintf(&buf_dir_name,
  532. "%siio:device%d/buffer", iio_dir, dev_num);
  533. if (ret < 0) {
  534. ret = -ENOMEM;
  535. goto error;
  536. }
  537. if (!notrigger) {
  538. printf("%s %s\n", dev_dir_name, trigger_name);
  539. /*
  540. * Set the device trigger to be the data ready trigger found
  541. * above
  542. */
  543. ret = write_sysfs_string_and_verify("trigger/current_trigger",
  544. dev_dir_name,
  545. trigger_name);
  546. if (ret < 0) {
  547. fprintf(stderr,
  548. "Failed to write current_trigger file\n");
  549. goto error;
  550. }
  551. }
  552. /* Setup ring buffer parameters */
  553. ret = write_sysfs_int("length", buf_dir_name, buf_len);
  554. if (ret < 0)
  555. goto error;
  556. /* Enable the buffer */
  557. ret = write_sysfs_int("enable", buf_dir_name, 1);
  558. if (ret < 0) {
  559. fprintf(stderr,
  560. "Failed to enable buffer: %s\n", strerror(-ret));
  561. goto error;
  562. }
  563. scan_size = size_from_channelarray(channels, num_channels);
  564. data = malloc(scan_size * buf_len);
  565. if (!data) {
  566. ret = -ENOMEM;
  567. goto error;
  568. }
  569. ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
  570. if (ret < 0) {
  571. ret = -ENOMEM;
  572. goto error;
  573. }
  574. /* Attempt to open non blocking the access dev */
  575. fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
  576. if (fp == -1) { /* TODO: If it isn't there make the node */
  577. ret = -errno;
  578. fprintf(stderr, "Failed to open %s\n", buffer_access);
  579. goto error;
  580. }
  581. for (j = 0; j < num_loops || num_loops < 0; j++) {
  582. if (!noevents) {
  583. struct pollfd pfd = {
  584. .fd = fp,
  585. .events = POLLIN,
  586. };
  587. ret = poll(&pfd, 1, -1);
  588. if (ret < 0) {
  589. ret = -errno;
  590. goto error;
  591. } else if (ret == 0) {
  592. continue;
  593. }
  594. toread = buf_len;
  595. } else {
  596. usleep(timedelay);
  597. toread = 64;
  598. }
  599. read_size = read(fp, data, toread * scan_size);
  600. if (read_size < 0) {
  601. if (errno == EAGAIN) {
  602. fprintf(stderr, "nothing available\n");
  603. continue;
  604. } else {
  605. break;
  606. }
  607. }
  608. for (i = 0; i < read_size / scan_size; i++)
  609. process_scan(data + scan_size * i, channels,
  610. num_channels);
  611. }
  612. error:
  613. cleanup();
  614. if (fp >= 0 && close(fp) == -1)
  615. perror("Failed to close buffer");
  616. free(buffer_access);
  617. free(data);
  618. free(buf_dir_name);
  619. for (i = num_channels - 1; i >= 0; i--) {
  620. free(channels[i].name);
  621. free(channels[i].generic_name);
  622. }
  623. free(channels);
  624. free(trigger_name);
  625. free(device_name);
  626. free(dev_dir_name);
  627. return ret;
  628. }