0

I am trying to read sensor data from a FIFO buffer embedded in the sensor (LSM9DS1), and store that data on a Teensy 3.2 board to later be put in a file. I can only read 6 bytes at a time from the FIFO.

The sensor's FIFO is read by the Teensy when an interrupt triggers an isr function. I want to store the data on the Teensy memory. Then, after the ISR store the memory, I plan to parse the data and do a few simple calculations in the loop() function before writing it to file.

What is the best way to accomplish this? I tried using a FIFO library for Arduino here, but it doesn't work with interrupts. I encountered errors with declaring it as a volatile memory type.

Could I used shared memory using the sys/shm.h library from C++? If so, how can I import this to my arduino code?

4
  • 1
    Shared memory?? All the memory is already shared, so just declare it as volatile (so the compiler does not "optimize" access to this variable) and you are done. Instead of using an external library, just write a circular buffer with a fixed size array (one array and two indices or pointers). Remember that with microcontrollers you should follow the KISS principle
    – frarugi87
    Mar 23, 2016 at 9:35
  • Hi frarugi. You're right, the data is shared. My idea with the shared memory was that by I could lock and release the variable as needed so that only one process, either the loop() or isr function, would be able to write/read at a time. I'm not sure if this will be a problem if I use a volatile object.
    – Alex K
    Mar 23, 2016 at 13:30
  • 1
    Well Alex, there is no such thing as "two processes", because that implies that there is a sort of scheduler. You won't have concurrent access, because you always know who is executing: if the ISR is working, then the ISR is executing, otherwise the loop. and you can't "pause" the ISR waiting for the loop to release the lock, because the uC won't execute the loop if it is in the isr. You just have to declare the variable as volatile, since it can be modified in the isr (and so in the loop the compiler can't save it to a register, since it can be modified in any moment)
    – frarugi87
    Mar 23, 2016 at 14:33
  • @frarugi87 Thanks, that clarifies things for me :)
    – Alex K
    Mar 23, 2016 at 14:59

1 Answer 1

2

Shared memory only makes any sense in two combined situations:

  1. You have a kernel arbitrating processes, threads and memory allocation, with process isolation
  2. You have multiple threads or processes in your application

You certainly don't have number 1 unless you can install an operating system on the Teensy 3.1 (some RTOS may provide a SHM analogue).

As for 2 yes, it could be said you have two threads. But you don't have any form of process isolation, so what one "thread" can access the other "thread" can access.

Both the ISR and the loop() function have access to the exact same memory. Any global variables are accessible to both. You may need to inform the compiler that a variable is modified in one thread and read in another though. The simplest way of doing that is to make the variable volatile by prepending the volatile keyword to the definition.

10
  • Thanks Majenko. I have a question about using volatile variables. What will happen to this variable if I am, say, in the middle of reading/deleting one entry, then the ISR is called. Then I will try to write new data into the volatile variable. Will this create any problems? This was one thing I was warned about when programming this.
    – Alex K
    Mar 23, 2016 at 13:24
  • 1
    It depends a) what the variable is, and b) what you are doing to it. You can google the phrase "Critical Sections" for ways around any problems that may arise. If your operations are atomic then there can be no problem. If they aren't they can be made atomic by making wrapping them in code to make them atomic, and there's a myriad of ways of doing that.
    – Majenko
    Mar 23, 2016 at 13:26
  • Thanks for the suggestion, seems to be just the right topic
    – Alex K
    Mar 23, 2016 at 15:13
  • @Majenko how can you make, for instance, a write to a int32_t atomic? I mean, they are at least four write instructions (and maybe shifts or counter increment). What if the ISR needs to be fired in the middle of this (and of course it needs to change the value of that int32_t )? You can't delay an ISR, so either you throw away the whole ISR (thus losing data) or you will have corrupted data. The solution can be not to work in the ISR (or at least limit the operations in the ISR only to 8 bit data)
    – frarugi87
    Mar 23, 2016 at 15:26
  • 1
    @frarugi87 The simplest way is to make a critical section around your "outside ISR" operation. Easiest method: cli(); ... your operation ... sei();
    – Majenko
    Mar 23, 2016 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.