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. Type struct question

Type struct question

Scheduled Pinned Locked Moved C / C++ / MFC
questionregexperformancediscussion
12 Posts 5 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.
  • J Jochen Arndt

    They don't share the same memory location. To do that the outer struct must be a union (see Union declaration - cppreference.com[^] ). From my point of view you are right that it looks like a definition for shared access and that is an error in the documentation. To verify this have a look at the register specifications in the data sheet.

    S Offline
    S Offline
    samzcs
    wrote on last edited by
    #3

    How about this struct:

    typedef struct {
    struct {
    u32_T ASID:10, /* Bit 0-15, Address space identifier */
    rsvd1:22; /* Bit10-31, reserved */
    } asid; /* ASID, 32-bit access */
    } ASID_T;

    it can implement the 32-bit access and bit access, right?

    J 1 Reply Last reply
    0
    • S samzcs

      How about this struct:

      typedef struct {
      struct {
      u32_T ASID:10, /* Bit 0-15, Address space identifier */
      rsvd1:22; /* Bit10-31, reserved */
      } asid; /* ASID, 32-bit access */
      } ASID_T;

      it can implement the 32-bit access and bit access, right?

      J Offline
      J Offline
      Jochen Arndt
      wrote on last edited by
      #4

      With that you have no access to the 32-bit value. Use a union instead:

      typedef union {
      u32_T asid; /* ASID, 32-bit access */
      struct {
      u32_T ASID:10, /* Bit 0-15, Address space identifier */
      rsvd1:22; /* Bit10-31, reserved */
      };
      } ASID_T;

      S 1 Reply Last reply
      0
      • J Jochen Arndt

        With that you have no access to the 32-bit value. Use a union instead:

        typedef union {
        u32_T asid; /* ASID, 32-bit access */
        struct {
        u32_T ASID:10, /* Bit 0-15, Address space identifier */
        rsvd1:22; /* Bit10-31, reserved */
        };
        } ASID_T;

        S Offline
        S Offline
        samzcs
        wrote on last edited by
        #5

        can't use union, MISRA-C rule 18.4, forbid to use union.

        J M 2 Replies Last reply
        0
        • S samzcs

          can't use union, MISRA-C rule 18.4, forbid to use union.

          J Offline
          J Offline
          Jochen Arndt
          wrote on last edited by
          #6

          Then use what you need in your code (struct or u32_T). As last resort you can also use casting:

          /* A pointer to ASID_T struct */
          ASID_T *asid = ASID_REG_ADDR;
          /* Cast it to a pointer to 32-bit reg value */
          u32_T *asidReg = (u32_T*)asid;

          L 1 Reply Last reply
          0
          • S samzcs

            can't use union, MISRA-C rule 18.4, forbid to use union.

            M Offline
            M Offline
            Munchies_Matt
            wrote on last edited by
            #7

            SO use pointers.

            1 Reply Last reply
            0
            • J Jochen Arndt

              Then use what you need in your code (struct or u32_T). As last resort you can also use casting:

              /* A pointer to ASID_T struct */
              ASID_T *asid = ASID_REG_ADDR;
              /* Cast it to a pointer to 32-bit reg value */
              u32_T *asidReg = (u32_T*)asid;

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

              From memory that breaks several other MISRA-C rules under section 11 ... 11.1 through 11.6 restrict what you can do with C casts. Hardware related implementations usually involve coding that MISRA rules see as "dangerous". I can tell you from experience the easiest way around them is drag it down to included assembler blocks. The assembler blocks fall outside the scope of MISRA. You could define two different extern's in a .h file to the same register with assembler which would essentially restore the use of the union yet be MISRA compliant :-)

              In vino veritas

              J 1 Reply Last reply
              0
              • L leon de boer

                From memory that breaks several other MISRA-C rules under section 11 ... 11.1 through 11.6 restrict what you can do with C casts. Hardware related implementations usually involve coding that MISRA rules see as "dangerous". I can tell you from experience the easiest way around them is drag it down to included assembler blocks. The assembler blocks fall outside the scope of MISRA. You could define two different extern's in a .h file to the same register with assembler which would essentially restore the use of the union yet be MISRA compliant :-)

                In vino veritas

                J Offline
                J Offline
                Jochen Arndt
                wrote on last edited by
                #9

                I suspected that casting may be limited too. I don't know MISRA rules well but when macros - or better - inline functions are allowed those can be used to split the 32-bit value into bits fields or vice versa.

                L 1 Reply Last reply
                0
                • J Jochen Arndt

                  I suspected that casting may be limited too. I don't know MISRA rules well but when macros - or better - inline functions are allowed those can be used to split the 32-bit value into bits fields or vice versa.

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

                  No those are still technically C and hence under MISRA rules. It's a really weird standard adopted by some automobile manufacturers and a few telco's as some sort of we will get better code think-tank. The reality is all studies have shown it has almost zero improvement on software bug numbers or severity. As I said, the few times I have run across it, I do what most do ... drop to assembler and go around the rubbish. That in itself tells you how good the standard is. Other than that you can go thru the process to raise a deviation (section 5.3.2) but that means documenting and getting approval for the variation which is far more red tape than most can handle. The standard libraries are also exempt from MISRA under a special rule 6.6 and so you can implement your own special standard library function to get around it. Think about it memcpy and memmove take void* and you have a specific register address target :-)

                  In vino veritas

                  1 Reply Last reply
                  0
                  • S samzcs

                    I read a demo code from a semiconductor producer, in cpu.h, there are some typedef structs for registers.

                    typedef struct {
                    u32_T asid; /* ASID, 32-bit access */
                    struct {
                    u32_T ASID:10, /* Bit 0-15, Address space identifier */
                    rsvd1:22; /* Bit10-31, reserved */
                    };
                    } ASID_T;

                    According to the comments, I think the writer thought he defined a struct to represent the asid register, and the struct can be accessed in 32 bit pattern or bit-field way. But, is this struct can do that, I mean, are the U32_T asid and the anonymous struct share a same memory location? I think it can't work. just want to hear some other opinions.

                    S Offline
                    S Offline
                    Stefan_Lang
                    wrote on last edited by
                    #11

                    This doesn't seem to make sense: the inner struct is just a type definition without an actual typename, but it does not define a variable of that type:

                    struct { // <-- no typedef, no tag to use as a struct identifier
                        u32\_T  ASID:10,          /\* Bit 0-15, Address space identifier \*/
                               rsvd1:22;         /\* Bit10-31, reserved \*/
                    }; // <-- end of type specification, but no variable name
                    

                    You might just as well delete that inner struct declaration, since, being unnamed and unused, there is no way to use it later. If you move the symbol asid to the end of that type declaration, asid would be a struct, not an int, although it would occupy exactly 4 bytes, which may or may not coincide with the size of an int in your system.

                    GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                    S 1 Reply Last reply
                    0
                    • S Stefan_Lang

                      This doesn't seem to make sense: the inner struct is just a type definition without an actual typename, but it does not define a variable of that type:

                      struct { // <-- no typedef, no tag to use as a struct identifier
                          u32\_T  ASID:10,          /\* Bit 0-15, Address space identifier \*/
                                 rsvd1:22;         /\* Bit10-31, reserved \*/
                      }; // <-- end of type specification, but no variable name
                      

                      You might just as well delete that inner struct declaration, since, being unnamed and unused, there is no way to use it later. If you move the symbol asid to the end of that type declaration, asid would be a struct, not an int, although it would occupy exactly 4 bytes, which may or may not coincide with the size of an int in your system.

                      GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                      S Offline
                      S Offline
                      samzcs
                      wrote on last edited by
                      #12

                      Sure, should has a struct variable name.it's a typo.

                      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