this is a brutally simple interface for a spi pin 1 - chip select cr pin 3 - clock cr pin 5 - mosi cr pin 17 - miso cr /spi call first. main loop .
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 ;
02 4A for unext ; approx. 2mhz cr -ckwait 05 2B !b ckwait ;
07 io b! -ckwait ;
0A 29 !b ;
0C if drop 10 then 2F or !b ckwait -ckwa
13 b- 80 7 for over over and spiw1 2/ ne
1A -b @b . -if drop - 2* - ; then drop 2
1E -b 0 7 for 0 spiw1 spir1 next 2/ ; cr 26 |
|
nxp pcf2123 calendar clock module.
initializes the pcf2123 clock cr rdt reads date and time
sets data and time port the cr |
852 list
7 node 0 org cr /cs 00 left a! @p .. cs ! ;
04 @p .. -cs ! ;
07 d- @p .. @p .. ! ! ;
0A -d @p .. !p .. ! @ ;
0D put @p .. spiw8 ! ;
11 @p .. spir8 ! get ;
14 @p .. /spi ! /cs 10 spiw 58 spiw c
1C -smhwdmy /cs 92 spiw spir spir spir spi
27 ymdwhms- /cs 12 spiw spiw spiw spiw spi
32 12 11 10 9 8 7 6 sdt ; cr 3C |
Showing posts with label GreenArrays. Show all posts
Showing posts with label GreenArrays. Show all posts
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.
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...
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 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
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 ;
05 io b! -ckwait ;
07 29 !b ;
09 if drop 10 then 2F . + !b ckwait -ckw
10 b- 80 7 for over over and spiw1 2/ ne
17 -b 0 7 for 2* dup or spiw1 @b . -if d 1 or dup then drop next 2/ ;
21 cs 10 spiw8 58 spiw8 -cs ;
27 -smhwdmy cs 92 spiw8 spir8 spir8 spir8
32 ymdwhms- cs 12 spiw8 spiw8 spiw8 spiw8 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.
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 ;-)
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'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 ;-)
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:
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.
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:
- Receive a temperature sample
- Is it at stasis? If so, keep track of how long
- Is it still rising? Compare it with "fire" levels -- there may be no pot on the burner or it is scorching
- Is the temperature still rising? Fast? Send an SMS alert
- Is it on late in the evening? Send an SMS alert
- Keep a running summary (timestamped) of what is going on. Log it.
- 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.
Monday, January 23, 2012
True Modular computing
I want to tie together my past 3 posts.
In Multi-computers vs multitasking vs interrupts I stated a problem (concurrent processing within the embedded realm) and teased you with a solution (GreenArray's GA144).
In Costs of a multiple mcu system I backed a bit away from the GA144 and wondered if a bunch of small, efficient and cheap MCUs could solve the problem.
In Building devices instead of platforms I offered a rationale to my pondered approaches.
So, here I sit composing an interrupt for an 8051 to service a GSM modem's UART (essentially to buffer all the incoming data). And... everything has just gotten complicated. I've been here before. I am no stranger to such code and the approach I am taking is text book. This is how code starts to get hairy and unpredictable.
But, really now... maybe I *should* consider breaking my tasks down into hardware modules (with each module consisting of dedicated software). If I dedicated an 8051 (tight loop, no interrupts) to just talking to the modem, collecting responses and sending just the relevant information to another 8051 (perhaps through I2C or SPI), then I build that module once, debug it once and be done with it.
This is modular design, isn't it?
So (during design) every time I find a need for an interrupt, I just fork another processor?
(This would work with a single GreenArray's GA144 as well as $3 Silabs 8051 MCUs)
In Multi-computers vs multitasking vs interrupts I stated a problem (concurrent processing within the embedded realm) and teased you with a solution (GreenArray's GA144).
In Costs of a multiple mcu system I backed a bit away from the GA144 and wondered if a bunch of small, efficient and cheap MCUs could solve the problem.
In Building devices instead of platforms I offered a rationale to my pondered approaches.
So, here I sit composing an interrupt for an 8051 to service a GSM modem's UART (essentially to buffer all the incoming data). And... everything has just gotten complicated. I've been here before. I am no stranger to such code and the approach I am taking is text book. This is how code starts to get hairy and unpredictable.
But, really now... maybe I *should* consider breaking my tasks down into hardware modules (with each module consisting of dedicated software). If I dedicated an 8051 (tight loop, no interrupts) to just talking to the modem, collecting responses and sending just the relevant information to another 8051 (perhaps through I2C or SPI), then I build that module once, debug it once and be done with it.
This is modular design, isn't it?
So (during design) every time I find a need for an interrupt, I just fork another processor?
(This would work with a single GreenArray's GA144 as well as $3 Silabs 8051 MCUs)
Building devices instead of platforms
The title of this posting is a concept that flies in opposition to conventional wisdom. Everything seems to be a platform these days. When you buy a gadget or appliance you are not buying a device, you are investing in a platform. Refrigerators are appearing with Android embedded. We are looking at a future of doing "software updates" to our appliances!
Of course, there is big talk about the "Internet of Things", and that could be grand (my washing machine could one day query my fridge about the tomato sauce stain it encountered on my shirt and then place an order on Amazon for the correct stain treatment product).
But, the consider the "elephant in the room": these devices will suffer from that dreaded of all software plagues: "ship now; fix later in an update".
This doesn't tend to happen when you talk about your appliances and devices containing "firmware" (in the original sense). My washing machine has embedded microprocessors but there is no evident way to upgrade the firmware. Hence, the engineers have got to get it right before it ships. The software is apparently sophistica Of course, this is not always the case, but the "get it right" mindset is there. You don't want to tell people they have to call a service technician and "upgrade" their washing machine when it locks up.
For all the smarts my washing machine has, it is still a "device" (not a platform).
This rant bleeds into the common "old fogy" rant that a cell phone should be (just) a phone. I don't think we need to start limiting the potential of our devices, but there are some that should just "work".
We are losing that when we start designing a device and our first step is to choose an OS.
Of course, there is big talk about the "Internet of Things", and that could be grand (my washing machine could one day query my fridge about the tomato sauce stain it encountered on my shirt and then place an order on Amazon for the correct stain treatment product).
But, the consider the "elephant in the room": these devices will suffer from that dreaded of all software plagues: "ship now; fix later in an update".
This doesn't tend to happen when you talk about your appliances and devices containing "firmware" (in the original sense). My washing machine has embedded microprocessors but there is no evident way to upgrade the firmware. Hence, the engineers have got to get it right before it ships. The software is apparently sophistica Of course, this is not always the case, but the "get it right" mindset is there. You don't want to tell people they have to call a service technician and "upgrade" their washing machine when it locks up.
For all the smarts my washing machine has, it is still a "device" (not a platform).
This rant bleeds into the common "old fogy" rant that a cell phone should be (just) a phone. I don't think we need to start limiting the potential of our devices, but there are some that should just "work".
We are losing that when we start designing a device and our first step is to choose an OS.
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:
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.
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:
Okay, you are getting desperate. You start thinking:
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...
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.
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.
Another GreenArrays blog
I've stumbled upon: http://greenarrays.blogspot.com
Oh, and also, look to the right of this entry (under Links) for the permanent home of my arrayForth cheat sheet (just revised today).
Oh, and also, look to the right of this entry (under Links) for the permanent home of my arrayForth cheat sheet (just revised today).
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?
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?
- Learn enough arrayForth (ColorForth) to be dangerous.
- Work my way around the board (nodes and I/O).
- 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.... ;-)
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.... ;-)
Subscribe to:
Posts (Atom)