Showing posts with label arrayForth. Show all posts
Showing posts with label arrayForth. Show all posts

Sunday, July 27, 2014

Concurrency and multi-core MCUs (GA144) in my house monitor

My house monitoring system monitors lots of sensors. This suggests a multi-core approach, doesn't it?

The problem with (the current concept of)  multi-cores is that they are typically ruled by a monolithic operating system. Despite what goes on in each core, there is one single point of failure: the operating system. Plus, without core affinity, our code may be moved around.  In a 8 core Intel processor, you are NOT guaranteed to be running a task per core (likely, for execution efficiency, your task is load balanced among the cores).  Each core is beefy too. Dedicating a whole core to a single sensor sounds very wasteful.

This, I believe, is flawed think  in our current concurrency model (at least as far as embedded systems go).

I want multiple "nodes" for computation. I want each node to be  isolated and self reliant.  (I'm talking from an embedded perspective here -- I understand the impracticality of doing this on general purpose computers).

If I have a dozen sensors, I want to connect them directly to a dozen nodes that independently manage them.  This isn't just about data collection. The nodes should be able to perform some high level functions.  I essentially want one monitoring app per node.

For example: I should be able to instruct a PIR motion-sensor node to watch for a particular motion pattern before it notifies another node to disperse an alert. There may be some averaging or more sophisticated logic to detect the interesting pattern.

Normally, you would have a bunch of physically separate sensor nodes (MCU + RF),  but RF is not very reliable. Plus, to change the behavior of the sensor nodes you would have to collect and program each MCU.

So, consider for this "use case" that the sensors are either wired or that the sensors are RF modules with very little intelligence built in (i.e. you never touch the RF sensor's firmware): RF is just a "wire".  Now we can focus on the nodes.

The Green Arrays GA144 and Parallax Propeller are the first widely-available MCUs (I know of) to encourage this "one app per node" approach.  But, the Propeller doesn't have enough cores (8) and the GA144  (with 144 cores) doesn't have enough I/O (for sake of this discussion, since the GA144 has so many cores I am willing to consider a node to be a "group of core").

Now, let's consider a concession...
With the GA144, I could fall back to the RF approach.  I'll can emulate more I/O by feeding the nodes from edge nodes that actually collect the data (via RF).  I can support dozens of sensors that way.

But, what does that buy me over a beefy single core Cortex-M processing dozens of sensors?

With the Cortex-M, I am going to have to deal with interrupts and either state machines or coroutines. (although polling is possible to replace the interrupts, the need for a state machine or coroutines remain the same).  This is essentially "tasking".

This can become heinous. So,  I start to think about using an OS (for task management).  Now I've introduced more software (and more problems).  But can I run dozens of "threads" on the Cortex-M? What's my context switching overhead?  Do I have a programming language that lets me do green threads?  (Do I use an RTOS instead?)

All of this begins to smell of  anti-concurrency (or at least one step back from our march towards seamless concurrency oriented programming).

So, let's say I go back to the GA144. The sensor monitoring tasks are pretty lightweight and independent. When I code them I don't need to think about interrupts or state machines. Each monitor sits in a loop, waiting for sensor input and  a "request status" message from any other node.
In C psuedo-code :

while (1) { 
  switch(wait_for_msg()) {
    case SENSOR: 
       if (compute_status(get_sensor_data()) == ALERT_NOW)
          send_status(alert_monitor);
       break;
    case REQUEST:
       send_status(requester);
       break;
  }
}

This loop is all there is.  The "compute_status" may talk to other sensor nodes or do averaging, etc.
What about timer events? What if the sensor needs a concept of time or time intervals?  That can be done outside of the node by having a periodic REQUEST trigger.

(This, by the way, is very similar to what an Erlang app would strive for (see my previous post GA144 as a low level, low energy Erlang).

Now, the above code would need to be in Forth to work on the GA144 (ideally arrayForth or PolyForth), but you get the idea (hopefully ;-)


Friday, February 17, 2012

arrayForth notes #6 - Improved PCF2123 SPI Code

There were a lot of errors in the note #4 listing. I made the post mainly because I was excited to see commands fly between the PCF2123 and GA144 as viewed by a logic analyzer (even though spir8 didn't really work correctly). So, here is where I clean up the code, refactor it a bit and offer something a little more functional. I could go on for pages the rationale I had behind why this code lives in Node 7 and 8 and how I hooked up the chip. But, that is for another time. I hate having broken code posted to my blog, so this post is mainly a means to offer something that works. BTW, this runs on the eval board target chip. It still has some inefficiencies (compared to the GreenArray supplied SPI code), but by doing this myself (essentially a "clean room" implementation), I got to learn a lot more about how to code the GA144.

this is a brutally simple interface for a spi
cr
pin 1 - chip select cr
pin 3 - clock cr
pin 5 - mosi cr
pin 17 - miso cr
cr
/spi call first. main loop .
ckwait
pauses for an effective rate of 2mhz cr
-ckwait asserts the clock line low for 2mhz cr
cs asserts the chip select line high cr
-cs asserts the chip select line low cr
                                              

   850 list
todd's simple spi code cr
8 node 0 org cr
/spi @ push ex . /spi ;
ckwait
02 4A for unext ; approx. 2mhz cr
-ckwait 05 2B !b ckwait ;
cs
07 io b! -ckwait ;
-cs
0A 29 !b ;
spiw1
0C if drop 10 then 2F or !b ckwait -ckwa
it ;

spiw8
13 b- 80 7 for over over and spiw1 2/ ne
xt drop drop ;

spir1
1A -b @b . -if drop - 2* - ; then drop 2
* ;

spir8
1E -b 0 7 for 0 spiw1 spir1 next 2/ ; cr
26                                            


nxp pcf2123 calendar clock module.
/pcf2123
initializes the pcf2123 clock cr
rdt reads date and time
sdt
sets data and time port the cr
                                              

   852 list
7 node 0 org cr
/cs 00 left a! @p .. cs ! ;
cs/
04 @p .. -cs ! ;
put
07 d- @p .. @p .. ! ! ;
get
0A -d @p .. !p .. ! @ ;
spiw
0D put @p .. spiw8 ! ;
spir
11 @p .. spir8 ! get ;
/pcf2123
14 @p .. /spi ! /cs 10 spiw 58 spiw c
s/ ;

rdt
1C -smhwdmy /cs 92 spiw spir spir spir spi
r spir spir spir cs/ ;

sdt
27 ymdwhms- /cs 12 spiw spiw spiw spiw spi
w spiw spiw spiw cs/ ;

testdate
32 12 11 10 9 8 7 6 sdt ; cr
3C                                            

Wednesday, February 15, 2012

arrayForth notes #5 - Observations and hints

I've since improved the code in the previous entry. I've slimmed it down to 59 words (out of a max of 64). I am not sure I can get it small enough to include the wiring, but I'll look further at exemplar SPI code in the baseline for some more slimming tricks. One thing I am noticing is that literals (numbers) are very expensive. Each literal takes a whole word (18 bit cell) of RAM. This is the reason for such non-intuitive tricks as "dup or" instead of coding the literal "0". "Dup or" doesn't take up a whole RAM cell, so it can be packed with other instructions. Calls take up quite a bit of space too. If your word is shorter than a single 18 bit cell, you will do better just coding it inline rather than do a word call. Programming the GA144 in arrayForth means that you must become an expert in how words are compiled. You can escape this by using polyForth or eForth, but you lose the benefit of understanding how the GA144 actually works. I am still trying to get my arms around wiring, but I remain convinced that the true strength of the GA144 is basically as an FPGA killer for simple concurrent processes. Whereas the strength of a Silabs 8051 or ARM Cortex M is in the richness of peripherals, the GA144 doesn't benefit much from peripherals. It is an FPGA level Erlang. And, like Erlang, it has specific strengths. It's biggest strength is power efficient massive concurrency. I would like to see more I/O, but that only lulls me into the traditional concurrency perspective. I need to stop thinking about having dozens of sensors outputs tied to dozens of GA144 inputs. This isn't a strength. Most assuredly , it is my ability to model dozens of sensors concurrently without dealing with interrupts or global state machines -- that is it's biggest strength.

Tuesday, February 14, 2012

arrayForth notes #4 - PCF2123 SPI Code

This is brutally tight code. It is not the most efficient code, but it does fit in 1 node (unfortunately, there is no room for "plumbing" -- so it will most likely need to be refactored into 2 nodes).

The code can be exercised (by the IDE), by using "call" to invoke /pcf2123 for initialization, sdt to set the date and rdt to read the date.  Values for "sdt" can be pushed onto the node's stack by using "lit".  I used a logic analyzer to look at the results.

There was a lot of setup to get this going, and I am not going to cover that right now.

I need to get the plumbing (wiring) right. Getting 1 node to talk to another is not as intuitive as I hoped. I also fear that the IDE gets critically in the way (hook et al can wipe out your node's RAM when creating paths).  This will mean that the IDE will be less useful for stuff that is very node position dependent (i.e. GPIO nodes).

I don't fully grok the inter-node comms yet. In particular, I am not sure how to "push" numbers from one node to another.  The IDE does this fine with "lit", but if my node isn't wired by the IDE all I have is "warm/await".  The apparent exemplar for passing values between nodes is to explicitly have the target node "fetch" values from the port. Unfortunately, as you can see from the code below, I am out of room (0x40 max words per node and I am at 0x3d).  I could shrink the code a bit more, but...

this is a brutally simple interface for the cr
nxp pcf2123 calendar clock module. cr
pin 1 - chip select cr
pin 3 - clock cr
pin 5 - mosi cr
pin 17 - miso cr
cr
ckwait pauses for an effective rate of 2mhz cr
-ckwait asserts the clock line low for 2mhz cr
cs asserts the chip select line high cr
-cs asserts the chip select line low cr
/pcf2123 initializes the pcf2123 clock cr
rdt reads date and time
sdt
sets data and time                        

   850 list
todd's simple pcf2123 clock code cr
8 node 0 org cr
ckwait 00 4A for unext ; approx. 2mhz cr
-ckwait 03 2B !b ckwait ;
cs
05 io b! -ckwait ;
-cs
07 29 !b ;
spiw1
09 if drop 10 then 2F . + !b ckwait -ckw
ait ;

spiw8
10 b- 80 7 for over over and spiw1 2/ ne
xt drop drop ;

spir8
17 -b 0 7 for 2* dup or spiw1 @b . -if d
rop
1 or dup then drop next 2/ ;
/pcf2123
21 cs 10 spiw8 58 spiw8 -cs ;
rdt
27 -smhwdmy cs 92 spiw8 spir8 spir8 spir8
spir8 spir8 spir8 spir8 -cs ;

sdt
32 ymdwhms- cs 12 spiw8 spiw8 spiw8 spiw8
spiw8 spiw8 spiw8 spiw8 -cs ;
cr
3D                                            

Wednesday, February 08, 2012

arrayForth notes #3 - SPI

I've finally begun to talk to the PCF2123 from the G144A12 eval board.  The SPI code is not space optimized, so just the basics are taking up  almost a full node. (More on that later).
So far, I've got "reset" and a register read working (return data not validated).  I am using Node 8 and it's 4 GPIO lines (for MOSI, MISO, CLOCK and ENABLE/CS).  The PCF2123 is odd in that CS active is high, not low. I've got a tight for unext loop pulse the CLOCK line at around 2Mhz:


In the above Saleae Logic screenshot, I am tracing two CS sessions:  First a "reset" (0x10 and 0x58), and then a request to read register 4. I am not sure the data returned is correct (yet), but the fact that I am getting something must mean that the device is happy with my query.  Unfortunately, my register read isn't returning the value 0x15 yet, but at least I know that my GPIO pin writes are working.

As I said above, just basic support of SPI is taking up precious space (currently the SPI routines take 36 words of RAM!). I am planning on doing some optimizing, but I think that the actual PCF2123 functionality will need to live in a separate node.

I have a business trip planned for the next couple of days, so if I don't get the SPI "read" working correctly tonight it will have to wait until the weekend. However, the plane ride and hotel stay will afford me some time to look into space optimization of the code and perhaps I will finally tackle the simulator.

And, yes! Code will be posted... once the damn thing works.


Tuesday, February 07, 2012

arrayForth notes Part 2

I'm trying to get my G144A12 Eval board to talk SPI to a  Calendar chip (NXP PCF2123).  I've managed to get a 2Mhz(ish) clock pulse running from Node 8 on the Target chip.  (I've picked the Target chip because I am overwhelmed with all of the stuff the Host chip is connected to -- I'm better at learning stuff from the ground up).

Unfortunately, I've been trying to get a test harness up and running in a different Node (9) and have been crashing the system every few minutes with my clumsy attempts at wiring and routing.  Documentation regarding wiring Nodes is much lacking.

I'm obviously very confused about node direction. I've been referring to "right" as "left". Looking down upon the Node map, I've been wondering why I couldn't get Node 9 to talk to Node 8.  Apparently, Node 8 is to the "right" of Node 9. So, I suppose I should imagine "lying down on my back" on a Node.

I'd like to get something going between the Calendar and the Eval board this week, but I am flying out of town for a couple of days for a business meeting.

I wonder how airport security would react to a bare eval board stuffed into my back pack? (and to say nothing of the reaction if I were to try and use it in flight ;-)

Monday, January 30, 2012

Apples and Oranges (GA144 and ARM Cortex A8)

In my previous posts I mention about how multiple CPU processors such as a GA144 are different than multi-core CPUs.  I also talked about how having multiple independent processes may work better some problem spaces.  In broad terms, the GA144 can be viewed as a very low level Erlang for modeling lightweight (low memory, low computationally-complex) problems. Viewing it this way, it really isn't competing (for my purposes -- a sensor base station) with most (bare) MCUs.
(Additional similarity:  Forth, like Erlang frowns upon having lots of variables so data is carried as functions/parameters (Erlang) or the words/stack (Forth).)

Now, if you throw an ARM + Linux + Erlang (http://www.erlang-embedded.com/) at my sensor base station, what do you get?  (If Erlang doesn't really work well on the ARM, replace it with your favorite language plus lots of processes/threads. Also, keep in mind that my sensor base station needs to run for days on battery backup.)

Now, let's pick an ARM/Linux system for comparison:  How about the beagleboard bone?
This $89 beauty looks really appealing. I could see using it as my base station.  It is based on a new Cortex A8 and is feature rich for its size.

I can't compare (yet) how well it would do against a GA144. The GA144 certainly looks anemic compared to it (from just the Cortex A8 perspective).

However, I can take a quick look at power:


  • The Beagleboard bone consumes 170mA@5VDC with the Linux kernel idling and 250mA@5VDC peak during kernel boot. (from pages 28-29 of http://beagleboard.org/static/BONESRM_latest.pdf )
  • The GA144 consumes 7uA@1.8VDC (typical)  with all nodes idling and 540mA@1.8VDC (typical)  with all nodes running. (from the G144A12 Chip Reference).
Of course, you can't directly compare the two, but consider this interesting tidbit: The power performance of the GA144 is directly related to how many nodes you run.

I haven't looked at any performance numbers between the two, but I'll wager that the Cortex A8 ultimately outperforms the GA144.  But, my sensor base station is neither CPU bound (no complex calculations) nor RAM bound (important data points are persisted in flash storage and fetched as needed).

The real question is: How much useful work can I get done in 1 node?




Saturday, January 28, 2012

GA144 as a low level, low energy Erlang

I've been reading some of the newsgroup threads regarding the GA144 and most of the critiques have been mostly from a low level perspective (GA144 vs FPGAs vs ARMs, etc).  One can argue that the processor can't compete when considering the anemic amount of memory each node has and the limited limited peripheral support.  But, let us put aside that argument for a moment (we'll get back to it later).

Here I primarily want to discuss the GA144 from a software (problem solving) architecture perspective. This is where my primary interests reside. I'd lilke the GA144 to have formal and flexible SPI support. I'd like to see more peripheral capability built in. I'd like to see 3.3-5VDC support on I/O pins so level shifter chips aren't needed.  But, I think the potential strong point of GA144 is in what you can do with the cores from a software (problem solving) architectural design perspective.

Notice I keep mentioning software and problem solving together?  I want to make clear that I am not talking about software architecture in terms of library or framework building.  I'm talking about the architecture of the solution space.  I'm talking about the software model of the solution space.
Let's look at an analogy.

If I were to build a large telecommunication switch (handling thousands of simultaneous calls) and I implemented the software in Erlang or C++ (and assuming that they both would allow me to reach spec -- maybe 99.9999% uptime, no packet loss, etc.) at the end of the day you wouldn't be able to tell the system performance apart.

However, one of the (advertised) benefits of Erlang is that it allows you to do massive concurrency. This is not a performance improvement, but (perhaps) a closer model to how you want to implement a telco switch.  Lots of calls are happening at the same time. This makes the software easier to reason about and (arguably) safer -- your implementation stays closer to the solution space model.

Do you see what I am getting at?

Now, let's look at the problem I've been talking about here on the blog (previously described in vague terms): I want to integrate  dozens of wireless sensors to a sensor base station.  The base station can run off of outlet power but must be able to run off a battery for days (in case of a power outage). It is designed to be small and discrete (no big panel mounted to the wall with UPS backup). It needs to run 24/7 and be very fault tolerant.

The sensors are small, battery efficient and relatively "dumb". Each samples data until it reaches a prescribed threshold (perhaps performing light hysteresis/averaging before wasting power to send data) and it is up to the sensor base station to keep track of what is going on. The base station collects data, analyzes it, tracks it and may send alerts via SMS or perhaps just report it in a daily SMS summary.

Let's consider one typical sensor in my system: A wireless stove range monitor. This sensor, perhaps mounted to a range hood, would monitor the heat coming from the burners. This sensor will be used to (ultimately) let a remote individual know (via SMS) that a stove burner has been left on an unusually long time.  Perhaps grandma was cooking and forgot to turn the burner off.

This stove range sensor probably shouldn't be too smart. Or, in other words, it is not up to it to determine if the stove has been on "too long".  It reports  a temperature reading once it recognizes an elevated temperature reading over a 5 minute interval (grandma is cooking).  It then continues to report the temperature every 10 minutes until it drops below a prescribed threshold.   This is not a "smart" sensor. But it is not too dumb (it only uses RF transmit power when it has sufficiently determined significant temperature events -- rather than just broadcasting arbitrary temperature samples all day long).

The sensor base station will need a software model that takes this data, tracks it and makes a determination that there is an issue. Just because the stove range is on for a few hours may not mean there is a problem. A slow elevated temperature rise followed by stasis may suggest that a pot is just simmering.  However, if the stove is exhibiting this elevated temperature past 11pm at night -- certainly grandma isn't stewing a chicken this time at night!    You don't want to get too fancy, but  there can be lots of data points to consider when using this stove range monitor.

Here is my solution model (greatly simplified) for this sensor monitor:


  1. Receive a temperature sample
  2. Is it at stasis? If so, keep track of how long
  3. Is it still rising? Compare it with "fire" levels -- there may be no pot on the burner or it is scorching
  4. Is the temperature still rising? Fast?  Send an SMS alert
  5. Is it on late in the evening?  Send an SMS alert
  6. Keep a running summary (timestamped) of what is going on. Log it.
  7. Every night at 11pm, generate a summary of when the range was used and for how long. Send the summary via SMS
Imagine this as a long running process. It is constantly running, considering elapsed time and calendar time in its calculations.


Now, this is just one of many types of sensor that the base station must deal with. Each will have its own behavior (algorithm).

I can certainly handle a bunch of  sensors with a fast processor (ARM?). But my software model is different for each sensor. Wouldn't it be nice to have each sensor model to be independent? I could do this with Linux and multiple processes. But, really, the above model isn't really that sophisticated. It could (perhaps) easily fit in a couple of GA144 nodes (the sensor handler, logger, calendar and SMS notifier would exist elsewhere). And It would be nice to code this model as described (without considering state machines or context switches, etc).

So, back to the argument at the top of this post... I don't care if the GA144 isn't a competitive "MCU". My software models are simple but concurrent.  My design could easily use other MCUs to handle the SMS sending or RF radio receives. What is important is the software model. The less I have to break that up into state machines or deal with an OS, the better.

This is my interest in the GA144: A low level, low energy means of keeping my concurrent software model intact.  I don't need the GA144 to be an SMS modem handler.  I don't need it to perform the duties of a calendar. I need it to help me implement my software model as designed.

Friday, January 20, 2012

Multi-computers (GA144) vs multitasking (ARM) vs interrupts (8051/MSP430)

You've got a system to design.  It is a multi-sensor network that ties to a small, efficient battery run base station. The sensor nodes are straightforward. You start thinking about the base station:

I've got a barrage of data coming at me over the air at 433Mhz.  I have a simple 2 byte buffer on the SPI connected transceiver so I don't have a lot of time to waste on the MCU. I must be there to receive the bytes as they arrive.
Once I've received the data, it must be parsed into a message, validated, logged (to persistent storage) and perhaps correlated with other data to determine if an action must be taken. An action can also be timer based (scheduled). Oh, and I must eventually acknowledge the message receipt or else the sender will keep sending the same data.
Additionally (and unfortunately), the action I need to perform may involve dialing a GSM modem and sending a text message. This can take some time. Meanwhile, data is flowing in.  What if a scheduled event must take place and I'm in the middle or processing a new message?

Now, this is the sort of thing that you would throw a nice hefty ARM at with a decent  OS (maybe linux) to do multitasking and work queue management.  But, let's think a second... Most of what I've just described works out to a nice simple flow diagram: Receive data -> parse data into message -> reject duplicate messages -> log message -> correlate message with previous "events" -> determine if we need to send a text message -> send text messages at specific times -> start over.

Each task is pretty straight forward.  The work is not CPU bound.  You really don't need a beefy ARM to do each task. What we want the ARM to do is to coordinate a bunch of concurrent tasks. Well that will require a preemptive OS.  And then we start down that road...  time to boot, link in a bunch of generic libraries, think about using something a little more high level than C, etc. We now have a fairly complex system.

And, oh... did I mention that this must all run nicely on a rechargeable battery for weeks?  And, yank the battery at any time -- the system must recover and pick up where it left off.   So, just having a bunch of preemptive tasks communicating via OS queues isn't quite enough. We will probably need to persistent all queued communication.  But I am getting distracted here.  The big system eats a little bit too much power...

Okay, so we get a bit smaller. Maybe a nice ARM Cortex-M3 or M0.  Okay, the memory size is reduced and its a bit slower than a classic ARM.  A preemptive OS starts to seem a bit weight-y.

So, how about a nice MSP430 (a big fat one with lots of RAM and program space).  Now start to think about how to do all of that without a preemptive OS (yes, I know you can run a preemptive time-sliced OS on the MSP430, but that is a learning curve and besides you are constraining your space even further).  Do you go with a cooperative OS?  Well, now you have to start thinking about a states... how do you partition the tasks into explicit steps?  At this point you start thinking about rolling your own event loop.

So, then there are the interrupts:

Oh, I forgot about that.  The SPI between the MSP430 and transceiver. The UART to the GSM modem. And the flash. Don't forget the persistent storage.  And  check pointing, the system needs to start where we left off if the battery runs out.

Okay, you are getting desperate. You start thinking:

 What if I had one MCU (MSP430, C8051, whatever) dedicated to the transceiver and one dedicated to the GSM modem.  The code starts to get simpler.  They'll communicate via the persistent storage.... But, who handles the persistent storage?  Can the transceiver MCU handle that too?  

This is where thoughts of multi-computers  come in. Not multi-cores (we are not CPU bound!), but multi-computers.  What if I had enough computers that I could dedicate each fully to a task? What if I didn't have to deal with interrupts?  What would these computers do?

- Computer A  handles the transceiver
- Computer B  handles logging (persistent storage interface, indexing, etc)
- Computer C  handles the GSM modem (AT commands, etc)
- Computer D  handles parsing and validating the messages
- Computer E  handles "scheduling" (time based) events
- Computer F handles check pointing the system (for system reboot recovery)
etc etc etc

This is where I start really, really thinking that I've found a use for my GA144 board: Performing and coordinating lots of really simple tasks.

It becomes GA144 vs ARM/Cortex + Linux.

Now if I can only figure out how to do SPI in arrayForth...

Sunday, November 20, 2011

arrayForth notes Part 1

I haven't had a lot of time to work on my EVB001 eval board.  The time between sessions can go weeks and I tend to forget a lot of stuff.  These are notes to myself... sort of dead simple exercises to use as restart points.  So...

Here is an example of just attaching to a node and getting it to do some computation. What you type into arrayForth is displayed in Courier font.

First, you need to make sure a-com is set to the attached COM port.
a-com (this should display the com port number)


If the com port is incorrect, you must change it.  Do this:
def a-com (enter into the editor)


Navigate to the value, make the change, type save and exit/re-enter arrayForth.
(Hint:  Press ';'  to position the cursor just after the number; press 'n' to delete it; use 'u' to insert the new number; press ESC to leave that mode; press SPACE to exit editor and then type save )


Check the value again (a-com).


Now, let's go ahead and hook into node 600:
host load panel (load host code and display the panel)
talk 0 600 hook upd (talk to the chip, wire up to node 600 and update the stack view)


You should now see a bunch of numbers on the stack, starting with line 3.


Now, let's throw a couple of numbers onto the node's stack:
7 lit 2 lit (lit pushes the numbers off of the x86 arrayForth stack and onto the node's stack)


You show now see 7 and 2 as the last two values on the 4th line. 
Remember, the stack display is in hex and the values you are entering is in decimal.
(If you wish to enter values in Hex mode, press F1 and precede hex numbers with a zero (0).)

Now, let's add the two numbers:
r+ (the "r" distinguishes the F18 addition word from the x86 "+" word)


You should now see 9 on top of the stack.


Simple.

Now, let's try one more contrived exercise.  Let's load some data into the node's RAM:
55 0 r! (take 2 values off of the x86 stack:  55 goes into location 0)


You won't see the changed memory until you type:
?ram


So, at last, we have something working "hands on".  The example in the arrayForth user guide is great, but sometimes a good start is to just to be able to interactively talk to the chip.


 





Saturday, October 01, 2011

GreenArrays arrayForth Keyboard cheat sheet

I'm having trouble wrapping my head around the arrayForth editor keyboard layout diagram in section 3.1 of the arrayForth user guide, so I am trying to put together a slightly modified version that more tightly associates the keyboard keys (and position) to function.  I am also dropping the grouping-via-color since I don't have a color printer at hand.  Here is a link to the PDF.

Tuesday, September 27, 2011

My GreenArrays EVB001 Eval Board Adventure

Okay, so I broke down and purchased an eval board last week. I got my shipment notice last Friday (which included a nice personal note from Greg Bailey mentioning that he saw my last blog post -- thanks Greg) and the board arrived Monday.

Now, to answer my own question (from that post): What to do with 144 cores?  I guess I'm going to have to figure that one out...

I've got a big learning curve ahead of me, and although I'm not the type to post daily updates on "learning experiences", I'll probably post now and then how it is going. If I get an overwhelming burst of energy, then I may even fork my EVB001 adventures to a new blog dedicated to just that.

Anyway, what are my current plans?


  1. Learn enough arrayForth (ColorForth) to be dangerous.
  2. Work my way around the board (nodes and I/O).
  3. Begin world dominating project.
Regarding #1, I have followed ColorForth for years, but I never really used it.  That being said, I am using Charley Shattuck's MyForth on my day job (shhh.. don't tell them)  and that is different enough from ANS Forths that the arrayForth "culture-shock" is low. 

Working around the board (#2) is critical as I have to figure out what my peripheral hook up options are.  I figure that I would try and get the board talking to an accelerometer (or other sensor). This would be a good goal.

Now, world domination (#3) is a bit vague.

Now, here is what I am thinking.... My usual approach of building tiny/simple things that can be replicated (low volume production runs) won't work here.  I simply can't afford to dedicate a $450 eval board to a single task.  Then again, I hate the idea of just using it as a "prototyping" board for various ideas.  I need a more singular goal.  

So, I am viewing the eval board as a "platform".  But, a platform for what?

When someone (for passion) designs and builds their own car, plane or boat, they are creating something unique. They are not making something with the end goal of mass production. They are building a "system" that satisfies their own needs. Now, if that "system" later results in replication due to demand, then that is great. But, it is all about building something unique -- something unlike the other guy's car, plane or boat.

You may see where I am getting... the usual place: Robotics.

But, here I use the word "Robot" in loose terms. I am thinking about building a platform to support the integration of sensors and actuators.  I want to load up the EVB001 with as many sensors as possible and have it collect, correlate and react through the manipulation of actuators.  However, I want to do this within the tightest time constraint possible: I want a tight coupling between sensors and actuators. I want a feedback mechanism. I want... my flocking Goslings (or at least one of them at this point).

Integrating lots of sensors with a single fast running ARM is certainly possible. But this would be interrupt hell (or polling hell or linux process/thread management hell). This is why I (and other sensible people) incorporate tiny 8051s, AVRs and MSP430s into dumb sensors -- to make them independently smarter.  Unfortunately, when you have a bunch of microcontroller enhanced sensors (and actuators) you have a communication nightmare. And you need a separate master CPU to integrate all of the "smart" data and manipulate the actuators.

None of this is new. None of this is rocket science. However, the robot I design would be my bot. It would be unique. 

More deep thoughts later... For now, I just need to figure out how to talk to my new toy ;-)

Monday, September 19, 2011

GreenArrays G144 - What to do with 144 cores?

I've been following the GreenArrays G144 since its inception.  Now a kit is available... programmable in colorforth (and eforth).  Forth chips aren't new to me. I remember devouring the Novix NC4000 back in the mid-80s (I couldn't afford one...).

So, the kit costs $450. I don't really have that kind of money to drop on a dev kit, but... if I did manage to scrape up the cash, what would I do with 144 computing cores?

Seriously, that is a good question for deep thinking. From an embedded computing perspective, what could one do with 144 computing cores?

If I can come up with some good ideas, this kit may be on my birthday wishlist.... ;-)