lancaster-university / microbit-dal

http://lancaster-university.github.io/microbit-docs
Other
256 stars 130 forks source link

timer interrupt events Realize #459

Closed zfm076 closed 4 years ago

zfm076 commented 4 years ago

@Lithimlin Not sure that's entirely true

It highly depends on what interrupts you're referring to. For the most part, interrupt handlers are defined in the mbed layer and so you could use any of the mbed classes to achieve your aims. For timing, Ticker and TimeOut are great classes to use.

Though the DAL aims to cater to most applications, some may have to directly access hardware peripherals in order to meet tight timing requirements, for example. In this case it is better to go for something that offers little abstraction (as @Lithimlin highlights) or override interrupt handlers defined in mbed to decrease interrupt latency .

Perhaps it would be better if you describe your project aims @zfm076?

Hi, I need a timer interrupt events to do something(Like Serial port sends compass data to computer regularly) I don't know how to implement this timer interrupt by using the bit library. Is there an example of that? Is it possible to do that with this function: class MicroBitSystemTimerCallback : MicroBitComponent ? I've been thinking about it for days.Can you give me some ideas?Thanks

Originally posted by @zfm076 in https://github.com/lancaster-university/microbit-dal/issues/352#issuecomment-574045573

zfm076 commented 4 years ago

include "MicroBit.h"

include "MicroBitSystemTimer.h"

MicroBit uBit;

void time_interrupt_fun(void) { uBit.serial.send('A'); }

int main() { uBit.init(); uBit.serial.baud(9600); uBit.serial.setRxBufferSize(254); MicroBitSystemTimerCallback* interrupt= new MicroBitSystemTimerCallback(time_interrupt_fun); uBit.addSystemComponent(interrupt);

while(1)
{
     if(uBit.serial.isReadable())
    {
        uBit.serial.send((char)uBit.serial.read(ASYNC)); 
    }
}

}

For example, in this code, void time_interrupt_fun(void) is not called regularly. I'm not sure I can use that.

jamesadevine commented 4 years ago

Would something like this not work? Do you actually need a timer callback at all?

#include "MicroBit.h"

MicroBit uBit;

int main()
{
    uBit.init();
    uBit.serial.baud(9600);
    uBit.serial.setRxBufferSize(254);

    while (1)
    {
        uBit.serial.printf("%d", uBit.compass.getHeading());
        uBit.sleep(500);
    }
}
zfm076 commented 4 years ago

Would something like this not work? Do you actually need a timer callback at all?

#include "MicroBit.h"

MicroBit uBit;

int main()
{
    uBit.init();
    uBit.serial.baud(9600);
    uBit.serial.setRxBufferSize(254);

    while (1)
    {
        uBit.serial.printf("%d", uBit.compass.getHeading());
        uBit.sleep(500);
    }
}

Hi,Thank you for helping me.It can work.But I don't want the uBit.sleep() in a while(1).Because there are other events that need to be processed quickly in the while(1).such as the parsing of the serial port data sent by the computer, and the data returned by the serial port after the parsing, and so on. So I don't want uBit.sleep() to be in while, In particular,frequent parsing of serial port data is required. The uBit.sleep() will reduce my processing time.

whaleygeek commented 4 years ago

sleep() will allow other fibers to run, and then you can do serial processing in that sleep time to get better overall performance? Do read the scheduling guide here:

https://makecode.microbit.org/device/reactive

Also, at a baud rate of 9600bps you have tons of time to do other stuff, that is quite a slow baud rate (1 character will arrive roughly every 1ms).

The serial transmit works by sending a buffer using a tx interrupt, (and again, at 9600 it will only send 1 character every 1ms), so your code will not be blocked while it is transmitting. Unless you use a higher baud rate, I suspect your performance bottleneck will be the serial port.