I’m sure this has been gone through before, but I cannot find an elegant solution for what I want to do.
I’m looking into making a library to use timers as quadrature encoder readers and one of the intended functionality for me would be to count the number of interrupts (and based on the direction of the count add or subtract this number).
My problem is that I cannot find a nice way of doing this. If I create a function, I cannot access the variable inside the class.
If I define a method as static, I cannot find a way of reusing the code for the different timers… or so it seems to me.
Any ideas?
And I don’t think there is solution, as its not possible to get a pointer to a function in C++ which you can use as an ISR
There was a thread about it on Arduino.cc but it must have been at least a year ago, so it may be hard to find.
You could try PM’ing someone like @Rick Kimball, he knows a knows a lot of clever coding stuff, but I doubt there is an elegant solution
I dont know if this is supported by stm32duino but it can be done.
Normally the interrupt vectors are located in the first bytes of Flash starting at 0x0800000 (or 0x08002000 if bootloader is used) and there are 59 vectors taking 236 bytes (this number is different across STM32 family).
The trick is to copy these vectors to RAM, changing a bit the link script it is possible to make the RAM segment to start at 0x20000100 instead of 0x20000000 (change the line that defines the ORIGIN and LENGTH of RAM segment), this leaves 256 bytes of free RAM memory.
Now in the beginning of your program it is very easy to copy the normal interrupt vectors from the FLASH to RAM and then change the pointer of interrupt vector table at 0x20000000.
I dont know how the libmaple names the system’s control registers (it must be something similar, maybe SCB_BASE->VTOR) but with the ST’s official naming this can be done with the following code :
#define NVIC_RAM_VECTOR_ADDRESS (0x20000000)
#define NVIC_NUM_VECTORS 59
uint32_t *vectors = (uint32_t *)SCB->VTOR;
uint32_t i;
uint32_t *old_vectors = vectors;
vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
for (i=0; i<NVIC_NUM_VECTORS; i++)
vectors[i] = old_vectors[i];
SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
.
// Somewhere in your code assign vector[x] = (uint32_t)foo; where foo() is your function
I think the problem, is that in C++ it is not possible to get a pointer to a function of a particular instance of an object.
So when writing a library, for example software I2C, where each instance has private variables ( properties) for SDA and SCL
you could not do
attachInterrupt(sdaPin,this.isrFunction);
because the compiler can not resolve this.isrFunction to an individual address
I suspect the way to do this in C++ may be to use templates, so that each instance is an instance of a different class , but the class is based on the same template.
The class also would need to have a static function for the ISR and also ideally would be a singleton
Perhaps there is a wrapper function, but I still think the issue that bubulindo is trying to solve is the pointer to method of an instance
When i was developing my frameworks, getting to know that part was quite a pain (i knew the principle, but never encountered it in practice), also libmaple already specifying handler routines for a lot of the interrupts made it a bit of a mess for me to figure out what was happening where
I’ve been able to work with it, but if you’d ask me now how to specify your own ISR routine, i’d probably be searching around in the code for quite a while to figure it out again.
If someone is well versed in this, maybe it’s worth writing a page on it on the wiki? And then also link threads like this to it for related questions/discussions.
But I’m not a C++ expert. :\
First requirement is to use interrupt vectors in RAM (look my previous post)
Then examine carefully the Callback.h from mbed sources : https://github.com/ARMmbed/mbed-os/blob … Callback.h
You can use it almost directly as the Callback class has no dependencies and it is a header only class (it is done by Templates)
Callback class is a helper class that extracts the address of a plain function or a member function during runtime.
Finally you can use it for interrupt vector assigment.
Read here a related question about InterruptIn (is the function that assigns a function to an External Interrupt) to see the use of Callbacks : https://developer.mbed.org/forum/mbed/topic/639/
I made some small tests and it seems that this method is working. I am trying to find a way to relocate the vectors without touching anything in stm32duino sources (the Callback.h can be used almost untouched) and I will post a complete example.
Stay tuned…..
I’ll stay tuned for sure as this could be very interesting development.
For example, GPIO has two versions of attachInterrupt()
void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode);
void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg,
ExtIntTriggerMode mode);

