From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Understanding GNAT Bare Board Run-time for Cortex-M Date: Mon, 8 Apr 2019 10:46:56 +0300 Organization: Tidorum Ltd Message-ID: References: <2d99a259-3288-4981-9bda-97145077a5bd@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net WiejIQvh7r4FlTian2DOGAl0zA/YUkTKgfQiHy2gbwN1jzSqV2 Cancel-Lock: sha1:6kPDtwoaCP6OaWsIFe4odAHPAoE= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 In-Reply-To: <2d99a259-3288-4981-9bda-97145077a5bd@googlegroups.com> Xref: reader01.eternal-september.org comp.lang.ada:56099 Date: 2019-04-08T10:46:56+03:00 List-Id: On 19-04-08 05:13 , Daniel Way wrote: > I'm trying to port the bare-board GNAT run-time to a Coretex-M0+ (NXP > KV11Z7) processor. I'm new to concurrency and have been reading > through the run-times for the STM32 targets to understand how the > tasks and protected objects are implemented, however, there seems to > be a web of dependencies between the different packages and wrappers > of wrappers of wrappers for types and subprograms. The wrappers of course try to isolate the target-specific code from the target-independent code. > * Is there any tool available to scan through the source code and > generate a graphical call graph to help visualize the different > dependencies? I know of no free tool that generates graphical call-graphs. I've used the non-graphical call tree information from GPS. > * Has anyone on the forum successfully ported a bare-board run-time? > What was your experience and do you have any tips? In my last project, I ported the small-footprint Ravenscar run-time for the SPARC architecture from the generic off-the-shelf AdaCore version to a specific SPARC LEON2 processor embedded in an SoC for processing satellite navigation signals, the AGGA-4 SoC. My advice is to first understand the differences between the original target processor and the new target processor, especially in these areas: - Basic processor architecture, and especially if there is some difference in the instruction set or in the sets of registers that must be saved and restored in a task switch. In my case there was no difference, so I did not have to modify the task-switch code nor the Task Control Block structure. For porting across various models of the same processsor architecture, perhaps the most likely difference is in the presence or absence of a floating-point unit and dedicated floating-point registers. - The HW timers. In my case the RTS used two HW timers, and there were some differences: the bit-width was different (32 instead of 24) and the HW addresses and interrupt numbers were different. The corresponding parts of the RTS had to be adapted, but in my case the changes were small, and the logic of the code did not change. - Interrupts and traps. Differences may have to be implemented in the assembly-language code that initially handles interrupts and traps. In my case, the architecture was the same (the structure of the trap table and most of the HW error traps) but the set of external interrupt traps was different, because of the particular I/O devices available on the new target. This difference (if any) becomes visible to application programs through Ada.Interrupts. - "Console" I/O, usually some form of UART accessible via GNAT.Text_IO. In my case, the UARTs in the new target were quite different from the standard LEON2 UARTs, so I had to reimplement the low-level I/O operations (Put character, Put string, etc.). - Memory layout. Where in the address space is the ROM (or flash), where is the RAM, where are the I/O control registers? Any differences in the layout must be implemented in the linker command script, which in my case was a file called leon.ld. The Ada RTS code probably does not have to change for this reason, and did not change in my case. Once all that is sorted out, you will probably have to modify the start-up assembly-language code, which in my case was in the file crt0.S. This deals with HW initialization (clearing registers, stopping any I/O that might be running, disabling interrupts, etc.) and SW initialization, which means to set up the stack for the environment task and then enter the body of that task. > * Is porting the run-time just a matter of updating the linker, a few > packages, and a GPR script, or is there some fundamental > implementation changes to consider? If you are porting from one implementation of the same architecture to another (in your case ARM Cortex M with the Thumb-1/2 instruction sets, if I understand right), IMO it is unlikely that any fundamental changes are required. However, if there are differences in the instruction set (with M0+ omitting some instructions available larger members and perhaps used in the original RTS) be sure to use the correct target options for the compiler so as to avoid generating code that will not run on the M0+. If there is a major difference in instruction sets (say, porting from Thumb-2 to Thumb-1) you will have to review and perhaps modify all the assembly-language RTS parts, and all assembly-language code insertions in the Ada RTS code, and all the code in crt0.S. HTH. I think others on this group have more experience with ARM Cortex run-time systems and can probably offer better advice. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .