Recent

Author Topic: I2C communications using BaseUnix: How to check write (busy) status  (Read 4883 times)

witenite

  • New Member
  • *
  • Posts: 41
Re: I2C communications using BaseUnix: How to check write (busy) status
« Reply #15 on: October 30, 2019, 02:51:36 am »
lately (but still) i develop my robot-project. RPi3 (master) through I2C "is talking" with 4 Arduino Unos (as a slave). I use in this case wiringPi. Some delay in exchange frame between RPi and Unos is needed. On this basis I think that probably BaseUnix would do such exchange in similar way.

Thanks for the feedback. Delays don't surprise me, and in fact are quite common when interfacing or cobbling various bits of hardware together. This is relatively normal and I'm well familiar with it in the micro-controller world. However it's a terrible exploit of resource in my opinion (unless the delay is extremely short, and alternative code would simply be more wasteful of time anyway). For example, when triggering an analog to digital conversion there is an acquisition time that you have to leave the ADC alone for, to do it's job. In low level software, I generally use that time to go and do some other housekeeping. I then either poll the ADC (and it tells me when it is complete) or I ensure my housekeeping takes a lot longer than the time required to complete data acquisition. I expect to apply the same principles in high level software too (IE Linux OS running a Lazarus developed application for example). I have been told by a fellow engineering colleague that A/D conversions as done by the Arduino standard libraries are process blocking (which equates to a delay until the acquisition is complete). For this reason he went on to use alternative hardware/software as he couldn't afford the time lost. I think this is just good software development practice.

witenite

  • New Member
  • *
  • Posts: 41
Re: I2C communications using BaseUnix: How to check write (busy) status
« Reply #16 on: October 30, 2019, 03:04:59 am »
Shouldn't you query return result of i2c writing function? For example, 16 should be returned for busy. Have you tried to display return result? Here is a starting point for the list of error codes: https://www.kernel.org/doc/Documentation/i2c/fault-codes and https://nuetzlich.net/errno.html. In FPC you can see that baseunix.pp includes errno.inc. That's where error codes are, and you can see that 16 is Sys_EBUSY.
Avra, thank you very much. This was exactly the information I was struggling to find (IE the error codes, and their availability etc.) As a person very unfamiliar with BaseUnix (I've been using Linux for several years now, but there's still so much I don't know) I had no idea as to it's capabilities or where there was any good documentation. I had found the earlier pages on BaseUnix (on Lazarus's website) but that was it. And that is also very lacking in detail. For example if you look up fpioctl, you can see it returns a cint result. But what is that result? I suspect it's most likely a Boolean Pass/Fail (type cast as an integer), but such information is lacking. Nevertheless, the fault codes you sent me, and fpgeterrno were exactly what I needed. I am now logging I2C faults etc. and can now improve the ADS1115 library to use this information for more robust communications. When I deliberately break communications (by disconnecting the data line wire) I get error 121 (I/O comms error) and 110 (timeout) coming through from the kernel via Base Unix. Perfect!

Do you use I2C-1 on pins 3 and 5 of the 40-pin connector (marked SDA and SCL on the Pi Wedge) or the other i2c which should be used for EEPROMS only?
Yes, using pins 3 and 5 on the GPIO header.

Once I have the code finalised, I will post the solution here (or at least a Github link) so people can find it should they want it. Again, thanks so much Avra (and the others here on this forum). You have helped me immensely. I owe you a round of beers should we ever meet face to face.  :)
« Last Edit: October 30, 2019, 03:09:40 am by witenite »

MarkMLl

  • Hero Member
  • *****
  • Posts: 8538
Re: I2C communications using BaseUnix: How to check write (busy) status
« Reply #17 on: October 30, 2019, 08:59:33 am »
I for one agree that the documentation could be improved, in fact it's something that I whine about on a fairly regular basis. But as I've said repeatedly, BaseUnix is one of a number of thin wrappers around the OS, and I think it's entirely reasonable to expect a user to be able to use the OS documentation: manpages and, where necessary, references to system-level header files (from -dev packages on Debian and derivatives) etc.

There are however a couple of caveats there. The first is that there are a number of most unpleasant Linux-related subsystems and libraries where there are hacks to handle things like processor-specific alignment. HID handling is one of those, and in that case it's /much/ better to find a higher-level library maintained by people fairly close to the kernel developers (and built using the same tools) than to try to replicate a layer of C macros and data structures: you don't want to be making direct ioctl calls in that sort of case. Been there done that.

The second is that Linux has the peculiarity that on different CPUs you are likely to find different system call numbers and slightly different structures being returned by e.g. a stat() kernel call. The reason for that is that when Linux was ported beyond the original i386 architecture Torvalds et al. decided to use call numbers and data structures to match the dominant unix dialect on that CPU, generally speaking the FPC libraries "do the right thing" in these cases but be extremely careful if you find yourself having to define something yourself: if a kernel operation really is missing from BaseUnix etc. you'll be better conferring with the core developers so that it can be implemented across all CPUs rather than going it alone.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

avra

  • Hero Member
  • *****
  • Posts: 2584
    • Additional info
Re: I2C communications using BaseUnix: How to check write (busy) status
« Reply #18 on: October 30, 2019, 10:07:58 am »
Shouldn't you query return result of i2c writing function? For example, 16 should be returned for busy. Have you tried to display return result? Here is a starting point for the list of error codes: https://www.kernel.org/doc/Documentation/i2c/fault-codes and https://nuetzlich.net/errno.html. In FPC you can see that baseunix.pp includes errno.inc. That's where error codes are, and you can see that 16 is Sys_EBUSY.
Avra, thank you very much. This was exactly the information I was struggling to find
I am glad it helped. I didn't do much. Just traced calls to ioctl and found error list online.

When I deliberately break communications (by disconnecting the data line wire) I get error 121 (I/O comms error) and 110 (timeout) coming through from the kernel via Base Unix. Perfect!
Nice, you can now grow on that.

Robustness is everything in 24/7 processes. If that is your goal, then you can continue in that direction by adding HW watchdog to protect from power line oscillations and lock ups, turning off swap to improve SD card life time, have read only OS to protect from SD card failures, and use something like Balena to remotely monitor and control fleet of your Pi devices.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

 

TinyPortal © 2005-2018