sameh4
Posts: 40
Joined: Wed Nov 29, 2017 6:58 pm

Trying to fully understand this C++ approach the Virtual GPIO Pins of the GPU

Thu Nov 30, 2017 12:10 am

Similar to many other new Bare Metal programmers with the Pi3, I have struggled for days to get a clean ACT LED blink to work. I have read many tutorials on how the CPU interacts with the LED using the Mailbox of the GPU.

I was also able to get it to work with some hacked assembly code, but of course that's not the point. I am trying to use the Pi 3 bare metal environment for learning C++.

Luckily I found this great , great, great framework that I am learning quite a bit from. https://github.com/rsta2/circle64/

In particular how he uses a GPIOVirtualPins class to handle the reading/writing. The constructor of this class does some interesting stuff

  • Gets the GPIO Base Address that starts at MEM_COHERENT_REGION == 3 MB
  • MEM_COHERENT_REGION is a calculation of kernel start at 512k + kernel size of 2MB + kernel stack size of 128k + kernel stack end
  • A Property Tags structs is initialized
  • This is where I get lost : CBcmPropertyTags::GetTag
https://github.com/rsta2/circle64/blob/ ... gs.cpp#L54


I am a little too hung up on the assert. I am not sure why he is using a bitwise & 3 there. What is he trying to defend against?

I put the structs into a single file and I ran through it by hand and here's what I've found:

Code: Select all

    # size of TPropertyBuffer = 8
    # size of TPropertyTagSimple = 16
    # size of u32 = 4
    # total = 28
    # 28 & 3 == 0 ; True

    /** code starts here **/
    typedef unsigned int u32;
    typedef unsigned char u8;
    
    struct TPropertyBuffer
    {
      u32 nBufferSize;// bytes
      u32 nCode;
      #define CODE_REQUEST 0x00000000
      #define CODE_RESPONSE_SUCCESS 0x80000000 
      #define CODE_RESPONSE_FAILURE 0x80000001
      u8 Tags[0];
      // end tag follows
    };
    
    struct TPropertyTag
    {
      u32 TagId;
      u32 nValueBufSize;// bytes, multiple of 4
      u32 nValueLength;// bytes
      #define VALUE_LENGTH_RESPONSE    (1 << 31)
      //u8ValueBuffer[0];// must be padded to be 4 byte aligned
    }
    PACKED;
    
    struct TPropertyTagSimple
    {
      TPropertyTag Tag;
      u32 nValue;
    };
    ...
    unsigned nBufferSize = sizeof (TPropertyBuffer) + sizeof(TPropertyTagSimple) + sizeof (u32);
    assert ((nBufferSize & 3) == 0);

I am new to C/C++ so I am guessing the reason the size of on the TPropertyBuffer struct is 8 is because it's a pointer?

But I am not sure why the size of the TPropertyTagSimple is 16?

Nor do I understand what the assert statement is protecting against?

rst
Posts: 311
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Trying to fully understand this C++ approach the Virtual GPIO Pins of the GPU

Thu Nov 30, 2017 11:32 am

sameh4 wrote:
Thu Nov 30, 2017 12:10 am
I am a little too hung up on the assert. I am not sure why he is using a bitwise & 3 there. What is he trying to defend against?
This assert ensures that the total size of the property tag structure is a multiple of 4 bytes. As I understand it, this is required by the firmware. See: https://github.com/raspberrypi/firmware ... -interface
I am new to C/C++ so I am guessing the reason the size of on the TPropertyBuffer struct is 8 is because it's a pointer?
No. The TPropertyBuffer struct contains two u32 fields (which is an 32-bit unsigned == 4 bytes long) and an u8 Tags array with zero elements (8-bits * 0 == 0 bytes long). The point is, that this Tags array does not reserve memory. It is only used to be able to access the address, where the actual tags have to be copied to. So the total size of TPropertyBuffer is 2*4 + 0*1 == 8.
But I am not sure why the size of the TPropertyTagSimple is 16?
TPropertyTagSimple consists of four u32 values in total (three in TPropertyTag and one in the structure itself. That is (3+1)*4 == 16.

sameh4
Posts: 40
Joined: Wed Nov 29, 2017 6:58 pm

Re: Trying to fully understand this C++ approach the Virtual GPIO Pins of the GPU

Thu Nov 30, 2017 2:08 pm

Thanks rst! That clears up a lot! Back to more reading today and hopefully new insights! I can't wait till I can digest this code, simplify it down to one or two files and actually run it just to see an LED blink :lol:

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 2 guests