We have upgraded the community system as part of the upgrade a password reset is required for all users before login in.

C++ raw GPIO?

  • Hello!

    I was wondering if there were a good example somewhere of just plain old pin output high/low in C or C++? I read through the fast-gpio code and almost almost could see what was going on, but there were so many layers of abstraction and other things that I don't need right now (input, pwm, irq, etc). I'd like to not use a library and just have a bare bare bones example to work from. Admittedly I'm new to C/C++ but am doing this project to learn a bit more; this is a stumbling block. I'm able to cross compile and run hello worlds all that, and I do want to use C++ over Python or shell scripts - this is a learning project. : )

    In the end what I'm trying to do is write a driver for those old sparkfun cell phone lcds, basically bit banging a few pins high low high low high low - I know it's not the most efficient way of doing it, but that seems like the best place to start tinkering. Even an address map or something would be helpful. On RISC devices I've always liked how I could just point a pointer to an address and flip a pin on or off. That may not be the case here, but it's all I know right now.

    Thank you so much for taking the time to read this!

  • On a build were /dev/mem worked (which is to say, not the current ones) you could access GPIO registers in much the manner you are thinking of. Or even more so if you write kernel-mode (driver) code.

    The other approach, slower and more indirect, is to use the /sys/class/gpio nodes, which basically act like text "files" to which you literally write() ascii characters like '1' and '0'... don't laugh, it works nicely with cat and echo from shell scripts, and is also fairly portable - you'll find comparable guides for the raspberry pi, beaglebones, etc. This incidentally does work despite the present /dev/mem issues, those those mean a lack of access to the pinmux so it only works for pins that are in GPIO mode from boot.

  • @Travis-Hyyppa said in C++ raw GPIO?:


    I was wondering if there were a good example somewhere of just plain old pin output high/low in C or C++?

    You may be interested in the suite of C/C++ libraries and programs I have published here: https://github.com/KitBishop/Omega-GPIO-I2C-Arduino - complete with reasonable documentation and instructions

    Currently these are specifically for the Omega1 and will need some modifications for the Omega2 - I will be doing this at some time but not sure when

  • @Chris-Stratton Ah, I hadn't considered the fact that a "file system" based approach could be portable. That could be a plus! I suppose if I abstracted the bit flipping enough later down the line I could swap it out for raw memory access.

    @Kit-Bishop I actually looked through your code before posting and it was the closest thing to what I was looking for. Very clean stuff, but it's polished and abstracted to the point of feeling like a full library - I couldn't prune the dirty bits out of it. hah GPIOAccess seems like where I would find that raw pin access? My eyes kind of glazed over when I hit line 106.

    #define WRITEREG(regOff, regVal) (*(regAddress + regOff) = regVal)
    #define READREG(regVal, regOff) (regVal = *(regAddress + regOff))
    #define SETBIT(regVal, bit, val) (regVal ^= (-val ^ regVal) & (1 << bit))
    #define GETBIT(regval, bit) ((regval >> bit) & 0x1)

    Is very very close to what I'd like to do, I just don't know where to find the registry addresses.

    Thank you both for your replies!

  • @Kit-Bishop Using your code I think I've boiled it down to the bare minimum required to get an led to toggle. Sharing in case anyone else may need an idea (if that's okay with you?)

    (keep in mind i'm new to C++ so this might break a ton of rules and leak memory like a sieve!)

  • @Travis-Hyyppa could you please provide a few basic steps on compiling your code including any opkg packages required that are not included in the firmware as standard?

  • @Costas-Costas the approach chosen by Kit and now Travis won't work on standard firmware until the /dev/mem issue is fixed.

  • @Chris-Stratton Yeah, I'm not sure if it will work on every device, mine is a fresh out of the box Omega 1 that hasn't had its firmware updated.

  • Sorry, easy to fall into a false assumption that everyone is now talking about Omega2.

    The /dev/mem issue is with current builds for the Omega2, not Omega1.

    Were it not for that, the same techniques could apply, but the actual registers would be different for the MT7688 chip on the Omege2 vs the AR933x on the Omega1

  • @Chris-Stratton Very good to know! Thank you!

  • @Costas-Costas I actually followed the guide written by @Kit-Bishop which you can find here. I don't have any packages installed on the omega and no weird dependencies. This is for the omega 1.

    I'm still toying with everything, but I've put what I have right now on github for you. The cmake file links paths to my local system, so that'd need to be changed for sure.

  • @Chris-Stratton said in C++ raw GPIO?:

    @Costas-Costas the approach chosen by Kit and now Travis won't work on standard firmware until the /dev/mem issue is fixed.

    Yes, one of the many reasons that I am holding off upgrading the code to Omega2
    The other main constraint (other than time availability) is that the endianess differs on the Omega1 and Omega2 and I need to check out the places where this is significant in the code (I know of at least one place)

Log in to reply

Looks like your connection to Community was lost, please wait while we try to reconnect.