Implementing TeensyLoader into a C# app?

Rezo

Well-known member
I'm in the process of creating a simple app for updating a teensy based product (to be) and I was wondering, how can I implement the teensy cli C file into my existing visual studio wrapper (.cs) app without having to call the Teensy Cli externally?

I see the CLI version, but not sure how to import the .c source code into my .cs project

Would love to hear suggestions from others who have done this before.

Thanks,
 
Sure, here https://github.com/luni64/TeensySharp a library which identifies Teenies on the bus and can upload firmware. For easy installation it is also available via nuget: https://www.nuget.org/packages/lunoptics.TeensySharp/

You basically do:
Code:
var Board = PJRC_Board.Teensy_31; 
var FlashImage = SharpUploader.GetEmptyFlashImage(Board);                   // generate an empty flash image for the required board
SharpHexParser.ParseStream(File.OpenText("firmware.hex"), FlashImage);      // parse the hex file into this image
...
USB_Device Teensy = Watcher.ConnectedDevices.FirstOrDefault();              // get the first teensy found on the USB bus
SharpUploader.StartHalfKay(Teensy.Serialnumber);                            // switch it to bootloader mode... 
SharpUploader.Upload(FlashImage, Board, Teensy.Serialnumber, reboot: true); // ... and upload the firmware

The idea is to be able to integrate firmware uploading into the user application. But, you can of course use it to do a simple customized standalone uploader as well.

Hope that helps.
 
Didn't use it for quite some time. I remember that I implemented the T4.0 when it came out. Chances are that it will work for the T4.1 as well. Let me know if not. If necessary, adapting it to the 4.1 is not a big deal.
 
Didn't use it for quite some time. I remember that I implemented the T4.0 when it came out. Chances are that it will work for the T4.1 as well. Let me know if not. If necessary, adapting it to the 4.1 is not a big deal.

You've really made a nice library, even for me as an amature, I started using Visual Studio 4 days ago, I still understand the basics of your lib. Well done!
Is there a way to see if no devices are connected? For example "if (!ConnectedDevices)"
 
Glad you like it.

Of course you can check if no boards are connected. Watcher.ConnectedDevices contains a list of all found Teensies. Simply check for Watcher.ConnectedDevices.count == 0.
If you are new to C# I recommend to have a close look at System.linq which is the standard way to work with data in c#. The following examples show how to use LINQ to filter the Teensy list for maybe interesting features.

Code:
using System;
using System.Linq;
using TeensySharp;
using static TeensySharp.USB_Device;

namespace sharptest
{
    class Program
    {
        static void Main(string[] args)
        {
            var Watcher = new TeensyWatcher();

            if (Watcher.ConnectedDevices.Count() == 0)
            {
                Console.WriteLine("No Teensy found");
            }

            var allT36s = Watcher.ConnectedDevices.Where(t => t.BoardType == PJRC_Board.Teensy_36); // select all connected T3.6 devices

            if (allT36s.Any())  // do we have at least one T3.6 on the bus?
            {
                Console.WriteLine("The following T3.6 devices where found on the USB bus");
                foreach (var teensy in allT36s)
                {
                    Console.WriteLine($"   T3.6 with Serialnumber {teensy.Serialnumber}");  // print serial number of the connected T3.5 devices
                }
                Console.WriteLine();
            }

            var myTeensy = Watcher.ConnectedDevices.FirstOrDefault(t => t.Serialnumber == 8077220);  // return the first Teensy with the given serial number. If not found return  null
            if (myTeensy != null)
            {
                Console.WriteLine("my teensy is connected");
            }


            var HalfKayedTeensies = Watcher.ConnectedDevices.Where(t => t.UsbType == USBtype.HalfKay);  // look for boards in programming mode 
            if (HalfKayedTeensies.Count() > 0)
            {
                Console.WriteLine("The following teensies are in programming mode");
                foreach (var teensy in HalfKayedTeensies)
                {
                    Console.WriteLine($"   Type {teensy.BoardType}, SN: {teensy.Serialnumber}");
                }
            }

            while (!Console.KeyAvailable) ;  // press key to stop
        }
    }
}
 
Glad you like it.

Of course you can check if no boards are connected. Watcher.ConnectedDevices contains a list of all found Teensies. Simply check for Watcher.ConnectedDevices.count == 0.
If you are new to C# I recommend to have a close look at System.linq which is the standard way to work with data in c#. The following examples show how to use LINQ to filter the Teensy list for maybe interesting features.

Code:
using System;
using System.Linq;
using TeensySharp;
using static TeensySharp.USB_Device;

namespace sharptest
{
    class Program
    {
        static void Main(string[] args)
        {
            var Watcher = new TeensyWatcher();

            if (Watcher.ConnectedDevices.Count() == 0)
            {
                Console.WriteLine("No Teensy found");
            }

            var allT36s = Watcher.ConnectedDevices.Where(t => t.BoardType == PJRC_Board.Teensy_36); // select all connected T3.6 devices

            if (allT36s.Any())  // do we have at least one T3.6 on the bus?
            {
                Console.WriteLine("The following T3.6 devices where found on the USB bus");
                foreach (var teensy in allT36s)
                {
                    Console.WriteLine($"   T3.6 with Serialnumber {teensy.Serialnumber}");  // print serial number of the connected T3.5 devices
                }
                Console.WriteLine();
            }

            var myTeensy = Watcher.ConnectedDevices.FirstOrDefault(t => t.Serialnumber == 8077220);  // return the first Teensy with the given serial number. If not found return  null
            if (myTeensy != null)
            {
                Console.WriteLine("my teensy is connected");
            }


            var HalfKayedTeensies = Watcher.ConnectedDevices.Where(t => t.UsbType == USBtype.HalfKay);  // look for boards in programming mode 
            if (HalfKayedTeensies.Count() > 0)
            {
                Console.WriteLine("The following teensies are in programming mode");
                foreach (var teensy in HalfKayedTeensies)
                {
                    Console.WriteLine($"   Type {teensy.BoardType}, SN: {teensy.Serialnumber}");
                }
            }

            while (!Console.KeyAvailable) ;  // press key to stop
        }
    }
}

That is brilliant, I read your code and I get the structure of it. Thanks for such a great example. This will help allot!
Im used to PHP and with this example I feel very much at home! Brilliant work once again :)
 
Luni, there is one thing I wonder.

When I have compiled the project it works fine in Visual Studio, it also starts fine as an executable .exe file in the debug folder.
But, as soon as I click a button that calls for TeensySharp, I get an error that it's missing.

I installed it via NuGet package, should I perhaps include it in some other way to get it to work?
My end goal is a standalone runable .exe without anything else.

Thanks
 
Since dotNet doesn't support static linking you can not have a dotNet application in a single exe if it uses additional libraries *). So, either use some tool to generate an installer (which can be a single exe) or simply zip the contents of the debug (or release) folder for distribution. You can delete the *.pdb files they only contain debug info. Actually, you can try to delete everything except the *.exe and the *.dll files and try if it still runs. To install you can simply unzip the folder wherever you want.

*) Well, technically you can, there are tools which will pack the dll's and the exe into a single file and unpack everything on startup but this is quite advanced and IMHO not worth the hassle. You can also include the TeensySharp sources directly in your application, but again, if you are new to this stuff you are better off with zipping the folder.
 
Since dotNet doesn't support static linking you can not have a dotNet application in a single exe if it uses additional libraries *). So, either use some tool to generate an installer (which can be a single exe) or simply zip the contents of the debug (or release) folder for distribution. You can delete the *.pdb files they only contain debug info. Actually, you can try to delete everything except the *.exe and the *.dll files and try if it still runs. To install you can simply unzip the folder wherever you want.

*) Well, technically you can, there are tools which will pack the dll's and the exe into a single file and unpack everything on startup but this is quite advanced and IMHO not worth the hassle. You can also include the TeensySharp sources directly in your application, but again, if you are new to this stuff you are better off with zipping the folder.

Thanks for your reply.
My goal will be to implement the source into my project.
Basically having your TeensySharp folder in my project and "including" it, I just need to figure out how to do that. I'm a quick learner, I already have a fully working program with functions, graphics and everything. Your library is the key to it all tho :p
 
My goal will be to implement the source into my project.

Just had a look at the sources. TeensySharp itself references moreLinq and hidLibrary. So, even if you include the TeensySharp sources you'll have the moreLinq.dll and the hidLibrary.dll to handle. You probably could get the corresponding sources but I don't know which libraries they use... then there are some system libraries and... I'm afraid that you will need to spend a lot of time fighting against the system instead of using dotNet as it was meant to be used.

BTW: what's wrong with a simple zip file or a single file installer?

Edit: This https://www.hanselman.com/blog/making-a-tiny-net-core-30-entirely-selfcontained-single-executable sounds interesting
 
Just had a look at the sources. TeensySharp itself references moreLinq and hidLibrary. So, even if you include the TeensySharp sources you'll have the moreLinq.dll and the hidLibrary.dll to handle. You probably could get the corresponding sources but I don't know which libraries they use... then there are some system libraries and... I'm afraid that you will need to spend a lot of time fighting against the system instead of using dotNet as it was meant to be used.

BTW: what's wrong with a simple zip file or a single file installer?

Edit: This https://www.hanselman.com/blog/making-a-tiny-net-core-30-entirely-selfcontained-single-executable sounds interesting

I see. An installer is fine as well but it just seems neat to use a executable exe, fancy puncy stuff xD
 
Just had a look at the sources. TeensySharp itself references moreLinq and hidLibrary. So, even if you include the TeensySharp sources you'll have the moreLinq.dll and the hidLibrary.dll to handle. You probably could get the corresponding sources but I don't know which libraries they use... then there are some system libraries and... I'm afraid that you will need to spend a lot of time fighting against the system instead of using dotNet as it was meant to be used.

BTW: what's wrong with a simple zip file or a single file installer?

Edit: This https://www.hanselman.com/blog/making-a-tiny-net-core-30-entirely-selfcontained-single-executable sounds interesting

Luni, I just wanted to let you know, I solved it. Now works with executable exe file. No other files needed.
I've spend many hours on this, and the solution was easy. I added Costura.Fody to my Visual Studio via NuGet. It just makes everything work as a standalone .exe. Just like magic.
So now you know, if you ever wanna make something standalone.

Once again thanks!
 
Sounds good. I'll have a look at this Costura.Fody. How large is the exe ?

Exe is 2.6mb, I have a few images and a nice style. And a web browser that loads an external URL to be able to show stuff inside the exe. And ofc your TeensySharp.
I just installed Costura.Fody in NuGet, it will then start to make every package available, so it will run for like 5 - 10 minutes, after that it just works automatically.
 
Hi,

I am trying to use TeensySharp with a teensy 4.1 and I am having some problems with uploading firmware.

Library detects teensy connected to PC, but when trying to open (.hex) file i Got an info that the array for memory is to small. I was trying to change your code to add teensy 4. 1 with memory set to 8192x1024 as teensy 4.1 has 8mb as flash memory but it did not work. Any help, plase
 
Sorry I have not looked at your code at all, but I remember back on getting teensy_loader_cli to work with T4,
we ran into memory issues as well, as the code starts at a very high address...
From Oct 8th 2019...

Code:
			if (code_size > 1048576 && block_size >= 1024 &&
			   extended_addr >= 0x60000000 && extended_addr < 0x60000000 + code_size) {
				// Teensy 4.0 HEX files have 0x60000000 FlexSPI offset
				extended_addr -= 0x60000000;
			}

I had version that did something similar...
So again sorry if this turns out not to be the issue.
 
Thanks for the input Kurt, but the 0x6000000 issue was the first I stumbled over when I extended the code for the T4 :) So that should work. Anyway, should be easy to fix as soon as the hex file is available.
 
Thanks for the input Kurt, but the 0x6000000 issue was the first I stumbled over when I extended the code for the T4 :) So that should work. Anyway, should be easy to fix as soon as the hex file is available.

Thank you for help, I will upload the hex tommorow. I left my laptop at work :( As far i remember the hex file is 1.3 mb so it should not be a problem with that.
 
1.3Mb is quite large, but lets see...
I'll be traveling tomorrow but I can have a look on Thursday
 
Hi,

This is my hex file. The problem is in this lines:

error.JPG

I also added Teensy 4.1 on dictonary:

board.JPG

View attachment MRKIV.zip
 
Meanwhile I had a look at the library. Since it is not used very often I have to admit that it is not very well maintained. The main problem is, that it can not detect Serial Teensies with the new (>TD1.53?) composite USB type. The problem is, that the used method of questioning the WMI database doesn't allow walking up the device tree to get the serial number of the Teensy (more likely I'm to stupid to do this...).

Good news:
Some time ago I did a complete rewrite of TeensySharp using low level access instead of the WMI queries.

I never did extensive tests, so it still lives in the development branch. I tried the new version with your firmware and found that I underestimated the time it takes to erase a large firmware from the processor. I fixed this and now it uploads without problems. After uploading your hex file the T4 prints stuff like <34/242/255/0/0/0/0/0/0/0/0/0/0/0/-1/0/0/><34.... to Serial. I assume this is what it is supposed to do?

Here a very simple console application showing how uploading works with the new library:

Code:
using libTeensySharp;
using System;
using System.IO;
using System.Linq;
using static System.Console;

namespace Firmware_Upload_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var watcher = new TeensyWatcher();

            WriteLine("===============================================================");
            WriteLine(" Firmware Upload Tester");
            WriteLine("===============================================================\n");
            WriteLine("Found the following Teensies on the USB bus---------------------");

            foreach (var t in watcher.ConnectedTeensies)
            {
                WriteLine(t);
            }

            WriteLine("\nPlease press 'u' to program the first teensy in the list above, any other key to abort");
            if (ReadKey(true).Key != ConsoleKey.U) Environment.Exit(0);

            var teensy = watcher.ConnectedTeensies.FirstOrDefault();
            if (teensy != null)
            {
                var firmware = Path.Combine(Path.GetTempPath(), "MRKIV.hex");    // change to a valid path to your hex file
                var result = teensy.Upload(firmware, reboot: true);
                WriteLine(result);
            }

            // cleanup            
            watcher.Dispose();

            WriteLine("\nPress any key to quit");
            while (!KeyAvailable) ;
        }
    }
}

Currently there is no documentation for the new library but the examples should show you how to use it.
Best to start with the Print&Watch example. It should give you some output like this:

Screenshot 2021-09-23 110150.gif

The output should be updating when you add/remove devices. If this works, everything is installed correctly and you should be able to upload firmware with the program from above.

As mentioned, this was not tested much. So, any bug reports are very welcome.
 
Last edited:
Back
Top