Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 28

Thread: Implementing TeensyLoader into a C# app?

  1. #1
    Senior Member
    Join Date
    Oct 2019
    Posts
    239

    Implementing TeensyLoader into a C# app?

    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,

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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.

  3. #3
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Thanks luni, this is great!
    Does it support the T4/4.1?

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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.

  5. #5
    Quote Originally Posted by luni View Post
    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)"

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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
            }
        }
    }

  7. #7
    Quote Originally Posted by luni View Post
    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

  8. #8
    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

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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.

  10. #10
    Quote Originally Posted by luni View Post
    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

  11. #11
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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/makin...gle-executable sounds interesting

  12. #12
    Quote Originally Posted by luni View Post
    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/makin...gle-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

  13. #13
    Quote Originally Posted by luni View Post
    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/makin...gle-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!

  14. #14
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    Sounds good. I'll have a look at this Costura.Fody. How large is the exe ?

  15. #15
    Quote Originally Posted by luni View Post
    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.

  16. #16
    Junior Member
    Join Date
    Sep 2021
    Posts
    6
    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

  17. #17
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    Can you post the hex file which shows the problem?

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,577
    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.

  19. #19
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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.

  20. #20
    Junior Member
    Join Date
    Sep 2021
    Posts
    6
    Quote Originally Posted by luni View Post
    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.

  21. #21
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    1.3Mb is quite large, but lets see...
    I'll be traveling tomorrow but I can have a look on Thursday

  22. #22
    Junior Member
    Join Date
    Sep 2021
    Posts
    6
    Hi,

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

    Click image for larger version. 

Name:	error.JPG 
Views:	17 
Size:	32.4 KB 
ID:	25933

    I also added Teensy 4.1 on dictonary:

    Click image for larger version. 

Name:	board.JPG 
Views:	11 
Size:	28.1 KB 
ID:	25934

    MRKIV.zip

  23. #23
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    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:

    Click image for larger version. 

Name:	Screenshot 2021-09-23 110150.gif 
Views:	18 
Size:	163.0 KB 
ID:	25951

    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 by luni; 09-23-2021 at 09:33 AM.

  24. #24
    Junior Member
    Join Date
    Sep 2021
    Posts
    6
    Thank you, this is a correct behavior of a Serial Port

    I will test it, but where can I get it?

  25. #25
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,626
    Sorry, thought I mentioned it :-)
    Its in the development branch of the Github repo. I.e. go to https://github.com/luni64/TeensySharp switch the branch from master to development and download it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •