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.

Driving GPIO, mmap slower than ioremap ?

Hi,

I am experimenting with GPIO on the dm816x evm. I am currently trying to toggle an IO pin as fast as possible. I tried two things :

  1. Manipulate the GPIO control registers directly from the kernel space using ioremap.
  2. mmap() the GPIO control registers without caching and using them from user space.

Both methods work, but the second is about 3 times slower than the first (observed on oscilloscope). I think I disabled all caching mechanisms.

Of course I'd like to get the best of the two worlds : flexibility and ease of development from user space with the speed of kernel space.

Does anybody know why the mmap() could be slower than the ioremap() ?

I attached my code, if you want to run it, you may need to do the following

  1. Adjust the makefiles to fit your environment
  2. Use the bootarg "omap_mux=sc1_data.gp0_io24=0x8"
  3. After inserting the kernel module, type "mknod /dev/ti81xx-usmap c 63 0"

3386.test-gpio.tar.gz

  • Some speculation on my part. No expert on this.

    From what I gather, mmap() creates and maps virtual memory in user space to the contents of a file. The user space code will read and write to memory as though it is was reading and writing to file. The mechanism for this requires that user space access to mapped memory will cause a page fault exception. The exception handler will transfer between mapped and file. I assume in your case, the file is "/dev/mem" which does the actual access to the GPIO controller memory. I think the extra processing time is for the exception handling and passing though all the file ops code.

    I think ioremap() configures maps virtual memory to physical memory using just the HW MMU. Accesses to virtual addresses will be translated tp physical addresses by the MMU. I think the "/dev/mem" will have the ioremap(). My guess anyways.

    Maybe try the "/sys/class/gpio" interface from userspace. I vaguely remember posts on ths forum that even with "Base Metal" code, that the GPIO controller is relatively slow in toggling a GPIO line.

  • Sorry for my late reply, I was experimenting with your ideas.

    Norman Wong said:
    The mechanism for this requires that user space access to mapped memory will cause a page fault exception. The exception handler will transfer between mapped and file. I assume in your case, the file is "/dev/mem" which does the actual access to the GPIO controller memory. I think the extra processing time is for the exception handling and passing though all the file ops code.

    I don't think that is correct. I do the mmap on my kernel module (source attached in question) which uses io_remap_pfn_range. As I understand this function, it writes some entries in the process's translation table. I don't think there is any software handling on read / write to the mmaped memory region, that would kill the whole purpose of mmap.

    Norman Wong said:
    I think ioremap() configures maps virtual memory to physical memory using just the HW MMU. Accesses to virtual addresses will be translated tp physical addresses by the MMU.

    Agreed.

    Norman Wong said:
    I think the "/dev/mem" will have the ioremap()

    I don't get it, what do you mean ?

    Norman Wong said:
    Maybe try the "/sys/class/gpio" interface from userspace. I vaguely remember posts on ths forum that even with "Base Metal" code, that the GPIO controller is relatively slow in toggling a GPIO line.

    I have tried that, but it is many times slower than my "ineffective" mmap solution.

    Thanks for your help.

  • The driver code behind "/dev/mem" is in "drivers/char/mem.c". There is probably a ioremap() call in there somewhere. Buried deep down.

    I am considering the usage of mmap with real files on media. In that case, mapped memory accesses would require some code to move data back forth from the file to mapped memory. It would need to this one the fly as the mapped memory is likely just a page in size and less than the file size. The mmap implementation would not be able to tell the difference between a real file and /dev/mem. The media driver would read and write media. The /dev/mem driver would read and write physical memory.