Shop OBEX P1 Docs P2 Docs Learn Events
Is Windows type messaging possible with the Propeller? — Parallax Forums

Is Windows type messaging possible with the Propeller?

idbruceidbruce Posts: 6,197
edited 2011-01-27 08:30 in Propeller 1
lllllllllllllllllllllll

Comments

  • Mike GMike G Posts: 2,702
    edited 2011-01-27 05:20
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 05:33
    Mike G

    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 : PropellerMessaging
    PM.PostMessage(PM_USER + 1)
    Other objects within a given application could also link to PropellerMessaging object to post and retrieve messages.
    PM : PropellerMessaging
    PM.GetMessage(MessagePointer)
    LOL Heck I don't know, just bouncing ideas off the wall.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 05:47
    Here are some other examples:
    • 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
  • Mike GMike G Posts: 2,702
    edited 2011-01-27 05:59
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 06:03
    Mike G

    Do you have an OBEX example?

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 06:05
    Mike G

    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
  • Mike GMike G Posts: 2,702
    edited 2011-01-27 06:06
    Some examples
    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]
    
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 06:09
    Mike G

    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
    #if(WINVER >= 0x0400)
    #define WM_NOTIFY                       0x004E
    #define WM_INPUTLANGCHANGEREQUEST       0x0050
    #define WM_INPUTLANGCHANGE              0x0051
    #define WM_TCARD                        0x0052
    #define WM_HELP                         0x0053
    #define WM_USERCHANGED                  0x0054
    #define WM_NOTIFYFORMAT                 0x0055
    #define NFR_ANSI                             1
    #define NFR_UNICODE                          2
    #define NF_QUERY                             3
    #define NF_REQUERY                           4
    #define WM_CONTEXTMENU                  0x007B
    #define WM_STYLECHANGING                0x007C
    #define WM_STYLECHANGED                 0x007D
    #define WM_DISPLAYCHANGE                0x007E
    #define WM_GETICON                      0x007F
    #define WM_SETICON                      0x0080
    #endif /* WINVER >= 0x0400 */
    #define WM_NCCREATE                     0x0081
    #define WM_NCDESTROY                    0x0082
    #define WM_NCCALCSIZE                   0x0083
    #define WM_NCHITTEST                    0x0084
    #define WM_NCPAINT                      0x0085
    #define WM_NCACTIVATE                   0x0086
    #define WM_GETDLGCODE                   0x0087
    #define WM_SYNCPAINT                    0x0088
    #define WM_NCMOUSEMOVE                  0x00A0
    #define WM_NCLBUTTONDOWN                0x00A1
    #define WM_NCLBUTTONUP                  0x00A2
    #define WM_NCLBUTTONDBLCLK              0x00A3
    #define WM_NCRBUTTONDOWN                0x00A4
    #define WM_NCRBUTTONUP                  0x00A5
    #define WM_NCRBUTTONDBLCLK              0x00A6
    #define WM_NCMBUTTONDOWN                0x00A7
    #define WM_NCMBUTTONUP                  0x00A8
    #define WM_NCMBUTTONDBLCLK              0x00A9
    #define WM_KEYFIRST                     0x0100
    #define WM_KEYDOWN                      0x0100
    #define WM_KEYUP                        0x0101
    #define WM_CHAR                         0x0102
    #define WM_DEADCHAR                     0x0103
    #define WM_SYSKEYDOWN                   0x0104
    #define WM_SYSKEYUP                     0x0105
    #define WM_SYSCHAR                      0x0106
    #define WM_SYSDEADCHAR                  0x0107
    #define WM_KEYLAST                      0x0108
    #if(WINVER >= 0x0400)
    #define WM_IME_STARTCOMPOSITION         0x010D
    #define WM_IME_ENDCOMPOSITION           0x010E
    #define WM_IME_COMPOSITION              0x010F
    #define WM_IME_KEYLAST                  0x010F
    #endif /* WINVER >= 0x0400 */
    #define WM_INITDIALOG                   0x0110
    #define WM_COMMAND                      0x0111
    #define WM_SYSCOMMAND                   0x0112
    #define WM_TIMER                        0x0113
    #define WM_HSCROLL                      0x0114
    #define WM_VSCROLL                      0x0115
    #define WM_INITMENU                     0x0116
    #define WM_INITMENUPOPUP                0x0117
    #define WM_MENUSELECT                   0x011F
    #define WM_MENUCHAR                     0x0120
    #define WM_ENTERIDLE                    0x0121
    #if(WINVER >= 0x0500)
    #define WM_MENURBUTTONUP                0x0122
    #define WM_MENUDRAG                     0x0123
    #define WM_MENUGETOBJECT                0x0124
    #define WM_UNINITMENUPOPUP              0x0125
    #define WM_MENUCOMMAND                  0x0126
    #endif /* WINVER >= 0x0500 */
     
    #define WM_CTLCOLORMSGBOX               0x0132
    #define WM_CTLCOLOREDIT                 0x0133
    #define WM_CTLCOLORLISTBOX              0x0134
    #define WM_CTLCOLORBTN                  0x0135
    #define WM_CTLCOLORDLG                  0x0136
    #define WM_CTLCOLORSCROLLBAR            0x0137
    #define WM_CTLCOLORSTATIC               0x0138
     
    #define WM_MOUSEFIRST                   0x0200
    #define WM_MOUSEMOVE                    0x0200
    #define WM_LBUTTONDOWN                  0x0201
    #define WM_LBUTTONUP                    0x0202
    #define WM_LBUTTONDBLCLK                0x0203
    #define WM_RBUTTONDOWN                  0x0204
    #define WM_RBUTTONUP                    0x0205
    #define WM_RBUTTONDBLCLK                0x0206
    #define WM_MBUTTONDOWN                  0x0207
    #define WM_MBUTTONUP                    0x0208
    #define WM_MBUTTONDBLCLK                0x0209
    #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
    #define WM_MOUSEWHEEL                   0x020A
    #define WM_MOUSELAST                    0x020A
    #else
    #define WM_MOUSELAST                    0x0209
    #endif /* if (_WIN32_WINNT < 0x0400) */
    #if(_WIN32_WINNT >= 0x0400)
    #define WHEEL_DELTA                     120     /* Value for rolling one detent */
    #endif /* _WIN32_WINNT >= 0x0400 */
    #if(_WIN32_WINNT >= 0x0400)
    #define WHEEL_PAGESCROLL                (UINT_MAX) /* Scroll one page */
    #endif /* _WIN32_WINNT >= 0x0400 */
    #define WM_PARENTNOTIFY                 0x0210
    #define WM_ENTERMENULOOP                0x0211
    #define WM_EXITMENULOOP                 0x0212
    #if(WINVER >= 0x0400)
    #define WM_NEXTMENU                     0x0213
    

    Bruce
  • Mike GMike G Posts: 2,702
    edited 2011-01-27 06:23
    No kidding... Windows messaging rides on, well, Windows. HUB memory is used to communicate between process in the Propeller.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 06:26
    Mike

    While your code may work, it is not a standardized object. A standardized object would include many definitions.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 06:35
    Mike G

    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
  • potatoheadpotatohead Posts: 10,261
    edited 2011-01-27 07:03
    Memory constraints are significant. The lesser method of building those messages needed to realize the task is common for that reason.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-01-27 07:07
    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

    best regards

    Stefan
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 07:14
    Okay Guys

    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
  • wjsteelewjsteele Posts: 697
    edited 2011-01-27 07:17
    I see no reason whey they would consume any more memory, as the message definitions would simply be constants that are compiled out, right?

    Bill
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 07:21
    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
  • potatoheadpotatohead Posts: 10,261
    edited 2011-01-27 07:31
    Well, the way that stuff usually works is somebody writes it, then it either catches on, or it doesn't.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 07:33
    Potatohead

    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
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-01-27 07:52
    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
  • potatoheadpotatohead Posts: 10,261
    edited 2011-01-27 07:59
    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.

    Cheers!
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 08:00
    Dave

    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
  • potatoheadpotatohead Posts: 10,261
    edited 2011-01-27 08:06
    I like that method. Just put some variables in the DAT, and then act on those.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 08:13
    Potatohead

    I still think it is very good idea. You have not convinced me.

    Bruce
  • Mike GMike G Posts: 2,702
    edited 2011-01-27 08:16
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 08:18
    Mike G

    Thanks for the input Mike. I am sure I will get to that point someday :)

    Bruce
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-27 08:19
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-27 08:30
    @Mike Green

    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.

    Thanks for your input Mike

    Bruce
Sign In or Register to comment.