Running natively on an Arduino Mega (ATmega1280)

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

Moderator: tfAteba

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

Running natively on an Arduino Mega (ATmega1280)

Post by utzig »

Hello,

I recently developed a board which is based on an Arduino Mega for some specific product. Today I created a BSP for running ChibiOS on this board. I'm attaching the board/* and demos/* files as they are right now and two separate patches for the Pal and Serial drivers.

The patch for the Pal driver simply adds support for ports H, J, K and L which are present on the ATmega640, ATmega1280 and ATmega2560. Pretty straight-forward.

The patch for the Serial has some compatibility changes. The SerialConfig was changed to give the number of bits per serial character through a macro instead of using direct register write. So, now the default_config instead of having "(1 << UCSZ1) | (1 << UCSZ0)" has "USART_CHAR_SIZE_8". The motivation for doing this as well as the other changes is that each serial port has its own registers with its own bit definitions. For ATmega128 you could do this:

UCSR0B = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE)

For ATmega1280 (640/2560/etc) these are not defined anymore. Instead of RXEN you have to use RXEN0. Although RXEN0, RXEN1, RXEN2, etc all have the same value, the former (RXEN) doesn't seem to be defined anymore. All these bit definitions (*0, *1, etc) were available before so it didn't impact current existing BSPs (I guess...). I compiled demos/AVR-AT90CANx-GCC and demos/AVR-ATmega128-GCC. Sadly I don't have ATmega128/AT90CAN boards to test if the changes hadn't broken something.

I also changed the naming of the macro UBBR2 (and UBRR2_F) to UBRR2x (baudrate multiplied by 2) because the former seems to be already defined for ATmega1280 and does something completely differente. This macros are not used by any code right now.

And to run this on an Arduino Mega the FUSE must be reprogrammed. To do that with avrdude just add the following extra commands:

-U lfuse:w:0xe7:m -U hfuse:w:0x99:m

Of course, as ChibiOS will run natively, Arduino bootloader will not be available anymore!

Here are the results:

*** ChibiOS/RT test suite
***
*** Kernel: 2.5.0
*** Compiled: May 21 2012 - 18:44:53
*** Compiler: GCC 4.3.3
*** Architecture: AVR
*** Core Variant: MegaAVR
*** Port Info: None
*** Platform: ATmega128
*** Test Board: Arduino Mega

----------------------------------------------------------------------------
--- Test Case 1.1 (Threads, enqueuing test #1)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.2 (Threads, enqueuing test #2)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.3 (Threads, priority change)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.4 (Threads, delays)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.1 (Semaphores, enqueuing)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.2 (Semaphores, timeout)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.3 (Semaphores, atomic signal-wait)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.4 (Binary Semaphores, functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.1 (Mutexes, priority enqueuing test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.2 (Mutexes, priority inheritance, simple case)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.3 (Mutexes, priority inheritance, complex case)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.4 (Mutexes, priority return)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.5 (Mutexes, status)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.6 (CondVar, signal test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.7 (CondVar, broadcast test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.8 (CondVar, boost test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.1 (Messages, loop)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.1 (Mailboxes, queuing and timeouts)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.1 (Events, registration and dispatch)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.2 (Events, wait and broadcast)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.3 (Events, timeouts)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 10.1 (Queues, input queues)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 10.2 (Queues, output queues)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.1 (Benchmark, messages #1)
--- Score : 30947 msgs/S, 61894 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.2 (Benchmark, messages #2)
--- Score : 24553 msgs/S, 49106 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.3 (Benchmark, messages #3)
--- Score : 24553 msgs/S, 49106 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.4 (Benchmark, context switch)
--- Score : 86488 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.5 (Benchmark, threads, full cycle)
--- Score : 19426 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.6 (Benchmark, threads, create only)
--- Score : 24670 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.7 (Benchmark, mass reschedule, 5 threads)
--- Score : 7982 reschedules/S, 47892 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
--- Score : 52320 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)
--- Score : 91888 bytes/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.10 (Benchmark, virtual timers set/reset)
--- Score : 85722 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.11 (Benchmark, semaphores wait/signal)
--- Score : 227564 wait+signal/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.12 (Benchmark, mutexes lock/unlock)
--- Score : 116724 lock+unlock/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.13 (Benchmark, RAM footprint)
--- System: 235 bytes
--- Thread: 32 bytes
--- Timer : 10 bytes
--- Semaph: 5 bytes
--- EventS: 2 bytes
--- EventL: 5 bytes
--- Mutex : 8 bytes
--- CondV.: 4 bytes
--- Queue : 16 bytes
--- MailB.: 18 bytes
--- Result: SUCCESS
----------------------------------------------------------------------------

Final result: SUCCESS
Attachments
avr_serial_fixes.patch.gz
Fixes for ATmega1280 serial driver
(1.47 KiB) Downloaded 581 times
avr_pal_ports_hjkl.patch.gz
Add support for AVR I/O ports H, J, K, L
(626 Bytes) Downloaded 529 times
chibios_arduino_mega_1280.zip
ChibiOS/RT for Arduino Mega
(17.91 KiB) Downloaded 598 times
utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Has thanked: 1 time
Been thanked: 20 times

Re: Running natively on an Arduino Mega (ATmega1280)

Post by utzig »

Questions:

1) Every port has to use CH_FREQUENCY == 1000?

Since switching tasks on an AVR is more expensive than CM3, for example, I would rather use a value like 100 or 250.

Regarding CH_TIME_QUANTUM, on chschd.c there's:

otp->p_preempt = CH_TIME_QUANTUM;

And this is decremented in chSysTimerHandlerI (currp->p_preempt--).

2) What I understand is that CH_TIME_QUANTUM is given in number of ticks. Is that right?

Fabio Utzig
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Running natively on an Arduino Mega (ATmega1280)

Post by Giovanni »

Hi,

Thanks for patches, I will try merging in the evening. About your questions:

1) No, you can use any value but you have to adjust the timer settings too in board.c. 100 is a good value for 8 bits micros.
2) Correct, 0=no preemption among threads at same priority level.

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

Re: Running natively on an Arduino Mega (ATmega1280)

Post by utzig »

Giovanni,

Do you intend to merge this?

Fabio Utzig
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Running natively on an Arduino Mega (ATmega1280)

Post by Giovanni »

I totally forgot it...

I will give it a try in the weekend.

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Running natively on an Arduino Mega (ATmega1280)

Post by Giovanni »

Hi, I merged the patches, could you please verify if everything is OK?

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

Re: Running natively on an Arduino Mega (ATmega1280)

Post by utzig »

Hi Giovanni,

Everything seems ok. The only thing which is different from my local code, is that set_error() functions is using a variable sts of type chnflags_t and at the end chnAddFlagsI() on this variable. My code was using type ioflags_t and chIOAddFlagsI(). I suppose this is some API change.

I just run it and it seems to be working. I'm using CH_FREQUENCY = 100 on my local copy but it seems to only give slightly better numbers in the TestThread().

Fabio Utzig
Post Reply