Peripheral Hardware Adresse welche mit define in C library angelegt ist in constexpr variable verwenden.



  • Hallo,
    ich versuche gerade eine bestehende C library in C++ zu integrieren. Dazu möchte ich ein pointer welcher auf die Peripherie zeigt als constexpr anlegen bzw. als template Parameter verwenden.
    Folgendes Beispiel:

    #include <cstdint>
    
    /* 
    C Code 
    The C Code in the real project is a framework, therefore I can't (wouldn't) change it.
    The pointer points to a peripheral hardware address, and the struct to each register.
    */
    typedef struct {
        uint32_t item1; 
        uint32_t item2;
    } MyStruct;
    
    #define POINTER_TO_HARDWARE ((MyStruct*)0x40000000U)
    
    
    /*
    C++ Code 
    Declare static constexpr to a pheripheral hardware pointer.
    */
    static constexpr MyStruct* HARDWARE_PTR{POINTER_TO_HARDWARE};
    static constexpr MyStruct* HARDWARE_PTR1{static_cast<MyStruct*>(POINTER_TO_HARDWARE)};
    static constexpr MyStruct* HARDWARE_PTR2{reinterpret_cast<MyStruct*>(POINTER_TO_HARDWARE)};
    

    Leider bekomme ich die mit define deklarierte Adresse nicht in eine constexpr variable. Der Compiler (ARM GNU Toolchain 7 2018) beschwert sich immer.

    Hat jemand eine Idee wie es funktionieren könnte?

    Link zu online Compiler:
    https://godbolt.org/z/Yqm5Dv





  • Hallo,
    danke für deine Antwort.

    Wenn ich es richtig verstanden habe, dann ist es also nicht möglich eine Hardwareadresse als constexpr anzulegen und somit als template parameter zu verwenden?

    Hmm blöd, da muss ich mir was anderes einfallen lassen.


  • Mod

    @godi sagte in Peripheral Hardware Adresse welche mit define in C library angelegt ist in constexpr variable verwenden.:

    Hmm blöd, da muss ich mir was anderes einfallen lassen.

    Was willst du denn dadurch erreichen, dass du einen Hardwarepointer als Templateparameter haben möchtest?



  • Du kannst auch Klassen machen die bestimmte Register lesen und/oder schreiben, und dann die Klassen als Template-Parameter verwenden.

    struct RegisterX {
        static uint32_t read() { ... se code wis se macros ... }
        static void write(uint32_t value) {  ... se code wis se macros ... }
    };
    
    struct RegisterY {
        static uint32_t read() { ... se code wis se macros ... }
        static void write(uint32_t value) {  ... se code wis se macros ... }
    };
    
    using MyDevice = Device<RegisterX, RegisterY>;
    


  • @SeppJ sagte in Peripheral Hardware Adresse welche mit define in C library angelegt ist in constexpr variable verwenden.:

    @godi sagte in Peripheral Hardware Adresse welche mit define in C library angelegt ist in constexpr variable verwenden.:

    Hmm blöd, da muss ich mir was anderes einfallen lassen.

    Was willst du denn dadurch erreichen, dass du einen Hardwarepointer als Templateparameter haben möchtest?

    Beispiel USART:
    Von diesen gibt es mehrere auf meinen µC, welche auch unterschiedliche Funktionalitäten bieten wie z.b. RS232, Handshaking, SPI, RS485, .... unterschiedliche Pins benötigen, und eben unterschiedliche Hardwareadressen haben.

    Dadurch macht es Sinn, eine template class zu erstellen, wo eben mit if constexpr usw. Optimierungen durch den Compiler ausgeführt werden könnten. Weiters kann diese template class von einer IRQHandler<structType, pointerToHardware> erben welche als statischen Parameter den Pointer zur template class hat, und somit in einer Interrupt Service Routine einfach z.b. IRQHandler<structType, pointerToHardware>::handle() aufrufen kann, welche intern den speziellen handler der template class aufruft.

    Was ich machen kann, ist den Pointer nicht direkt zu übergeben, sondern eine ID und aufgrund der ID den richtigen Pointer als static const anlegen.

    @hustbaer sagte in Peripheral Hardware Adresse welche mit define in C library angelegt ist in constexpr variable verwenden.:

    Du kannst auch Klassen machen die bestimmte Register lesen und/oder schreiben, und dann die Klassen als Template-Parameter verwenden.

    Ja, dazu müsste ich aber ein Framework Nachprogrammieren wo sicher einige Personenjahre an Arbeitsstunden drinstecken. Also lieber nicht. An dem Framework an sich möchte ich auch nicht zu viel ändern, denn wenn da ein Update / Bugfix kommt, dann muss ich die Erweiterungen auch manuell nachziehen und testen.



  • @godi Aha.
    ps: Würde vielleicht helfen wenn du uns verraten würdest wie dieses Framework aussieht.

    ps2:

    struct RegisterX {
        static uint32_t volatile* address() { return SE_MAKRO; }
    };
    


  • Hallo,
    Danke für eure Antworten, habe eine Lösung gefunden.

    Es handelt sich um das Atmel Software Framework bzw mittlerweile Microchip Advanced Software Framework.
    http://asf.atmel.com/docs/latest/

    Da es in diesem Framework auch eigene Interrupt nummern gibt (bzw die interrupt Nummern für ARM NVIC), habe ich diese jetzt als template parameter verwendet und den Pointer dann über diese Nummer als inline static definiert.


Log in to reply