• 0
Victor

Access to the GPIO with the API

Question

Posted (edited)

Hello all,

I did access to the GPIOs under SDK with the following program:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

#define GPIO_0_out  0x41200000          //  GPIO_0 output custom 4bits      // 4 LEDs

#define GPIO_0_in     0x41200008          //  GPIO_0  input custom 4bits         // 4 Buttons

int main()
{

  unsigned char temp;

..................................................

*(unsigned int*)(GPIO_0_out | 0x0004) = 0x00000000;  // configure GPIO_0_out as output
*(unsigned int*)(GPIO_0_in | 0x0004) = 0xFFFFFFFF;       // configure GPIO_0_in as input

..................................................

    temp = *(unsigned char*)(GPIO_0_in);
    *(unsigned char*)(GPIO_0_out) = temp;

   return 0;

}

 

But under Petalinux direct access to the phisical address does not works.

Please help find the API functions
- for setting mode of the GPIO port;
- for writing to GPIO port;
- for reading from GPIO port.


Thank you.

Best regards,

Victor

Edited by Victor

Share this post


Link to post
Share on other sites

14 answers to this question

Recommended Posts

  • 0
On 4/20/2020 at 4:10 AM, Victor said:

But under Petalinux direct access to the phisical address does not works.

I'm not competent to lecture on software best practices but this topic merits discussion. Perhaps a few comments will kick one off and lure people better qualified than me to participate.

There are ways of accessing hardware from software applications in just about anyway you choose. That doesn't mean that hey are all ideal or even acceptable. As a rule, using well worn libraries are preferred. In general they are not the fastest or the easiest or most simple way to interact with hardware. For safety, consistency, and  orderliness they are better than reference by address.  One concept is hard to argue against. If there is a possibility that another application or process has access to the same hardware then direct manipulation of hardware is a very dangerous thing to do. For some embedded projects you are guaranteed that only your code is running. This doesn't mean that direct access is a wise choice, especially if you have levels of interrupts running. For embedded systems that have an OS or RTOS where hardware is specifically isolated from end user applications by design, direct access of hardware is rather foolish because you have no control over what code the processor(s) is running a any given instant. Worse yet direct manipulation of hardware creates a situation in which neither you nor your OS can know what the state of your hardware is at any given moment. You can always alter your OS by adding kernel mode drivers if the standard ones don't fit your needs. The bottom line is understand the consequences for your design choices and code safely. You are guaranteed to pay for bad choices. For software development a general rule of thumb is that if what you are doing is direct and simple then it's likely a bad idea.

Share this post


Link to post
Share on other sites
  • 0

@Victor,

Either you like my pronouncement that I'm incompetent or you like my thoughts on software development.... it's hard to tell. But either way I win so if you're happy, so am I. :)

Evidently, my work here is done.

Share this post


Link to post
Share on other sites
  • 0

@zygot

Thank you.

I  know that OS (acept similar to DOS may be)  isolates HW from end user applications,

but it does not help me to resolse simple (as I thought earlier) task:  

- to setting mode of the GPIO port;
- to write data to the GPIO port;
- to read data from GPIO port.

Share this post


Link to post
Share on other sites
  • 0

Hello Cristian

it is enought  redundant way for me to use the interrupts.

I intend to use only usual polling.

Can you  suggest me  how to resolve this task with  the ready to use program example  for Petalinux? 

Thank you

Share this post


Link to post
Share on other sites
  • 0

Hi @Victor,

Your question is more of a general Linux programming question than a particular Petalinux one. 

Like zygot mentioned, it's better to use the drivers when there are drivers to be used. If you have a custom IP or one that dose not have a driver, UIO is your friend. GPIOs are simple enough for them to have one and generally have it loaded (petalinux does that automatically when it finds a GPIO in the imported .hdf). Here is a simple example of how to write a C code using the driver and how it interconnects:

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842398/Linux+GPIO+Driver

-Ciprian

Share this post


Link to post
Share on other sites
  • 0

Hello @zygot, @Ciprian

I had no intend to use direct access to GPIO within Petalinux.

Earlier I used ready to use driver in Debian.
E.g. for PCIe it was only 2 things for using the registers
(that were connected to GPIO and so could be controlled with the processor):
1) within the Debian:
   root...> insmod xbmd.ko
2) in the user program:
   #include "xbmd.h"

   .................

uint32_t XPCIe_ReadReg (int fd,uint32_t dw_offset){
    io_struct_VC707 q_reg;
    q_reg.MemAddr=dw_offset;
    if(ioctl(fd,WRITE_STRUCT,&q_reg)<0){
            printf("Error ioctl  WRITE_STRUCT \n");
        }
    if(ioctl(fd,READREG,&q_reg)<0){
                printf("Error ioctl  READREG \n");
        }
   return q_reg.ValueAddr;
}

void XPCIe_WriteReg (int fd,uint32_t dw_offset, uint32_t val){
     io_struct_VC707 q_reg;
     q_reg.MemAddr=dw_offset;
     q_reg.ValueAddr=val;

     if(ioctl(fd,WRITEREG,&q_reg)<0){
                     printf("Error ioctl  WRITEREG \n");
     }
}
......................

int main(int argc, char** argv){
    int df = open( "/dev/vc707_wo_dma", O_RDWR);
    uint32_t reg
 
   if(df>0){
    reg = XPCIe_ReadReg(df,(0x3E));
    XPCIe_WriteReg(df,(7),reg);    
   }

close(df);
}

No more.

I understand that Petalinux is far from Ubuntu, Debian or Raspbian(embedded Linux),
but there is a very much steps to use the HW under one. 
First of all each of these steps necessary deeply to understand.
It will take a lot of time.
Of course it is my problem, but hundred FPGA designers are forced to learn oneself 
the steps that will not necessary for them in the main work. 

For example in this reference
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842398/Linux+GPIO+Driver

1)
Kernel Configuration
To enable GPIO in the kernel, the following configuration options need to be enabled:

CONFIG_GPIO_SYSFS=y
CONFIG_SYSFS=y
CONFIG_GPIO_ZYNQ=y

Where I have to use these strings ?
In the Petalinux configuration process ?
In which step ?
What is the "y" ?

2)
Devicetree

[email protected] {
               #gpio-cells = <2>;
               #interrupt-cells = <2>;
               compatible = "xlnx,zynq-gpio-1.0";
               clocks = <&clkc 42>;
               gpio-controller;
               interrupt-controller;
               interrupt-parent = <&intc>;
               interrupts = <0 20 4>;
               interrupt-controller;
               #interrupt-cells = <2>;
               reg = <0xe000a000 0x1000>;
       };

Where should I use these strings ?
In the application program ?
What means the expression 
"[email protected]"
I did not met them in the C earlier.

3)
Using the GPIO driver from User Space
Figuring out the exact GPIO was not totally obvious when there were multiple GPIOs in the system. One way to do is to go into the gpiochips in /sys/class/gpio and view the label as it should reflect the address of the GPIO in the system. The name of the chip appears to be the 1st GPIO of the controller.

> [email protected]_2:~# cd /sys/class/gpio/
  /* For ZynqMP */
> [email protected]_2:/sys/class/gpio# ls
  export    gpiochip306    gpiochip322    gpiochip338    unexport
.............................................................
> [email protected]_2:/sys/class/gpio# cat gpiochip906/label
  zynq_gpio
  The above line indicates that gpio 0th pin starts from 906 and ends at 1023 (GPIO has total 118 pins for Zynq)

What is the
"gpiochip338" ?

4)
Demo Application

#include <stdio.h>
.....................
#include <linux/input.h>
  
#define LED_BRIGHTNESS    "/sys/class/leds/led-ds23/brightness"
#define    LED_TRIGGER    "/sys/class/leds/led-ds23/trigger"
#define    INPUT_EVENT    "/dev/input/event0"
#define    LED_MAX_SPEED    10
#define    PERIOD_COEFF    16000
...............................

I do not understand how to tell for Petalinux phisical addresses of the LEDs and Buttons
that in the SDK were described as:
#define GPIO_0_out  0x41200000            // 4 LEDs
#define GPIO_0_in     0x41200008           // 4 Buttons

etc,etc.


Excuse me for the extra questions.
I searched the step by step instruction how to use HW in Petalinux.
Now I have lot of difficulties in this way because I have not enought skills in the embedded SW.

Thank you.

Best regards,
Victor.

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)
2 hours ago, Victor said:

I do not understand how to tell for Petalinux phisical addresses of the LEDs and Buttons

You don't want to do that in any OS, including a Linux varitety.

2 hours ago, Victor said:

Now I have lot of difficulties in this way because I have not enought skills in the embedded SW.

Well, not just embedded SW, but Linux. I'm no Linux developer though I have done some interesting things. There are a number of kernel mode libraries that you might be able to add to your FPGA Linux installation. As @Ciprian mentioned UIO is one. There's also MRAA, ADI Libiio and many many others. You can also access hardware as a device in Linux. Linux is a vibrant and open ecosystem. Unfortunately, this means that anyone wanting to do Linux development has a LOT of reading and preparation ahead of them. That's just the way it is.

Be aware that most Linux distributions using recent kernel versions use systemd. This is another wrinkle.

Sorry that there's no shortcut to figuring this all out. You will just have to put in the work to research tutorials and educational material. On the positive side there are lots of sources for this information. Learning embedded SW best practices in Linux is not a bad way to go, even though not many distributions are aimed at real time embedded applications.

My advise is to narrow your internet searches to 'low-level Linux', 'embedded Linux', and similar phrases until you hit a site with information that's understandable and helpful for you.

Since you are struggling, you might just stick to Xilinx standalone SDK development until you feel confident. Adding the complexity of Linux and the development flow won't make this easier.

 

Edited by zygot

Share this post


Link to post
Share on other sites
  • 0

Dear  @ zygot

>You don't want to do that in any OS, including a Linux varitety.

Where can I find concrete GPIOs  (used in my own FPGA design)  within the Petalinux ?

 

>Since you are struggling, you might just stick to Xilinx standalone SDK development until you feel confident. Adding the complexity of Linux and the development flow won't make this >easier.

I have no  problems in the application programs using GPIO within SDK.

Petalinux is necessary me for supporting hi-level interfaces on Zibo-Z7-10,  for using the programs suporting the Internet and some another useful programs.

These interfaces are: 

- Ethernet (Xilinx driver in the SDK do not supports them on Zibo because of it was writen for another phisical level chip);

- USB;

Thank you.

Best regards,
Victor.

 

 

 

Share this post


Link to post
Share on other sites
  • 0
15 minutes ago, Victor said:

Petalinux is necessary me for supporting hi-level interfaces on Zibo-Z7-10,  for using the programs suporting the Internet and some another useful programs.

Well, perhaps not.

You're going to have to pick your poison. Anyway you go, you will have to do a fair amount of research. As you've found out using an OS that you didn't build, or understand what was involved with the build just presents more levels of confusion.

If you simply have to use Linux, again that's in doubt because you don't know enough to make that decision, then perhaps you should try and understand how to access hardware on the device level. While it's possible to install a version of Linux on an FPGA target learning basic Linux device programming might be easier on a Raspberry Pi or other platform. 

You don't need Linux to use Ethernet. Admittedly, FPGA vendors aren't too interested in making this easy. There are a few ways of interacting with your Ethernet MAC that don't involve normal drivers or full TCP/IP stacks.

You can waste a lot of time and energy looking for a short-cut only to discover, after lots of frustration, that it would have taken less time to just dig in and do your homework. I say this from experience...

Share this post


Link to post
Share on other sites
  • 0

Hi @Victor,

@zygot is right, you need to pick and choose what you need to do and what your options are. Besides this he is also right when he says that there are different ways of implementing control in user space for IPs. I have suggested UIO because this is the way we do it, and as far as I've seen Xilinx has some examples with it as well. 

4 hours ago, Victor said:

Excuse me for the extra questions.
I searched the step by step instruction how to use HW in Petalinux.
Now I have lot of difficulties in this way because I have not enought skills in the embedded SW.

You will most probably not find anything more detailed, in one document, which will explain everything you need to know. You need to take in to account that petalinux is a tool which simplifies an embedded linux build process (which has a lot of different components: FSBL, u-boot, bit streams, device-tree, kernel, user space, etc.) but you still need to understand how they interact and what they are in order to configure it. Once you do your research and stuff clears up you will notice that embedded linux is a powerful tool which can, on the long run, simplify many complex designs which have complicated software stacks. 

As for the "ioctl" control of a device (similar to what you have used with PCI), the driver must be written in a way that the user space API can grant you ioctl access. Either way, there are some user space libraries that can help with GPIO, like libgpiod which can be added in the petalinux rootfs from the menu. Here is a link to the features:

https://kernel.googlesource.com/pub/scm/libs/libgpiod/libgpiod/+/v0.2.x/README.md

Good luck,

-Ciprian

Share this post


Link to post
Share on other sites
  • 0

Hello @ Ciprian

I read the document in this link and tied to use  one of the command-line tools: 

[email protected]__my1:/# gpiodetect
-sh: gpiodetect: command not found

What means this reply from Petalinux ?

Thank you

Victor.

 

 

 

Share this post


Link to post
Share on other sites
  • 0

 

Hello  @ zygot

>You don't need Linux to use Ethernet. Admittedly, FPGA vendors aren't too interested in making this easy. 

It seems for me as very strange manner to promote FPGAs.

Can you gives some comments about it ?

Tnanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now