-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reorganize task scheduling and fix bug in use of volatile variables #148
Comments
It's not possible to combine the Fsm object with Knitter because the FSM governs both the knitting and testing states. I'm thinking that you could cache |
I would do the following:
/*!
* \brief Initialize interrupt service routine for Encoders object.
*/
void Encoders::setUpInterrupt() {
// (re-)attach ENC_PIN_A(=2), interrupt #0
detachInterrupt(digitalPinToInterrupt(ENC_PIN_A));
#ifndef AYAB_TESTS
// Attaching ENC_PIN_A, Interrupt #0
// This interrupt cannot be enabled until
// the machine type has been validated.
attachInterrupt(digitalPinToInterrupt(ENC_PIN_A), GlobalEncoders::encA_interrupt(), CHANGE);
#endif // AYAB_TESTS
}
/*!
* \brief Update machine state data.
*/
void Knitter::update() {
// update machine state data
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
m_position = GlobalEncoders::getPosition();
m_direction = GlobalEncoders::getDirection();
m_hallActive = GlobalEncoders::getHallActive();
m_beltShift = GlobalEncoders::getBeltShift();
m_carriage = GlobalEncoders::getCarriage();
}
} This way you don't need cached values (Knitter values are safe/nerver overwritten from ISR) and these values are always consistent (updated within a critical section). |
The suggestions by @jpcornil-git are:
main.cpp
to something like:fsm
should really be part of theknitter
object whileisr
code should move fromknitter
toencoders
care should be taken to synchronize handover of machine state data between interrupt and main contexts
An example of a bug is the following:
At the moment this is done in the interrupt context (https://github.com/AllYarnsAreBeautiful/ayab-firmware/blob/v1.0-dev/src/ayab/knitter.cpp#L107) but it is not safe because if an interrupt fires between L402 and L403 of the same file,
m_direction
may change in-between.To fix this,
Knitter::update()
should call, before running thefsm::update()
, an encoderupdate()
method that enter a critical section/disable interrupts, update machine state data, exit the critical section and return.This bug is mostly hidden today as most of the code is executed after and interrupt/before the next one but if something takes more time than expected and delay fsm code such that it hits the next interrupt it may expose it (and a webserver will add more tasks moving forward).
The text was updated successfully, but these errors were encountered: