Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

ziggurat29's Content

There have been 241 items by ziggurat29 (Search limited from 20-April 23)


By content type

See this member's


Sort by                Order  

#51469 Referencing Boolean variables from other Methods, Serial issues too...

Posted by ziggurat29 on 16 July 2013 - 03:48 AM in Netduino Plus 2 (and Netduino Plus 1)

The loss of red squiggles

oft gives one the giggles,

but the code that does run

is really more fun.

 

Good luck, have fun debugging!




#51466 Referencing Boolean variables from other Methods, Serial issues too...

Posted by ziggurat29 on 15 July 2013 - 11:50 PM in Netduino Plus 2 (and Netduino Plus 1)

some things:

*  Is 'Light_State' reachable in Status()?  Because it is a local in Lights().  So it shouldn't compile as you have shown.  You could define Light_State as a (static) member variable, like your did with the serialA and serialB; then it will be reachable.

*  Light_State is not a boolean itself, it's an OutputPort, but you need to call Read().  (much like you don't assign, but you call Write()).  So your line 63 would read something like:

  if ( Light_State.Read() )

*  you initialized LIght_State on D2, but this will presumably conflict with serialB when you get around to implementing that, which uses that line as COM2 RXD.

*  you're creating and opening your serial port in Status().  Normally you wouldn't do this.  Normally you'd do that early in the program, and then just use the open instance later.  As written here, it goes out-of-scope at the end of Status().  But this doesn't mean the hardware is actually released at that time, because you did not close and (more importantly) Dispose().  So the next time you go into Status(), you might find you can't open it.

 

HTH




#51357 Bug: Netduino DHCP requests not asking for DNS

Posted by ziggurat29 on 11 July 2013 - 04:21 PM in Netduino Plus 2 (and Netduino Plus 1)

It is interesting, I have never had to do this, and I can attest that I use a dns name to reach my server from the netduino (which is on the Internet, not the lan), and I use dhcp to get all my config.  I would think that would mean that I must be using dns to resolve the name, and that since there is no specific configuration of the dns server name, that it must have come in through dhcp, automatically, without explicit programmatic action.  FWIW I am using 4.2.2.1.

 

Your mention that, at work, that you find that "the DNS entry is my home router, not my work DNS" is interesting.  What do you mean by that?  There's not a power-cycle-to-power-cycle persistent storage of a dynamically assigned dns name.




#51355 Public key encryption with Microsoft.SPOT.Cryptography.PKCS11

Posted by ziggurat29 on 11 July 2013 - 04:10 PM in General Discussion

crypto is a stub in the netduino firmware; you'll need to do it managed (or make your own firmware).

 

I have had mostly success using the BouncyCastle implementation.  But you cant just build bouncy castle and use, you'll need to find and pull out the particular modules you need.  It can be tedious, but when you're done you're done.

 

You'll sometimes need to be judicious in what alternative implementation you use, or the build tools will croak (e.g., I had to use AES 'light', because the 'fast' will not compile).  In particular, the 'metadata processor' will croak if you have large constant data.  For example, for me the sboxes of the fast implementations pushed it over the edge.

 

I should also mention that, in my case, I did not use asymmetric crypto; I used aes, sha, hmac, and dealt with key management the old fashioned way.  So structly I cannot attest that you can successfully integrate the asymmetric stuff from personal experience, but it is worth a try.




#51308 Can you buy ND+2 without the female headers soldered on?

Posted by ziggurat29 on 10 July 2013 - 04:53 PM in Netduino Plus 2 (and Netduino Plus 1)

yes, reverse the header pins on your board and mount the np2 'upside down' with respect to what you are originally thinking.




#51253 Debug.GC

Posted by ziggurat29 on 09 July 2013 - 01:31 PM in Netduino 2 (and Netduino 1)

I think that 60k is a conservative estimate.  The device itself has 128k ram, with some of that consumed by CLR.

This minimal program:

namespace Nada{	public class Program	{		public static void Main()		{			Debug.Print(Debug.GC(true).ToString());		}	}}

will emit:

 

81972

 

(and can wiggle around that number run-to-run, but more-or-less the same value)




#51230 Main Thread Hangs

Posted by ziggurat29 on 08 July 2013 - 07:49 PM in Netduino Plus 2 (and Netduino Plus 1)

it gets some execution before locking up.  A couple things I observed:

*  connecting a scope to the onboard LED

  *  always flashes 8 times before 'locking up' (with code as above)

  *  this in my limited manually executed tests of maybe 20 attempts (tedious!)

*  if the code is running not-locked-up (because of debugger connection)

  *  you can detach the debugger (with the 'stop' button)

  *  even close VS

  *  continues to run

and I'm sure everyone has noticed that the flashing of the onboard led is much much faster with no debugger (before it locks up).

I did verify that all the threads are running at priority 'normal'  (although even if they were at different priorities, that should not starve a thread, and I have coincidentally verified that in a separate test in the past, but not relative to the main thread).

 

Anyway, I think for most folks the underlying problem is masked, because either they are sleep'ing at some point, or do a sleep(infinite) on the main thread, and do all their stuff in the workers.




#51216 Unmount and MountSD; do they work on NP2?

Posted by ziggurat29 on 08 July 2013 - 04:46 PM in Netduino Plus 2 (and Netduino Plus 1)

Folks;

Does anyone know definitively whether the APIs:

StorageDevice.Unmount()

and

StorageDevice.MountSD()

do or do not work on the Neduino Plus 2?  From experience?

 

Here is a test app that, for me, fails attempting to Unmount().

//testing StorageDevice.Unmount and StorageDevice.MountSD on the NP2using System;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.IO;    //NOTE:  you will need to add reference SecretLabs.NETMFIO.IOusing Microsoft.SPOT.IO;      //NOTE:  you will need to add reference Microsoft.SPOT.IOnamespace NP2VolumeMountTest{    public class Program    {	    public static void Main()	    {		    bool bJoy = false;		    try		    {			    //first, get mounted volume names as a sanity check			   				 Debug.Print("listing mounted volumes...");			    VolumeInfo[] volumes = VolumeInfo.GetVolumes();			    foreach (VolumeInfo volumeInfo in volumes)				    { Debug.Print("volume:  " + volumeInfo.Name); }			    Debug.Print("finished listing mounted volumes");		   				 //now, we will try to unmount and re-mount the SD card			    Debug.Print("attempting to unmount SD card...");			    StorageDevice.Unmount(@"SD");			    Debug.Print("unmount success!");			    //from schematic			    //using cpu spi module 3, /CS is B0, /CARDPRESENT is B5, /POWERCTL is B1			    //from firmware .DeviceCodeTargetsNativeSTM32ManagedCodeHardwareCPU.cs			    //public const Cpu.Pin GPIO_PIN_B_0 = (Cpu.Pin)16;			    //public const Cpu.Pin GPIO_PIN_B_1 = (Cpu.Pin)17;			    //public const Cpu.Pin GPIO_PIN_B_5 = (Cpu.Pin)21;			    Debug.Print("attempting to re-mount SD card...");			    StorageDevice.MountSD(@"SD", SPI.SPI_module.SPI3, (Cpu.Pin)16, (Cpu.Pin)21);			    Debug.Print("re-mount success!");			    bJoy = true;		    }		    catch (SystemException e)		    {			    Debug.Print("failure;  exception:  " + e);			    Debug.Print(e.StackTrace);		    }		    Debug.Print("Test application main() terminating.  " + ( bJoy ? "Have a nice day." : "It will be a long day." ) );	    }    }}

Let me know if there is a change that will make it work, and ideally what firmware version you are using.  I myself have tested on firmware versions 4.2.1.0, 4.2.1.1, 4.2.1.2, 4.2.2.0, 4.2.2.1, 4.2.2.2.

 

While looking into a different problem (that of filesystem flushing), I started with the often-suggested workaround of doing an Unmount().  Of course, one would want to remount, right?  Which was the motivation for this test:  to figure out the MountSD parameters, but then I discovered that Unmount fails beforehand.

 

FWIW, I also tried fiddling with the "SD", trying upper, lower, leading slash, trailing slash, and null.  (Examining the source, I didn't really expect those to help, but now you know I did try anyway).

 

Any confirmation that Unmount/MountSD do in fact work on the NP2 is useful, along with whatever beyond what I showed above that is necessary to make those calls work.

 

-knave




#51209 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 08 July 2013 - 02:23 PM in Netduino Mini

we've got functioning dev boards and plenty of coding work to do.  Have fun on holiday (well, if it is holiday; 'good luck' if it's business)




#51206 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 08 July 2013 - 01:22 PM in Netduino Mini

Sweet Jesus!  That's great valkyrie; if you want, go ahead and put it on the codeplex; it probably would be messy to shuffle intermediate builds back and forth as forum attachments, and possibly confusing for someone who wants to download it.  I've not used the codeplex, but I imagine it is similar to all the other hosted scm, but with a dotnet focus.

I look forward to checking it out!

 

Hanzibal, I'd love to see your board layout when your ready to share (and if you're open to possibly annoying but respetful feedback).  Maybe even you could stick your eagles in a directory in the hypothetical hosted scm?




#51205 Proper way to multithread on Netduino

Posted by ziggurat29 on 08 July 2013 - 01:15 PM in Netduino 2 (and Netduino 1)

I'd like to add to hanzibal's suggestion that also, the interrupts are delivered on an internal worker thread that runs at Highest priority.  You don't really want to do much significant work there beyond hanzi's suggestion of queueing it for further processing on other threads (I'm speaking form personal experience on that; it's confusing, then amusing, to see the rest of the system running in slo-mo just because you're doing work in a button event handler rather than handing it off).

 

Lastly, as you've observed, the first 'main' thread seems internally to have some other duties.  It also has some scheduling oddities, e.g. as reported in this thread (no pun intended):

http://forums.netdui...ngs/#entry50924

I think most folks mask that effect because they sleep, but still it's interesting to be aware of it.




#51137 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 06 July 2013 - 01:57 AM in Netduino Mini

...

@ziggurat29: Have you ever considered politics or have they perhaps already got to you?  :P  SMD.

politics?  never.  you got me beat this time on the reference joke, though!

 

But the ancient dusty frustum of a pyramid numbered 3^3 + 3 - 3/3 will give it a rest until the day of the moon....




#51135 OT: Lamp Powered by Ethernet Switch?

Posted by ziggurat29 on 06 July 2013 - 01:55 AM in General Discussion

think nothing of it!

I believe the answer to your question is 'no'.  The ethernet switch -- outside of something like PoE -- supplies no power at all to the various ports rj45.  Indeed that is what PoE is for!




#51128 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 05 July 2013 - 09:35 PM in Netduino Mini

Only comments I can add (for what they're worth) to Baxter's statement are:

*  LDO; low dropout from what input?  If it's a big enough difference, like 5 > 3.3., maybe ldo is not needed?  or maybe my bar for low is high? haha

*  it seems there are two potential hardware realizations:]

  1) a DIP form factor, with a premium on size/shape

  2) a shield form factor, with a premium on electrical compatibility (3.3/5v) (and also a form factor, but that's easy to achieve, but please do support the v3 pinout)

 

'2' speaks for itself, I think, and you'd probably be just fine using the Vin pin without needed a barrel connector.  Or if you really want to, use the Vin, and support an unpopulated barrel connector that can be selected via jumper or probably even solder bridge, because I suspect that the need for external versus using Vin is rare.

 

'1' maybe bears more discussion.  I do personally put a premium on the 0.6" spacing, and similarly on a 24/28/40 pin layout.  Also, I am not a mini user, so I'm naive to that market.  But...  Secret Labs' made a conscientious choice in designing the mini to be BASICStamp compatible (much as the netduinii are arduino compatible), ostensibly because this makes them more marketable by being able to leverage the existing community.  I think this has definitely worked with the 'duino' line -- can't say about mini because I'm unfamiliar.  Maybe what folks want more is 'small' rather than 'basicstamp compatible'.  In which case, I'd argue to make a 40-pin factor, with whatever pinout gives the strongest capability.

 

Lastly, out of respect for our host, Secret Labs is a hardware company.  They don't make anything off the software at all.  The software is free, and open (happily), and exists to support their hardware sales.  So, personally I feel a little awkward about discussing too much the notion of making alternative hardware in this forum, unless it's in the context of 'if you build this, we will come'.  Everything discussed up to this point has been completely open, but I mention this now really just to be explicit and clear.




#51125 OT: Lamp Powered by Ethernet Switch?

Posted by ziggurat29 on 05 July 2013 - 08:16 PM in General Discussion

it's not clear to me what you are saying.  I'm unclear because:

 

'ethernet switch'  to me means 'a box with a bunch of rj45 jack for switching ethernet packets'.  is that what you mean?  or some other interpretation of 'switch'

 

'led lamp powered by the switch'.  are you meaning: 'Power over Ethernet (PoE), that can power whatever, in this case happens to be an LED lamp'

 

'NP2 will communicate with ethernet'.  I understand that, except how it relates to the switch and the lamp.  Im guessing the so-connected NP2 is controlling the lamp?

 

If you do indeed mean 'I want to have an network controlled LED, managed by the NP2, connected through a PoE capable ethernet switch, and have the NP2 and the lamp be powered that way, without needed yet-another wall wart', here's some things:

 

*  ethernet itself provides no (significant) power, but there is a standard for PoE whereby power can be delivered over the same twisted pair cable used for networking.

*  and there are many non-standard implementations of supplying power over the networking cables, since this double-duty is a fairly common desire

*  you need a switch (or whatever is at the other end of your cable) specifically designed to do this.  It will be marked as being able to do PoE.  If it is not so marked, then consider it not capable, since this is unusual and its not at all free for the manufacturer to support

*  PoE supplies a pretty high voltage (and variable, since it is also subject to all sorts of IR losses along the line), and so will require some sort of regulation at your device anyway

 

It is a nice capability, and it's a real pity it's not more widespread.  My house is littered with wall warts and dangly wires.  You'd think it was the early 1900's.

 

On the other hand, if my interpretation is wildly not what you mean, then nevermind!




#51124 N+ 2 "hangs" after a while. How to debug?

Posted by ziggurat29 on 05 July 2013 - 07:50 PM in Netduino Plus 2 (and Netduino Plus 1)

...

I was thinking in the direction of the network stack as I had these kind of "hang ups" during early development when I was fiddling with the network cables etc... I have spend some time writing code to avoid this kind of situations, but it looks like it isn't failsave at all.

 

Do you mind sharing the "detection code" you use? Or give me some pointers to work with?

...

 

I don't mind sharing my detection code at all.  You'll be underwhelmed, it's rather simple and not really network specific.  Rather, it is simply a 'nonresponsive thread' detection, and is dependent on your not using blocking calls (or at least, use blocking calls with a timeout).  I think it will be easier to explain verbally.  Then if you still want code, I'll provide it.

 

1)  I have a 'client thread' that connects to a server, and sends (and receives) data.  In my case it is a socket-level protocol, and over a persistent connection, and not web based, but that detail shouldn't really matter.

 

2)  that thread's logic, oversimplified, looks like this:

  while ( should be connected )

  {

  // 'point A'

  if ( ! connect )

  {

  log failure

  sleep before retrying

  }

  else

  {

  // 'point B'

  if ( poll ( timeoutR, read )

  {

            // read and dispatch data

  } else if ( haveStuffToWrite and poll ( timeoutW, write ) )

  {

  // write stuffs

  } else

  {

  // nothing to do this go-round

  }

  }

  // 'point C'

  }

 

  So, this is basically a blocking loop with timeouts (so strictly it is not really blocking, but you get it), that should always be executing something at least as often as timeoutR + timeoutW, if not more frequently.  This is the key point.

 

3)  at the points labelled as 'point A', 'B' and 'C', I perform a watchdog 'checkin' action to a separate application component, called, ironically enough, the 'watchdog service'.

 

4)  this 'watchdog service' is a separate worker thread structured this way:

 

member vars:

hastable; mapping 'tag' to 'entry'.  a 'tag' is an arbitrary integer that I will explain, and an entry is a struct containing an expiration time (and I add an arbitrary text string for logging)

hardware watchdog pin (I will explain this later; its not crucial for this discussion but I want you to know it's there)

 

  thread function:

 

  while ( should be running )

  {

foreach hastable entry

  if ( entry is expired )

  log failure, and entry text string

  issue reboot

 

whack hardware watchdog (if you have one)

 

sleep ( watchdog polling interval, about 250ms )

  }

 

  and this component exposes two methods:

 

  checkin ( tag, duration )

  cancel checkin ( tag )

 

5)  in the points labelled 'point A' 'B' and 'C', in the 'client thread' of bullet point 1 above, the calls to 'checkin' and 'cancel checkin' are made.

 

6)  finally, the 'tag' is an arbitrary integer that each of my subsystems has.  for example, that 'client thread' in bullet point '1', above, would have some arbitrary number assigned to it.  It could be hard-coded so long as one 'subsystem' you are tracking uses it consistently in its calls to 'checkin' and 'cancel checkin'

 

//end=============

 

OK, so here's how it comes together if you haven't figured it out already:  In your thread of execution that manages your 'thing' be it network, or whatever, at any place you want, make a call to 'checkin' with a timeout that specifies 'if you don't hear back from me in XXX seconds, reboot the board'.  Then make sure that you can do another checkin before that time elapses in normal cases.  Subsequent checkin's (on the same tag) will delete and replace previous checkins.  If you don't want to track the service anymore, you issue 'cancel checkin', which will just remove the entry from the hastable of things being tracked.

 

At 'point A', I call checkin with a timeout of 60 sec, because connect can sometimes be a slow operation in real-world cases, but longer than that probably means the board is hung.

 

At 'point B', I call checkin with a timeout being equal to timeoutR + timeoutW plus  some overhead for correctly processing the data in worst-case scenarios, which in my case I have at 5 sec

 

At 'point C', my service is shutting down, an no longer needs to be tracked, so I call 'cancel checkin'.

 

OK, so the hardware watchdog bit.  If you don't have one, then ignore it.  However, it is entirely possible for the whole system to become locked up, including the 'watchdog service' I described above.  Then you're hosed -- you will need to physically reboot the system.  So, if you do have a hardware watchdog, then the 'watchdog service' would have the responsibility of whacking it at the point I marked above (at the end of its polling loop).

 

So this mechanism is not only compatible with a hardware watchdog, and actually makes it more useful:  Hardware watchdogs typically cannot be stopped, cannot have their time period altered (usually about 1/3 sec), and cannot conditionally monitor several components.  Aside from convenience, this is a bit of a serious issue because 3rd party (or firmware) code that you cannot modify (such as the internals of what 'connect' does), may easily block for longer than the hardware watchdog timeout period, then you are hosed.  You can't use it at all.

 

Lastly, in this description I showed my network service running as a worker thread.  You don't really have to do this if you don't want.  The 'watchdog service' does have to run as a separate thread, but if your existing code is a single thread of execution that is fine, because you always can issue 'cancel checkin' at the end of the code sequence you are monitoring.

 

Also, lastly lastly, if you do use this approach, you will be very much happier in life if you avail yourself of some logging mechanism, and use the free form text string (or whatever) I indicated in the 'entry' struct of the watchdog service.  That way, you can log why you are rebooting the board:  what code point failed.  Oh, and while developing, not actually reboot, which is really annoying when single-stepping code!

 

OK so that's my knumbskull hung thread detection mechanism:  a software watchdog service.  Thats also compatible with an optional hardware watchdog.

 

 

I don't use beta firmware as I don't want to spend to much time running into undocumented problems. My devices have firmware v4.2.2.2 and are using the v4.2 SDKs (as you do).

 

Wise.  and truthfully I don't use greater that 4.2.2.1, because the x.2 source hasn't ever been posted, and I personally experienced some I2C anomalies in x.2 with it that seemed to go away in x.1




#51122 Are my netduino 2s fried?

Posted by ziggurat29 on 05 July 2013 - 06:44 PM in Netduino 2 (and Netduino 1)

mercy!  stop blowing them up, haha.

 

I can tell your from personal experience that the 'hissing' sound is probably the inductor on the switching supply being overloaded trying to regulate.  This is not a good sign.  I myself broke an NP2 somehow (I like to blame it on a cruddy shield I was using, but truthfully it could have been from ESD that was purely my fault).  In that case, the processor was damaged, and sunk a lot of current, loading the regulator, and producing a detectable whine.  For a while I used the dead board for measurements for mounting brackets, but then one day I decided to use it for soldering practice, and removed the cpu and replaced it with a new one.  Now I have a resurrected NP2! (and with a nicer processor with crypto accelleration)  I don't know that I'd recommend doing that in general, but now you know you can, at least.  If the processor is the actually damaged part (though likely it is since these circuits are so simple).

 

Big question is probably why you are killing so many of them (3+1=4 now?).  I do second Nighthawk's experience that TX-TX is not an automatic death sentence -- I've made that booboo a couple times too and gotten away unscathed -- but then again you aren't supposed to do that, and logically you'd think it would be bad news if they were driving opposite ways, so certainly avoid it.




#51115 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 05 July 2013 - 03:18 PM in Netduino Mini

your mention (hanzibal) of the .6 dip header reminded me of something:  The width of the cc3000 is such that the pins would be under the edges of the unit;  since the sparkcore photo shows the pins will to the side of the radio module, then I suspect that it is not a standard DIP footprint, that it is two rows of pin headers on a .7 or maybe even .8 width.

well I'll be back in town in a few days.  we'll see if any coding work is left for me to do....




#51085 N+ 2 "hangs" after a while. How to debug?

Posted by ziggurat29 on 04 July 2013 - 03:33 PM in Netduino Plus 2 (and Netduino Plus 1)

Heres some things I have done that may or may not help:

 

*  run your unit attached to the debugger until it fails.  there sometimes is useful output you cannot otherwise catch.

*  oh, before that, can you reliably stimulate the failure?  the more reliably your can stimulate it, the more confidence you have in your tests.

*  sometimes the easiest way to find a bug, is to make it worse; a kind of 'homeopathic debugging'.  For example, if you think you have memory problems, you could allocate a chunk to waste some, and see how that changes things.  Obviously you have to do this judiciously because obviously you can allocate a big chunk and make the system fail.  Rather, can you allocate a small chunk that should surely not cause a failure, but yet it causes you to fail significantly sooner or more often.

*  since the code is .net, run it on the desktop.  you will be able to debug more easily, and if fails there then you know you have a bug.  if it does run there, then you haven't disproved a bug, but you have a little more confidence at least.

*  make a logger and log to a file.  this is particularly useful if it is impractical to run in the debugger, or if the presence of the debugger masks your problem (it happens).  alas, be aware of some existing file writing issues (specifically, folks have had problems with their final writes not being committed, and that sort of thing really diminishes the value of a debug log since of course the interesting bits up to the point of failure are at the end).  also know that for certain root causes, logging can mask the origin of the problem. also know that for certain failures, logging can exacerbate your problem! but don't let that stop you.

*  if your code is running in a loop, toggle the onboard led; this is perhaps the least disruptive and simplest way of showing 'my code running here', that can be useful to prove the existence of lockups and paths of execution.  also, you have two lights at your disposal:  the blue onboard led, but you also can programmatically turn off the white power one, so that makes a potential second.

 

 

some other stuff:

*  you said a 'lockup'.  try to qualify lockup' to mean either a thread that stops running, or a piece of code that is running, but doesn't execute the way you want (that simply manifests the same symptoms).  I mention this because there are some instances of the halted thread related to networking that you can find elsewhere on this forum (sorry no direct link but I remember a recent thread was something like 'we have reproduce a lockup' or something like that).

*  if it is a halted thread of execution, see if other threads in your app are similarly halted, or just that one.  you only have a single thread?  well make another.  (actually I would suggest this as a design choice anyway, but thats separate)

*  if the other threads are responsive, then it could be some problem with some driver (e.g. the point the networking).  if you can find the call that halts, then you might be able to figure out a way to work around

 

ok, you asked about memory:

*  Debug.Print ( "mem:  " + Debug.GC(true) );

  this will print out your currently free memory.  it will also stimulate compaction.  (NB I wrote this as I post from memory, so double check for typos)

*  netmf is supposed to stimulate automatic GC when needed, and maybe it does much of the time, but I'm telling you from experience that you will probably want to do a Debug.GC(true) yourself periodically.  I have definitely restored a system to functionality simply by adding those calls prior to functional steps which create a bunch of temp stuff, but I suggest that you don't do this as a first line of defense.  Rather, find the failing point, see if you can repeatably stimulate the failure, then add the line and see if the behaviour is changed dramatically.

*  when considering the free mem as a result of Debug.GC(true), realize that this is after compaction.  Meaning that the act of looking at the memory available has changed the availability of that memory (for the better).  So if it is failing, and you notice 'I have 30k available), then really it was probably failing when you had more memory availble, but fragmented such that it was not usable.

*  netmf, when running low, will first become 'softly' unstable.  by this I mean that calls will internally fail due to memory problems, but not throw exceptions that you can catch and handle, leaving it in what appears to the program as a functional state, but in fact not so much.  If you have your debugger attached, you can see the internal failures happen, with the call returning rather than throwing.  I find this starts to happen when you get down to about 20K free as reported by GC(true), but this is a soft limit that I'm sure depends on my apps use of memory.

 

Eventually, you may get to a point where you decide you have found the bug, and it's out of your control to fix it.  Hopefully not, but it can happen.  Then you have to consider work-arounds.  Some might be:

*  can you detect yourself being in a state that will result in failure, in time to do something about it?

*  if you can, is it a viable option to:  stop your web service, CG(true), then start it back up?  No?

*  if you can't detect it beforehand and react, can you observe it from afar?  If only one thread is 'locked up', can you use a second non-lockedup thread to observe that the first has failed, and at least reset the board?  (you can also forcibly terminate a thread, but this generally introduces more instability.  better to just reboot.  boot is quite quick on an embedded system).

 

Here are a couple of tales from the trenches from my personal experience:

 

*  I have a component which operates a GSM modem.  I use regexs to do my parsing.  These are monstrously convenience, but they are also monstrously memory intensive.  I cannot precompile all the machines I need beforehand, so I build them on the fly as needed and then throw them away afterwards.  While this is 'wasteful' of CPU, I actually have way more than enough CPU resources, and am tight on RAM, so this is a good time/size tradeoff.  But, it introduces a new problem of memory fragmentation.  It was difficult to narrow down the point of failure, because it moved out in the code, but near-ish one area.  I could deliberately manipulate the problem by allocating chunks of a few K, and then I could also mask the problem by doing a GC(true).  So I concluded probably memory fragmentation issues.  (I say 'probably' because 'proven' would require an actual heap walk, which is not easy to do.  But I was satisfied with 'probably' and instead I used testing over several days of continuous running to make the uncertainty diminish.  Oh, BTW, two boards are better than one, if you can afford it.  You can have one board doing a lifecycle test, while you continue to develop on the other).

 

*  As a design style, I mostly prefer blocking calls and threads.  However, I always (well almost always), use a variation with a timeout value.  This helps because your thread can at least actively let someone know that it is alive when it times out.  flick an LED or check in with a watchdog log a message, whatever.  And 'whatever' can be stuff you haven't thought of yet, like 'add a call to GC(true)'

 

* I use a bunch of serial ports.  The orthodox way of using the serial ports is to set up a DataAvailable event handler that is invoked when data is available.  However, I (and others) have found this event to inexplicably stop being fired.  I ran this same code on the desktop, using one of those FTDI usb serial port devices connected to my hardware and found it to run perfectly, so I felt pretty good about the code being 'correct'.  I was initially worried about re-engineering the code to not use the DataAvailable event, but then I realized that I could emulate that event with a worker thread, and surgically slip that into my already developed code.  Point being is that sometimes you have to devise a workaround to a defect that does not originate in your own code.

 

*  I (and others) have had some deadlock issues with networking.  In my experience, I can reliably deadlock when I perform a socket connect() to a host that is reachable, but not listening on the port to which I am trying to connect (e.g., the listening server is down for whatever reason). I have also found that this only deadlocks the thread making that call -- all the others are still responsive.  That call does not have a timeout option (and I don't know if it would work anyway since its not supposed to lock like this to begin with).  However, it is possible for me to reliably detect that the 'lockup' has occurred, and I can reliably reboot the board in the case that it has.  Beautiful?  No, it's hideous, but my alternative is to not deliver product.  This scenario, though a 'negative case' (in the positive case there is always my infrastructure server listening for incoming calls), is actually easy to stimulate:  if I need to upgrade the server binarie, then it will be offline during the brief moment that I replace the binary and restart it.  This will then cause all my clients (i.e. boards) in the field to become immediately deadlocked, each requiring a power cycle.  But since I have modded the firmware to detect this scenaro and reboot, now those using are able to restore themselves to functionality.

 

HTH




#51083 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 04 July 2013 - 02:10 PM in Netduino Mini

You can usually ignore those warnings, vendors typically stress such things on samples to maximize the probability of users achieving success in evaluating the part. I'm pretty sure you can leave the bag open for years and it will still work and yield an ok product for hobby purposes.

yes, moisture can absorb into the epoxy, potentially causing issues in reflow oven, so they recommend baking to drive it back out if it becomes 'moist' (i think physical distortion during the process, but I can't recall precisely).  important if you're wondering why your yields are lower than expected when making a zillion units, but if you're prototyping, you're probably more suspicious of your manual soldering; at least I always am haha.




#51050 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 03 July 2013 - 03:32 PM in Netduino Mini

oh cool, so you have a working system to compare against; that will be a helpful sanity check when diagnosing problems.

 

BTW, If you happen to see in your spi'ing, a case where an asynchronous event is reported before a command's return packet, let me know.  the doc is not clear about whether that can or cannot happen.




#51026 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 02 July 2013 - 06:08 PM in Netduino Mini

WOW.  I have a long weekend coming up and I know what I will be doing now!  ...

 

Haha, have phun hacking!

 

...

I completely agree with the managed approach.  It reminds me of the enc28j60 driver that Hanzibal ported from C.  When I saw the raw packets coming in, my eyes lit up and I knew it was doable to do everything managed.  And the debugging was much easier because of it.  Once we have the communication and the ..

 

I'm very impressed you and hanzibal got a tcp stack and ethernet device driver working in managed on netmf.  Thats a lot of work.

 

...

command message objects, we should be able to take it all the way.  One thing that could accelerate things greatly would be if I can get just get raw packets to work, I can bolt on mIP and immediately have a usable solution.  To me the next step would be to leverage the cc3000 TCP stack to offload the work to improve ...

My only concern with the managed approach is future changes to the cc3000 firmware and hardware may also require changes in the wrapper (but that is likely to be minimal).  

 

I'm somehow sceptical that you'll be able to get raw packets, but my understanding of this device is far from comprehensive, so don't take my word for it.  (I think it's whole raison detre is to present a high-level berkeley sockets-esque api, so that's why I'm doubtful about that).  But no matter, it will make the job 'easier' to not have to fiddle with windows, retries, mtu, congestion control, etc.  Oh wait, you already did that.  Nevermind!

 

The managed implementation is especially worthwhile if you make a shield based this device, because then you can add it onto some existing platform.  It is a small wonder to me that shield vendors do not supply rich, robust, support software, but perhaps that's due to the dynamic of this DIY market.  Still, it seems a fertile ground for an enterprising person to produce a cc3000-based shield, supply excellent support software, and just beat the pants off all the current alternatives.  (well lasting until at least the next person makes a cc3000 board, and tells folks to download your free support software, haha, but that's part of how this market works.  then you have to differentiate a different way.)

 

I suspect that they won't change the firmware and hardware in a way that would break your implementation.  That would be bad business.  Maybe they would come out with a new device, shipping both, then obsolescing this one.  But its a moderately new part.




#51017 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 02 July 2013 - 01:24 PM in Netduino Mini

Ziggurat29, You have to let me help you.  I was just gearing up to do a .NET MF port myself.  I have an CC3000EM and I was about to setup an Arduino and ...

 

Sure, why not?

My plans (up to this point) were:

*  prove hardware interface (done)

*  prove SPI communications (done, I believe)

*  first make a managed code 'driver'

*  then make a native code integration with the firmware

So, two 'products' come out, one managed, and one native.  I want to do the managed version first because I believe it will be easier to experiment and debug in that context, and should cement my understanding of the part (the documentation is stunningly poor), and because I think it is a useful end in it's own right.  Once I have a thorough understanding of the device, then for the firmware it's a separate exercise to plan the integration, ostensibly replacing lwip (or maybe they can coexist, but I need to get into netmf's networking code to see what that means, since you'd effectively be making a multihomed system).

 

...  Can you post a zip of what you have so far?  Being able to start with (at least) the basic SPI stuff working would be very helpful.  

 

What I have right now, such as it is, is really exploratory code with no design to speak of, so it would be an embarrassment for me to post it.  If you really need it, I can douche out my more spirited comments and send it to you PM or something, but really I can sum it up this way:

 

Electrical:

using NP2

D13 - sck

D12 - miso

D11 - mosi

D6 - /IRQ

D5 - PWREN

D4 - /CS

3.3v  - pwr *

GND - no 'earth'ly idea

 

*  this will have to change soon as I start doing radio stuff; too much load

 

I am manually managing /CS and monitoring /IRQ for now -- maybe forever.  The SPI transactions often have to be done in two parts, and /IRQ is irksome in that it has mixed duty and doesn't seem useful to use it as an interrupt source, at least not so far, and anyway it gives me the feel of being level-sensitive and that's not supported on the NP2, but I'm not sure.

 

Software:

 

things:

SPI cc3000;   //I spi something that begins with the letter 'cc'    OutputPort cs;    //active low    OutputPort pwren;  //active high    //InterruptPort irq;  //interrupt; active low    InputPort irq;    //YYY I'm going to poll this for now until I understand this device better  

config:

  //make our spi (mode 1)      cc3000 = new SPI(new SPI.Configuration(        Pins.GPIO_NONE,    // SS-pin (we will manually do it)        false,        // SS-pin active state (low)        0,          // The setup time for the SS port YYY 50 uSec        0,          // The hold time for the SS port        false,        // The idle state of the clock (low)        false,        // The sampling clock edge (trailing)        1000,        // The SPI clock rate in KHz        SPI_Devices.SPI1));  // The used SPI bus (refers to a MOSI MISO and SCLK pinset)      //make our (manually controlled) cs (active low)      cs = new OutputPort(Pins.GPIO_PIN_D4, true);      //make our power control (active high)      pwren = new OutputPort(Pins.GPIO_PIN_D5, false);      //make our interrupt input (active low)  //XXX holding off on this until I understand the device better      //irq = new InterruptPort(Pins.GPIO_PIN_D6, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);      irq = new InputPort(Pins.GPIO_PIN_D6, false, Port.ResistorMode.Disabled);  

  //power up      pwren.Write(true);  

 

the spi clock speed was chosen semi arbitrarily, to make debugging with the scope easier.  Side note:  specifying 1000 KHz actually gave me a clock of 640 KHz.  I measured.  Maybe a Gates reference joke -- 'who will ever need more than 640K'?  anyway....

 

action:

 

The SPI transactions are mostly normal.  'Mostly', because:

*  the first one only after powerup requires a 50usec pause after the 4th byte before continuing.  seems like a workaround for device bug.  I do this by two sequential WriteRead operations.  netmf is slow enough that you don't have to use any delay code, and you get about 84 us delay.  happily there doesn't appear to be a max delay.

*  the reads involve retrieving a length of the variably sized payload that follows, so you need to do those transactions in two phases also.

 

goofy first write (also this required to be a 'link start' command):

 

  //wait for the signal that its ready      //XXX III support a timeout      while (irq.Read()){}      begin();  //assert cs and (redundantly) wait for irq      //delay(50usec);      //goofy first write has a little pause after the first busy bit before moving on with the rest      cc3000.WriteRead(pktLinkStart, 0, 4, null, 0, 0, 0);      //delay(50usec);        //and then the rest of it      cc3000.WriteRead(pktLinkStart, 4, 6, null, 0, 0, 0);      end();  //negate cs  

reading is a little interesting in that you must retrieve the length, and then complete the reading:

 

  //wait for the signal that its ready      //XXX III support a timeout      while (irq.Read()) { }      begin();  //assert cs and (redundantly) wait for irq      //write header and read the length bytes      cc3000.WriteRead(pktReadHeader, 0, 5, pktReadPayloadLen, 0, 2, 3);      //make length into a number; header is big endian.  other things are little.      int nPayloadLen = ( pktReadPayloadLen[0] << 8 ) | pktReadPayloadLen[1];      if (0 != nPayloadLen)      {        byte[] pktBogoWrite = new byte[1];  //dummy        //read payload        //XXX sanity check on length        byte[] pktReadPayload = new byte[nPayloadLen];        cc3000.WriteRead(pktBogoWrite, 0, 1, pktReadPayload, 0, nPayloadLen, 0);        //XXX III 'spatchy      }      end();  //negate cs  

OK looks like I did wind up posting most of what I did so far, haha!

 

Some things:

 

*  a healthy level of distrust of the documentation is worthwhile.  For instance, they contradict themselves in what is the spi mode to use.  It is spi mode 1.

*  you can tell that different engineering teams worked on this, not necessarily in concert for whatever reason.  For instance, some values are big endian, and others are little endian, so watch for that.

*  the 5 byte header I would probably re-phrase as:

  *  unsigned char byDir;  //1 = write, 3 = read;  from the spi master perspective

  *  unsigned short sWriteLen;  //little-endian;  when op=1, master indicates payload length; otherwise zero

  *  unsigned short wReadLen;  //little-endian;  when op=3, slave indicates payload length; otherwise zero

 

I think this covers most of the SPI; I still need to get a handle on whether there is more /IRQ consideration since the doc claims it serves some double duty, and that there is collision resolution to be performed.

 

Beyond that, I planned to do some reading in the light of my newfound knowledge, before I do much more coding.  There's something called 'patches' which are not really clear to me if I care about, and they use the term 'event' which I think really means 'return value' and 'asynchronous notification'.

 

On the plus side, it looks like the part is what I would describe as:

*  SPI-based RPC mechanism to Berkeley sockets, with some added stuff as needed (e.g. setting mac, wifi keys, etc).

 

So I think it should be straightforward to implement an API even on the managed side that very closely resembles the existing network api, and possibly on the native side to mesh with what exists there as well.  Hope springs eternal!




#50991 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 01 July 2013 - 04:57 PM in Netduino Mini

Well, stop your grinnin' and drop your linen, it responded back to my kookily-crafted initial packet in a cogent way.  Now I will have to Shake a Leg, haha.




#50989 Spark Core (TI CC3000) Porting for Super WiFI Mini?

Posted by ziggurat29 on 01 July 2013 - 03:40 PM in Netduino Mini

I did try the dead chicken routine but nothing in particular happened (other than our old parrot arising from the dead which was kind of freaky btw).

 

I too have a Bus Pirate laying somewhere, still untouched since I use the scope instead, it works pretty ok for me.

 

Vdd is 3V3 but I might have accidentally applied 5V logic at some point effectively killing the pin (I'm using my own USB explorer board, not a Netduino).

 

Btw, are you also using the older TiWi-SL eval board from LS Research?

Posted ImageTiWi-SL.jpg

I soldered short wires onto pins 7 - 12 on both the J4 and J5 headers (and left all other pins unused), then stuck it down a regular breadboard.

 

well, at least you can have the chicken for dinner.  and zombie parrots are quite the thing I hear, but careful of the bite.

 

I did read that the boards are very un 5v friendly, so you may indeed be hosed.

 

Yes, that is the board I am using.  Didn't know there was a newer one, and digikey didn't have any advice, but it was kinda spendy anyway.

I probably should have taking your pin route (on the breadboard); I make a 'conventional' upward facing header that I could use the ever-popular-and-formerly-scorned-by-myself-but-now-I-am-a-convert jumper wires with female ends, so I could simply plug them into my NP2, but then I can't connect probes at the same time, so I had to solder additional free leads to probe with.  Would have been better your way on a breadboard!

 

Anyway, I'll give it just a couple more hours, then I have to go back to my regularly scheduled work for the rest of the week, alas...





home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.