NilRTOS - A Fast Tiny Preemptive RTOS

Type any character to start
Free RAM: 1109
Type is FAT32
Starting print test.  Please wait.

Test of println(uint16_t)
Time 9.97 sec
File size 128.89 KB
Write 12.93 KB/sec
Maximum latency: 20828 usec, Minimum Latency: 176 usec, Avg Latency: 491 usec

Test of printField(uint16_t, char)
Time 3.15 sec
File size 128.89 KB
Write 40.92 KB/sec
Maximum latency: 18748 usec, Minimum Latency: 60 usec, Avg Latency: 150 usec

Test of println(double)
Time 15.06 sec
File size 149.00 KB
Write 9.89 KB/sec
Maximum latency: 19160 usec, Minimum Latency: 572 usec, Avg Latency: 746 usec

Done!

Type any character to start

Edit: Try making the stack for thread 1 larger like this:
Code:
NIL_WORKING_AREA(waThread1, 100);

..no luck..

Do the other NilRTOS examples work?

I can't do anything more since everything I try works fine. I don't have a working xp system.

Edit: Here is one more idea. Change nilSysBegin() to nilSysBeginNoFill(). This will prevent filling stacks when NilRTOS starts so the final message will be wrong.

Change nilSysBegin() to nilSysBeginNoFill().

..the same issue..

other stuff ie.:
nilblink blinks

nilBlinkPrint:

Count: 628299, Unused Stack: 57 28 1663
Count: 628306, Unused Stack: 57 28 1663
Count: 628304, Unused Stack: 57 28 1663
Count: 628302, Unused Stack: 57 28 1663

nilSemTest:

micros overhead = 4
sem switch tasks micros = 28
Thd1 Done
sem immediate timeout = 4
sem immediate OK = 4
Thd2 Done

It may be a problem with Serial.read(). nilFifoDataLogger is the only example with Serial.read().

I have tried many Arduino boards and two Windows 7 computers with no problem.

Load the nilTemplate1 example and put the following at the beginning of loop() like this.

void loop() {
  int c = Serial.read();
  if (c < 0) return;
  Serial.print((char)c);
  return;

Run the example and type one or two characters into the serial monitor and see if they are echoed.

Also run nilFifoDataLogger with no SD card and see if this prints:

type any character to begin
SD problem
SD errorCode: 0X1,0X0

Also run nilFifoDataLogger with no SD card and see if this prints:
Quote
type any character to begin
SD problem
SD errorCode: 0X1,0X0

type any character to begin
SD problem
SD errorCode: 0X1,0X0

Yes they are echoed (after pushing Send):

33
54
pito
Q

:slight_smile:

type any character to begin
type any character to end
Done
Unused Stack: 141 342

** overrun errors **

with:

// SD chip select pin.
const uint8_t sdChipSelect = 10; //SS;

pito,

Could you put a continue statement in thread 1 like this so no data is taken.

  while (1) {
    // Sleep until time for next data point
    nilThdSleep(intervalTicks);
    continue;

Let me know what happens.

type any character to begin
type any character to end
Done
Unused Stack: 141 445

data.csv is 0kB

No idea what is the issue, with "continue" it always works, with "//continue" it sometimes works, sometimes does not.

How was this run? Was any data recorded?

type any character to begin
type any character to end
Done
Unused Stack: 141 342

** overrun errors **

with:
Code:

// SD chip select pin.
const uint8_t sdChipSelect = 10; //SS;

The output is from the old example. It should look like this from today's pito.zip file.

type any character to begin
type any character to end
Done
Maximum SD write latency: 3748 usec
Unused Stack: 57 407

Yes, when ran the old one I got csv data (100-200kB).

I cannot get it working with the new version yet.. Still the same issue, with =10 or =SS.. It works with "continue;" only:

type any character to begin
type any character to end
Done
Maximum SD write latency: 0 usec
Unused Stack: 57 480

No idea what to do in order to get it working..

With new one I get now this

type any character to begin
type any character to end
Done
Maximum SD write latency: 48548 usec
Unused Stack: 141 372

with:

// Read ADC data.
    p->value = 555; //analogRead(0);

Strange..

It seems this does the trick (the original example, 115k2) :

void setup() {

  Serial.begin(115200);
  
  analogReference(INTERNAL);

:cold_sweat:

type any character to begin
type any character to end
Done
Maximum SD write latency: 19736 usec
Unused Stack: 57 456
NA	252	0
1024	41	0
1024	47	0
1024	48	0
1024	46	0
1024	45	0
1024	36	0
1024	33	0

I need to think about this. I don't touch the ADC stuff.

I must go out with my wife now.

Another issue I've found - I have to use:

struct FifoItem_t {
  uint16_t usec;        // Low 16-bit of time in usec.
  uint16_t value;  // ADC value.
  uint8_t error;   // Overrun count since last point.
};

otherwise the adc value read is not correctly passed to p->value. It seems our compiler has got a problem with passing values to bitfields ..

I don't understand. I store this counter in thread 1

  //  p->value = analogRead(0);
     p->value = nr;
     nr = nr < 1023 ? nr + 1: 0;

and the correct result is written to the SD. The bit field works fine. I ran it for many cycles of 0 - 1023.

Why can't I reproduce your results?

Edit: I now can show that only 8-bit of the ADC value get stored even though the counter works.

Edit: I got rid of the bit fields and now the ADC values in the file match a fixed voltage applied to pin A0.

.. you may see for example (when p->value is a bitfield):

p->value = 1023;      //this works
p->value = analogRead(0); //this does not work, only 8bits passed
p->value = temp;      //this does not work, only 8bits passed

PS: now it seems to me all above issues I saw here were caused by the bitfield issue..

pito,

Do you still need the call to analogReference() after changing FifoItem_t?

I really would like to get to the bottom of why you need the analogReference() call. All it does is set the global analog_reference. My experience has been that things like this are a symptom of a nasty bug.

uint8_t analog_reference = DEFAULT;

void analogReference(uint8_t mode)
{
	// can't actually set the register here because the default setting
	// will connect AVCC and the AREF pin, which would cause a short if
	// there's something connected to AREF.
	analog_reference = mode;
}

I have more cases where bit fields work and a lot where they don't. Clearly they are to be avoided.

I do not need analogreference when not using bitfields.

I modified the program to log three ADC channels every 1024 microseconds.

I added another performance measure, the minimum number of free data records. For the the three ADC test the result is:

Done
Maximum SD write latency: 48364 usec
Minimum free record count: 89
Unused Stack: 57 152

I ran for about 15 minutes with a high quality industrial SD. I allocated 150 FIFO records and the minimum number of free records was 89 so I was never close to an overrun.

The log file size was about 10 MB.

pito,

Thanks for your effort to find the compiler bit field bug. Compiler bugs can be nasty.