Cosa: An Object-Oriented Platform for Arduino programming

The Cosa project is slowly approaching beta test level. Time to let friends have a look.

https://github.com/mikaelpatel/Cosa

A blog is available at http://cosa-arduino.blogspot.se/. Hope to get time to write about the design principles and how it can be used. Or at least explain the examples and demo code in some more detail :-). The documentation is on-line.

http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/index.html

To install Cosa download from github and unzip in your Sketchbook hardware directory.

https://github.com/mikaelpatel/Cosa/archive/master.zip

Restart the Arduino IDE and the Cosa example sketches and board support will be available in the File>Sketchbook> and Tools>Boards> menus.

Advanced users should git clone instead to allow faster update.

Use the issue handling at github for trouble reports and improvement suggestions. Do not forget "Watch/Star" the repo in github.

Cheers!

Great! I've tried with my ST7735R and IDE 1.5.2. Works fine.. :) Changed /cs and a0 pins to 7 and 8 with:

ST7735R tft(Board::D7, Board::D8);

PS: I want to use it with 1284p - is the board.hh the only place to enhance?

Wow! Costa is amazing, it beats other object-oriented event-driven systems for Arduino.

I hope people invest some time trying it.

If you are an experienced C++ programmer browse the code implementing Cosa, it has great style.

pito: Great! I've tried with my ST7735R and IDE 1.5.2. Works fine.. :) Changed /cs and a0 pins to 7 and 8 with:

ST7735R tft(Board::D7, Board::D8);

PS: I want to use it with 1284p - is the board.hh the only place to enhance?

There are some ifdef's in the different classes so Board.hh is only where you start and then you have to check adapt these classes. But if you wait a few hours or a day or so ;-) I will check more in detail whats special with the 1284p. If it is similar to 328P this is a piece of cake. Right now adding a new Board class is only part of the work.

Only boards based on ATmega328P, Atmega2560 and the ATtiny85 family are supported out of the box. Basically what I have to play with at home.

Thanks for your support with this project and taking the time to test Cosa.

Cheers

pito:
Great! I’ve tried with my ST7735R and IDE 1.5.2. Works fine… :slight_smile:
Changed /cs and a0 pins to 7 and 8 with:

ST7735R tft(Board::D7, Board::D8);

PS: I want to use it with 1284p - is the board.hh the only place to enhance?

BW: Did you test more of the ST7735 driver and the Canvas class? Would be nice to hear more about this and especially the graphics script engine I have put in there. There are some examples on this.

There is also a simple off-screen canvas to help drawing to LCD devices such as the very cheap PCD8544 (Nokia 84x48). The driver is actually defined as an IOStream to allow direct printing with all the IOStream functions and operators (<<).

I put a lot of work into making the Trace support really easy to use on different devices. You can for instance trace directly to the ST7735 by just changing the trace.begin() parameter. The support macros follow the Linux syslog format and will include the function and line in the output. This helps debugging without a debugger :wink:

Cheers.

But if you wait a few hours or a day or so ;-) I will check more in detail whats special with the 1284p.

Yes, I'll do :). The 1284p uses a separate core folder - ie. I am using the "mighty" stuff ..\hardware\arduino\avr\cores\mighty1284p..) and pin defs in \hardware\arduino\avr\variants\mighty1284p\pins_arduino.h

pito:

But if you wait a few hours or a day or so ;-) I will check more in detail whats special with the 1284p.

Yes, I'll do :). The 1284p uses a separate core folder - ie. I am using the "mighty" stuff ..\hardware\arduino\avr\cores\mighty1284p..) and pin defs in \hardware\arduino\avr\variants\mighty1284p\pins_arduino.h

I have pushed an update with support for the ATmega1284P.

https://github.com/mikaelpatel/Cosa/commit/568177b054478886f11a3bdcfed10f6b928a430d

Needed to add a new Board class but also update Interrupt and PWM pin handling. I don't have a board with this processor so the only test I have done is verifying build with the mighty1284p arduino core (as above). Actually I only used the boards.txt file. Please test.

I really liked the spec of the ATmega1284P!

Cheers.

It seems the uart needs a fix. 1284p has got two uarts. When running ie CosaBenchmarkThread example I do not get serial output in terminal..

pito: It seems the uart needs a fix. 1284p has got two uarts. When running ie CosaBenchmarkThread example I do not get serial output in terminal..

Missed that. Will have a look. But it seemed to compile alright ;-) Do you have a link to the board schematics? Which of the two UARTs are used for the serial output. I assumed UART0.

https://github.com/mikaelpatel/Cosa/commit/97d796808389a58544815ebba441e28eafe4d2bd

I have updated so the two UARTs are supported but I think there is something else that is the problem. Baudrate?

Cheers.

What is the board spec for the UART? Do you have a link to the board schematics?

mighty1284p.bmp.jpg

Fantastic! The fastest port ever (1284p mighty @16MHz/3V3)…

CosaBenchmarkThread: started
sizeof(Thread) = 9
sizeof(Counter) = 13
113:loop:info:31 us per dispatch (496 cycles)
113:loop:info:31 us per dispatch (496 cycles)
113:loop:info:31 us per dispatch (496 cycles)

CosaBenchmarkRTC: started
free_memory() = 15932
Watchdog::ms_per_tick() = 16
Watchdog::get_ticks() = 0
58:setup:info:RTC::micros(): 4
63:setup:info:RTC::millis(): 4
68:setup:info:DELAY(1): 4

CosaBenchmarkFSM: started
free_memory() = 15916
sizeof(Event::Handler) = 2
sizeof(Link) = 6
sizeof(FSM) = 12
sizeof(Echo) = 14
F_CPU = 16000000
I_CPU = 16
EVENTS_MAX = 100000
132:loop:info:27 us per event (432 cycles)
132:loop:info:27 us per event (432 cycles)
132:loop:info:27 us per event (432 cycles)

CosaBenchmarkPins: started
free_memory() = 15889
sizeof(Event::Handler) = 2
sizeof(InputPin) = 4
sizeof(OutputPin) = 4
sizeof(AnalogPin) = 9
74:setup:info:Loop: 504 us per 1,000 nop loops

85:setup:info:Arduino: 6478 us per 1000 digitalRead(7)
95:setup:info:Cosa(10X): 629 us per 1000 inPin.is_set()
106:setup:info:Cosa(10X): 629 us per 1000 inPin >> var
116:setup:info:Cosa(11X): 567 us per 1000 InputPin::read(7)

128:setup:info:Arduino: 9812 us per 1000 digitalWrite(8, 1); digitalWrite(8, 0)
139:setup:info:Cosa(1X): 5032 us per 1000 outPin.write(1); outPin.write(0)
150:setup:info:Cosa(4X): 2328 us per 1000 outPin.set; outPin.clear()
161:setup:info:Cosa(4X): 2328 us per 1000 outPin << 1; outPin << 0
172:setup:info:Cosa(1X): 5535 us per 1000 OutputPin::write(8, 1); OutputPin::write(8, 0)

183:setup:info:Arduino: 9623 us per 1000 digitalWrite(8, !digitalRead(8))
193:setup:info:Cosa(2X): 3711 us per 1000 outPin.write(!outPin.read())
203:setup:info:Cosa(4X): 2139 us per 1000 outPin.is_set/clear/set()
215:setup:info:Cosa(4X): 2076 us per 1000 outPin >> var; outPin << !var
225:setup:info:Cosa(4X): 2076 us per 1000 outPin.set/is_clear()
235:setup:info:Cosa(8X): 1196 us per 1000 outPin.toggle()
245:setup:info:Cosa(3X): 3145 us per 1000 OutputPin::write(8, !OutputPin::read(8))
258:setup:info:Cosa(2X): 3271 us per 1000 OutputPin::read/write(8,0/1)
268:setup:info:Cosa(12X): 755 us per 1000 OutputPin::toggle(8)

283:setup:info:Arduino: 14 us per bit data transfer() digitalWrite()
297:setup:info:Cosa(2X): 7 us per bit data transfer() pin.write()
311:setup:info:Cosa(3X): 4 us per bit data transfer() pin.write/toggle()
325:setup:info:Cosa(1X): 9 us per bit data transfer() OutputPin::write()
339:setup:info:Cosa(3X): 4 us per bit data transfer() OutputPin::write/toggle()
373:setup:info:Cosa(4X): 3 us per bit data transfer() pin.write/toggle() unrolled

383:setup:info:Arduino: 16 us per bit data transfer() shiftOut()
393:setup:info:Cosa(4X): 4 us per bit data transfer() dataPin.write()

401:setup:info:Arduino: 112 us per analogRead()
408:setup:info:Cosa(1X): 112 us per analogPin.sample()
417:setup:info:Cosa(1X): 112 us per analogPin >> var
424:setup:info:Cosa(1X): 112 us per AnalogPin::sample()

pito: Fantastic!

CosaBenchmarkThread: started
sizeof(Thread) = 9
sizeof(Counter) = 13
113:loop:info:31 us per dispatch (496 cycles)

CosaBenchmarkRTC: started free_memory() = 15932

Looking good!

free_memory() = 15916

Wow! Thats something I only dream of ;-). There is a lot of design in Cosa to use PROGMEM when ever possible and cut down on SRAM usage. With 16K I could put in a real RTOS with processes ;-)

Do you have the number on CosaBenchmarkPins? This shows how much faster Cosa is compared to Arduino/Wiring with regard to pin functions.

Cheers - and thanks for your effort testing Cosa!

Do you have the number on CosaBenchmarkPins?

See above.

With 16K I could put in a real RTOS with processes ;-)

A ATmega1284P has 16KB of SRAM and is pretty simple to get working in the arduino IDE.

Lefty

Wow! Thats something I only dream of ;-). There is a lot of design in Cosa to use PROGMEM when ever possible and cut down on SRAM usage. With 16K I could put in a real RTOS with processes ;-)

There should be no problem with that much memory.

ChibiOS/RT http://www.chibios.org/dokuwiki/doku.php is a nice little preemptive RTOS that easily runs on an Uno. It does a semaphore take plus a context switch in 12 usec.

Giovanni Di Sirio, the author of ChibiOS wrote an experimental preemptive kernel called Nil RTOS that is really small.

I have been playing with it on Uno and each thread takes only a few bytes plus stack space. It does a context switch a little faster than ChibiOS.

The Arduino versions are here http://code.google.com/p/rtoslibs/downloads/list.

You can really speed up pin I/O using a template class. I just posted a library that does writes in two cycles or 0.125 usec on an Uno. That library is at the above location.

It is interesting how much know-how and energy do spend/invest people into retro-computing stuff (when talking 8-bitters) :) PS: PIC32MX250F128B costs the same as the atmega328p and less than the atmega1284p..

fat16lib:

Wow! Thats something I only dream of ;-). There is a lot of design in Cosa to use PROGMEM when ever possible and cut down on SRAM usage. With 16K I could put in a real RTOS with processes ;-)

You can really speed up pin I/O using a template class. I just posted a library that does writes in two cycles or 0.125 usec on an Uno. That library is at the above location.

I looked at your library recently and found that it uses much the same techniques as in Cosa and Jeelab. The current Arduino/Wiring style can be improved a lot with regards to speed and abstraction. Using C++ is a way forward.

The more important issues are abstracting and structuring the code base so that drivers, libraries, etc, can be added in a methodological fashion. Also I see a need to abstract IO functionality so that devices can be extended, replaced, etc. The IOStream/Canvas and IOBuffer classes in Cosa help a lot with this.

It would be nice to have a device driver framework for Arduino that allows a component view of both hardware modules/shields and software. Cosa is a small step in this direction. 1-Wire, I2C, SPI, etc, needs an abstraction layer and protocol generation so that integration becomes as easy as build in Arduino today. The research done in the d-tools project is an excellent starting point but we need to look at platform support for communicating systems; e.g. application build onto multiple boards, processors, etc, communicating over wire or wireless.

Hardware wise Arduino is a great contribution to getting cheap hardware for schools, university, prototyping and hobby projects. Software wise we have a lot more to do. Much has been done but additional structuring and refactoring is needed for the next quantum leap. Arduino/Wiring is great for beginners but it has some obstacles when it comes to scaling to larger projects. And 32-bits processors are not the answer even if they remove some of the resource limitations (memory, etc).

I think that there is a fair number of professionals with many years of experience of software design and implementation out there/here using Arduino for fun which could and should contribute in this process.

Cheers!

pito: It is interesting how much know-how and energy do spend/invest people into retro-computing stuff (when talking 8-bitters) :) PS: PIC32MX250F128B costs the same as the atmega328p and less than the atmega1284p..

A chip alone does not a board make. I think you underestimate the fun of making a '8 bitter' do what one can make them do. It's a hobby dude. We don't do it to try and impress the ladies. ;)

Lefty

The more important issues are abstracting and structuring the code base so that drivers, libraries, etc, can be added in a methodological fashion. Also I see a need to abstract IO functionality so that devices can be extended, replaced, etc. The IOStream/Canvas and IOBuffer classes in Cosa help a lot with this.

This won't happen as long as the Arduino company controls the IDE and you fit your stuff into that environment. The average user just won't use Cosa since what they get from Arduino is good enough for hobby use.

I was involved with BSD Unix at Berkeley. The goal of BSD was to replace AT&T Unix, not fit in. The open source Unix evolved into Linux and is the base for OS X and Android.

Open source Uinx happened because AT&T was impossible to deal with. The Arduino company provides a product hobbyists like or at least live with.

I have ported popular open source RTOSs to Arduino but don't see much interest.

I just accept Arduino and build little add-on libraries that may be useful to users.

I do think serious embedded systems need a preemptive priority scheduler. The research in the 1970s on scheduling with the Liu and Layland theorem on rate monotonic scheduling and Horn’s algorithm (earliest deadline first) are key to modern tools and design.

Object-oriented technology is nice but is hardly mentioned in modern courses on embedded system software like this http://chess.eecs.berkeley.edu/eecs149/.

Models of computation with time and concurrency are much more important than object-oriented software methods.

fat16lib: This won't happen as long as the Arduino company controls the IDE and you fit your stuff into that environment. The average user just won't use Cosa since what they get from Arduino is good enough for hobby use.

I was involved with BSD Unix at Berkeley. The goal of BSD was to replace AT&T Unix, not fit in. The open source Unix evolved into Linux and is the base for OS X and Android.

Open source Uinx happened because AT&T was impossible to deal with. The Arduino company provides a product hobbyists like or at least live with.

I have ported popular open source RTOSs to Arduino but don't see much interest.

I just accept Arduino and build little add-on libraries that may be useful to users.

Supporting a movement like Arduino is not an easy task as the main focus is not programming and the majority of users (and founders) are not programmers. But all this risks graining to a halt when scale starts to play in. The lack of structure will need to be addressed sooner or later and the foundation needs to be production quality; rock solid.

Using a Due with current Ardunio software should be compared to, for instance, using a RaspberryPI. Due gives for the average user just more memory, speed and ports. Trying to integrate different libraries is near impossible as the problem was not so much the lack of memory as the lack of structure. I think that the Mega has already shown this problem.

Professionals don't really use the Arduino IDE. It is basically a toy. A nice toy - but still a toy. The thing is to work around it and replace it in increments. Show the alternatives - slowly. Obviously Cosa can be built without any of the Arduino IDE/library/etc. The only essential part is AVR tools with GCC etc. GNU emacs and make works just fine as an IDE replacement ;-)

I think it is important to show possible steps forward with regard to structuring and using the full power of the programming language C++ for small scale embedded systems. I intend to include a Forth-like virtual machine (working name Avanti) in Cosa. This would gives direct access to the Arduino hardware without a compiler when needed and the possibility to add Domain Specific Languages for teaching, rapid prototyping, etc. The concurrency.cc project is a good inspiration in this regard.

If you think OOP is too larger step for the Arduino community then RTOS is "from here to eternity" ;-)

BW great comments and insights!

Cheers.