ChibiOS on Arduino < 1024uS thread interval possible?

ChibiOS public support forum for topics related to the Atmel AVR family of micro-controllers.

Moderator: tfAteba

Post Reply
dylanfm
Posts: 3
Joined: Thu Jun 04, 2015 7:46 pm

ChibiOS on Arduino < 1024uS thread interval possible?

Post by dylanfm »

Hello,

I'm using ChibiOS on a Arduino Pro Mini 3.3V @ 8MHz. I'm trying to run an SD data logger that logs some I2C sensor data to an SD card every 1.5ms. Using the data logger example as a base I got it all working fine with no overruns, but no matter what I do I can't get it to log faster than 1 sample every 2ms.

I think part of the problem is that I'm using an 8MHz board. Using the example code with it set up like:

Code: Select all

// interval between points in units of 1024 usec
const uint16_t intervalTicks = 2;


Then it actually collects data at a 4ms rate, and when I change intervalTicks to 1 the it collects at a 2ms rate. I can live with having to adjust my code to reflect half of what I want the sample right to be, but I need to collect data at something in between 1 and 2ms

So tried changing the thread sleep function to:

Code: Select all

chThdSleepMicroseconds(1500);

But didn't work either.

I tried playing with the "#define CH_FREQUENCY (F_CPU/16384L)" and "#define CH_TIME_QUANTUM 20" settings in the .h files but no matter what I did it still collects at 2.048ms.

I don't understand where the settings are that make my "intervalTicks" double and more importantly I can't figure out how to set an interval that isn't a multiple of 1024us. It seems like it should be possible.

The reason I'm running at 8MHz is because I need a small, 3.3V compatible arduino board and didn't have at 16MHz. I have a Teensy 3.1 that might also work, but looking at the example file in the ChibiOS_Arm folder it looks like that comment about "intervals of 1024us" is in there also and I don't want to tear my hardware setup all apart if it is going to have the same problem.

Can anybody help point me in the right direction?

Thanks,
Dylan
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by utzig »

Just to be sure, did you select the right board/processor/clock in the Arduino IDE?
dylanfm
Posts: 3
Joined: Thu Jun 04, 2015 7:46 pm

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by dylanfm »

Yes, i have the correct board selected in the IDE.
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by utzig »

I was just investigating how exactly the timings are generated on Arduino and ChibiOS-Arduino.

The keys functions are:

https://github.com/arduino/Arduino/blob ... ing.c#L243

And:

https://github.com/greiman/ChibiOS-Ardu ... oard.c#L40

Basically the Arduino firmware already configures Timer 0 in mode 3 (Fast PWM) which means it counts up to 0xFF and generates an overflow interrupt which the firmwares uses to updates its internal time to enable use of millis, for example. What ChibiOS-Arduino does is to also enable the compare A interrupt when the value of the counter reaches 128. Smart! So the same Timer 0 is shared by both the Arduino firmware and ChibiOS. Also the arduino firmware configures the timer with a prescaler value of 64. So what you get is a timer that generates an interrupt every 2ms:

Code: Select all

1 / (8000000 / 64 / 256)


Ah, and btw that is also why the CH_FREQUENCY has the value F_CPU / 16384, where 16384 is the result of 64 * 256 (prescaler times resolution).

So if you want more resolution you could always configure the prescaler (register TCCR0B bits CS0x) to a lower value and adjust the CH_FREQUENCY accordingly. But that would probably impact every Arduino library you use because they all depend on millis(), delay(), etc to do their timings.

Cheers,
Fabio Utzig
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by utzig »

Ah, forgot to mention but with F_CPU equal to 16MHz the configured tick would really be 1ms...
dylanfm
Posts: 3
Joined: Thu Jun 04, 2015 7:46 pm

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by dylanfm »

Thank you for the information. I will have to look at his more. If changing the prescaler register doesn't mess up my I2C communication then I might just change it and only for programming this project.

I still don't understand why if it is configuring the compare interrupt at half of 0xFF it isn't triggering at half the arduino tick of 1024? Or why I cant just change that compare interrupt to be 64 and change CH_FREQUENCY to something else and get what I want.

Admittedly I am a very amateur coder.

Thanks again,
Dylan
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by utzig »

dylanfm wrote:If changing the prescaler register doesn't mess up my I2C communication then I might just change it and only for programming this project.


The Wire driver doesn't use timings so you should be good.

dylanfm wrote:I still don't understand why if it is configuring the compare interrupt at half of 0xFF it isn't triggering at half the arduino tick of 1024? Or why I cant just change that compare interrupt to be 64 and change CH_FREQUENCY to something else and get what I want.


The counter configuration makes it run up to 255 every time. You will always end up counting 256 no matter were you put the compare interrupt. I guess the main reason for choosing 128 is that it is half-way through, so that both interrupts have minimal interference with each other.

Cheers,
Fabio Utzig
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: ChibiOS on Arduino < 1024uS thread interval possible?

Post by utzig »

If you really need a faster tick, I would suggest changing boardInit to:

Code: Select all

void boardInit(void) {
  /*
   * Timer 0 setup.
   */
  OCR0A = 128;
  TCCR0B &= ~CS00;                                        /* change default prescaler to 8 */
  TIMSK0  |= (1 << OCIE0A);                               /* IRQ on compare.  */
}


And CH_FREQUENCY to (F_CPU/2048L).

That should give you a tick of 250uS. And maybe some new issues! :P
Post Reply