How do new methods show up in Visual Studio when you update TinyClr

I’m creating a new method in the SPI definition of the TinyClr for the G120. How does that method show up in visual studio?

Creating a new definition in SPI where? I’m not sure what you mean

I’m trying to create a new method in the C++ file: LPC17_SPI.cpp

TinyCLR_Result LPC17_Spi_TransferFullDuplexWithOffsets(const TinyCLR_Spi_Provider* self, const uint8_t* writeBuffer, size_t& writeOffset, size_t& writeLength, uint8_t* readBuffer, size_t& readOffset, size_t& readLength, size_t& startReadOffset) {

in the SPI source file. But how do I get this method to show up in visual studio intellisense after I compile the firmware.

1 Like

Unless your compile took 5mins to run your changes will not be in your image :wink:

So then, it didn’t compile everything. How do I do a complete compile?

You don’t, the only way would be to get John to add it as all the white man’s magic is closed and pre compiled.

looks like “…Read the code; fork the code; fix the code; problem solved…” does not work :grin:

1 Like

I guess not Kevin.

Hmm, This questions doing my head in!!!

So It was an excuse to pulled down the TinyCLR porting source and managed to compile the firmware for a G120 for the first time.
That was fun, enjoyed seeing that getting built and seeing those G120Firmware.glb files appear !

Um SO the reason this is doing my head in (I’m stupid so its easy!) is a few reasons and I might be having a brain fade day, but I’ve just confused myself big time thinking about this. So I thought Id embarrass myself, as maybe I’ll learn something!

First I thought this sounds doable, but then went ummm err!!!??
I thought of using an mock extension method, as a work around just to get it to appear in IntelliSense, but…

From what I think your saying is you roughly want to add a method to the SPI controller in the G120 firmware, and then see that new method pop up in the IntelliSense in Visual Studio.?
Um… but isn’t this Native code on the Hardware, and C# CLR managed code in VS?
The DLL’s in VS which are installed via the nuget packages are c# libraries.

To call the ‘new method’ in the G120 firmware, would you have to call out ‘invoke’ from C# to native code?

Oh man! This is doing my head in.
Can some smart person please explain all this as my head is spinning!!!
Can we get a over view of Firmware / What the source ‘builds’ / Whats in the NuGet GHIElectronics.TinyCLR packages, and how those .DLL’s are built (do we not have access to the source for these?)

Am also confused at what ‘’ is at

Seems both links pull down “” even though source link points to “”, maybe GitHub works like that and I’ve never noticed?

Just adding a new method in the CPP file isn’t enough. There are two separate concepts in TinyCLR: interops and APIs.

Interops are what allow you to call from managed code into native code. You can’t add more interops to an existing class in our library just like you can’t add new methods to our libraries. You can, however, create your own library that has its own interops. Interops are very similar to our old RLP, but now they’re much more integrated with the core and easier to use (there are many more improvements coming).

APIs are just a published way to interacting with various services. All the services we define are listed in TinyCLR.h. You cannot add your own methods to this file, but you can create your own API. You’ll just have to distribute your definition to other users. If you reuse an existing TinyCLR_Api_Type, you’ll be expected to conform to the corresponding API we defined. 0x80000000 and up are reserved for custom types. Particularly useful is the “API Provider” api itself. It is used to find other APIs in the system and an instance of it is passed to each interop call and to the firmware port on startup.

The real power is when these two are combined. In an interop, you’re running native code so you can access any device registers you need. What may be easier is to find and interact with an existing API in the system. Some APIs you may have to, like time and memory. The interop API is very useful since it allows you to marshal data to and from managed code, raise managed events, and interact with and create managed objects.

For GHIElectronics.TinyCLR.Devices (and our other libraries), the managed and interop APIs are very similar But you’re free to create your own if you need to. The TinyCLR core no longer has any knowledge of any specific device peripheral. All that it needs is passed to the various TinyCLR_Startup functions in the firmware main(). Particularly: heap location, devince name and version, the debugger API, plus the deployment, time, interrupt, and power APIs. The main.cpp we provide is just a reference implementation. You can always create your own as long as you call the functions as required.

Based on your other thread, it seems the SPI api is a bit ineffcient since it requires exact sized arrays. I agree it’s not ideal, but we’re following the Windows IoT API in our official GHIElectronics.TinyCLR.Devices package. While we’re investingating a more low level package that Devices will build on top of, in the mean time you can always create your own custom SPI API if you need.

Just clone ports and get the latest core library. Clone whichever device you’re starting with, say the G120, and change the name and various IDs as required in the Device.h file. Depending on the changes you want to make, cloning a new port may be required. In either case, change LPC17_Spi_GetApi to use the API struct that you define (make sure to follow the pattern from TinyCLR.h exactly and use function pointers) and update the read write functions to take an additional index and offset. Update the API name and author, type too to custom.

Now that you’ve defined your API, you actually need to use it. So you’ll want to create a new class library that has whatever interops you deem appropriate, likely mirroring what you have in your custom API. Design the managed API as you see fit as well. Then in the native code for your interops, you’ll get an instance of the API provider API from the TinyCLR_Interop_MethodData parameter in the interop. You can use this to get an instance of your custom SPI provider that you interact with by calling the function pointers. You’ll also need to get an instance of the interop api so you can read the parameters passed to the function.

Of course, you could just implement the SPI functions directly in your interop and not use an API at all. Defining an API has the benefit that other systems in the firmware can use your API. A long term goal of ours is that you can distribute that API and interop source with a nuget pacakge that gets built and shiped along to the device by the build system. So you’ll add a reference to some other nuget package and get to use its native functionality.

The reason you need to use the Custom API type for another SPI provider is that when fetching APIs, if you get one back that has the SpiProvider API type, it is expected to conform to the SPI API we define in TinyCLR.h.

You can find and interact with the various APIs and interops registered on the system with the types available under the System.Runtime.InteropServices namespace.

Keep in mind master is the stable 0.6.0 release while dev is changing a lot between releases. The STM32F4 port is currently the cleanest but there is still a lot of work we want to do on all of them.

One unfortunate limitation in the current interop setup is that you need to compile an interop to a specific window in memory and use that in your linkerscript, then pass the address of a specific object to the interop Add method. So you’ll need to create custom compilations for each device you want to support. To support this, we’ve set aside a few KB in ram in each device that you can use to put your interops. We want to improve this story going forward, perhaps with dynamic loading and fixups.

The interop and API docs under porting have some more specific info and steps as well.


Had to get a cup of coffee to sit down and read that overview.

Ok, Onward!

1 Like