Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How should I manage my register addresses and expose some of them properly and ensure consistency?

How should I manage my register addresses and expose some of them properly and ensure consistency?

Scheduled Pinned Locked Moved C / C++ / MFC
collaborationhelpquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    arnold_w
    wrote on last edited by
    #1

    My product has registers that are accessed via addresses:

    #define MY_REG_0 ((uint32_t)0)
    #define MY_REG_1 ((uint32_t)1)
    #define MY_REG_2 ((uint32_t)2)

    Some of these registers (but not all!) need to be shared with another product and I have put them in a common git submodule:

    #define MY_PRODUCT_MY_REG_1 ((uint32_t)1)

    Is this the recommended way to do it? I would like to have a macro

    CHECK_ADDR_MACRO(MY_REG_1, MY_PRODUCT_MY_REG_1);

    that generates static_assert compile time error if: a) MY_REG_1 and MY_PRODUCT_MY_REG_1 are not equal. b) Neither MY_REG_1 or MY_PRODUCT_MY_REG_1 are defined (the register was removed, but someone forgot to remove the check. Can someone please recommend a way to implement the macro CHECK_ADDR_MACRO?

    D 1 Reply Last reply
    0
    • A arnold_w

      My product has registers that are accessed via addresses:

      #define MY_REG_0 ((uint32_t)0)
      #define MY_REG_1 ((uint32_t)1)
      #define MY_REG_2 ((uint32_t)2)

      Some of these registers (but not all!) need to be shared with another product and I have put them in a common git submodule:

      #define MY_PRODUCT_MY_REG_1 ((uint32_t)1)

      Is this the recommended way to do it? I would like to have a macro

      CHECK_ADDR_MACRO(MY_REG_1, MY_PRODUCT_MY_REG_1);

      that generates static_assert compile time error if: a) MY_REG_1 and MY_PRODUCT_MY_REG_1 are not equal. b) Neither MY_REG_1 or MY_PRODUCT_MY_REG_1 are defined (the register was removed, but someone forgot to remove the check. Can someone please recommend a way to implement the macro CHECK_ADDR_MACRO?

      D Offline
      D Offline
      Daniel Pfeffer
      wrote on last edited by
      #2

      If you have common functionality in two products, what's wrong with abstracting the common functionality into a shared module (or library)? You then have only one definition to worry about, and don't need this macro at all. The bonus is that the code need be maintained once only. If the products have different functionality but happen to share the same register numbers, they are two different products.

      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

      A 1 Reply Last reply
      0
      • D Daniel Pfeffer

        If you have common functionality in two products, what's wrong with abstracting the common functionality into a shared module (or library)? You then have only one definition to worry about, and don't need this macro at all. The bonus is that the code need be maintained once only. If the products have different functionality but happen to share the same register numbers, they are two different products.

        Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

        A Offline
        A Offline
        arnold_w
        wrote on last edited by
        #3

        It's not common functionality, they are products that can be connected/disconnected on the fly and they have a bus in between them (when connected). The register set I want to expose to the other product is a subset of all the registers, that are only available to an administrator PC-application via a USB-cable. In the shared h-file I also have some structs and enums that are needed to understand what the bytes in the different registers mean.

        L 1 Reply Last reply
        0
        • A arnold_w

          It's not common functionality, they are products that can be connected/disconnected on the fly and they have a bus in between them (when connected). The register set I want to expose to the other product is a subset of all the registers, that are only available to an administrator PC-application via a USB-cable. In the shared h-file I also have some structs and enums that are needed to understand what the bytes in the different registers mean.

          L Offline
          L Offline
          leon de boer
          wrote on last edited by
          #4

          It doesn't change what he said generally you want to abstract the interface to functionality not physicality ... you are connecting things. You are doing "things" when you have to access the registers, you don't just randomly decide to access the registers. At the moment you are worrying so much about the physical you aren't even thinking about the functionality. If you consider something like ReadFile or WriteFile they are functions, yet they can whack all sorts of registers from COM port, USB drives, SATA drives. You don't have to provide registers to those functions it works it out from the name and it is all nicely hidden behind the interface. Even consider ethernet socket programming, lots of registers getting used but not once do you ever deal with them. You deal with functionality connect, listen, send, poll etc. If you consider Linux and Windows and how complex they are they never expose registers outside the driver and the driver interface is purely a functional api. Granted they have the added problem they may need to share registers between threads/tasks etc but that is just another reason to hide register access below a functional abstraction. So stop and think what functionality are you doing when you need to whack the registers and can you make a nice functional interface that hides the registers into a common block so they don't ever have to be exposed.

          In vino veritas

          A 1 Reply Last reply
          0
          • L leon de boer

            It doesn't change what he said generally you want to abstract the interface to functionality not physicality ... you are connecting things. You are doing "things" when you have to access the registers, you don't just randomly decide to access the registers. At the moment you are worrying so much about the physical you aren't even thinking about the functionality. If you consider something like ReadFile or WriteFile they are functions, yet they can whack all sorts of registers from COM port, USB drives, SATA drives. You don't have to provide registers to those functions it works it out from the name and it is all nicely hidden behind the interface. Even consider ethernet socket programming, lots of registers getting used but not once do you ever deal with them. You deal with functionality connect, listen, send, poll etc. If you consider Linux and Windows and how complex they are they never expose registers outside the driver and the driver interface is purely a functional api. Granted they have the added problem they may need to share registers between threads/tasks etc but that is just another reason to hide register access below a functional abstraction. So stop and think what functionality are you doing when you need to whack the registers and can you make a nice functional interface that hides the registers into a common block so they don't ever have to be exposed.

            In vino veritas

            A Offline
            A Offline
            arnold_w
            wrote on last edited by
            #5

            My product is quite low-level, i.e. I'm setting up impedances, gains, current limiters, bias voltages, differential signal on/off, generating PWM signals, etc. Also, communication protocols are cascaded, for example a PC is transmitting a USB-packet to a microcontroller, who in turn forwards this over an SPI-bus to another microcontroller, who in turn forwards this over a CAN-bus, etc and then an ACK/NACK-packet has to travel the opposite direction. So, to have "local" interfaces between different microcontrollers would make this packet forwarding extremely confusing. Especially the CAN-bus is a bit troublesome because of the limited payload size (8 bytes/packet and no, we can't use the improved version that clocks the data faster) and sometimes I need to send several kBytes of data.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups