Hardware Abstraction Layer


  • Mod

    Andromeda schrieb:

    C ist gewissermaßen sowas wie eine portable Assemblersprache. Für einen HAL gibt es quasi nicht Besseres.

    Das reicht nicht. Damit C die bessere Wahl ist, muss die Größe der ausführbaren Datei eine große Rolle spielen - das ist das einzige Kriterium, was mir auf die Schnelle einfällt, um überhaupt irgendeinen Einsatz von C per se zu rechtfertigen. Und selbst dort kann ein C++ Compiler optimieren ( -Os , -s & UPX). Es gibt auch einen Grund für die Definition von "freestanding implementation".

    In C++ kanst du zu 99.9% Plain-C programmieren, wenn du willst.

    Oder man kann sich der Vielfalt an Abstraktionen bedienen, die Programmieren um einiges Erleichtern. Mein Vorposter hat ja schon einiges erwähnt. Wenn dir das nicht relevant scheint, bist du eben bescheuert, daher die Frage.

    Problematisch wird es aber immer dann, wenn man die erweiterten Features von C++ einsetzen will. Du siehst ja selbst, auf welche Hindernisse du stößt. Aber vielleicht ist es ja gerade diese intellektuelle Herausforderung, die dich besonders anspornt.

    Nix ist "problematisch". Wenn sowohl die Variable als auch die entsprechenden Funktionen als constexpr deklariert werden, wird der Compiler all die Funktionsaufrufe mit Sicherheit weg optimieren. Und bei der Template-Lösung gab es überhaupt keine Probleme. Du scheinst überdies außer Acht zu lassen, dass jedes unproblematische Feature von C++ (was praktisch fast alle sind) einen weiteren, womöglich großen Nutzen für den Programmierer darstellt. Keine Last.

    Im Übrigen hat dein C Fundamentalismus in diesem Jahrzehnt wenig verloren.



  • Arcoth schrieb:

    Im Übrigen hat dein C Fundamentalismus in diesem Jahrzehnt wenig verloren.

    http://www.tiobe.com/tiobe_index



  • Die Statistik ist ja jetzt sehr allgemein gehalten. Mich würde mehr Interessieren, wie es im Embedded Bereich aussieht!





  • ieee schrieb:

    http://spectrum.ieee.org/static/interactive-the-top-programming-languages-2015

    Du würdest Dich bei der Wahl eines Werkzeuges eher an Statistiken, als an Argumenten orientieren? Warum?



  • Und wann habe ich das gesagt? Genau, gar nicht. Hör also auf, hier Unsinn zu schreiben.



  • ieee schrieb:

    Und wann habe ich das gesagt? Genau, gar nicht. Hör also auf, hier Unsinn zu schreiben.

    Genau, weil ich Deine Einwerfen dieser Statistiken nicht verstanden habe, habe ich gefragt, warum Du diese Statistiken hier in die Diskussion wirfst.

    Wo habe ich da gesagt, dass Du etwas gesagt hast? Ich habe Dich etwas gefragt. Vielleicht solltest Du dich mal nicht so schnell, persönlich auf den Schlips getreten fühlen? 😉

    mfg Torsten



  • Mich interessiert einfach der Trend. Für die Auswahl spielt das erstmal keine Rolle, aber vllt. lohnt es sich mal genauer nachzuschauen warum eine bestimmte Sprache einen hohen Trend aufweißt.

    Ich bin mal gespannt wie lange es dauert, bis sich eine Sprache mit besserer Meta-Programmierung durchsetzt. Die C++ Metaprogrammierung war ja eher ein glücklicher Zufall. Ich denk da an sowas wie VHDL und "generate". Wobei sich die Frage stellt, ob es überhaupt "besser" umgesetzt werden kann, als in C++ ...



  • Das D mit fast 50% vertreten ist finde ich jetzt schon etwas überraschend 😃



  • Torsten Robitzki schrieb:

    Genau, weil ich Deine Einwerfen dieser Statistiken nicht verstanden habe, habe ich gefragt, warum Du diese Statistiken hier in die Diskussion wirfst.

    Nein, das hast du nicht gefragt.

    Torsten Robitzki schrieb:

    Du würdest Dich bei der Wahl eines Werkzeuges eher an Statistiken, als an Argumenten orientieren?

    Du fragst mich etwas aufgrund einer Aussage, welche ich nie getätigt habe. Dass ich mich an Statistiken orientiere habe ich nie behauptet.

    Meine Statistik war der Hinweis, dass C immer noch häufiger verwendet wird als C++, unabhängig davon, welche Lieblingssprache man hat. Ich sehe diesen Fundamentalismus eher auf C++-Seite.


  • Mod

    tiobe schrieb:

    http://www.tiobe.com/tiobe_index

    http://bit.ly/265UfoV

    Meine Statistik war der Hinweis, dass C immer noch häufiger verwendet wird als C++, unabhängig davon, welche Lieblingssprache man hat.

    Toll. Dir ist aber klar, dass das damit zusammenhängt, dass a) eine gigantische Menge von C Code existiert, der auch weiterentwickelt wird, und b) es u.U. einfacher sein kann, kompetente C Programmierer statt C++ Programmierern zu finden und engagieren? Wenn willst du hier von der Modernität einer Sprache überzeugen, indem du solche Statistiken verlinkst? Demnach wäre es auch nicht ungesund VW Fundamentalistisch, einen Golf über einen R8 zu empfehlen, weil ersteres statistisch stärker vertreten ist (und nicht etwa billiger!).



  • Arcoth schrieb:

    Dir ist aber klar, dass das damit zusammenhängt, dass a) eine gigantische Menge von C Code existiert, der auch weiterentwickelt wird

    Aha, er wird also weiterentwickelt.

    Hm, aber ich dachte, dein Satz wäre eher so zu verstehen, als dass C sich auf dem absteigenden Ast befindet? Wie kann das sein, wenn noch "gigantische Mengen C Codes" existieren?

    Arcoth schrieb:

    und b) es u.U. einfacher sein kann, kompetente C Programmierer statt C++ Programmierern zu finden und engagieren?

    C-Programmierer erreichen das gleiche wie C++-Programmierer, einfach weil so viel C in C++ steckt. Aber C-Programmierer müssen sich den zusätzlichen Balast von C++ nicht reinziehen, der zur Entstehung von Java beigetragen hat und der mit jedem weiteren Standard noch komplexer wird. Programme werden nicht automatisch dadurch wartbarer, dass du sie bis zur Unkenntlichkeit abstrahierst. Du musst sie mit Sinn und Verstand abstrahieren.

    In der Regel sehe ich fehlende oder ungenügende Abstrahierung bei C und zu viel Abstrahierung bei C++. C hat nicht genug, C++ zu viel Abstrahierung.

    Arcoth schrieb:

    Wenn willst du hier von der Modernität einer Sprache überzeugen, indem du solche Statistiken verlinkst?

    Sag mal, ist heute Strohmann-Nacht? Ob C modern ist oder nicht, habe ich doch nie zur Debatte gestellt. Folglich will ich auch niemanden davon überzeugen.

    Nur die Aussage, dass C in der "Moderne" nicht mehr verwendet werden wird, ist Entengrütze.


  • Mod

    ieee schrieb:

    Hm, aber ich dachte, dein Satz wäre eher so zu verstehen, als dass C sich auf dem absteigenden Ast befindet?

    Nein, und das ist leider nicht direkt der Fall.

    C-Programmierer erreichen das gleiche wie C++-Programmierer

    Und produzieren dabei wahrscheinlich bei größerem Zeitaufwand auch mehr Fehler.

    Du musst sie mit Sinn und Verstand abstrahieren.

    Kein Scheiß. Und C Programmierer, brauchen die Sinn und Verstand?

    C hat nicht genug, C++ zu viel Abstrahierung.

    Blödsinn. Hast du dir zu viel Boost.Graph reingezogen?

    Ob C modern ist oder nicht, habe ich doch nie zur Debatte gestellt.

    Nein, so dumm wärst du nicht gewesen! Das ist aber effektiv was ich zur Debatte stellte, als ich es für unklug befand, diese Sprache im Angesicht derartiger Alternativen weiterhin zu empfehlen.



  • Hallo zusammen,

    habe den Thread gerade erst entdeckt, daher bin ich etwas spaet dran 😉

    wer interessiert ist, kann sich ja auch mal das hier angucken:

    http://electronicdesign.com/dev-tools/evolution-special-function-register-abstraction

    http://kvasir.io/

    ich muss dazu sagen, dass ich Kvasir nicht wirklich benutzbar finde. das ist ein gigantischer wust von templates, den ich sehr schwer zu durchschauen finde. aber vielleicht sind meine TMP-skills auch einfach nicht ausreichend...



  • Ich bin nun dabei das multiplexen jeweils in die einzelnen Module zu verschieben (Bisher hatte ich eine Pin Template Klasse, mit der man die Pins konfigurieren konnte).

    Beispielsweise sieht das ganze für den Uart0 so aus:

    template<UartName t_uart_name>
    class Uart {
    public:
    
    	...
    
    	template<PinName t_pin_name>
    	static inline void mux_rx(...) {
    		// Wenn diese Funktion verwendet wird, soll ein Fehler ausgegeben werden.
    	}
    
    	...
    };
    
    template<> template<>
    inline void Uart<k_uart0>::mux_rx<k_pin_a1>(...) {
    	PORTA->PCR[ 0] = ...;
    }
    template<> template<>
    inline void Uart<k_uart0>::mux_rx<k_pin_a15>(...) {
    	PORTA->PCR[15] = ...;
    }
    template<> template<>
    inline void Uart<k_uart0>::mux_rx<k_pin_b16>(...) {
    	PORTB->PCR[16] = ...;
    }
    template<> template<>
    inline void Uart<k_uart0>::mux_rx<k_pin_d6>(...) {
    	PORTD->PCR[ 6] = ...;
    }
    

    Jetzt würde ich gerne wie in dem Kommentar angegeben einen Fehler ausgeben, wenn versucht wird den Uart auf einen Pin zu multiplexen, auf den garkeit Pin gemultiplext werden kann!

    Mir fallen leider nur 2 Lösungen ein:
    1. static_assert - Da muss ich jedoch in der Condition alle möglichen Kombination angeben, z.b. so:

    static_assert((t_uart_name == k_uart0)&&(t_pin_name == k_pin_a1 || t_pin_name == k_pin_a15 || t_pin_name == k_pin_b16 || t_pin_name == k_pin_d6), "UARTx can not be muxed on this pin!");
    

    Die Lösung finde ich jedoch sehr unelegant!

    2. assert(false) - Wird dann aber erst zur Laufzeit erkannt ...

    Hätte jemand eine Idee wie man das hübscher lösen könnte?



  • http://kvasir.io/ hat dafür laut dem Tutorial eine Lösung - kompiliert dann eben nicht - abgucken?



  • fenrayn schrieb:

    Hätte jemand eine Idee wie man das hübscher lösen könnte?

    Allein wegen der Skalierbarkeit, würde ich Pin-Namen, Port und Pin in einen Typen stecken, diese in eine Typ-Liste und dann in einer Implementierung von mux_rx(), Port und Pin über den Pin-Namen nachschlagen. Wenn es keinen Eintrag in der Liste gibt, dann gäbe es eine entsprechende Fehlermeldung via static_assert.

    Vielleicht wird es insgesamt einfacher, wenn Du aus t_pin_name einen Typen machst, der Port und Pin enthält. Eine gemeinsame Basisklasse zu so einem class template könnte dann evtl. noch genutzt werden, falls Du wirklich noch irgend wo die Anforderungen hast, so einen Port pin zur Laufzeit zu speichern.



  • "höhere" Meta-Programmierung wie z.B. Typenlisten möchte ich versuchen zu vermeiden. Aber was das verwenden von Typen anstatt Konstanten gefällt mir. Ich stell mir das so vor:

    Es gibt die Basistypen, beispielsweise Uart0, Uart1, etc ... . Und die eigentliche Uart Klasse bekommt dann einen Basistypen als Templateparameter, also z.B. Uart<Uart0>.

    In Uart0, Uart1, etc ... werden dann für diesen Uart spezifische Teile implementiert, z.B. wird bei meinem Board Uart0 und Uart1 mit dem Systemtakt getaktet, alle anderen Uarts nur mit dem Bustakt. Die algemeine Templateklasse Uart verwendet dann diese Informationen.

    Hast du das etwa so gemeint? 🙂



  • fenrayn schrieb:

    Hast du das etwa so gemeint? 🙂

    Nein, ich meinte eigentlich, statt none type template parameter, einfach Typen zu verwenden, die die gleichen Informationen enthalten:

    template < port_t* U, unsigned P >
    struct pin {
       ...
    };
    
    using k_pin_a1 = pin< port_a, 1 >;
    
    template<> 
    template< class Pin > 
    void Uart< k_uart0 >::mux_rx< Pin >(...) {
        using check = typename find_in_list< std::tuple<
            k_pin_a1, k_pin_a2, k_pin_a3 >, Pin >::type;
    
        static_assert( !std::same_type< not_found, check >, "Unsupported rx Pin for Uart0" );
    }
    

    Das war auch nicht als Design-Vorschlag für Deine Uart-Abstraktion gemeint, sondern als Vorschlag, für Dein konkretes Problem, wie Du testen kann, dass der verwendete Pin nur aus einer ganz bestimmten Menge kommt.

    mfg Torsten



  • fenrayn schrieb:

    "höhere" Meta-Programmierung wie z.B. Typenlisten möchte ich versuchen zu vermeiden. Aber was das verwenden von Typen anstatt Konstanten gefällt mir. Ich stell mir das so vor:

    Es gibt die Basistypen, beispielsweise Uart0, Uart1, etc ... . Und die eigentliche Uart Klasse bekommt dann einen Basistypen als Templateparameter, also z.B. Uart<Uart0>.

    In Uart0, Uart1, etc ... werden dann für diesen Uart spezifische Teile implementiert, z.B. wird bei meinem Board Uart0 und Uart1 mit dem Systemtakt getaktet, alle anderen Uarts nur mit dem Bustakt. Die algemeine Templateklasse Uart verwendet dann diese Informationen.

    Hast du das etwa so gemeint? 🙂

    So mache ich das gerade, denke das ist an sich nicht verkehrt. Die konkreten "Instanzen", also Uart1, Uart2 etc. sind bei mir allerdings keine Klassen im eigentliche Sinne, sondern ledglich Register-Abstraktionen.

    Also in etwa so:

    template<typename Instance>
    class Uart {
        template<typename Conf>
        static constexpr void init(){
            set(Instance::ControlRegister::enable);
            ...
        }
    };
    

    Mein code sieht nicht ganz so aus, aber die Idee wird hoffentlich klar. Fuer Uarts die sich anders verhalten kann man dann noch das Template spezialisieren. Ich arbeite da noch dran und bin mir noch nicht so sicher ob das das Gelbe vom Ei ist...


Anmelden zum Antworten