-
Notifications
You must be signed in to change notification settings - Fork 223
Update STM32F4 HAL to include latest official HAL from ST #405
Comments
@smaillet-ms risking asking the obvious: |
Yes, Llilum was built with full awareness of things like mBed and CMSIS, which didn't exist when NETMF was created. The goal was to minimize the amount of HAL like code we define or standardize around. One of the challenges with NETMF is the rather blurry lines between HAL, PAL, CPU and CLR code layering. With Llilum things are more clear because of the C# vs C/C++ split. So, what I think we need to do with NETMF is migrate in stages:
The biggest change for NETMF will be at the HAL level, however, by leveraging the existing CMSIS support from silicon vendors the SOC specific parts of that are already there. The major work is in the board specific configuration and drivers for any peripherals on the board that aren't part of the SOC itself. Thus this transition is focused more on what you don't have to write than what you do. In that respect there's not likely much of a migration path for those using the current "do it however you like" model. Rather it would be like starting over but, hopefully, it would be much easier to do since you'd be leveraging the existing library support instead of porting it with lot's of modifications and tweaks to fit into the old NETMF HAL API. |
I'm not familiar with PAL layer. I've only dip my toes in the HAL. I think I understand what you are suggesting. Can you "draw" a picture of what you are thinking? Maybe a folder structure with the proposed layout to implement such changes... that would help fully understand you ideas on this. |
The best picture available is this one from the Wiki. The folder layout isn't planned to be any different than what we have now. I imagine the new universal CMSIS-PAL could be located DeviceCode\Targets\OS\CMSIS-PAL. This would likely just reference the Targets\OS\CMSIS-RTX support already present. It might be useful to further adjust the %SPOCLIENT%\CMSIS folder a layout that matches the standard ARM tooling CMSIS-PACK repository. Thus the current folder would be moved to %SPOCLIENT%\Pack\ARM\CMSIS. Ideally we could use the pack folders already installed by the MDK tools if you have them installed so that we'd have an Environment var to point to the pack root (i.e. CMSIS_PACK_ROOT). Unfortunately, we need to add the NETMF project files into the picture so that we can actually build the code. Thus we either need to completely replicate the pack folder in the NETMF tree (Basically what we are doing now) OR we change our project files to reference the source files form their pack install location. For example, the dotnetmf.proj file for RTX Thus the source can remain intact and isolated from the NETMF build requirements. (e.g. reduce the copying and tweaking needed to leverage the existing code for NETMF.) Further, using the standard layout allows using the standard pack mechanism to download and install packs. While we don't want to ties ourselves to only supporting CMSIS we should be able to support it as it is intended to be used without needing to perform significant "porting" efforts. As mBed 3.0 evolves we can look into the "Yota" system they are using, For managed code and our own code we can use Nuget. With some time and experience with those mechanisms we should be able to formulate an abstraction to enable a NUGET like development experience that incorporates multiple packaging technologies. (But that's a ways out yet - baby steps...) For now I'd be happy with download and install the packs manually. As long as we can use them without modification we've solved the major problem, the rest is about usability and convenience. |
If the goal is to make NETMF "hardware agnostic" the current DeviceCode should live under each Solution folder, correct? Having an RTOS "under" the NETMF, or should I say the CLR?, is probably a good idea. I mean always, not only because of the network. This will help better management on power, having async drivers, non blocking tasks, etc. Should we follow a complete "mBeddish" approach here stick to that architecture? From what I can see on their roadmap for v3 they'll have a lot of good stuff coming that NETMF could benefit from. |
Device code is where it is, if for no other reason than to not break existing users. Additionally it should stay there as the intent for that model was that you would likely have the same peripherals hanging of a several chips (or even on the same SOC within a family) that concept still applies and, for any platforms not using CMSIS we still need to have a model for sharing common code so that's where it goes. Forget mBed for the moment v3 is still pre-release and v2.0 is a completely different animal from CMSIS and mBed OS 3.0 - CMSIS is real now, stable with LOTS of silicon vendor support. Once we've got CMSIS worked out we can loop back to an mBed PAL or any other "common" layer for other architectures like Zephyr A key point to remember is that NETMF is CPU and software platform neutral. CLR doesn't require an RTOS underneath and we won't be adding a requirement for one. It does it's own threading, which, due to the nature of the interpreter is much more efficient than a native code kernel. (The memory overhead for storing a thread is quite a bit smaller for the interpreter as it doesn't need to save any CPU registers or state, etc...) |
I believe that is very important to have all this working with mkd and gcc, so please keep that in mind. All in all I understand that you have all that pretty much figured out, so I'm not seeing that any further input is required at this time... |
Regarding the hardware initialization: I'm not sure about the benefits of having the scatter file being parsed/generated from those xml files on the solution folders. |
They are xml and generate the output file because not all of the tools use ld files, in fact the arm tools use scatter files with a completely different syntax - GCC uses ld scripts. Other tool chains use other solutions. The use of XML helps to abstract all of that and enables tooling to parse them more simply. (e.g. we don't need a unique link/locate language parser for every tool-chain supported, just an XML parser will do). While I think the usefulness of the XML is probably coming to an end, unless/until the entire build system is re-worked, I don't see a lot of value in re-working just that. |
Understood about the loader files. I was - wrongly - under the impression that the mdk and the gcc ld files were equivalent, just had different name and extension. |
@smaillet-ms could you please add a new branch to submit PRs for this? |
@smaillet-ms what should be the naming convention/layout for the "new" DeviceCode folder? Something like... Or... |
Just: The whole point of building a PAL that relies on CMSIS APIs is to make it completely SOC and board neutral for Cortex-M based devices. |
@smaillet-ms You've lost me there... I understand that you are referring to the PAL, but we still need a place for each platform HAL, right? ST provides HAL headers, source and CMSIS specific headers for each series (F0, F1, etc) and for each device inside the series (407xx, 410cx, 429xx, etc). All these files are supplied in separate packages for each series (F0, F1, etc). How do you suggest we handle this? |
Is the following enough to address your requirement of "getting NETMF out of defining or controlling the startup sequence":
|
Essentially, yes. Though it is important to note that anything other than implementing main() to initialize your PAL and calling ApplicationEntryPoint() to kick off the CLR everything else is platform/HAL and tool dependent and not officially mandated in any way by NETMF. That said, for any given platform+tools there likely common solutions that would be literally copy pasted from one project to another - such cases should be standardized into a common library for that particular platform+tool (I.e. NETMF_CMSISvX.x_MDK_HAL.lib) |
@smaillet-ms OK. Still need a clarification about the folder structure for the HAL drivers and the PAL stuff. But what about the PAL headers that are platform/series/device specific? And the HAL drivers that are platform/series/device specific too? DeviceCode\Targets\ST\STM32F0xx_HAL_Driver DeviceCode\Targets\Native\CMSIS This structure allows to easily add new vendors/platforms/series/devices. |
CMSIS-PAL should be completely independent of the target, that's the point of it. It relies exclusively on the headers defined in CMSIS.
This is the key break from the past - we need to simplify re-use of existing source and keep from the perpetual maintenance cycle of downloading, updating and testing lots of third party code. The CMIS-Pack model is designed to support multiple versions of the packs installed on a system at a time. When you reference the project code the version is part of the path to getting it. Thus you can add support for the latest super chip in a family without breaking or even requiring a single change in any projects that use the current packs Thus for CMSIS based systems we want a tree layout in NETMF that matches the tree layout for the standard pack folder used by the tools leveraging CMSIS-Pack. In the NETMF tree the only thing that is checked in is the project and settings files needed for building the code that is located in some other folder. Ideally we'd be able to automate the creation of such projects from the information contained in the pack descriptions but for starters if we can get one done manually to understand what is needed we should be ok. |
@smaillet-ms I have a suggestion regarding the HAL features "configuration". I believe this makes it much easier when you are tweaking a solution, instead of having to add all those individual projects or the stubs. |
Maybe I'm missing something but I don't see how your proposal changes the story... Ultimately the user has to choose which modules to include or not. CMSIS-pack has a means to express dependencies including API/interface dependencies (along the lines of - "I'm the network stack so I need at least one network interface conforming to API-XYZ to be useful, don't care what particular implementation"). |
It's about how easy it is two choose which features go into a solution. The current approach is to add individual projects and libcatproj to the tinyclr proj. That doesn't work so well when you add CMSIS. Not to mention that can be confusing and takes time. My suggestion is all about simplifying that process. |
I'm still missing WHAT you are actually proposing. It seems to me you are moving where you have to add the projects (e.g. from TinyCLR.proj to some other proj) either way you still have to choose which ones you want in a given device image. Putting them into a single "HAL" so the choice is done once doesn't work for all scenarios either. While it might cover the 90% case of a development board it doesn't help a real commercial platform that has to deal with trade-offs of functionality vs. hardware resource costs and constraints. There's no way to automate the decision making required for that. Someone has to choose to include libraries or not. Unfortunately, with the way the CLR is currently implemented that's not a true pay for play story in NETMF. (e.g. there are strong API dependencies at multiple levels, and the solution for that was to use stub libraries, thus deliberately including code that doesn't do anything useful and forcing the user to make an explicit choice which to use.) I don't think a truly better solution lies in the HAL, but instead lies in the upper layers and removing the need for the stubs. Specifically, the CLR should have little or no dependencies on anything other than the most basic of facilities required for it to execute the interpreter loop. Everything else should be optional and added as needed. If we fix the "stubs" problem to deliver on a true "pay for play" model in NETMF, then the CMSIS problem becomes a no-brainer (e.g. CMSIS-PACK) |
@smaillet-ms Would it be too much of a breaking change to rework the USB_DYNAMIC_CONFIGURATION struct?
I suggest that the product name, manufacturer, VID and PID remain configurable. All the rest should go into the driver. |
I suggest that the product name, manufacturer, VID and PID remain configurable. I vote also for the device serial number (currently not used). |
The design of the configuration is based on the USB specification for the USB descriptors. There's nothing in the configuration that belongs in the driver. The driver shouldn't care about what the USB configuration is. The configuration data structures are an in memory representation of the raw USB descriptors. This format keeps the USB device side configuration code fairly simple. Ultimately I'd like to see this simplified fro the developer as well but altering the format used at runtime doesn't strike me as the way to go. Instead of modifying the format, which breaks existing BSPs we could use a different language to describe the data structures and letting a tool do the mundane computations of string lengths etc.. would be a preferred approach. We actually have such a representation in the form of an XML file that can be pushed to a device via MFDeploy (if USB isn't used for debugging or the device has explicitly allowed reconfiguring the USB descriptors). Unfortunately our current build tooling doesn't use it for creating the default configuration information. Nor does it support a simple notation for the common extended descriptors. Adding that to the XML schema and building a tool to generate the current C++ code file formats wouldn't be a huge effort for one person to take on. |
I understand that the configuration format is based in the USB descriptors. And I also understand how USB descriptors work. My point here is that there are a lot of details in USB configuration that are being exposed unnecessarily and that makes it confusing to use. Adapting the current USB PAL to use ST USB CMSIS compliant library is difficult. As a matter of fact let me tell you that ST has USB CMSIS compliant libraries for USB devices (all classes) and USB hosts. Considering all that I would suggest rethinking the USB implementation along these lines:
How to accomplish this? We would have:
I believe that this would bring simplicity to the USB configuration and implementation. Not to mention that it helps adding support for new devices/hosts that don't exist today. As a final comment: I believe that this is not to much of a breaking change for current solutions that are based in the official repository code. The USB debug would be there from the start. Any other USB support that may exist today in private repositories will work anyway along with this new approach. |
I've been thinking about the USB configuration for some time now and had a chance to try an experiment recently. The idea is to Simpify the expression of the configuration and let a tool generate whatever data structures a given HAL, framework or run-time requires. For example the reference standard USB configuration for MCBSTM32F400 could be expressed using a MUCH simpler XAML form such as: <!--
This file provides an example of a XAML based USB Configuration descriptor.
XAML, at its core, is an XML representation of an object graph, which fits
extremely well with the hierarchical data structures for USB descriptors.
Since the Descriptor types are defined in an actual .NET assembly, the
mechanism for defining descriptors is extensible. It is possible to express
a Device as a set of low level primitives including interfaces, endpoints,
etc... directly or by using higher order descriptors, such as this example
uses to provide the NETMF Debug transport interface. Any common USB-IF
defined interfaces, configurations or functions can be defined this way.
Using higher order descriptor classes simplifies the expression of USB
configuration to just defining the vendor specific details leaving the rest
to the standard implementation.
This XAML will load at runtime into an object graph of descriptors that is
normally used by a tool to generate the data structures needed for a particular
runtime. (e.g. for NETMF this would generate the otherwise VERY tedious and
error prone static USB Configuration section data structure.) That is this is
a platform neutral representation and has use across multiple libraries and
frameworks.
-->
<DeviceDescriptor
xmlns="http://schemas.microsoft.com/NETMF/2016/UsbDescriptors"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Manufacturer="{x:Reference Name=ManufacturerName}"
Product="{x:Reference Name=ProductName}"
VendorId="0x0483"
ProductId="0xA08F"
DeviceRelease="0x0200"
Version="V2_0"
ExtendedOsDescriptorVendorId="0xA5"
>
<ConfigurationDescriptor
Attributes="SelfPowered"
MaxPower="255"
ConfigurationValue="1"
>
<!--
This single interface entry defines all the endpoints and OS extension descriptors
for a NETMF Debug interface. (e.g. this includes the 'WINUSB' Extended Compat ID
and the DeviceInterfaceGuid Extended OS Property)
-->
<NetmfDebugInterfaceDescriptor />
</ConfigurationDescriptor>
<DeviceDescriptor.Strings>
<!--
In USB, Each individual string can have multiple values depending on the language ID requested.
Currently, NETMF PAL libraries only support en-us but the XAML description allows for more if
NETMF ever enables systems with full language support.
-->
<StringDescriptor x:Name="ManufacturerName" Index="1">
<LocalizedString LocaleId="EnglishUnitedStates" Value="Microsoft .NET Foundation" />
</StringDescriptor>
<StringDescriptor x:Name="ProductName" Index="2">
<LocalizedString LocaleId="EnglishUnitedStates" Value="MCBSTM32F400" />
</StringDescriptor>
<!--
NOTE: Since the device has the ExtendedOsDescriptorVendorId property set
an OsStringDescriptor is automatically added to the string descriptors
with the correct value including the specified vendor code. This is the
simplest way to get set up the OS string descriptor as it doesn't require
manually coordinating the vendor specified code.
-->
</DeviceDescriptor.Strings>
</DeviceDescriptor> That's a whole heck of a lot simpler then the C data strucutre and, as the comments suggest, can be enhanced to handle any standard Configurations (CDC, USB-MIDI, USB-MS, etc...) Ultimately, it all reduces down to the few items an OEM must provide. While the higer level elements help keep things simpler, it is possible to use lower level primitive elements such as interfaces, endpoints, and custom descriptors directly for anything that doesn't have an existing higher level class defined. Furthermore, when edited in VS you can even get intellisense! The build system can be extended to generate the actual code/binary files from this simpler format whenever it is changed. |
@smaillet-ms as I've mentioned before regarding the USB configuration I totally agree that the current one is tedious and error prone. Your suggestion is pretty much inline with what we have proposed in our PR #434.
And this doesn't require any particular changes to the current build system. See here at line 33. |
Yep, we're thininking in similar directions, the XAML approach is more of a continuing evolution of the idea that allows for, easy extensibility to other configurations, and allows code generation for wildly different HAL/PAL implementations (i.e. the STMCube libraries, MDK middleware libs, existing NETMF PAL) while maintiing an independence from the project settings. That last point is important as part of the rework of the projects I'm driving at is to remove the "special NETMF knowledge" from the build infrastructure itself so it is easier to leverage existing build system and project representations. (There's actually someone looking into porting the NETMF build to NetBSD! 😮 ) |
Glad to know that you think that. |
I have read through the PR and while I'm sure it solves the problems for you, it doesn't solve the broader general problems I'm looking to solve for NETMF going forward. (Some of that I've written up already but it's a REALLY big topic and I've haven't gotten it all wirtten down yet). The short form is I want to get NETMF out of the HAL business, and mostly out of the PAL business, so it remains focused on its true core as a .NET runtime. In the past we had no choice - there weren't any alternatives. Now there are multiple HAL/PAL type layers available and NETMF needs to adapt to that so we can focus on developing the core and not the plumbing it runs on top of. This is a pretty broad, and bold shift that I'm sure will meet with some resistance from any places. That is, I can imagine responses like "Why do all that, if you just tweak this one rough area everything would be perfect..." unfortunately that setiment often leaves off the implicitly subjective "for me". While the tweak in question might well help in that particular case it doesn't really address the larger issue that the world has changed around NETMF since it was first created and it is just plain too hard and time consuming to port/use for many real world devices it would otherwise be a great platform for. There are a LOT of reasons for this complexity, the USB config is certainly a part of that but the real problem is much much bigger. NETMF has danced around the problem for several major and minor release for a while now. It's time to face up to the reality and do the work. It's not pretty work, it'snot a big long check list of new feautures the marketing folks love to show off. But it is necessary for the future usability of NETMF. There's an old saying an Engineering manager I work with has "Sometimes you have to stop and sharpen the saw. If you are cutting wood, you can't just keep going cutting wood non-stop efficiently. At some point you need to stop, clean and sharpen the saw so you can make new progress" So, by all means please keep doing what you need to do to ship your products, and keep feeding back your progress, successes and failures with new ways of thinking about this stuff. Everything helps contribute to a better NETMF. Though it is important to remember we can't gurantee any specifc work or idea will end up as the next solution to the problems as there are a lot of factors including consistency with how other similar kinds of problems will be solved in other areas fo the system (e.g. multiple perfectly valid ways of solving a particular problem may be proposed but only one fits consitently with the patterns used throughout the rest of the system, thus, raising that one above the rest) |
Accomplishing all that is not an easy task. That's for sure! PS1: Let me stress this: my team and I we are only trying to contribute to NETMF. We are doing it in the spirit of open source and in a modest and humble way. If - at any point - it looked differently I do apologise for that! Also know that I'm not trying to push our ideas as the best possible ones. And for sure I won't be whining for any of those to reach the final version. PS2: I hear you on that saying about the lumberjack and its efficiency with the saw. That manager of yours must have been boy scout. Baden-Powell mentions that story in its Scouting for Boys and it's obviously famous among scouts. 😉 |
No problems - With only text it is sometimes difficult to communicate all aspects of thought/intent. It's only natural some confusion can creep in so it's often worth pre-emptively clarifying to help ensure it doesn't turn into a problem. The NETMF core team hasn't really done a good job of defining, let alone communicating, a proper design contribution process/workflow. I've been reviewing what other projects have done over the last few weeks on that and will try and get something posted for discussion. RE: Llilum Llilum shares the same HAL/PAL problems that NETMF does, albeit without nearly as much of a legacy problem, so my thinking is that this level of change, while big for NETMF on it's own, is also applicable to Llilum (e.g. a shared common PAL abstraction). Thus, I see this as worth the investment to help bring them together. Furthermore there are still cases where, as an interpreter, NETMF has value (e.g. easy sandboxing / dynamically loading third party code). So NETMF still has a life of it's own. I'd like to be able to get to where NETMF is on par with CoreCLR and Llilum from the perspective of the runtime itself. Thus moving code around between them becomes plausible and reasonable. While NETMF won't be 100% complete feature for feature in the runtime. It can be a well defined strict subset. Thus there are two broad arcs I'm looking at for the NETMF roadmap:
I'd love to see the day where NETMF itself was entirely written in C# with Llilum thus gaining the best of both worlds when an interpreter is desired. I was actually toying around with that idea over a year ago as I was ramping back up on NETMF to help better understand the internals of an IL Interpreter but implementing such a thing for real is a looooong ways out. |
That sure looks an outstanding job. You have my vote! 😄 Let me suggest that you open this discussion to the community. It can get better if more people contribute with ideas and views from different perspectives. Speaking of which I strongly suggest that you guys start doing something about the NETMF community. I mean the repository for NETMF is here but the "home" of NETMF doesn't look to be here... It probably lives at the GHI forum... To clarify: I don't think that there is something wrong with the GHI forum. I tip my hat to GHI: they've done a great job with NETMF. Specially in promoting it and make it usable by everyone, from hobbyists to companies (probably more than Microsoft itself...) but they are not the NETMF. Often times when people have general questions with NETMF they go to that forum. Again there is nothing wrong with that, but it does seem awkward. And there is a reason for that... This repository should be the NETMF home, but it is not. |
Although working the existing headers for the STM32F4 are outdated. This is a problem when creating new solutions based in STM32F4 devices other than the '407. "Marrying" with current CMSIS headers and code can be also be difficult.
I have a branch with the latest official HAL from ST.
The HAL code files were updated were required (mostly UART, SPI and PWM because there are diferences on what modules are available on each device).
The HAL projects were cleaned up.
The templates were updated.
The platform_selector.h in the solutions was updated to use the new device identifier.
A new file with the HAL configuration was added to the solutions.
The text was updated successfully, but these errors were encountered: