You mean like a stack. Push item on the stack and pop items off the stack. This concept has been around a long time and it only takes a few line of code. I use this approach with the spinneret web server to create dynamic web pages and to pass POST and GET variables down the http pipe.
I am talking about a standardized object, which would contain PM_MESSAGES for other existing objects, and PM_USER_DEFINED messages for custom messages. As far as the stack goes, I am uncertain how to implement it, I just know it would be nice if there was a standardized object.
For instance, lets say that I am linking to the PropellerMessaging object, and in my object, I want to post a user defined message of PM_USER + 1 so that other objects may get the message.
This is a pretty common thing to do with the propeller. We all have to pass messages from one process to another if they are to work together. Simply define your type then carve out some HUB memory.
I am certain that I am talking much more in depth than what you are talking about. I am talking standardized keyboard messages, mouse messages, etc....
PRI PushDynamicContent(content)
' Write the content to memory
' and update the pointer
bytemove(dynamicContentPtr, content, strsize(content))
dynamicContentPtr := dynamicContentPtr + strsize(content)
return
PUB PushDir(startAddress, numberOfBytes) | e
' Pointer to the end of the string
e := directoryStackPtr[directoryStackDepth] + numberOfBytes
bytemove(directoryStackPtr[directoryStackDepth], startAddress, numberOfBytes)
bytefill(e, STR_TERM, 1)
directoryStackPtr[++directoryStackDepth] := e+1
PUB PeekDir(index)
if(index > directoryStackDepth-1)
result := -1
return
result := directoryStackPtr[index]
in my opinion all those definitions for messages for mouse, keyboard, LCD etc. eat up too much memory for a system only 32kB big.
If you switch over to a system with external RAM or SD-card you get this windows behaviuor of swapping memory around and loosing deterministic behaviour of the code
So if you want to have a comfortable windows messaging system how about an mini ITX-board? The price-difference to a propeller board with extenal RAM isn't that big
As Mike G pointed out, this is not Windows. Let's say 50 object defined messages. Wouldn't that be equivalent to 50 longs, which would be defined in the object? The message queue itself would only contain a new message until it was processed or until a new one arrived. 50 longs isn't that much or is there some other issue that I am unaware of?
I can't answer that Bill, but I think it would be an insignificant factor when compared to the advantaged that could be gained by a common object. Additionally, applications that did not want or need it just would not link to it.
When I first started working with the Prop I thought it would be useful to create message queues that would allow all the cogs to talk to each other. My motivation was to be able to do remote method calls, where one cog could call a method in another cog. I never pursued this because there were easier ways to implement this functionallity, such as the command/response mailbox that is used with the floating point object.
It might be useful if you could create a sample of the idea your proposing. You could make a modified version of FullDuplexSerial that would send messages whenever a key is pressed. Cog 0 would run a Windows-like polling loop that would receive messages and dispatch them. I have a method pointer object in the OBEX that you could use to associate a method to a message.
Your message queue could be a circular buffer that contains pointers to message blocks, or you could use a linked list to link the message blocks together to form the queue.
Yeah, I get that. But, with windows there is a whole OS there. Makes sense to provide services. There is often room (though some question the wisdom of that), and a large user base where those things make sense. General purpose computing model right there. Technical computing, like for energy, life sciences, medical, automotive, etc... also makes sense, and there one will find other kinds of services related to visualization, parallel computing, etc....
All of that builds on the general parameters of the niche being served. Here in micro / embedded land, it's all different. The design constraints are often significant, as are time lines, as well as available means and methods. So then, it makes sense to have the minimal environment. I'm quite sure many would love the EEPROM on the chip, for example, just so the component count goes down by one!
There is scope too. Parallax provides the processor, and some support code and documentation that gets the tech out there. From there, it's user land, and the users all are highly differentiated. That's the next layer out, and little communities and economies center around various things, and some local standards form, tools, etc...
So that's where we are. We've got the OBEX, and it's a really great thing! Lots of goodies in there, and some of them see very heavy use, others none at all, or a coupla users, depending on what people need to get done, and the scope of functionality the object provides.
A few longs in the hub, constants, and the basics are done. To go beyond that, a supervisor kind of task is needed, and that's generally going to cost a COG, or all the relevant objects need to have code added that will write the data needed. Many objects do output status info, depending, so there is that too.
I am currently just discussing the idea of it. I have too many irons in the fire at the moment to undertake such a project. However, it would be nice just to be able to process user defined messages at the moment.
Let me ask you this Dave. If I link to an object, of course I can talk to that object through its methods and get returns from it. However, now let's suppose that I create a new cog with that linked object, and it creates a value that would be hard to get a return from. Is there any way to that value without a return?
EDITED : I know, set up a variable in that object and get the value of the variable. Still thinking through all this.
I see the Prop as a 8 separate processes that communicate through shared memory. So if I want COG1 communicate with COG2, I might expose the message through getters and setters or through a known pointer. If I need to deal with many messages to many COG, I might use a stack and push and pop items or a queue. No matter what mechanism, I always write to HUB memory. The structure of the serialized message is up to the programmer or task at hand.
To me, the architecture of the Propeller is a messaging system where COGs communicate through HUB memory.
Spin neither has true objects nor does it have any provisions for "including" files, so that makes libraries like what you're used to with Windows problematic. There are ways around this by using an object with no global VARs, like one or two of the serial I/O drivers for example, that are designed to be referenced from several other objects.
Anyway, the bigger question is whether a general purpose messaging system is appropriate for general use in memory-limited embedded systems like the Propeller. There's no question that it may be useful in some circumstances. Almost anything is useful sometimes. Very few things are useful most of the time. The idea of a message passing primitive is probably way more useful than a particular implementation of it as a widely used object. It's like implementing string primitives. A few very simple ones may be generally useful like BYTEMOVE, STRSIZE, and STRCOMP, particularly when they're trivially done in native instructions and very very fast. Others will be necessary in some classes of applications like GPS applications or something with text-based input, but useless otherwise.
Bottom line: It's useful for you and you like it. Write one and refine it over time. Share it with others who are interested and let them refine it as well. You'll rapidly find out what works and is useful for Spin and Propeller use. As usual with embedded systems, be careful of having too much in the way of or too many layers of abstraction in your code. It's very very useful conceptually, but costly in time and memory space.
Well that was a very nice perspective, that I must agree with. Especially the following quote:
Almost anything is useful sometimes. Very few things are useful most of the time.
My programs generally don't use a lot of memory, but I can imagine some of the programs out there that do. Like you said, it could be useful in some circumstances.
Comments
I am talking about a standardized object, which would contain PM_MESSAGES for other existing objects, and PM_USER_DEFINED messages for custom messages. As far as the stack goes, I am uncertain how to implement it, I just know it would be nice if there was a standardized object.
For instance, lets say that I am linking to the PropellerMessaging object, and in my object, I want to post a user defined message of PM_USER + 1 so that other objects may get the message.
PM.PostMessage(PM_USER + 1)
PM.GetMessage(MessagePointer)
Bruce
- PM_LCD_UPDATED
- PM_LCD_UPDATE
- PM_RTC_UPDATED
- PM_RTC_UPDATE
- PM_COMMAND
- PM_LBUTTONUP
- PM_LBUTTONDOWN
- PM_RBUTTONUP
- PM_RBUTTONDOWN
Just a few, etc...Bruce
Do you have an OBEX example?
Bruce
I am certain that I am talking much more in depth than what you are talking about. I am talking standardized keyboard messages, mouse messages, etc....
Bruce
That is no where near a Windows Messaging system.
Mike as an example here are some definitions of Windows Messages from winuser.h of Visual Studio C++ 6.0
Bruce
While your code may work, it is not a standardized object. A standardized object would include many definitions.
Bruce
I am not trying to insult you. So please don't be offended. I am just saying that while you are talking apples, I am talking oranges.
Bruce
If you switch over to a system with external RAM or SD-card you get this windows behaviuor of swapping memory around and loosing deterministic behaviour of the code
So if you want to have a comfortable windows messaging system how about an mini ITX-board? The price-difference to a propeller board with extenal RAM isn't that big
best regards
Stefan
As Mike G pointed out, this is not Windows. Let's say 50 object defined messages. Wouldn't that be equivalent to 50 longs, which would be defined in the object? The message queue itself would only contain a new message until it was processed or until a new one arrived. 50 longs isn't that much or is there some other issue that I am unaware of?
Bruce
Bill
I can't answer that Bill, but I think it would be an insignificant factor when compared to the advantaged that could be gained by a common object. Additionally, applications that did not want or need it just would not link to it.
Bruce
If it was available, I would probably use it in every project. I believe winuser.h is included in every exe file, except maybe win32 exe files.
Bruce
When I first started working with the Prop I thought it would be useful to create message queues that would allow all the cogs to talk to each other. My motivation was to be able to do remote method calls, where one cog could call a method in another cog. I never pursued this because there were easier ways to implement this functionallity, such as the command/response mailbox that is used with the floating point object.
It might be useful if you could create a sample of the idea your proposing. You could make a modified version of FullDuplexSerial that would send messages whenever a key is pressed. Cog 0 would run a Windows-like polling loop that would receive messages and dispatch them. I have a method pointer object in the OBEX that you could use to associate a method to a message.
Your message queue could be a circular buffer that contains pointers to message blocks, or you could use a linked list to link the message blocks together to form the queue.
Dave
All of that builds on the general parameters of the niche being served. Here in micro / embedded land, it's all different. The design constraints are often significant, as are time lines, as well as available means and methods. So then, it makes sense to have the minimal environment. I'm quite sure many would love the EEPROM on the chip, for example, just so the component count goes down by one!
There is scope too. Parallax provides the processor, and some support code and documentation that gets the tech out there. From there, it's user land, and the users all are highly differentiated. That's the next layer out, and little communities and economies center around various things, and some local standards form, tools, etc...
So that's where we are. We've got the OBEX, and it's a really great thing! Lots of goodies in there, and some of them see very heavy use, others none at all, or a coupla users, depending on what people need to get done, and the scope of functionality the object provides.
A few longs in the hub, constants, and the basics are done. To go beyond that, a supervisor kind of task is needed, and that's generally going to cost a COG, or all the relevant objects need to have code added that will write the data needed. Many objects do output status info, depending, so there is that too.
Cheers!
I am currently just discussing the idea of it. I have too many irons in the fire at the moment to undertake such a project. However, it would be nice just to be able to process user defined messages at the moment.
Let me ask you this Dave. If I link to an object, of course I can talk to that object through its methods and get returns from it. However, now let's suppose that I create a new cog with that linked object, and it creates a value that would be hard to get a return from. Is there any way to that value without a return?
EDITED : I know, set up a variable in that object and get the value of the variable. Still thinking through all this.
Bruce
I still think it is very good idea. You have not convinced me.
Bruce
To me, the architecture of the Propeller is a messaging system where COGs communicate through HUB memory.
Thanks for the input Mike. I am sure I will get to that point someday
Bruce
Anyway, the bigger question is whether a general purpose messaging system is appropriate for general use in memory-limited embedded systems like the Propeller. There's no question that it may be useful in some circumstances. Almost anything is useful sometimes. Very few things are useful most of the time. The idea of a message passing primitive is probably way more useful than a particular implementation of it as a widely used object. It's like implementing string primitives. A few very simple ones may be generally useful like BYTEMOVE, STRSIZE, and STRCOMP, particularly when they're trivially done in native instructions and very very fast. Others will be necessary in some classes of applications like GPS applications or something with text-based input, but useless otherwise.
Bottom line: It's useful for you and you like it. Write one and refine it over time. Share it with others who are interested and let them refine it as well. You'll rapidly find out what works and is useful for Spin and Propeller use. As usual with embedded systems, be careful of having too much in the way of or too many layers of abstraction in your code. It's very very useful conceptually, but costly in time and memory space.
Well that was a very nice perspective, that I must agree with. Especially the following quote:
My programs generally don't use a lot of memory, but I can imagine some of the programs out there that do. Like you said, it could be useful in some circumstances.
Thanks for your input Mike
Bruce