Program Storage and Execution
#1
Posted 07 December 2010 - 02:43 PM
#2
Posted 07 December 2010 - 03:47 PM
The tutorial is very basic and the .Net compact framework documents are .Net specific; not netduino specific and that's why I ask these questions. Thanks.
Please note that you should be referencing documentation on the .NET Micro Framework API and not the .NET Compact Framework API as they are two different things.
#3
Posted 07 December 2010 - 03:51 PM
Does the netduino (or possibly the netduino plus) allow storage and execution of binaries from an SD card? This is something desirable for microcontroller hobbyists and most controllers don't allow (from what I've seen, I'm not a pro microcontroller developer) that because it appears to add a decent amount of complexity to the controller firmware.
Yes, it is possible to load assemblies (e.g. dll's) from external storage at runtime. You should probably search StackOverflow for solutions to make this work. The way to do this is probably the same for both the .NET Micro Framework and the full .NET Framework.
StackOverflow search results for loading assemblies at runtime in .NET
#4
Posted 07 December 2010 - 04:00 PM
#5
Posted 07 December 2010 - 04:03 PM
Please note that you should be referencing documentation on the .NET Micro Framework API and not the .NET Compact Framework API as they are two different things.
My mistake, thanks for pointing that out.
#6
Posted 07 December 2010 - 04:04 PM
While I'm on the subject, can multiple programs execute at once (like a program pool of some type) or can a program spawn an instance of another?
I'm pretty certain you can't run multiple executables on the .NET Micro Framework at the same time. I could be wrong and maybe someone else knows otherwise.
Aside from that, if you want to have a different set of code run while your main code runs you should look into System.Threading. For example, you could have your main code running and then at some point you can have some other code to execute on a different thread while the main code runs its own thread.
Again, you should probably look to StackOverflow for solutions or read the MSDN documentation. If you are completely new to the .NET framework in general, you should probably pick up in introductory book first.
#7
Posted 07 December 2010 - 04:08 PM
Yes, it is possible to load assemblies (e.g. dll's) from external storage at runtime. You should probably search StackOverflow for solutions to make this work. The way to do this is probably the same for both the .NET Micro Framework and the full .NET Framework.
StackOverflow search results for loading assemblies at runtime in .NET
I think it could be beneficial to have a program running in memory that could read a manifest on SD storage that contained metadata on executables on SD. The thing is, could those executables execute from the external storage or would they need to be copied into memory?
Maybe threading could work but it would be nice to have the controller software handle process management for me when I don't have to.
#8
Posted 07 December 2010 - 04:11 PM
I'm pretty certain you can't run multiple executables on the .NET Micro Framework at the same time. I could be wrong and maybe someone else knows otherwise.
Aside from that, if you want to have a different set of code run while your main code runs you should look into System.Threading. For example, you could have your main code running and then at some point you can have some other code to execute on a different thread while the main code runs its own thread.
Again, you should probably look to StackOverflow for solutions or read the MSDN documentation. If you are completely new to the .NET framework in general, you should probably pick up in introductory book first.
I'll check out StackOverflow and see what's going on for Netduino questions there. I'm new to Netduino development as a hobbyist and .Net software engineer by day. That's why I chose the platform for microcontroller development. Thanks for the info needed to whet my appetite and getting me in the right direction.
#9
Posted 07 December 2010 - 04:45 PM
From the website "Pyxis 2 is an open-source operating environment based on NETMF technology."
#10
Posted 07 December 2010 - 05:24 PM
The contents of 'AppLoader.cs' is probably what you'll want to use. It essentially grabs a byte array and uses 'System.Reflection' to load it as an executable assembly. This should work, but I see problems with a lack of memory while using the Netduino.
Contents of AppLoader.cs so you don't have to download the Pyxis source:
/* Copyright 2010 Thomas W. Holtquist Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ using System; using System.Collections; using System.IO; using System.Reflection; using System.Runtime; using Microsoft.SPOT; namespace Skewworks.Pyxis.Kernel { internal static class AppLoader { /// <summary> /// The interface for a standlone application /// </summary> interface IApplication { void RunFromBytes(ref ApplicationKey AppKey, ref PyxisAPI APIRef, ref string path, ref string[] parameters); AppIcon GetAppIcon(byte[] bytes); } /// <summary> /// A class that can be loaded across applicaiton domains which /// implements the IApplicaiton interface /// </summary> public class Application : MarshalByRefObject, IApplication { /// <summary> /// we need a defautl consturctor to create an instance of this object /// across an application domain /// </summary> public Application() { } public AppIcon GetAppIcon(byte[] bytes) { // Attempt to execute DLL try { Assembly asm; MethodInfo[] m; asm = Assembly.Load(bytes); if (asm == null) { return new AppIcon(); } Type[] t = asm.GetTypes(); for (var j = 0; j < t.Length; j++) { m = t[j].GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); for (int i = 0; i < m.Length; i++) { if (m[i].Name == "PyxisIcon") { return (AppIcon)m[i].Invoke(asm, null); } } } } catch (Exception e) { // Do nothing } return new AppIcon(); } public void RunFromBytes(ref ApplicationKey AppKey, ref PyxisAPI APIRef, ref string path, ref string[] parameters) { string[] supporting = Directory.GetFiles(Path.GetDirectoryName(path)); for (int i = 0; i < supporting.Length; i++) { if (supporting[i] != path) { try { Assembly.Load(File.ReadAllBytes(supporting[i])); } catch (Exception) { // move along } } } RunAppFromBytes(AppKey, APIRef, File.ReadAllBytes(path), parameters); } private void RunAppFromBytes(ApplicationKey AppKey, PyxisAPI APIRef, byte[] bytes, string[] parameters) { // Attempt to execute DLL try { Assembly asm; MethodInfo[] m; asm = Assembly.Load(bytes); if (asm == null) { return; } Type[] t = asm.GetTypes(); for (var j = 0; j < t.Length; j++) { m = t[j].GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); for (int i = 0; i < m.Length; i++) { if (m[i].Name == "PyxisApp") { AppStartup myStartup = (AppStartup)m[i].Invoke(asm, new object[] { AppKey, APIRef, parameters }); APIRef.ActivateApplication(myStartup, AppKey); } } } } catch (Exception e) { // Do nothing APIRef.Prompt("Failed to launch program.\n" + e.Message, "System Alert", PromptType.OKOnly); } } } #region Variables private static IApplication iApp = null; #endregion /// <summary> /// The executable entry point. /// </summary> public static void LaunchApplication(PyxisAPI APIRef, string path, string[] parameters) { int AppID = GetAppID(APIRef); // Create the Application PyxisApplication PA = new PyxisApplication(); PA.Forms = new ArrayList(); PA.Domain = AppDomain.CreateDomain("PyxisApp" + AppID); PA.Key = new ApplicationKey(AppID, PA.Domain); APIRef._runningApps.Add(PA); // create an instance of the IApplication type // please note that the following call will also load the assembly that contains that type // which we pass as first parameter try { iApp = (IApplication)PA.Domain.CreateInstanceAndUnwrap(typeof(IApplication).Assembly.FullName, typeof(Application).FullName); // Allow system time to catch up System.Threading.Thread.Sleep(100); // Launch the Program iApp.RunFromBytes(ref PA.Key, ref APIRef, ref path, ref parameters); } catch (Exception e) { APIRef.Prompt("Failed to launch application!\n" + e.Message + "\n" + e.InnerException.ToString(), "System Alert", PromptType.OKOnly); APIRef._runningApps.Remove(PA); return; } } public static AppIcon GetApplicationIcon(byte[] bytes) { AppIcon AI; // Create the Domain AppDomain ad = AppDomain.CreateDomain("PyxisAppDesktopIcon"); // create an instance of the IApplication type // please note that the following call will also load the assembly that contains that type // which we pass as first parameter if (iApp == null) { try { iApp = (IApplication)ad.CreateInstanceAndUnwrap(typeof(IApplication).Assembly.FullName, typeof(Application).FullName); } catch (Exception e) { AppDomain.Unload(ad); return new AppIcon(); } } // Get the Icon AI = iApp.GetAppIcon(bytes); // Destroy Domain iApp = null; AppDomain.Unload(ad); return AI; } private static int GetAppID(PyxisAPI APIRef) { bool bConflict = false; int AppID = 0; int i; PyxisApplication PA; while (true) { bConflict = false; for (i = 0; i < APIRef._runningApps.Count; i++) { PA = (PyxisApplication)APIRef._runningApps[i]; if (PA.Domain.FriendlyName == "PyxisApp" + AppID) { bConflict = true; break; } } if (!bConflict) return AppID; AppID++; } } } }
Unrelated side note: Would it be possible to get a 'spoiler' tag added so you can embed long pieces of code in collapsible block?
#11
Posted 15 December 2010 - 05:35 PM
#12
Posted 16 December 2010 - 02:54 AM
#13
Posted 24 December 2010 - 10:37 PM
#14
Posted 25 December 2010 - 05:09 AM
#15
Posted 30 December 2010 - 12:00 AM
Cheers,
-Fabien.
#16
Posted 30 December 2010 - 03:08 PM
Just closing the loop: I figured out how to load assemblies dynamically and wrote post about it on my blog: http://fabienroyer.w...ith-a-netduino/
Thanks so much!
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users