This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to access individual GPIO DM355 pin through MontaVista

Hi,

How do I write code to access individual pins to say turn on a LED on the GPIO through C Code.  Is there an example for this?

Thanks in advance

  • This is a bit of a difficult question relative to how it sounds, on the positive side there is GPIO code already in the kernel tree (/arch/arm/mach-davinci/gpio.c, include/asm-arm/arch-davinci/gpio.h) however this driver code as it is does not have any user space control, it is sort of an internal driver that other drivers in the kernel can depend on. This being said, to access this from user space you would need to create a driver that leverages this existing GPIO driver with some APIs that can be accessed from user space.

    Though there is nothing official that does this, code has been written to handle just this situation, which I have attached to this post in a zip file as an unofficial example. The user_gpio.c is for a module you can insert into the kernel to give you the user space API, and the main.c is an example exercising the API from user_gpio.c in user space. This was originally done on a DM6467 so you probably want to change what pin it is trying to use as GPIO in the main.c, but the API is shown at least, at a minimum this could be used as an example for creating your own GPIO user space driver.

    This same code could be used as a base for DM6446 or DM6467 as well as DM355.

    DavinciGPIOExample.zip
  • Is this going to be this complicated to do with the DM365 as well?

  • The situation is similar for the DM365 as well.

  • In order to link this file into the kernel, what are the steps to do that?  The building is described I beleive in the Getting Started Guide, but once these C files are created, how does one link them into the kernel?

    Thanks

  • You can insert a kernel object into the kernel using the insmod command, you can actually see this done in the loadmodules.sh script that is run before running the demos as an example.

  • Hi Bernie,

                     I was trying to run the code that you have provided on a DM6467 board. I compiled it and linked it with the kernel using insmod. However, when i run it, i get the following error :

               Failed to read gpio 34

    I tried with other GPIO numbers also.But still the result was the same. Could you please let me know where i am going wrong.

    Regards,

    Afzal

  • I just had a quick look at the source code attached to this post and it appears it is providing a driver stub to allow user space application to access the kernel gpio driver included with DVSDK (only accessible by other kernel drivers).  This is a great resource to have.

    Digging a little more into the GPIO driver itself, I noticed that it assumes all muxed pin options have been properly configured to allow access to the desired GPIO pins.  This is where there is a disconnect between DM355 and DM6467; their pin-muxing is quite different and you must ensure that the GPIO pin you are trying to access is not being shared by some other important peripheral that may be enabled instead of GPIO (e.g. EMIF bus used for DDR2).

    In addition, not all GPIOs are pinned out on DM6467; for example GPIO34 which you mentioned above is not pined out.  For more details on which GPIO pins are not pinned out, please see section 7.28.1 of data-sheet. http://focus.ti.com/lit/ds/symlink/tms320dm6467.pdf

  • Thanks for the quick response .

    I have feeling that "user_gpio_ioctl ()" itself is not getting called when the ioctl call is made.

    Could it be possible that it is failing because of "/dev/user_gpio" ? .Actually i had created this using

    mknod /dev/user_gpio c 1 1

    Was that the right approach?

  • looking at the source code Bernie sent you; it appears this should be created by the driver and you should not have to type mknod.  Therefore, you might be on to something here.  You can always add printk (smilar to printf) statements at the driver level (user_gpio.c) to see if the driver is being called or not.

  • Hi Jaun,

    I compile the user_gpio.c & .h and create user_gpio.ko on DM6467 platform ok.

    BUT when I insmod the user_gpio.ko, there is no /dev/user_gpio appear !!!!

    Use lsmod I can see the module been inserted:

    Module                  Size  Used by
    user_gpio               3784  0

    What happen ?

     

    Tai

  • Tai,

    The GPIO register settings are different across DM355 and DM6467 and the code Bernie posted was meant more as reference code for writting your own GPIO driver rather than using it as a GPIO driver for all platforms.

    FYI, if you upgrade to the latest DVSDK 2.0, it includes GPIO driver for DM6467 (as well as other platforms): http://software-dl.ti.com/dsps/dsps_registered_sw/sdo_sb/targetcontent//dvsdk/mv_dvsdk/index.html

     

  • Hi Juan,

    I will try to modify the gpio driver for user mode accessable.

     

    Thank you !!

     

  • I'm using MontaVista5 and DVSDK2. I'm trying to compile user_gpio.c but am getting following error:

    root@electrobian:/opt/montaVista5/montavista/pro/devkit/lsp/ti-davinci/linux-2.6.18_pro500# make CROSS_COMPILE=/opt/montaVista5/montavista/pro/devkit/arm/v5t_le/armv5tl-montavista-linux-gnueabi/bin/ ./drivers/DaVinciGpio
    make: Nothing to be done for `drivers/DaVinciGpio'.

     

    My Makefile looks like this:

    TARGET    = user_gpio
    KDIR    ?= /opt/montaVista5/montavista/pro/devkit/lsp/ti-davinci/linux-2.6.18_pro500/drivers/DaVinciGpio

    AS        = $(CROSS_COMPILE)as
    LD        = $(CROSS_COMPILE)ld
    CC        = $(CROSS_COMPILE)gcc
    CPP        = $(CC) -E
    AR        = $(CROSS_COMPILE)ar
    NM        = $(CROSS_COMPILE)nm
    STRIP        = $(CROSS_COMPILE)strip
    OBJCOPY        = $(CROSS_COMPILE)objcopy
    OBJDUMP        = $(CROSS_COMPILE)objdump

    ${TARGET}.o: ${TARGET}.c
        $(CC) -c ${TARGET}.c

    default:
        $(MAKE) -C $(KDIR) M=$(PWD) modules
        $(CC) -o gpioApp main.c

    clean:
        rm -rf *.ko *.o *.mod.c .tmp_versions *.symvers gpioApp reg led

    Is any tweaking needed in code or does it get compiled out of box?

  • As I suggested earlier, "the code Bernie posted was meant more as reference code for writting your own GPIO driver "; this was back when there was no GPIO driver included in our DVSDK release.  DVSDK 2.0 should have a GPIO driver available so you may not need to write or port one on your own.  However, if you do find to need to write your own, the above code has not been tested with DVSDK 2.0 or MV-Pro-5 so it is only offered as reference code.

  • Hi Juan,

    I'm on an DM365 and have a need to control a GPIO. How does one find the documentation to use this driver? How would I even know if my kernel supports it? Is there any example code? Are there any Wiki articles (I find these to be the most useful). Are we expected to search through the code for the correct files? I'm just really confused as to the expectations TI has for developers of this platform.

    Can you also describe when the pin muxing occurs? For instance I can imagine changing the mux on a pin to an output but how do I guarantee that this is not clobbered by other code? I'm wondering if there is a central place where the pin mux is set for everything.

    Thanks,

    Ken

  • Hello , there is some one that you have a solution for the driver gpio dm365 , i don't see the user_gpio in the dev directory  , so i have "Failed to open device"

    Thanks

  • Please help me! I have no experience to write own driver. Does anyone find GPIO driver for dm355 in DVSDK 2.0 (LSP2.0 v1.4.0) and documentation for it?

  • Alexey Yakovlyev said:
    Does anyone find GPIO driver for dm355 in DVSDK 2.0 (LSP2.0 v1.4.0) and documentation for it?

    Did you take a look at the post from Bernie Thompson earlier in this thread?  He provided some example code for using the GPIO pins.  The driver used in the kernel is located in the LSP directory under /arch/arm/mach-davinci/gpio.c and include/asm-arm/arch-davinci/gpio.h.  There is also some documentation in the LSP directory under /Documentation/gpio.txt.

  • Hi All,

    I have the same problem (I am working with DM365) pointed out by others in this thread: the user_gpio module is loaded but I don't have any device 

    /dev/user_gpio ,

    and, of course, I can not open the device.

    Someone has found a solution?

     

     

     

     

     

  • Hi, this code compiles well and the module is loaded but for some reason I can not see the installed device (under /dev/), and when I run the application fails to open.

    I see I am not the only with this issue, and at the moment I am still struggling in the dark: maybe someone has fixed or found a solution for this.

  • Hi, I am using the user_gpio module with the DM365 and I have been encountering some strange issues that I've tracked down to this module.  My application polls (well, reads in a loop with a small delay) a gpio input in one thread, and it is possible to read or write a gpio from another thread.  The gpio operations work fine, but I was seeing Resizer_execute lockups and Venc1_process lockups intermittently.  When I disabled the gpio thread, the problems went away.  I found that adding a mutex lock during the user_gpio module read and write functions was the correct solution to allow multithreaded gpio access.  If there is a better solution, please let me know.

  • Hi there

        I've also been looking at this module recently. It seems to me that you do need to create the device node(s) yourself. See, for example, this part od 'Linux Device Drivers, Rev. 3':

    http://www.makelinux.net/ldd3/chp-3-sect-2.shtml

    Which has an example of a script to load a driver (via insmod) and create the device nodes as well.

    I'm just looking at creating some similar scripts for user_gpio.ko on the DM365

        Hope this helps

        Jon N

     

  • Hi All,

     

    After the driver is compiled and you have insmod the driver (.ko file), then you have to do mknod by yourself and the format is

     

    mknod <driver_name> <type> <Major_number> <Minor_number>

     

    hope this helps......

     

    Thanks,

    Lokesh

  • I'm not an expert in this, but it seems to work doing the following:

    $> insmod user_gpio.ko

    $> more /proc/devices

    Note the major number (250 in my case)

    The minor number is set in the file user_gpio.c by the function "alloc_chrdev_region" as 0.

    $>mknod /dev/user_gpio 250 0

    Now run the user space example and it should work.

     

    -Brad

  • Hi ,

    There is a small correction i want to make....

    Instead of this

    $>mknod /dev/user_gpio 250 0

    you have to follow

    $>mknod /dev/user_gpio c 250 0

     

    here "c" stands for the type of the driver you are inserting....

     

    Thanks,

    Lokesh

  • Version linux-2.6.18_pro kernel is quite old. Recent versions of the mainline kernel have established a "official" way to handle GPIOs from user space. The linux-2.6-33-rc4 kernel of DVSDK3.2 has this GPIO driver. This version also includes edge notification. Backporting from 2.6.33 to 2.6.18 probably would not be easy but at least the your user space app will be compatible with the future versions of the mainline kernel. If you can, better to move to DVSDK3 or newer and from Montevista to Codesourcery.