Pages: 1 ... 28 29 [30]   Go Down
Author Topic: Cosa: An Object-Oriented Platform for Arduino programming  (Read 86421 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 2
Posts: 59
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The news on the latest updates in Cosa.

1. IOStream
The IOStream class has a new member function to allow simple command line reading; IOStream::readline(buf, size). It will read available characters and append to the given string and return the buffer pointer when the line has been completed. The function will handle backspace, carriage-return and line-feed.

Does this mean that I can use the RFM69/nRF24 also to handle 'shell' commands? In other words I can easily create a serial to LAN/WiFi/Radio translator/gateway??

BTW: You seem to be working om my secret COSA wish list I have while developing prototype hardware. It's magic  smiley-twist
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does this mean that I can use the RFM69/nRF24 also to handle 'shell' commands? In other words I can easily create a serial to LAN/WiFi/Radio translator/gateway??
Not really there yet. You need an IOStream::Driver that will use a Wireless Driver for transportation. There is a mockup https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/IOStream/Driver/WIO.hh that does output only. See the example sketch https://github.com/mikaelpatel/Cosa/blob/master/examples/Wireless/CosaWirelessIOStream/CosaWirelessIOStream.ino. With input handling (i.e. recv) and buffering in the Shell you have all the necessary components for remote commands (at least on the NRF24L01P which has built-in acknowledgement and retransmission).

I am actually working on a telnet and http service that uses the shell. Seems like an interesting challenge. See how much of that ends up in the Cosa source.

BTW: You seem to be working om my secret COSA wish list I have while developing prototype hardware. It's magic  smiley-twist
I have suspected that we have somewhat the same agenda smiley

Cheers!
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some news on the latest updates in the Cosa project:

1. New pin index to Cosa pin symbol mapping.
In many example sketches there has been a need to map between a pin index to the program level pin symbol. There are two mapping tables available. See https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/Board.hh#L100

2. More accurate delay when using the RTC class (timer that implement micros() and millis()).
The Cosa global delay() function is a function pointer and can be redefined. The default implementation uses busy-spin. When the Watchdog is used the Watchdog::delay() is installed instead. This gives low power mode during the delay. The Watchdog accuracy is at most 16 ms tick. When the RTC is used it will install the RTC::delay() function which also gives low power mode but also better accuracy (1 ms). The order of calling Watchdog and RTC begin() defines which version is used.

3. Telnet Shell example sketch.
The CosaShell example sketch has been integrated with the Telnet Server sketch to show how to communicate with the shell over Ethernet. Below is a screenshot with left) build, upload and serial monitoring, and right) telnet connection and commands to the shell.

For more details see https://github.com/mikaelpatel/Cosa/blob/master/examples/Ethernet/CosaTelnetShell/CosaTelnetShell.ino#L108

Cheers!
« Last Edit: August 01, 2014, 06:03:17 pm by kowalski » Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some performance measurements on the Cosa Telnet Shell and a short update:

1. CosaTelnetShell performance
The test bench is an Arduino Mega 2560, Ethernet Shield and a D-Link DWL-810+ Ethernet Wifi Bridge. Connecting through a Wifi Router and back to a laptop (HP Probook 4540s with Ubuntu 12.04 LTS).

a. Max burst string output
To measure the performance of pure text output from the sketch the command "help" can be used. It will print the command help text. Using the command "repeat 1000 help" will generate a longer period to measure. The measured throughput on the laptop is 60-64 K received bytes per second for this test case (using GNOME Terminal/telnet and PuTTY).

The max performance when filling buffers on the W5100 is 250 KBps (8 MHz SPI, 4 byte command to transfer 1 byte data, 1/4 MBps). This is excluding chip select and all the commands necessary to initiate and check status for the W5100 SEND command.

b. Max analog sample rate
The command "analogread a4" will sample the analog pin a4 and print the value to the io-stream (socket). Again the repeat command can be used to find the upper limit of sampling, converting and sending per second; "repeat -t 2500 analogread a4" will measure the time to execute 2500 analogread. The max rate is between 2000-3000 samples per second (sample values are converted to text, printed to the iostream/socket and sent over Ethernet/Wifi).

The variation is due to other traffic and drops on Wifi but also the sample value as the text conversion time depends on the value. Please note that the max sample rate at 112 us per sample is 8900 samples per seconds. And that the above results is for a pure sequential implementation without interleaving. It is possible to, for instance, run number conversion to text in parallel with the sampling (ADC). This could give as much as 4000-5000 samples (in textual format) per second over Ethernet/Wifi from the Arduino board.

c. New example shell commands
i. Command "pinmode" to get or set the pin mode; input, output and pullup. The command "pinmode all" will print the pin mode for all pins.

ii. The CosaShell/CosaTelenetShell are mainly to demonstrate how to use the Cosa command line support (class Shell) but may also be used as debugging tools; check hardware connections, etc. Two new commands have been added to allow scanning of 1-Wire and I2C (OWI and TWI).

iii. Setting date/time and accessing the Cosa RTC timer. The command "date" may be used to display or set the current date/time.

2. New SPI function; clock()
The new static SPI function clock() will map from frequency to the SPI clock rate setting. This allows device drivers to be written independent of the MCU system clock setting and knowledge of the SPI rate command. A SPI device driver only needs to supply the max frequency required on the bus (for the connected device).

3. Boosting W5100 performance
The W5100 device driver uses the new interleaving SPI API (spi.transfer_start/next/await) so that memory access (load/store) can be executed in parallel with SPI transfers. This gives a performance improvement of 10-20%.

4. Bug fixes
a. Analog mux setting on Mega. Failed to read bandgap correctly after using higher analog pin numbers.
b. Improved W5100::Driver::flush() robustness when client or server disconnects.

Cheers!

« Last Edit: August 10, 2014, 02:50:58 am by kowalski » Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Next step in integrating Cosa Shell with Ethernet protocols; A HTTP Server that runs the command line handler.



This HTTP server is simply put together by filtering the HTTP query and passing it to the same command handler as in the previous examples (telnet and serial). Below is a snippet from the request handler:

Code:
void
WebServer::on_request(IOStream& page, char* method, char* path, char* query)
{
  static const char header[] __PROGMEM = ...
  static const char footer[] __PROGMEM = ...
  UNUSED(method);
  UNUSED(path);
  int res = -1;
  page << header;
  if (query != NULL) {
    char c;
    for (char* qp = query; (c = *qp) != 0; qp++)
      if (c == '&') *qp = ' ';
    res = shell.execute(query);
  }
  if (res != 0) page << PSTR("illegal query") << endl;
  page << footer;
}
https://github.com/mikaelpatel/Cosa/blob/master/examples/Ethernet/CosaShellWebServer/CosaShellWebServer.ino

The command line is the URL query where space between options and parameters are replaced with ampersand.

Cheers!
« Last Edit: August 10, 2014, 07:16:52 am by kowalski » Logged

Georgia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see the Teensy 2 is supported.  How about the Teensy 3.1?

Thanks,
Jim
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see the Teensy 2 is supported.  How about the Teensy 3.1?
Hi Jim!

I am sorry to say that the Teensy 3.1 is currently not supported. It is actually a totally different architecture and has much more resources (memory, DMA, etc) which would allow a very different approach to building small to medium scale embedded systems with both RTOS and library support.

Cosa is very much tailored for the AVR and very limited memory resources. On the bright side there is only a hand full classes that are accessing hardware registers etc. The Cosa HAL smiley.

I do have a couple of the Teensy 3.1 boards but have not yet come around to start playing with them. The Teensy 3.1 Arduino core could be an excellent source for kick-starting the porting of Cosa to ARM/SAM/Teensy 3.1.

Cheers!
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A short update on the latest development in the Cosa project.

1. CosaShell
The command line support has been extended with privilege level definition and checking. The built-in levels are GUEST, USER and ADMIN. The Shell::execute() member function will check that the privilege level setting before calling action functions.

The action function may also perform further checking of privilege level depending on options and parameters or even program state. See Shell::is_privileged().
Code:
static int date_action(int argc, char* argv[])
{
  if (argc == 3) {
    if (!shell.is_privileged(Shell::ADMIN))
      return (Shell::PERMISSION_DENIED);
    uint32_t value;
    time_t now;
    char* sp;
    value = strtoul(argv[1], &sp, 10);
    if (*sp != '-' || value < 2000 || value > 2099)
      return (Shell::ILLEGAL_COMMAND);
    ...
}
Please see the example sketch for more details on how this can be used: https://github.com/mikaelpatel/Cosa/blob/master/examples/Sandbox/CosaShell/Commands.cpp#L711 and https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/Shell.hh.

2. Boosting build performance
Cosa can be used with the Arduino IDE and the makefile based build support. The latest update introduces parallel build jobs to reduce build time further. Below is a comparison of the build time.

The Cosa build dramatically reduces the time to compile the core library but also rebuilding sketches after editing. The measurements are performed on a HP ProBook 4540s (Intel® Core™ i5-3230M CPU @ 2.60GHz × 4) with 60 GB SSD , Ubuntu 14.04 LTS (32-bit). Please note that the version 1.5.7 is with link time optimization and extra compiler checking. The Cosa build improvement compared to the Arduino IDE build is approx. X3 for Cosa core library build and over X8 for sketch rebuild. Please note that the Arduino 1.5.7 core source code is approx. 8 KLOC (commented) while the Cosa core is over 62 KLOC (commented) and includes all library functions and support for ATtiny, Mighty, Mega, and many clone boards all in the core library.

3. Telnet Server support class
The Telnet class has be refactored to better support servers based on the Shell class. The Telnet::Server class will handle client connect/disconnect and call a set of virtual member functions on events such as data available. Please see https://github.com/mikaelpatel/Cosa/blob/master/examples/Ethernet/CosaTelnetShell/CosaTelnetShell.ino#L54 and the interface https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/INET/Telnet.hh#L38.

Cheers!
« Last Edit: August 23, 2014, 09:12:31 am by kowalski » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Interesting stuff going on here! I just stumbled upon Cosa and it looks very nice.

After some easy examples I tried to migrate a NMEA (GPS messages) parser library I wrote. The library works in-stream, every character is parsed as it arrives and not put in a buffer to be parsed later. It uses very little memory and is fast. It looked like a great idea to implement it as a subclass to IOStream::Device and attach it as input buffer to a SoftUART instance.

Good news first: It worked more or less on first try. As it is a IOStream::Device it actually executes inside the interrupt where the new characters are received and works completely in the background. Perfect! The Arduino-version also uses UBX messages (a proprietary protocol used by uBlox GPS receivers) but I can't bring this to life on Cosa. I'm able to send UBX commands which are executed on the GPS module but I never receive the answer. I see the answers "on wire" using a logic analyzer but the data is not sent to IOStream::Device::put char(char c). Any ideas why this could happen? Why do I get every NMEA message without problems but it just kinda skips the UBX messages? NMEA is only using 7bit ASCII and UBX messages start with a 0xB5 byte. Is there some kind of 8bit mode I have to activate first?

I may have a chance to work around this and completely ditching UBX messages but I'm still interested why it does not work.

Is there a place where there are some How-To's regarding Cosa? I found the blog on blogspot but it doesn't look complete at all. Sure, the API is documented but for me this is not enough to understand the concepts and ideas behind the whole library (Events, Multi-Threading, ...).

Thanks for taking time to read though my message…
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 452
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Interesting stuff going on here! I just stumbled upon Cosa and it looks very nice.
...
Good news first: It worked more or less on first try. As it is a IOStream::Device it actually executes inside the interrupt where the new characters are received and works completely in the background. Perfect!
Thanks for your interest in Cosa. I am happy to learn that you could port your NMEA parser library and got it working. Good job!

Any ideas why this could happen? Why do I get every NMEA message without problems but it just kinda skips the UBX messages? NMEA is only using 7bit ASCII and UBX messages start with a 0xB5 byte. Is there some kind of 8bit mode I have to activate first?
I would need to see some more details to say what is the problem. How did you set up the SoftUART? There might be a problem with 7-bit mode.

Update: I checked the SoftUART putchar() code and it could return a negative value and cause higher functions to think it was EOF or an error. There is an update that fixes this. https://github.com/mikaelpatel/Cosa/commit/d26d0d46eecd6b10e5d27f288bfd72a31a4692a1

Is there a place where there are some How-To's regarding Cosa? I found the blog on blogspot but it doesn't look complete at all. Sure, the API is documented but for me this is not enough to understand the concepts and ideas behind the whole library (Events, Multi-Threading, ...).
Yes, the blog is old stuff. Nearly a year of development has gone by without any updates to the blog. Hopefully I will get time to come back to that. Most of the concepts in Cosa are standard Computer Science and Software Engineering adapted for small scale Embedded Systems. There are over 150+ example sketches that show different aspects of Cosa and how to use the different classes.

The Cosa "blue-prints" and teaching material are unfortunately not yet open-source.

Cheers!
« Last Edit: August 31, 2014, 01:56:18 pm by kowalski » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Update: I checked the SoftUART putchar() code and it could return a negative value and cause higher functions to think it was EOF or an error. There is an update that fixes this. https://github.com/mikaelpatel/Cosa/commit/d26d0d46eecd6b10e5d27f288bfd72a31a4692a1

Great catch! I've written a small test program which clearly proves that this is the problem:
Code:
class DevTest : public IOStream::Device {
   
public:
    volatile char last;
   
    int putchar(char c) {
        last = c;
    }
};


DevTest testDev;
Soft::UART sUart(Board::D9, Board::PCI8, &testDev); // RX on D8

void setup() {
    uart.begin(57600);
    sUart.begin(9600);
   
    trace.begin(&uart, PSTR("Test code started"));
}

void loop() {
    char printed = 0;
    while (1) {
        if (testDev.last != printed) {
            printed = testDev.last;
            INFO("Seen %d", printed);
        }
    }
    while (sUart.available()) {
        INFO("Received character with code: %d", sUart.getchar());
    }
}

This is the output I get while feeding in increasing byte values:
Code:
82:void loop():info:Seen 121
82:void loop():info:Seen 122
82:void loop():info:Seen 123
82:void loop():info:Seen 124
82:void loop():info:Seen 125
82:void loop():info:Seen 126
82:void loop():info:Seen 127
82:void loop():info:Seen -128
82:void loop():info:Seen -127
82:void loop():info:Seen -126
82:void loop():info:Seen -125
82:void loop():info:Seen -124
82:void loop():info:Seen -123
82:void loop():info:Seen -122
82:void loop():info:Seen -121

I've applied your patch but this did not fix the issue. I finally realized that 'char' is 8bit signed… As soon as I moved from char to uint8_t my problems are solved. Your patch does not change the behavior in my specific case. I've simply chosen the wrong data type. So I'm back on track, thanks for your support.

I'll continue to investigate how Cosa is working. Really love what I've seen so far. Thanks again…
Logged

0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5908
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is better the unsigned char type, it use less Ram that unsigned int
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is better the unsigned char type, it use less Ram that unsigned int

I'm using uint8_t , which is typedef'd to unsigned char. I just prefer to write uint8_t over unsigned char ;-)
Logged

0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5908
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sorry I had not seen the 8  smiley
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Pages: 1 ... 28 29 [30]   Go Up
Jump to: