• chevron_right

      Google plans RISC-V Android tools in 2024, wants developers to “be ready”

      news.movim.eu / ArsTechnica · Tuesday, 31 October - 18:55 · 1 minute

    Google plans RISC-V Android tools in 2024, wants developers to “be ready”

    Enlarge (credit: Google)

    Android is slowly entering the RISC-V era. So far we've seen Google say it wants to give the up-and-coming CPU architecture "tier-1" support in Android, putting RISC-V on equal footing with Arm. Qualcomm has announced the first mass-market RISC-V Android chip , a still-untitled Snapdragon Wear chip for smartwatches. Now Google has announced a timeline for developer tools via the Google Open Source Blog. The last post is titled " Android and RISC-V: What you need to know to be ready ."

    Getting the Android OS and app ecosystem to support a new architecture is going to take an incredible amount of work from Google and developers, and these tools are laying the foundation for that work. First up, Google already has the "Cuttlefish" virtual device emulator running, including a gif of it booting up. This isn't the official "Android Emulator"—which is targeted at app developers doing app development—Cuttlefish is a hardware emulator for Android OS development . It's the same idea as the Android Emulator but for the bottom half of the tech stack—the kernel, framework, and hardware bits. Cuttlefish lets Google and other Android OS contributors work on a RISC-V Android build without messing with an individual RISC-V device. Google says it's working well enough now that you can download and emulate a RISC-V device today, though the company warns that nothing is optimized yet.

    The next step is getting the Android Emulator (for app developers) up and running, and Google says: "By 2024, the plan is to have emulators available publicly, with a full feature set to test applications for various device form factors!" The nice thing about Android is that most app code is written with no architecture in mind—it's all just Java/Kotlin. So once the Android RunTime starts spitting out RISC-V code, a lot of app code should Just Work. That means most of the porting work will need to go into things written in the NDK, the native developer kit, like libraries and games. The emulator will still be great for testing, though.

    Read 1 remaining paragraphs | Comments

    • chevron_right

      Qualcomm announces first-ever mass-market RISC-V Android SoC

      news.movim.eu / ArsTechnica · Tuesday, 17 October, 2023 - 17:34 · 1 minute

    Qualcomm sign

    Enlarge (credit: Qualcomm)

    The Android ecosystem is hurtling toward a RISC-V future. The puzzle pieces for the up-and-coming CPU architecture started falling into place this past year when Google announced official RISC-V support in Android and plans to make it a "tier 1 platform" on equal footing with Arm. With the OS support underway, what we need now is hardware, and Qualcomm is stepping up to announce the first-ever mass-market RISC-V Android SoC .

    It doesn't have a name yet, but Qualcomm says it's developing a "RISC-V Snapdragon Wear" chip in collaboration with Google. The company says it plans to "commercialize the RISC-V based wearables solution globally including the US." For Google and Qualcomm, this chip represents everyone's first swing at a commercial RISC-V Android project, and as far as we can tell, it's the first announced mass-market RISC-V Android chip ever. Qualcomm says the groundwork it and Google lay out "will help pave the way for more products within the Android ecosystem to take advantage of custom CPUs that are low power and high performance."

    RISC-V represents a big threat to the Arm CPU architecture that currently dominates all mobile devices. RISC-V architecture is open source, which can make it cheaper and more flexible than Arm. If companies want to design their own chips, they can do that without paying a licensing fee to Arm. Since the architecture is open source, it's possible to create a fully open source chip. If you're a chip-design firm, you can make your own proprietary chip designs and license them, making you a competitor to Arm's chip-design business.

    Read 4 remaining paragraphs | Comments

    • chevron_right

      Carte Tinker V : Asus pour l’amour du RISC-V

      news.movim.eu / JournalDuGeek · Sunday, 26 March, 2023 - 09:00

    sans-titre-5-44-158x105.jpg

    Avec le Tinker V, Asus se lance à l'assaut du marché des nano-ordinateurs, dominé de la tête et des épaules par le Raspberry Pi. Mais le constructeur ne cherche pas à concurrencer directement la vedette incontestée du secteur, il veut plutôt proposer une alternative qui pourrait peser lourd dans l'avenir.

    Carte Tinker V : Asus pour l’amour du RISC-V

    • chevron_right

      Linux 6.0 arrives with support for newer chips, core fixes, and oddities

      news.movim.eu / ArsTechnica · Monday, 3 October, 2022 - 17:41 · 1 minute

    And there was much rejoicing, as a new Linux kernel version had arrived before its founder ran out of fingers and toes for counting.

    Enlarge / And there was much rejoicing, as a new Linux kernel version had arrived before its founder ran out of fingers and toes for counting. (credit: Getty Images)

    A stable version of Linux 6.0 is out , with 15,000 non-merge commits and a notable version number for the kernel. And while major Linux releases only happen when the prior number's dot numbers start looking too big—" there is literally no other reason "—there are a lot of notable things rolled into this release besides a marking in time.

    Most notable among them could be a patch that prevents a nearly two-decade slowdown for AMD chips , based on workaround code for power management in the early 2000s that hung around for far too long. Intel's Dave Hansen wrote the patch that made it into 6.0, noting in a comment on an Ars post that the issue had become an expensive drain as AMD systems gained higher CPU core counts. The average desktop user won't see huge gains, but larger systems working on intensive input/output applications should benefit.

    Intel's new Arc GPUs are supported in their discrete laptop form in 6.0 (though still experimental). Linux blog Phoronix notes that Intel's ARC GPUs all seem to run on open source upstream drivers , so support should show up for future Intel cards and chipsets as they arrive on the market.

    Read 5 remaining paragraphs | Comments

    • chevron_right

      First RISC-V laptop expected to ship in September

      news.movim.eu / ArsTechnica · Tuesday, 5 July, 2022 - 17:07

    First RISC-V laptop expected to ship in September

    Enlarge (credit: RISC-V International )

    The world's first laptop to use the RISC-V open source instruction set architecture (ISA) will reportedly start shipping in September.

    The Roma laptop is available for pre-order on Xcalibyte's website , but the site merely takes interested parties' information without providing much detail or any pricing. According to a report from The Register on Friday, the laptop will start shipping in September, according to spokespeople from Xcalibyte, which did system tuning for the laptop, a company called DeepComputing, which engineered the laptop, and RISC-V International.

    According to the announcement from DeepComputing (which shares the same CEO with Xcalibyte, The Register reported), Roma uses an unspecified quad-core processor with a 28 nm or, for the "pro" version, 12 nm node in a system-on-module (SoM) package. There's also an Arm SecurCore SC300 security enclave processor, an unnamed GPU and neural processing unit, and a feature accelerator.

    Read 6 remaining paragraphs | Comments

    • Li chevron_right

      Prise en main de la carte Longan Nano RISC-V de GigaDevice

      AnthonyRabine · pubsub.eckmul.net / linuxfr · Wednesday, 23 December, 2020 - 13:13 · 40 minutes

    <h2 class="sommaire">Sommaire</h2> <ul class="toc"> <li><a href="#toc-pr%C3%A9sentation-de-larchitecture-du-risc-v">Présentation de l'architecture du RISC-V</a></li> <li><a href="#toc-gigadevice-et-nuclei">Gigadevice et Nuclei</a></li> <li><a href="#toc-un-peu-dassembleur">Un peu d'assembleur !</a></li> <li><a href="#toc-pr%C3%A9sentation-de-la-carte-%C3%A9lectronique">Présentation de la carte électronique</a></li> <li><a href="#toc-arsenal-de-d%C3%A9veloppement">Arsenal de développement</a></li> <li><a href="#toc-le-hello-world-de-lembarqu%C3%A9--blinky">Le Hello World de l'embarqué : Blinky</a></li> <li><a href="#toc-hello-world-plus-pouss%C3%A9--luart">Hello World plus poussé : L'UART</a></li> <li><a href="#toc-les-diff%C3%A9rentes-fr%C3%A9quences-et-le-timer">Les différentes fréquences et le timer</a></li> <li><a href="#toc-nmsis-et-le-systick">NMSIS et le SysTick</a></li> <li><a href="#toc-solutions-de-d%C3%A9bogage">Solutions de débogage</a></li> <li><a href="#toc-conclusion">Conclusion</a></li> </ul> <blockquote> <p>Nous avons déjà parlé du RISC-V dans un article précédent avec la carte HiFive dotée d'un microcontrôleur pas si intéressant. Celui présenté cette fois-ci semble beaucoup plus standard : il fait le plein de périphériques et de mémoire Flash embarquée.</p> </blockquote> <h2 id="toc-présentation-de-larchitecture-du-risc-v">Présentation de l'architecture du RISC-V</h2> <p>Nous avons déjà un peu présenté l'historique du RISC V dans l'article précédent. Essayons maintenant de découvrir le modèle de programmation ; cela nous servira plus tard lors de débogages et développement bas niveau.</p> <p>La fondation RISC a rédigé deux spécifications de cette nouvelle ISA (Instruction Set Architecture) :<br> - Un document général à l'accès non-privilégié<br> - Les spécifications des accès privilégiés</p> <p>Qu'est ce que c'est que l'accès privilégié ? Il faut savoir que les processeurs de type "PC", qui sont voués à être utilisés avec un gros système d'exploitation type Linux/Windows/Mac disposent de protection d'accès physique. En gros, c'est le processeur qui s'assure qu'une instruction assembleur peut être exécutée. Cela permet d'offire une séparation entre les processus systèmes et utilisateur. Sous Linux par exemple, un utilisateur privilégié est 'root'. </p> <p>Intéressons-nous à cette première documentation qui décrit le coeur RISC-V minimal, le RV32I, ainsi que toutes les extensions optionnelles. En effet, l'architecture décrite permet de créer des processeurs de 32-bits, 64-bits ou 128-bits, c'est à dire du petit microcontrôleur au processeur dopé pour serveurs ou calculs scientifiques (c'est à l'origine le but de cette architecture créée à l'université de Berkley).</p> <p>Cette première documentation nous montre donc le modèle de programmation, la liste des registres :</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f72697363762d7265676973746572732e706e67/riscv-registers.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/riscv-registers.png"></p> <p>L'architecture est donc assez simple, j'aime bien. Nous avons 32 registres à usage générique, tout du moins si on est seul au monde et que l'on ne souhaite pas développer quelque chose de "portable". Typiquement un logiciel développé en assembleur. Bien entendu, il s'agit ici des registres entiers. L'architecture RISC-V dispose de beaucoup d'extensions optionnelles dont par exemple l'extension offrant un jeu de registres flottants (IEEE 754).</p> <p>Rappel de la codification des extensions :</p> <ul> <li>Coeur RV32 'I' (A load-store ISA with 32, 32-bit general-purpose integer registers) avec les options : <ul> <li>M : Integer Multiplication and Division</li> <li>A : Atomics</li> <li>C : 16-bit Compressed Instructions</li> <li>F : Single-Precision Floating-Point</li> <li>D : Double-Precision Floating-Point</li> <li>Q : Quad-Precision Floating-Point</li> </ul> </li> </ul> <p>Au moment de l'écriture de cet article, plusieurs extensions supplémentaires sont prévues mais non encore décites (Bit manipulation, Dynamically Translated Languages, Vector Operations …). On le voit, cette architecture est vouée à évoluer dans les prochaines années.</p> <p>Enfin, la spécification décrit également le langage assembleur et spécifie une convention d'appel et de comportement (ABI, Application Binary Interface) des registres, ceci étant nécessaires pour préciser quels registres sont utilisés pour les arguments des fonctions, les divers pointeurs, adresses de retour etc.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f7374616e646172645f63616c6c696e672e706e67/standard_calling.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/standard_calling.png"></p> <p>Chaque coeur RISC-V dispose de non propre contrôleur d'interruption appelé CLIC (Core Local Interrupt Controller), il est dit logical car rattaché à un seul coeur ce qui peut avoir sens dans un composant multi-coeurs.</p> <h2 id="toc-gigadevice-et-nuclei">Gigadevice et Nuclei</h2> <p>D'après mes recherches et ce que j'en ai compris, l'IP du coeur RISC-V est pris chez la société Nuclei qui dispose d'un catalogue complet de coeurs (<a href="https://www.nucleisys.com/product/rvipes/n200/">https://www.nucleisys.com/product/rvipes/n200/</a>). Le notre, c'est celui-ci :</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6e75636c65695f6e3230302e706e67/nuclei_n200.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/nuclei_n200.png"></p> <p>Ce qui va nous intéresser ici est la présence d'un timer dans le coeur même. Typiquement, l'usage sera pour séquencer un système ; chez ARM, ils l'ont standardisé et l'ont appelé SystTick. Je suis un peu déçu d'ailleurs sur ce point, car avoir un timer standardisé permet de passer du code d'un microcontrôleur à l'autre sans ce soucier de ce point.</p> <p>Pour la performance, le coeur s'annonce plus véloce et moins gourmand que son principal concurrent, la famille Cortex-M :</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6e3230305f706572666f726d616e63652e706e67/n200_performance.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/n200_performance.png"></p> <p>Bon c'est une documentation constructeur, il faut en prendre et en laisser car on ne connaît pas les conditions de test. En réel, cela dépendera beaucoup de la performance de la Flash embarquée au MCU et de bien d'autres paramètres.</p> <h2 id="toc-un-peu-dassembleur">Un peu d'assembleur !</h2> <p>Essayons de tâter un peu plus profondément l'architecture. Pour s'amuser, nous allons utiliser le simulateur en ligne BRISC. On copie le programme ci-dessous qui réalise une petite boucle d'incrémentation d'un registre. Retirez les commentaires, ils ne passent pas sur le simulateur :</p> <pre><code class="asm"> <span class="nf">.file</span> <span class="s">"example.c"</span> <span class="nf">.option</span> <span class="nv">nopic</span> <span class="nf">.text</span> <span class="nf">.align</span> <span class="mi">2</span> <span class="nf">.globl</span> <span class="nv">example</span> <span class="nl">main:</span> <span class="nf">li</span> <span class="nv">a0</span><span class="p">,</span> <span class="mi">3</span> <span class="err">#</span> <span class="nb">ch</span><span class="nv">argement</span> <span class="nv">imm</span><span class="err">é</span><span class="nb">di</span><span class="nv">at</span> <span class="nv">d</span><span class="err">'</span><span class="nv">une</span> <span class="nv">valeur</span> <span class="nf">li</span> <span class="nv">a1</span><span class="p">,</span> <span class="mi">10</span> <span class="err">#</span> <span class="nv">a1</span> <span class="nv">contiendra</span> <span class="nv">notre</span> <span class="nv">valeur</span> <span class="nv">finale</span> <span class="nv">de</span> <span class="nv">sortie</span> <span class="nl">loop:</span> <span class="nf">addi</span> <span class="nv">a0</span><span class="p">,</span> <span class="nv">a0</span><span class="p">,</span> <span class="mi">1</span> <span class="err">#</span> <span class="nv">a0</span> <span class="err">=</span> <span class="nv">a0</span> <span class="o">+</span> <span class="mi">1</span> <span class="nf">bne</span> <span class="nv">a0</span><span class="p">,</span> <span class="nv">a1</span><span class="p">,</span> <span class="nv">end</span> <span class="err">#</span> <span class="nv">Branch</span> <span class="nv">if</span> <span class="nv">Not</span> <span class="nv">Equal</span> <span class="nf">j</span> <span class="nv">loop</span> <span class="err">#</span> <span class="nb">si</span><span class="nv">non</span> <span class="nv">on</span> <span class="nv">saute</span> <span class="s">'Jump'</span> <span class="nl">end:</span></code></pre> <p>Il est possible d'avancer pas à pas et de voir graphiquement le changement des différents registres.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f62726963735f73696d756c61746f722e706e67/brics_simulator.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/brics_simulator.png"></p> <p>Si vous voulez aller plus loin, Western Digital diffuse un tutorial complet d'assembleur sur Youtube en utilisant la carte HiFive : <a href="https://www.youtube.com/watch?v=KLybwrpfQ3I&amp;list=PL6noQ0vZDAdh_aGvqKvxd0brXImHXMuLY">https://www.youtube.com/watch?v=KLybwrpfQ3I&amp;list=PL6noQ0vZDAdh_aGvqKvxd0brXImHXMuLY</a>.</p> <p>N'oubliez pas le petit émulateur développé par le génie Fabrice Bellard : <a href="https://bellard.org/tinyemu/">https://bellard.org/tinyemu/</a> qui fournit en plus une image Linux prête à l'emploi !</p> <h2 id="toc-présentation-de-la-carte-électronique">Présentation de la carte électronique</h2> <p>La société GigaDevice a donc conçu ce microcontrôleur à base du coeur libre RISC-V dans une version RV32IMAC. La version que nous allons utiliser ici est la référence GD32VF103CBT6 qui embarque 128Ko de Flash et 32Ko de RAM. La fréquence du processeur monte à 108 Mhz et les périphériques sont légions : USART, I2C, SPI, CAN, USB, I2S, ADC 12 bits. Bref, le minimum syndical ! Les GPIO des périphériques sont remappables, attention toutefois, dans une certaine mesure (la liste est dans la datasheet).</p> <p>Que ce soit dans le code source des drivers et le nommage, l'inspiration STM32 est totale et c'est tant mieux car j'adore les STM32. J'ai lu quelque part que le composant était même totalement compatible broche à broche avec certaines versions de STM32.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f676433322d626c6f636b2d6469616772616d2e706e67/gd32-block-diagram.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/gd32-block-diagram.png"></p> <p>La carte que nous allons utiliser est la Longan Nano et coûte 5 Euros, avec en option un écran LCD. Ce qui rend le tout assez sympa.<br> <img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6c616e67616e2d6e616e6f2e6a7067/langan-nano.jpg" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/langan-nano.jpg"></p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6c6f6e67616e2d6e616e6f2d70696e6f7574732e6a7067/longan-nano-pinouts.jpg" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/longan-nano-pinouts.jpg"></p> <p>Sur une des extrémités, vous trouverez un port USB-C et à l'autre bout un connecteur JTAG : merci d'y avoir pensé, c'est assez rare pour le souligner. À côté du JTAG, sur le même connecteur, on y trouve l'UART0 qui va nous servir comme organe de débogage (même si a priori on peut s'en servir pour programmer la carte à la manière d'Arduino).</p> <p>Point d'entrée pour vos documents :<br> * <a href="https://longan.sipeed.com/en/">https://longan.sipeed.com/en/</a><br> * <a href="https://dl.sipeed.com/LONGAN/Nano/DOC/">https://dl.sipeed.com/LONGAN/Nano/DOC/</a></p> <h2 id="toc-arsenal-de-développement">Arsenal de développement</h2> <p>Pour commencer, nous allons utiliser Visual Studio Code avec l'extension PlatformIO : à la manière d'Arduino, il vous simplifie le démarrage rapide sur une nouvelle carte en permettant de coder et programmer votre premier bout de code très facilement, en quelques clics ! Ce genre d'outils est idéal pour essayer une carte, même si je pense qu'il faut s'en éloigner si on veut produire du code industriel qui se vend, notamment pour des problématiques de maintenance.</p> <p>Quoiqu'il en soit, une connexion USB-C suffit pour envoyer votre code dans le micro. La manipulation est la suivante : maintenez le bouton reset et le bouton boot0 situés sur la carte, puis relachez le reset : le bootloader intégré sera exécuté ce qui créera un dispositif de type DFU sous Linux. Cliquez ensuite sur "upload" et c'est parti !!</p> <p>Comme éditeur de code : restons sur Visual Studio Code, l'intégration avec Segger est possible. Nous tenterons également QtCreator qui fournit une interface C/C++ exemplaire tant au niveau de l'édition de code que du débogage. Il est réactif !</p> <p>Au niveau de la librairie fournie par GigaDevice : c'est un sans fautes, pour le moment. Là encore on sent l'inspiration ST, ici vous êtes en terrain connu. La librairie est toute simple, légère, de fines fonctions d'abstraction des registres des périphériques. Messieurs les autres fondeurs, merci de vous en inspirer et arrêtez avec vos interfaces graphiques de génération de code, c'est horrible. Un dossier d'exemples est fourni, bref normalement nous avons tout ce qu'il faut pour commencer facilement.<br> <img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6669726d776172655f6c6962726172792e706e67/firmware_library.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/firmware_library.png"></p> <p>Point d'entrée pour le tutorial PlatformIO : <a href="https://docs.platformio.org/en/latest/boards/index.html#gigadevice-gd32v">https://docs.platformio.org/en/latest/boards/index.html#gigadevice-gd32v</a></p> <p>Si vous voulez obtenir un compilateur déjà pré-compilé pour vos développements, Nuclei en fournit un ici : <a href="https://www.nucleisys.com/download.php">https://www.nucleisys.com/download.php</a>.</p> <h2 id="toc-le-hello-world-de-lembarqué--blinky">Le Hello World de l'embarqué : Blinky</h2> <p>Le but est ici de faire clignoter une LED. La carte dispose d'une LED RGB tricolore câblée comme ceci :<br> <img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6c65645f736368656d61746963732e706e67/led_schematics.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/led_schematics.png"></p> <p>Le PlateformIO dispose d'un exemple tout fait permettant de faire clignoter la LED embarquée. Pour réaliser un délai entre l'extinction et l'allumage de la LED, l'exemple utilise une lecture bloquante du timer embarqué dans chaque coeur RISC. Attention donc, c'est utile mais cela bloque tout et dans un contexte multi-tâches on utilisera d'autres moyens non bloquants.</p> <pre><code class="c"><span class="cp">#include</span> <span class="cpf">"gd32vf103.h"</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">"systick.h"</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span> <span class="cm">/* BUILTIN LED GREEN*/</span> <span class="cp">#define LED_PIN BIT(1)</span> <span class="cp">#define LED_GPIO_PORT GPIOA</span> <span class="cp">#define LED_GPIO_CLK RCU_GPIOA</span> <span class="kt">void</span> <span class="nf">longan_led_init</span><span class="p">()</span> <span class="p">{</span> <span class="cm">/* enable the led clock */</span> <span class="n">rcu_periph_clock_enable</span><span class="p">(</span><span class="n">LED_GPIO_CLK</span><span class="p">);</span> <span class="cm">/* configure led GPIO port */</span> <span class="n">gpio_init</span><span class="p">(</span><span class="n">LED_GPIO_PORT</span><span class="p">,</span> <span class="n">GPIO_MODE_OUT_PP</span><span class="p">,</span> <span class="n">GPIO_OSPEED_50MHZ</span><span class="p">,</span> <span class="n">LED_PIN</span><span class="p">);</span> <span class="n">GPIO_BC</span><span class="p">(</span><span class="n">LED_GPIO_PORT</span><span class="p">)</span> <span class="o">=</span> <span class="n">LED_PIN</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">longan_led_on</span><span class="p">()</span> <span class="p">{</span> <span class="n">GPIO_BC</span><span class="p">(</span><span class="n">LED_GPIO_PORT</span><span class="p">)</span> <span class="o">=</span> <span class="n">LED_PIN</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">longan_led_off</span><span class="p">()</span> <span class="p">{</span> <span class="n">GPIO_BOP</span><span class="p">(</span><span class="n">LED_GPIO_PORT</span><span class="p">)</span> <span class="o">=</span> <span class="n">LED_PIN</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">longan_led_init</span><span class="p">();</span> <span class="n">init_uart0</span><span class="p">();</span> <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">){</span> <span class="cm">/* turn on builtin led */</span> <span class="n">longan_led_on</span><span class="p">();</span> <span class="n">delay_1ms</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="cm">/* turn off uiltin led */</span> <span class="n">longan_led_off</span><span class="p">();</span> <span class="n">delay_1ms</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span></code></pre> <p>Comme le montre la documentation, il va falloir créer une règle Linux pour pouvoir programmer le composant :</p> <pre><code>sudo nano /etc/udev/rules.d/90-longan-nano.rules ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666" udevadm control --reload-rules &amp;&amp; udevadm trigger </code></pre> <h2 id="toc-hello-world-plus-poussé--luart">Hello World plus poussé : L'UART</h2> <p>Cette fonction sera autrement plus pratique : lors de vos développements embarqués, avoir une console série qui affiche le bon déroulement de votre programme est indispensable. Cela doit être une des premières choses à prévoir dans votre développement car cela vous servira tout le temps !</p> <p>Donc là rien de bien compliqué : il faut d'abord repérer quelle broche nous allons utiliser. Sur le longan, le connecteur d'extrémité contient le brochage Tx/Rx typiquement mis là pour cet usage.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f6c6f6e67616e5f7478302e706e67/longan_tx0.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/longan_tx0.png"></p> <p>Le code d'initialisation est en deux parties :<br> - D'une part nous allons utiliser le mode alternatif de la broche PA9, c'est-à-dire non pas en GPIO mais en UART<br> - D'autre part la configuration du module UART proprement dit à la fréquence voulue :</p> <pre><code class="c"><span class="k">static</span> <span class="kt">void</span> <span class="nf">init_uart0</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// enable GPIO clock </span> <span class="n">rcu_periph_clock_enable</span><span class="p">(</span><span class="n">RCU_GPIOA</span><span class="p">);</span> <span class="n">gpio_init</span><span class="p">(</span><span class="n">GPIOA</span><span class="p">,</span> <span class="n">GPIO_MODE_AF_PP</span><span class="p">,</span> <span class="n">GPIO_OSPEED_50MHZ</span><span class="p">,</span> <span class="n">GPIO_PIN_9</span><span class="p">);</span> <span class="c1">// enable USART0 clock </span> <span class="n">rcu_periph_clock_enable</span><span class="p">(</span><span class="n">RCU_USART0</span><span class="p">);</span> <span class="c1">// configure USART0</span> <span class="n">usart_deinit</span><span class="p">(</span><span class="n">USART0</span><span class="p">);</span> <span class="n">usart_baudrate_set</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="mi">115200U</span><span class="p">);</span> <span class="n">usart_word_length_set</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_WL_8BIT</span><span class="p">);</span> <span class="n">usart_stop_bit_set</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_STB_1BIT</span><span class="p">);</span> <span class="n">usart_parity_config</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_PM_NONE</span><span class="p">);</span> <span class="n">usart_hardware_flow_rts_config</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_RTS_DISABLE</span><span class="p">);</span> <span class="n">usart_hardware_flow_cts_config</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_CTS_DISABLE</span><span class="p">);</span> <span class="n">usart_receive_config</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_RECEIVE_ENABLE</span><span class="p">);</span> <span class="n">usart_transmit_config</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_TRANSMIT_ENABLE</span><span class="p">);</span> <span class="n">usart_enable</span><span class="p">(</span><span class="n">USART0</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// retarget the C library printf function to USART0</span> <span class="kt">int</span> <span class="nf">_put_char</span><span class="p">(</span><span class="kt">int</span> <span class="n">ch</span><span class="p">)</span> <span class="c1">// used by printf</span> <span class="p">{</span> <span class="n">usart_data_transmit</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span> <span class="n">ch</span> <span class="p">);</span> <span class="k">while</span> <span class="p">(</span><span class="n">usart_flag_get</span><span class="p">(</span><span class="n">USART0</span><span class="p">,</span> <span class="n">USART_FLAG_TBE</span><span class="p">)</span> <span class="o">==</span> <span class="n">RESET</span><span class="p">){</span> <span class="p">}</span> <span class="k">return</span> <span class="n">ch</span><span class="p">;</span> <span class="p">}</span></code></pre> <p>Notez ici que la fonction _put_char est re-définie : c'est cette fonction qui est au bout d'un printf et se charge d'envoyer un caractère uniquement quelque part : par défaut je pense qu'elle ne fait rien, car nous sommes dans un environnement embarqué. Nous allons envoyer tout caractère reçu vers l'UART.</p> <p>Et enfin la fonction principale est modifiée en ajoutant notre initialisation et l'appelle du printf();</p> <pre><code class="c"><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">longan_led_init</span><span class="p">();</span> <span class="n">init_uart0</span><span class="p">();</span> <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">){</span> <span class="n">printf</span><span class="p">(</span><span class="s">"ON</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="cm">/* turn on builtin led */</span> <span class="n">longan_led_on</span><span class="p">();</span> <span class="n">delay_1ms</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="cm">/* turn off uiltin led */</span> <span class="n">printf</span><span class="p">(</span><span class="s">"OFF</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">longan_led_off</span><span class="p">();</span> <span class="n">delay_1ms</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span></code></pre> <p>Maintenant munissez-vous d'un contrôleur USB-série quelconque pour relier le port série du Longan au PC :</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f7573625f73657269616c5f676433322e6a7067/usb_serial_gd32.jpg" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/usb_serial_gd32.jpg"></p> <p>Ouvrez un terminal série sur votre port série créé par la puce FTDI et observez !</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f74785f6f75747075742e706e67/tx_output.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/tx_output.png"></p> <h2 id="toc-les-différentes-fréquences-et-le-timer">Les différentes fréquences et le timer</h2> <p>Ok alors jusqu'à maintenant, nous avons copié-collé un peu de code pris à droite et à gauche. Sauf que nous ne maîtrisons pas grand chose sur la fréquence de fonctionnement. A priori, le délai bloquant fourni par la librairie standard fonctionne vu la fréquence de clignottement de la LED, mais on ne sait pas à quelle fréquence tourne le CPU.</p> <p>On affiche la fréquence en récupérant la valeur de la variable globale SystemCoreClock qui est initialisée au démarrage, avant le main().</p> <pre><code class="c"><span class="n">printf</span><span class="p">(</span><span class="s">"[OST] Starting with CPU=%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">SystemCoreClock</span><span class="p">);</span></code></pre> <p>Voici le schéma de la PLL, le CPU est donc bien cadencé à la fréquence maximale ici, soit 108 MHz.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f706c6c2e706e67/pll.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/pll.png"></p> <p>Notons que le timer SysTick offert par le coeur Nuclei est lui divisé par 4 en entrée. Le meilleur moyen de vérifier si la fréquence CPU est correcte est de faire bagoter un GPIO à l'aide d'un timer. Si notre calcul de timer est bon et la fréquence CPU correcte, alors nous devrions voir la bonne fréquene à l'oscilloscope.</p> <h2 id="toc-nmsis-et-le-systick">NMSIS et le SysTick</h2> <p>Nous l'avons vu, le coeur Nuclei nous offre un timer "bonus" en plus des Timers 0 à 6 que le fondeur GigaDevices propose. Ces derniers sont assez complexes et servent généralement à sortir des PWM, compter des impulsions ou commander des moteurs. Si on peut éviter de s'en servir, profitons-en.</p> <p>Comment y accéder ? Eh bien, c'est un peu obscure. En fait, la société Nuclei a pondu un ensemble de "standards" d'appellations exactement comme … ARM, avec son CMSIS et Nuclei l'a donc fort logiquement appelé NMSIS.</p> <p>On y trouve donc dedans ce qui a trait au coeur, dont notre fameux SysTick.</p> <p>Malheureusement, au moment de l'écriture de cet article, la librairie NMSIS s'intègre très mal à PlatformIO. Il faut donc mieux commencer par l'ensemble cohérent fournit par Nuclei, sur le Github : <a href="https://github.com/Nuclei-Software/nuclei-sdk">https://github.com/Nuclei-Software/nuclei-sdk</a> qui contient également la librairie du GD32 adaptée pour l'occation.</p> <p>Ce qu'il est possible de faire pour le moment est de copier coller le code se rapportant au SysTick en provenance du NMSIS. Il suffit alors de récupérer l'exemple fournit par Nuclei :</p> <pre><code class="c"><span class="k">static</span> <span class="k">volatile</span> <span class="kt">uint32_t</span> <span class="n">msTicks</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">static</span> <span class="k">volatile</span> <span class="kt">bool</span> <span class="n">tick_1s</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">static</span> <span class="k">volatile</span> <span class="kt">uint32_t</span> <span class="n">tick_1s_counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="cp">#define CONFIG_TICKS (TIMER_FREQ / 1000)</span> <span class="cp">#define SysTick_Handler eclic_mtip_handler</span> <span class="kt">void</span> <span class="nf">SysTick_Handler</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* SysTick interrupt Handler. */</span> <span class="n">SysTick_Reload</span><span class="p">(</span><span class="n">CONFIG_TICKS</span><span class="p">);</span> <span class="cm">/* Call SysTick_Reload to reload timer. */</span> <span class="n">msTicks</span><span class="o">++</span><span class="p">;</span> <span class="cm">/* See startup file startup_gd32vf103.S for SysTick vector */</span> <span class="n">tick_1s_counter</span><span class="o">++</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">tick_1s_counter</span> <span class="o">&gt;=</span> <span class="mi">1000</span><span class="p">)</span> <span class="p">{</span> <span class="n">tick_1s_counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">tick_1s</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span></code></pre> <p>Et le main :</p> <pre><code class="c"><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="n">longan_led_init</span><span class="p">();</span> <span class="n">init_uart0</span><span class="p">();</span> <span class="n">longan_bp1_init</span><span class="p">();</span> <span class="kt">uint32_t</span> <span class="n">returnCode</span> <span class="o">=</span> <span class="n">SysTick_Config</span><span class="p">(</span><span class="n">CONFIG_TICKS</span><span class="p">);</span> <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">tick_1s</span><span class="p">)</span> <span class="p">{</span> <span class="n">tick_1s</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="n">printf</span><span class="p">(</span><span class="s">"[OST] SysTick=%d</span><span class="se">\r\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">msTicks</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span></code></pre> <p>Et voilà, sur l'UART vous devriez observer le tick qui s'incrémente. N'oubliez pas le mot clé 'volatile' pour les variables incrémentées dans l'interruption : sans cela, le compilateur effectuera une optimisation ce qui rendra le code non fonctionnel ; en effet, selon son analyse la fonction SysTick_Handler n'est jamais appelée donc il va la supprimer. En ajoutant le mot clé volatile, on lui dit simplement "t'inquiète, cette variable sert bien quelque part, t'occupe et ne touche à rien".</p> <p>La table des vecteurs d'interruptions est localisée dans le fichier start.S :</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6438732e65752f6173736574732f61727469636c65732f72697363762d676433322f696e746572727570745f6e616d65732e706e67/interrupt_names.png" alt="image" title="Source : https://www.d8s.eu/assets/articles/riscv-gd32/interrupt_names.png"></p> <h2 id="toc-solutions-de-débogage">Solutions de débogage</h2> <p>Le coeur RISC-V étant assez nouveau, il existe peu de solutions. Je suggère notamment :</p> <ul> <li>L'incontournable JLink, attention toutefois à la version matérielle de votre sonde ; un tableau résume quelle version est supportée : <a href="https://wiki.segger.com/Software_and_Hardware_Features_Overview">https://wiki.segger.com/Software_and_Hardware_Features_Overview</a> </li> <li>Sipeed USB-JTAG/TTL RISC-V Debugger, un espèce de clone de ST-Link mais qui a l'air de supporter le RISC-V, je l'ai commandé je testerai</li> <li>BlackMagic Probe : l'intégration du RISC-V est en cours, non encore fonctionnelle a priori</li> <li>OpenOCD via un moniteur série : je ne l'ai pas testé !</li> </ul> <h2 id="toc-conclusion">Conclusion</h2> <p>Voilà une carte bien sympatique. Il est maintenant tant de réaliser un petit projet avec, et si possible doté d'une sone JTAG !</p> <p>Le code source du tutorial est ici : <a href="https://github.com/arabine/risc-v-tutorial">https://github.com/arabine/risc-v-tutorial</a></p> <div><a href="https://linuxfr.org/users/belegar--2/journaux/prise-en-main-de-la-carte-longan-nano-risc-v-de-gigadevice.epub">Télécharger ce contenu au format EPUB</a></div> <p> <strong>Commentaires :</strong> <a href="//linuxfr.org/nodes/122710/comments.atom">voir le flux Atom</a> <a href="https://linuxfr.org/users/belegar--2/journaux/prise-en-main-de-la-carte-longan-nano-risc-v-de-gigadevice#comments">ouvrir dans le navigateur</a> </p>
    • Li chevron_right

      Un RISC-V sous Linux pour $12.50

      martoni · pubsub.eckmul.net / linuxfr · Monday, 9 November, 2020 - 20:32 · 3 minutes

    <p>Cher journal,</p> <p>On continue dans la montée en puissance <a href="https://fr.wikipedia.org/wiki/RISC-V">du jeux d'instructions initié à Berkeley</a> (mais dont la fondation est désormais <a href="https://www.april.org/01net-risc-v-demenage-en-suisse-pour-echapper-a-la-guerre-commerciale-sino-americaine">hébergée en suisse</a>) avec un processeur qui nous viens de Chine : le XuanTie C906.</p> <p>C'est la société Sipeed (spécialisé dans les kit de développement et autres module à base de puces chinoises) qui la annoncé sur le <a href="https://mastodon.partipirate.org/@Martoni/103799809556246892">silo social</a> <a href="https://twitter.com/SipeedIO/status/1324632751157374977">«twitter»</a>.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f6c696e757867697a6d6f732e636f6d2f66696c65732f7369706565645f7875616e746965633930365f707265766965772e6a7067/sipeed_xuantiec906_preview.jpg" alt="Architecture du C906" title="Source : https://linuxgizmos.com/files/sipeed_xuantiec906_preview.jpg"></p> <p>Difficile d'avoir plus d'info que ce piaillement. Le <a href="https://www.t-head.cn/">site chinois du constructeur t-head</a> est un peu capricieux pour afficher la description de ses produits et semble ne pas encore avoir mis la page pour le C906. Cependant, <a href="https://www.sipeed.com/">Sipeed</a> se vante d'avoir déjà lancé la fabrication d'un module PCB basé sur ce processeur. Cette société <a href="https://www.seeedstudio.com/sipeed">nous a prouvé par le passé</a> qu'elle n'était pas adepte du vaporware, il est donc probable que cette annonce soit vraie, il faudra voir les délais.</p> <p><img src="//img.linuxfr.org/img/68747470733a2f2f6c696e757867697a6d6f732e636f6d2f66696c65732f616c6c77696e6e65725f7269736376736f6d5f636e782e6a7067/allwinner_riscvsom_cnx.jpg" alt="Titre de l'image" title="Source : https://linuxgizmos.com/files/allwinner_riscvsom_cnx.jpg"></p> <p>Ce qu'on peut dire c'est que c'est un bon vieux mono-core 64bits (<a href="https://en.wikipedia.org/wiki/RISC-V#ISA_base_and_extensions">RV64GCV</a>) comme on n'en fait plus pour nos PC de bureau de nos jour. Qu'il est pourvu d'une <a href="https://en.wikipedia.org/wiki/Memory_management_unit">MMU</a> et donc parfaitement capable de tourner sous Linux.</p> <p>Même si je ne me risquerais pas à le qualifier de «PC de bureau ;) » c'est un ordinateur parfaitement calibré pour les systèmes industriels, heu non embarqués, heu non pour l'«IoT», heu non pour l'Informatique en périphérie (Edge computing), heu non «insérez ici le nouveau mot à la mode pour désigner un système embarqué».</p> <p>L'information est encore toute chaude, restons sur le pont pour en savoir plus.</p> <div><a href="https://linuxfr.org/users/martoni/journaux/un-risc-v-sous-linux-pour-12-50.epub">Télécharger ce contenu au format EPUB</a></div> <p> <strong>Commentaires :</strong> <a href="//linuxfr.org/nodes/122172/comments.atom">voir le flux Atom</a> <a href="https://linuxfr.org/users/martoni/journaux/un-risc-v-sous-linux-pour-12-50#comments">ouvrir dans le navigateur</a> </p>