Direct Access to Ports

  • Hello,


    Have you already seen our digitalio driver ? With this driver you can set/clear/read I/O pins at connector J5. It is also possible to use I/O pin as interrupt.
    Regards
    Holger

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Quote from "froelich"

    Hello,


    Have you already seen our digitalio driver ? With this driver you can set/clear/read I/O pins at connector J5. It is also possible to use I/O pin as interrupt.
    Regards
    Holger


    Dear froelich
    I saw your document for working with DIO and wrote a sample code like that document, but i saw read from (or Write to) DIO with "ReadFile"(or "WriteFile") is very slow for my application in addition I would like using NetDCU board for multitasking purpose and "WaitForSingleObject" is pooling not real interrupt.
    I would like access to ports and interrupt pins directly.
    I'm very appreciate if you lead me.
    Thanks

  • Hello,
    What are your timing requirements ?
    I think WaitForSingleObject() is very fast when your thread has high priority.
    Regards
    Holger

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Quote from "hamid"

    I would like access to ports and interrupt pins directly.


    Well the problem is that different GPIOs of the microcrontroller are used internally for different purposes, not just the external GPIO that you see. When accessing the (internal) ports, you have to make sure, that your access does not interfere with the internal access of other device drivers using the other pins.


    So you can't just read and write the processor registers, but you *must* call some functions providing mutual exclusive access. There is no way of avoiding this or the board will eventually crash. And exactly this mutual exclusive access is provided by our DIO driver. Therefore I can't see how you can get much faster by direct access to the GPIO.


    Regards,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Dear keller
    I would like send data to DIO at least with 100kHz but I can not do it.
    Max frequency of DIO is 15.6kHz and it is vely slow for me.
    could you tell me how can I acces to DIO Faster than that?
    Thanks

  • Quote from "hamid"

    I would like send data to DIO at least with 100kHz but I can not do it.
    Max frequency of DIO is 15.6kHz and it is vely slow for me.


    Here you see one disadvantage of using an OS. Let me explain this a little bit more.


    The main problem is that the processor of the NetDCU8 has no special set and clear commands for the individual GPIO port bits. It only has port data registers. To set a single bit, you have to read the data register, add the new bit by OR, then write back the data register. To clear a single bit, you have to read the data register, remove the bit by AND, then write back the data register. Therefore all accesses are Read-Modify-Write cycles. These accesses have to be atomic. They must not be interrupted before having successfully modified the register.


    If you don't use an OS, this is easy. Simply disable all interrupts, do the Read-Modify-Write access, enable the interrupts again and you're done. This is very fast.


    Now when you do use an OS, disabling interrupts in a user space program is strictly forbidden. Only the kernel is allowed to do this. There are other means of synchronising things, like mutexes and critical sections. But all these data structures have in common, that they must be shared by everybody who wants to access them. As the GPIO pins must be accessed by almost every driver, the best place to do this is within the kernel.


    Now let's exercise an example. What happens when you access port 1 of GPIO. Even as this port only has 4 valid bits, they are located in two different internal port registers, namely Port E and Port G. Now when you write a new value to this port 1, the context is switched from your user space program to the driver program. There the corresponding masks for Port E and G are computed. Then Port E is modified by calling an Atomic Read-Modify-Write function in the kernel. This happens immediately again, when changing port G. Then the driver is done and returns to the user program.


    So there are 6 context changes:


    1. user program to driver
    2. driver to kernel (for port E)
    3. kernel to driver
    4. driver to kernel (for port G)
    5. kernel to driver
    6. driver to user program


    These context switches are the slow part of the whole process. And as I already explained, you can't get rid of the kernel call for the atomic Read-Modify-Write cycle.


    Quote

    could you tell me how can I acces to DIO Faster than that?


    Well it depends a little bit on your application. If your access uses several port bits at once, I see no way other than writing your own device driver.


    But if your access is restricted to one single pin, there is a way of directly setting, clearing and reading a port bit by DeviceIoControl() and codes IOCTL_DIO_SET_PIN, IOCTL_DIO_CLR_PIN and IOCTL_DIO_GET_PIN. Simply give the pin number in the lpInBuffer of DeviceIoControl().


    The pin number is the sum of the bit number and the port number multiplied by 8. For example to modify Pin 11 of connector J5, look at the table in the NetDCU device driver document. It shows that this is bit 2 of port 1. So the pin number is 2 + 1*8 = 10.


    So the call to set this pin would be:

    Code
    1. BYTE pin = 10;
    2. DeviceIoControl(hDev, IOCTL_DIO_SET_PIN, &pin, 1, NULL, 0, NULL, NULL);


    But please keep in mind that all these solutions, even the special purpose device driver, have to call the atomic access function in the kernel, which slows down things noticeably. Really high speeds are not possible this way.


    Best regards,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.