Đọc trạng thái GPIO bằng C


8

Tôi đã triển khai ví dụ này để làm quen với lập trình GPIO cơ bản trong C. Mã trình bày cách ghi vào các chân GPIO nhưng không nêu rõ cách đọc trạng thái của các chân. Tôi nghi ngờ rằng WiresPi cuối cùng sẽ là một giải pháp tốt hơn vì cuối cùng tôi sẽ muốn đọc trạng thái của pin đầu ra , nhưng trong khi đó tôi muốn hoàn thành chuyến đi của mình thông qua mã của Dom và Gert. Làm thế nào sau đó, tôi có thể đọc giá trị của một pin?


Quan tâm để giải thích các downvote?
bobthechemist

2
Các downvote là vô lý, có lẽ bạn đã làm phiền một số người tại một số điểm. +1 từ tôi chỉ để bù đắp.
goldilocks

Câu trả lời:


6

Ví dụ đó từ elinux sử dụng IO ánh xạ bộ nhớ . Nhân cũng xuất giao diện không gian người dùng thông qua /sys/class/gpio, 1 cũng được ghi lại trên elinux . Làm việc trong C bạn sẽ sử dụng mức độ thấp read()/ write()thay vì echo, rõ ràng. Không sử dụng các hàm dựa trên luồng cấp cao hơn.

Một số lập trình viên trở nên hơi khó chịu khi được yêu cầu sử dụng giao diện tệp cho những việc mà họ tin rằng nên được thực hiện với các cuộc gọi hệ thống. Đây hoàn toàn là một vấn đề về phong cách - chúng tương đương với chính xác . Không có "chi phí I / O bổ sung", v.v., truy cập một tệp trong trường hợp này vì đó không phải là tệp thực, đó là giao diện kernel. Chính xác như mọi hệ thống ABI khác bạn từng sử dụng, chỉ khác nhau. Việc sử dụng /proc/syscác nút đã được các nhà phát triển nhân ưa thích từ lâu, nhưng tôi vẫn thấy mọi người quyết tâm sử dụng các cuộc gọi hệ thống ở nơi họ có thể - ví dụ sysfs(), mặc dù thực tế đã man 2 sysfsnói rõ:

Cuộc gọi hệ thống dẫn xuất System-V này đã lỗi thời; đừng dùng nó Trên các hệ thống có / Proc, thông tin tương tự có thể được lấy thông qua / Proc / filesystems; sử dụng giao diện đó thay thế.

Đó là trang man thư viện C bảo bạn sử dụng /procgiao diện . Nếu điều đó không đủ tốt để thuyết phục bạn, thì không có gì. /syslà loại tương tự. Điểm là: chỉ vì bạn đang sử dụng một nút tập tin thay vì một số C cụ API không có nghĩa là bạn không làm lập trình thực sự, hoặc hiệu suất mà sẽ bị ảnh hưởng, vv vv Một số người có thể nói rằng nó thực sự là một đẹp tính năng. Đây cũng là phương pháp được đề xuất bởi những người đã viết kernel OS.

Giới thiệu nhanh về giao diện GPIO có thể được tìm thấy trong [kernel-src]/Documentation/ABI/testing/sysfs-gpio:

  GPIOs are only made available to userspace by an explicit
  "export" operation.  If a given GPIO is not claimed for use by
  kernel code, it may be exported by userspace (and unexported later).
  Kernel code may export it for complete or partial access.

  GPIOs are identified as they are inside the kernel, using integers in
  the range 0..INT_MAX.  See Documentation/gpio.txt for more information.

    /sys/class/gpio
        /export ... asks the kernel to export a GPIO to userspace
        /unexport ... to return a GPIO to the kernel
        /gpioN ... for each exported GPIO #N
            /value ... always readable, writes fail for input GPIOs
            /direction ... r/w as: in, out (default low); write: high, low
            /edge ... r/w as: none, falling, rising, both
        /gpiochipN ... for each gpiochip; #N is its first GPIO
            /base ... (r/o) same as N
            /label ... (r/o) descriptive, not necessarily unique
            /ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)

Dường như có nhiều hướng dẫn khác nhau và trực tuyến như vậy ngoài elinux. Tôi chỉ sử dụng I2C, nếu không tôi sẽ cho bạn câu trả lời trực tiếp hơn.

Nếu bạn quan tâm đến việc viết mã không gian kernel truy cập GPIO, bạn có thể xem tại đây , mặc dù tôi nghĩ rằng nó thực sự chỉ hữu ích nếu bạn muốn viết trình điều khiển cho một thiết bị cụ thể và tạo API không gian người dùng của riêng bạn.


1. Vì IO được ánh xạ mem cũng phải sử dụng đọc / ghi, tôi không chắc liệu một phương thức này có mang lại lợi thế đáng kể so với phương pháp khác ở đây không. Sử dụng /sysgiao diện chắc chắn sẽ dễ mang theo hơn, nếu bạn đang tìm kiếm mã sẽ chạy trên những thứ khác ngoài pi mâm xôi.


Cảm ơn. Ngôn ngữ của tôi là Mathicala, vì vậy khi nó được chuyển sang RPi, tôi đã nhảy. Truy cập GPIO thông qua các lệnh Wolfram bản địa hiện tại hơi chậm chạp, vì vậy tôi đang cố gắng học đủ c để tránh cho tôi khỏi rắc rối. (vì vậy không có mã không gian kernel viết cho tôi!)
bobthechemist

read()/ write()và các chức năng mô tả tệp được liên kết (trái ngược với các luồng tệp ) thực sự không phải là Tiêu chuẩn C, nhưng chúng là POSIX và tiêu chuẩn trên linux. Có một phần giới thiệu ở đây: gnu.org/software/libc/manual/html_node/NH Các luồng tệp tiêu chuẩn có thể hoạt động, nhưng theo kinh nghiệm của tôi, chúng cũng gặp vấn đề với WRT /sys/proc; sử dụng các mô tả cấp thấp hơn không còn khó xử hay khó khăn nữa. Chúc may mắn!
goldilocks
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.