Wrapping XC in c++ is rubbish

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

void read(char &result)
This would mean every byte received requiring a function call including stack dumps etc.. it would also tie up ones thread preventing it from doing something more useful. Inputting using a select statement in the ADC/SPI module would be much more efficient and your usage of that module could just employ a channel in a select to receive data efficiently without wasting cycles.

regards
Al


User avatar
octal
XCore Addict
Posts: 228
Joined: Thu Jan 27, 2011 3:30 pm
Location: Argenteuil - France

Post by octal »

for point #1: YES I see XMOS more as FPGA with some MCU capabilities than like a chip programmable the MCU way.

Interactive_Matter wrote: Omitting completely to respond your answer in detail I just read the following from it:
To make XC want me forget C++ we need in XC:
  • Modules with name spaces and private data
THIS IS Modula2/3 !!! ;)

Contracts handling can be a good addition indeed!
but I can see more complex things where it becomes needless to use object orientation.
When you write simple protocols encapsulated inside classes, your main program can have parallel sections (and multiple threads). The main prog can be written in XC, and the XC satements can instaciate your classes to ask them to do something (with all needed initilisation stuff to manage them).

But Imagine when you need parallel sections to handle input/output INSIDE YOUR CLASSES. if you need some kind of conditions that may vary, the only way to implement such thing is to subclass your main class, or to make a function that handles that (passing to it some kind of handles ....) and to assign this function to some event handler (or such) of your instance of class.

here object orientation do not solve the problem in an elegant way, it make things worse!!! You'll find yourself just translating the problem, from a simple linear solution in XC to a more complex solution that adds no clarity to the program at all.

Maybe a good solution for your problem is to have something like ObjectiveC sublayer on top of XC. It will give you the object orientation you need without having to deal with C++.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

Folknology wrote:
Omitting completely to respond your answer in detail I just read the following from it:
We do need to cover this, else we mis one of the most important advantages
OK convinced will go into detail.
Folknology wrote:
The SPI interface is an object, handing in the ports, clocks and clock division as parameters. Internaly they are stored for the XC implementation in the struct spi_master_interface. The constructor would call spi_init
The destructor would call spi_shutdown.
These are what I would classify as module lifecycle functionality, controlled by messages over channels
It is hard for me to understand the difference between a lifecycle and an object lifecycle - too much into the OO world. Since as long as there is somebody I can takl to it is an instanceof something.
But I will try to forget it ;)
Folknology wrote:
spi_out_* would be hidden in member function write(), function overloading would automatically select the right function spi_out_word, spi_out_short, spi_out_byte, spi_out_buffer.
Again I would use channels (and protocols) to output to an SPI module. Protocols would determine frame/width etc.. with the benefit of typing the interface (obviously we have to work around this for now as we lack protocols, but could use structured headers for example).
You are right: If I call a method or send a message over an channel it does not make a difference. It is just sending a bunch of parameters and perhaps getting a response.
The only thing I would not like about the current message over channel idea is the tedious switch/case to respond to different methods. I really like that the compiler does that for me and also does all the neccessary checkings.
Perhaps we can learn from script languages and duck typing to get a more flexible approach. Since from my point of view strong and irrational hierarchical object models are not really the way to got. There is already too much OO baklava code out there.

I was really thinking using BSON as communication protocol over channels can be a good idea. Probably not. But the idea behind it that you get a message and either you understand and respond to it or not. Duck typing
But a BSON like structure can be most easily interpreted as an object - but you can get away with structs & methods.

But encapsulting all methods in channels and message would throw a way a good part of the job of the compiler. It checks for me if the correct parameters are given. On the other hand with duck typing this would throw away the most of the flexibility - that I jsut can try to talk to the module.
Folknology wrote:
I do not know if this would be done for the read function - because then you would need to hand in the result variable as reference not the nicest way. But perhaps the cleanest way in using overloading.
This is important and a place I believe your plan may come unstuck please provide a basic example and I will expand.
By that you can reduce the interface virtuall to two functions: read & write
Or a single/dual channel/s interface (reading and writing is implicit)
See my example above - it is awkward.
Folknology wrote:
To make XC want me forget C++ we need in XC:
Modules with name spaces and private data
protocols to get around this 'encode data in channels' mess
Yup modules with namespaces make stuff more readable and its a nice to have

Protocols are essential longterm so the compiler can check the contract, in the meantime we can use documentation and practice instead (think dynamic language approach)
Agreed, see above.
Folknology wrote:
If you add some kind of contract so that different modules can fulfill the same contract (see my example about ADCs above you got me
This is simpler than the SPI example really as it only inputs data, over a channel. The module does however support config/control via a channel.
This could also be solved by duck typing - It seems I am loosing focus ;)
Folknology wrote:
Are contracts hierarchical? Is a multi input ADC a specialisation of a single input ADC?
It would be trivial for the ADC module to provide an array of input channels as manys as are required for the application configured at start up.

regards
Al
That would be a whole lot of channels - or perhaps it is just an optional field in the message: 'channel' A multi channel ADC would assume '0' if the channel is not given.

I think I want C++ just because there are contracts or services which I can implement or use and this is currently missing in XC.

What I realised only yesterday is important too: in XC is already about inversion of control. This is really good. Everything is controlled by the main function. It instatiates (excuse my wording) the building blocks of the application and configures them So if my LED sink driver uses an SPI protocol it not grabs one of the SPI ports, but asks kindly to provide an SPI configuration as part of it's configuration. This is xtremely important for configurability, flexibility and reuse. Like!
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

octal wrote:for point #1: YES I see XMOS more as FPGA with some MCU capabilities than like a chip programmable the MCU way.

Interactive_Matter wrote: Omitting completely to respond your answer in detail I just read the following from it:
To make XC want me forget C++ we need in XC:
  • Modules with name spaces and private data
THIS IS Modula2/3 !!! ;)
Learned something without effort ;)

And I think that you are right. The more I do with XMOS the more I see it as an coprocess or for other MCUs.

On the other hand it is quite easy to implement systems in XC and treat it as MCU. And I think it could be possible (just to provoke you) to port the linux kernel and with full thread support. Not that I really want to do it.

Still not convinced of any of the views: FPGA or MCU. It has both functionalities so that you do not change your point of view (FPGA vs MCU) which perhaps leads to my confusion.
octal wrote: Contracts handling can be a good addition indeed!
but I can see more complex things where it becomes needless to use object orientation.
When you write simple protocols encapsulated inside classes, your main program can have parallel sections (and multiple threads). The main prog can be written in XC, and the XC satements can instaciate your classes to ask them to do something (with all needed initilisation stuff to manage them).

But Imagine when you need parallel sections to handle input/output INSIDE YOUR CLASSES. if you need some kind of conditions that may vary, the only way to implement such thing is to subclass your main class, or to make a function that handles that (passing to it some kind of handles ....) and to assign this function to some event handler (or such) of your instance of class.

here object orientation do not solve the problem in an elegant way, it make things worse!!! You'll find yourself just translating the problem, from a simple linear solution in XC to a more complex solution that adds no clarity to the program at all.

Maybe a good solution for your problem is to have something like ObjectiveC sublayer on top of XC. It will give you the object orientation you need without having to deal with C++.
Hmm, ObjectiveC with it's much stronger bounds to Smalltalk is perhaps a better idea.

As stated above: I just need services and service contracts. So a lot of the building blocks are there.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

OK A really simple example ADC Module usage

Code: Select all

ADC :> sample;
A complicated version

Code: Select all

ADC[2] :> sample;
regards
Al
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

Folknology wrote:OK A really simple example ADC Module usage

Code: Select all

ADC :> sample;
A complicated version

Code: Select all

ADC[2] :> sample;
regards
Al
Or to save a bit on channels:

ADC(2) :> sample

or ADC(channel=2) :> sample

But what if the answer is a bit more complicated (e.g. has a timestamp):

ADC(channel=2):> message

if (message.timestamp .... do something

??
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Or to save a bit on channels:

ADC(2) :> sample
Noooo function call, stack usage,lost cycles for what?

Why are you trying to save channels they are there for a reason!!

regards
Al
Last edited by Folknology on Tue May 10, 2011 10:39 pm, edited 1 time in total.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

or ADC(channel=2) :> sample

But what if the answer is a bit more complicated (e.g. has a timestamp):

ADC(channel=2):> message

if (message.timestamp .... do something

??

Code: Select all

ADC[2] :> sample;
if(sample.ts == somecondition) do something;
But I wouldn't actually do it this way because its not structured

Not sure why you would branch on the sample timestamp?

regards
Al
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

A more structured example might be example:

Code: Select all

select {
  case ADC[2] :> sample : {
    switch(sample.ts) {
      case TS1 : do ts1 thing;
      case TS2 : do ts2 thing;
      default : do default thing;
    }
  }
}
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

A more pratical example might be:

Code: Select all

select {
  case ADC[TEMP] :> temperature {
    if(temperature > MAX) { 
      Motor[X] < STOP;
      Motor[Y] < STOP;
    }
  }
  case ADC[XPOS] :> samplex : {
    if (samplex.val == Px) Motor[X] < PAUSE
    else Motor[X] < STEP;
    }
  case ADC[YPOS] :> sampley : {
    if (sampley.val == Py) Motor[y] < PAUSE
   else Motor[Y] < STEP;
    }
  }
}
But even this isn't completely structured, I would likely abstract it further, but for the thread it makes the point

regards
Al
Last edited by Folknology on Wed Mar 23, 2011 2:10 pm, edited 7 times in total.