{"id":133,"date":"2023-11-05T17:24:21","date_gmt":"2023-11-05T09:24:21","guid":{"rendered":"http:\/\/xuzhe.tj.cn\/?p=133"},"modified":"2025-05-03T09:51:52","modified_gmt":"2025-05-03T01:51:52","slug":"%e6%b7%b1%e5%85%a5%e7%90%86%e8%a7%a3gpio%e6%8e%a7%e5%88%b6%ef%bc%9a%e4%bb%8e%e6%a6%82%e5%bf%b5%e5%88%b0%e5%ae%9e%e8%b7%b5","status":"publish","type":"post","link":"https:\/\/www.xuzhe.tj.cn\/index.php\/2023\/11\/05\/%e6%b7%b1%e5%85%a5%e7%90%86%e8%a7%a3gpio%e6%8e%a7%e5%88%b6%ef%bc%9a%e4%bb%8e%e6%a6%82%e5%bf%b5%e5%88%b0%e5%ae%9e%e8%b7%b5\/","title":{"rendered":"\u6df1\u5165\u7406\u89e3GPIO\u63a7\u5236\uff1a\u4ece\u6982\u5ff5\u5230\u5b9e\u8df5"},"content":{"rendered":"<h1>1. \u4ec0\u4e48\u662fGPIO\u63a7\u5236\uff1f<\/h1>\n<p>GPIO\uff08General-purpose input\/output\uff09\u5373\u901a\u7528\u8f93\u5165\u8f93\u51fa\u7aef\u53e3\uff0c\u662f\u5d4c\u5165\u5f0f\u8bbe\u5907\u4e2d\u975e\u5e38\u57fa\u7840\u7684\u4e00\u90e8\u5206\u3002\u5b83\u4eec\u5141\u8bb8\u5d4c\u5165\u5f0f\u7cfb\u7edf\u4e0e\u5916\u754c\u73af\u5883\u4ea4\u4e92\uff0c\u53ef\u4ee5\u88ab\u914d\u7f6e\u4e3a\u8f93\u5165\u6216\u8f93\u51fa\u6a21\u5f0f\u3002\u5728\u8f93\u5165\u6a21\u5f0f\u4e0b\uff0cGPIO\u53ef\u4ee5\u8bfb\u53d6\u6765\u81ea\u4f20\u611f\u5668\u3001\u5f00\u5173\u7b49\u5916\u90e8\u8bbe\u5907\u7684\u4fe1\u53f7\uff1b\u5728\u8f93\u51fa\u6a21\u5f0f\u4e0b\uff0c\u5b83\u53ef\u4ee5\u63a7\u5236LED\u706f\u3001\u7535\u673a\u7b49\u5916\u90e8\u8bbe\u5907\u3002GPIO\u662f\u786c\u4ef6\u548c\u8f6f\u4ef6\u4e4b\u95f4\u901a\u4fe1\u7684\u6865\u6881\uff0c\u901a\u8fc7\u7f16\u7a0b\u53ef\u4ee5\u7075\u6d3b\u5730\u63a7\u5236\u5b83\u4eec\u8fdb\u884c\u5404\u79cd\u64cd\u4f5c\u3002<\/p>\n<p><!--more--><\/p>\n<p>GPIO\u63a7\u5236\u5219\u662f\u6307\u901a\u8fc7\u8f6f\u4ef6\u5bf9\u8fd9\u4e9bGPIO\u5f15\u811a\u7684\u7535\u5e73\u72b6\u6001\u8fdb\u884c\u8bfb\u53d6\u548c\u8bbe\u7f6e\uff0c\u5b9e\u73b0\u5bf9\u5916\u63a5\u8bbe\u5907\u7684\u63a7\u5236\u548c\u6570\u636e\u4ea4\u6362\u3002<\/p>\n<p>\u5728\u5d4c\u5165\u5f0f\u8bbe\u5907\u4e2d\uff0c\u8bb8\u591aIO\u7aef\u53e3\u53ef\u4ee5\u901a\u8fc7\u5185\u90e8\u7684\u590d\u7528\u673a\u5236\u88ab\u914d\u7f6e\u4e3a\u7279\u5b9a\u7684\u529f\u80fd\uff0c\u5982SPI\uff08\u4e32\u884c\u5916\u8bbe\u63a5\u53e3\uff09\u3001UART\uff08\u901a\u7528\u5f02\u6b65\u6536\u53d1\u4f20\u8f93\u5668\uff09\u3001USB\uff08\u901a\u7528\u4e32\u884c\u603b\u7ebf\uff09\u6216\u7f51\u53e3\u7b49\u63a5\u53e3\u7684\u5f15\u811a\u3002\u8fd9\u65f6\uff0c\u5bf9\u8fd9\u4e9b\u5f15\u811a\u7684\u63a7\u5236\u901a\u5e38\u9700\u8981\u901a\u8fc7\u7279\u5b9a\u7684\u786c\u4ef6\u63a7\u5236\u5668\u6765\u8fdb\u884c\uff0c\u6bd4\u5982SPI\u63a7\u5236\u5668\u3001UART\u63a7\u5236\u5668\u7b49\u3002\u867d\u7136\u7269\u7406\u5f15\u811a\u53ef\u80fd\u76f8\u540c\uff0c\u4f46\u5176\u5728\u8f6f\u4ef6\u5c42\u9762\u7684\u63a7\u5236\u65b9\u5f0f\u4f1a\u6839\u636e\u5176\u914d\u7f6e\u7684\u529f\u80fd\u800c\u6709\u6240\u4e0d\u540c\u3002\u56e0\u6b64\uff0c\u5f53IO\u7aef\u53e3\u88ab\u8bbe\u7f6e\u4e3aSPI\u3001UART\u3001USB\u6216\u7f51\u7edc\u63a5\u53e3\u65f6\uff0c\u5176\u63a7\u5236\u901a\u5e38\u4e0d\u518d\u79f0\u4f5c\u662fGPIO\u63a7\u5236\uff0c\u800c\u662f\u79f0\u4e3a\u76f8\u5e94\u63a5\u53e3\u7684\u63a7\u5236\u3002\u4f8b\u5982\uff0c\u5f53\u4e00\u4e2aIO\u7aef\u53e3\u88ab\u914d\u7f6e\u4e3aSPI\u7684MOSI\uff08\u4e3b\u8bbe\u5907\u8f93\u51fa\u4ece\u8bbe\u5907\u8f93\u5165\uff09\u7ebf\u65f6\uff0c\u5b83\u5c31\u662fSPI\u63a5\u53e3\u7684\u4e00\u90e8\u5206\uff0c\u7531SPI\u63a7\u5236\u5668\u8fdb\u884c\u6570\u636e\u4f20\u8f93\u7684\u63a7\u5236\uff0c\u800c\u4e0d\u662f\u4f5c\u4e3a\u4e00\u4e2a\u901a\u7528\u7684\u8f93\u5165\u8f93\u51fa\u7aef\u6765\u76f4\u63a5\u63a7\u5236\u3002<\/p>\n<p>\u8fd9\u91cc\u53ea\u4ecb\u7ecd\u505a\u4e3a\u666e\u901aIO\u4f7f\u7528\u7684GPIO\u7684\u63a7\u5236\u65b9\u6cd5\u3002\u638c\u63e1\u5176\u63a7\u5236\u65b9\u6cd5\u5bf9\u4e8e\u5d4c\u5165\u5f0f\u8f6f\u4ef6\u5f00\u53d1\u81f3\u5173\u91cd\u8981\u3002<\/p>\n<h1>2. \u547d\u4ee4\u884c\u63a7\u5236 &#8211; sysfs\u63a7\u5236\u65b9\u6cd5<\/h1>\n<p>\u5728Linux\u7cfb\u7edf\u4e2d\uff0cGPIO\u8bbe\u5907\u53ef\u901a\u8fc7\u6587\u4ef6\u7cfb\u7edf\u8fdb\u884c\u64cd\u4f5c\uff0cOpenWRT\u4ea6\u91c7\u7528\u8fd9\u79cd\u65b9\u5f0f\u3002\u8fd9\u79cd\u65b9\u5f0f\u4e5f\u88ab\u79f0\u4e3asysfs\u63a7\u5236\uff0c\u5373\u901a\u8fc7sysfs\u6587\u4ef6\u7cfb\u7edf\u5bf9GPIO\u8bbe\u5907\u8fdb\u884c\u63a7\u5236\u3002<\/p>\n<p>sysfs \uff08system filesystem\uff09\u662f Linux \u7cfb\u7edf\u4e2d\u7684\u4e00\u79cd\u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u5b83\u5728 \/sys \u76ee\u5f55\u4e0b\u63d0\u4f9b\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\uff0c\u6620\u5c04\u4e86\u5185\u6838\u7684\u8bbe\u5907\u6a21\u578b\u3002\u4e3b\u8981\u7528\u4e8e\u5bfc\u51fa\u5185\u6838\u5bf9\u8c61\u7684\u4fe1\u606f\u5230\u7528\u6237\u7a7a\u95f4\uff0c\u5141\u8bb8\u7528\u6237\u6001\u5e94\u7528\u7a0b\u5e8f\u4ee5\u6587\u4ef6\u7684\u5f62\u5f0f\u8bbf\u95ee\u8bbe\u5907\u548c\u9a71\u52a8\u7a0b\u5e8f\u7684\u5c5e\u6027\u3002<\/p>\n<p>sysfs \u662f\u5728 2.6 \u5185\u6838\u4e2d\u5f15\u5165\u7684\uff0c\u65e8\u5728\u4ee3\u66ff\u65e7\u7684 proc \u6587\u4ef6\u7cfb\u7edf\u4e2d\u7528\u4e8e\u7cfb\u7edf\u4fe1\u606f\u7684\u90e8\u5206\uff0c\u5e76\u63d0\u4f9b\u4e00\u79cd\u7ed3\u6784\u5316\u7684\u65b9\u6cd5\u6765\u8bbf\u95ee\u5185\u6838\u5bf9\u8c61\u7684\u5c5e\u6027\u3002<a href=\"https:\/\/zh.wikipedia.org\/zh-hans\/Sysfs\">sysfs\u66f4\u8be6\u7ec6\u7684\u8bf4\u660e<\/a><\/p>\n<p>\u5177\u4f53\u800c\u8a00\uff0c\u5728<code>\/sys\/class\/gpio\/<\/code>\u76ee\u5f55\u4e0b\uff0c\u6bcf\u4e2aGPIO\u90fd\u88ab\u6620\u5c04\u4e3a\u4e00\u4e2a\u6587\u4ef6\u5939\u3002\u901a\u8fc7\u5bf9\u8fd9\u4e9b\u6587\u4ef6\u7684\u8bfb\u5199\uff0c\u53ef\u4ee5\u63a7\u5236GPIO\u5f15\u811a\u7684\u884c\u4e3a\u3002<\/p>\n<p>\u9996\u5148\uff0c\u8981\u64cd\u4f5c\u4e00\u4e2aGPIO\uff0c\u8981\u7528<code>export<\/code>\u6587\u4ef6\u5c06\u5176\u6ce8\u518c\u5230\u7528\u6237\u7a7a\u95f4\u3002\u4f8b\u5982\uff0c\u901a\u8fc7\u6267\u884c<code>echo GPIO8 &gt; export<\/code>\u547d\u4ee4\uff0c\u7cfb\u7edf\u4f1a\u5728<code>\/sys\/class\/gpio\/<\/code>\u4e0b\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a<code>gpio8<\/code>\u7684\u6587\u4ef6\u5939\uff0c\u5176\u4e2d<code>GPIO8<\/code>\u662f\u8981\u63a7\u5236\u7684GPIO\u7f16\u53f7\u3002<\/p>\n<p>\u5728\u8fd9\u4e2a\u6587\u4ef6\u5939\u5185\u90e8\uff0c\u6709\u8fd9\u4e9b\u6587\u4ef6\uff0c\u5305\u62ec\uff1a<\/p>\n<ol>\n<li>\n<p><code>active_low<\/code>\uff1a\u8be5\u6587\u4ef6\u7528\u4e8e\u8bbe\u7f6eGPIO\u5f15\u811a\u7684\u7535\u5e73\u89e6\u53d1\u65b9\u5f0f\u3002\u5199\u5165&quot;1&quot;\u610f\u5473\u7740\u5c06\u8be5\u5f15\u811a\u7684\u7535\u5e73\u89e6\u53d1\u903b\u8f91\u7ffb\u8f6c\uff08\u5373\uff0c\u786c\u4ef6\u4e0a\u7684\u9ad8\u7535\u5e73\u88ab\u89c6\u4f5c\u903b\u8f91\u4e0a\u7684\u4f4e\u7535\u5e73\uff0c\u786c\u4ef6\u4e0a\u7684\u4f4e\u7535\u5e73\u88ab\u89c6\u4f5c\u903b\u8f91\u4e0a\u7684\u9ad8\u7535\u5e73\uff09\u3002\u5199\u5165&quot;0&quot;\u5219\u8868\u793a\u4f7f\u7528\u6b63\u5e38\u7684\u7535\u5e73\u89e6\u53d1\u903b\u8f91\u3002<\/p>\n<\/li>\n<li>\n<p><code>direction<\/code>\uff1a\u901a\u8fc7\u8fd9\u4e2a\u6587\u4ef6\u53ef\u4ee5\u8bbe\u7f6eGPIO\u5f15\u811a\u662f\u4f5c\u4e3a\u8f93\u5165\u8fd8\u662f\u8f93\u51fa\u3002\u5199\u5165&quot;out&quot;\u5c06GPIO\u914d\u7f6e\u4e3a\u8f93\u51fa\u6a21\u5f0f\uff0c\u5199\u5165&quot;in&quot;\u5219\u5c06\u5176\u914d\u7f6e\u4e3a\u8f93\u5165\u6a21\u5f0f\u3002<\/p>\n<\/li>\n<li>\n<p><code>edge<\/code>\uff1a\u8fd9\u4e2a\u6587\u4ef6\u7528\u4e8e\u914d\u7f6e\u4e2d\u65ad\u89e6\u53d1\u8fb9\u7f18\uff0c\u53ea\u5bf9\u8bbe\u7f6e\u4e3a\u8f93\u5165\u6a21\u5f0f\u7684GPIO\u6709\u6548\u3002\u53ef\u5199\u5165\u7684\u503c\u901a\u5e38\u6709\uff1a&quot;none&quot;\uff08\u65e0\u89e6\u53d1\uff09\uff0c&quot;rising&quot;\uff08\u4e0a\u5347\u6cbf\u89e6\u53d1\uff09\uff0c&quot;falling&quot;\uff08\u4e0b\u964d\u6cbf\u89e6\u53d1\uff09\uff0c\u6216&quot;both&quot;\uff08\u4e0a\u5347\u6cbf\u548c\u4e0b\u964d\u6cbf\u90fd\u89e6\u53d1\uff09\u3002<\/p>\n<\/li>\n<li>\n<p><code>uevent<\/code>\uff1a\u8fd9\u4e2a\u6587\u4ef6\u5141\u8bb8\u7528\u6237\u5411\u7528\u6237\u7a7a\u95f4\u53d1\u9001\u4e8b\u4ef6\uff0c\u901a\u77e5\u5173\u4e8eGPIO\u5f15\u811a\u72b6\u6001\u7684\u53d8\u5316\u3002<\/p>\n<\/li>\n<li>\n<p><code>value<\/code>\uff1a\u8fd9\u4e2a\u6587\u4ef6\u8868\u793aGPIO\u5f15\u811a\u7684\u5f53\u524d\u503c\u3002\u5bf9\u4e8e\u8f93\u51fa\u6a21\u5f0f\u7684GPIO\uff0c\u5199\u5165&quot;1&quot;\u6216&quot;0&quot;\u53ef\u4ee5\u6539\u53d8\u5f15\u811a\u7684\u7535\u5e73\u72b6\u6001\u3002\u5bf9\u4e8e\u8f93\u5165\u6a21\u5f0f\u7684GPIO\uff0c\u8bfb\u53d6\u8fd9\u4e2a\u6587\u4ef6\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u5f15\u811a\u7684\u7535\u5e73\u72b6\u6001\uff08&quot;1&quot;\u8868\u793a\u9ad8\u7535\u5e73\uff0c&quot;0&quot;\u8868\u793a\u4f4e\u7535\u5e73\uff09\u3002<\/p>\n<\/li>\n<\/ol>\n<p>\u4f7f\u7528\u8fd9\u4e9b\u6587\u4ef6\u65f6\uff0c\u901a\u5e38\u9700\u8981\u5177\u6709\u76f8\u5e94\u6743\u9650\u7684\u7528\u6237\u64cd\u4f5c\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740\u9700\u8981root\u6743\u9650\u6216\u8005\u901a\u8fc7\u914d\u7f6eudev\u89c4\u5219\u6388\u6743\u7ed9\u7279\u5b9a\u7528\u6237\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u8981\u5c06GPIO8\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\uff1a<\/p>\n<pre><code class=\"language-shell\">echo out &gt; \/sys\/class\/gpio\/gpioGPIO8\/direction \/\/\u8bbe\u7f6e\u4e3a\u8f93\u51fa\necho 1 &gt; \/sys\/class\/gpio\/gpioGPIO8\/value       \/\/\u8f93\u51fa\u9ad8\u7535\u5e73<\/code><\/pre>\n<p>\u5728\/sys\/class\/gpio\/gpioGPIO8\/\u76ee\u5f55\u4e0b\uff0c\u53ea\u9700\u8981\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u5373\u53ef\u5c06GPIO8\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff1a<\/p>\n<pre><code class=\"language-shell\">echo out &gt; direction \/\/\u8bbe\u7f6e\u4e3a\u8f93\u51fa\necho 1 &gt; value       \/\/\u8f93\u51fa\u9ad8\u7535\u5e73<\/code><\/pre>\n<p>\u5982\u8981\u5c06GPIO8\u7684\u8bbe\u7f6e\u4e3a\u8f93\u5165\u5e76\u8bfb\u53d6\uff0c\u53ef\u4ee5\u4f7f\u7528\u5982\u4e0b\u547d\u4ee4\uff1a<\/p>\n<pre><code class=\"language-shell\">echo in &gt; \/sys\/class\/gpio\/gpioGPIO8\/direction   \/\/\u8bbe\u7f6e\u4e3a\u8f93\u5165\ncat \/sys\/class\/gpio\/gpioGPIO8\/value             \/\/\u8bfb\u53d6\u8f93\u5165\u7535\u5e73<\/code><\/pre>\n<p>\u5728\/sys\/class\/gpio\/gpioGPIO8\/\u76ee\u5f55\u4e0b\uff0c\u53ea\u9700\u8981\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u5373\u53ef\u5c06GPIO8\u8bbe\u7f6e\u4e3a\u8f93\u5165\u5e76\u8bfb\u53d6\uff1a<\/p>\n<pre><code class=\"language-shell\">echo in &gt; direction \/\/\u8bbe\u7f6e\u4e3a\u8f93\u5165\ncat value           \/\/\u8bfb\u53d6\u8f93\u5165\u7535\u5e73<\/code><\/pre>\n<p>\u5982\u679c\u8981\u53d6\u6d88\u5bf9GPIO\u7684\u63a7\u5236\uff0c\u53ef\u4ee5\u4f7f\u7528<code>unexport<\/code>\u6587\u4ef6\u3002\u4f8b\u5982\uff0c\u6267\u884c<code>echo GPIO8 &gt; unexport<\/code>\u547d\u4ee4\u5373\u53ef\u53d6\u6d88\u5bf9GPIO8\u7684\u63a7\u5236\u3002<\/p>\n<p>\u53ef\u80fd\u4f1a\u9047\u5230\u7684\u95ee\u9898\uff1a<\/p>\n<ol>\n<li><code>Device or resource busy<\/code> \u9519\u8bef<\/li>\n<\/ol>\n<p>\u5982\u679c\u6267\u884c<code>echo GPIO8 &gt; export<\/code>\u547d\u4ee4\u65f6\uff0c\u5f97\u5230<code>Device or resource busy<\/code>\u7684\u9519\u8bef\uff0c\u8bf4\u660eGPIO8\u5df2\u7ecf\u88ab\u5176\u4ed6\u8fdb\u7a0b\u5360\u7528\u3002\u6b64\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7<code>lsof<\/code>\u547d\u4ee4\u67e5\u770b\u5360\u7528GPIO8\u7684\u8fdb\u7a0b\uff0c\u7136\u540e\u901a\u8fc7<code>kill<\/code>\u547d\u4ee4\u6740\u6b7b\u8be5\u8fdb\u7a0b\uff0c\u518d\u91cd\u65b0\u6267\u884c<code>echo GPIO8 &gt; export<\/code>\u547d\u4ee4\u5373\u53ef\u3002 <\/p>\n<p><code>lsof<\/code> \u4ee3\u8868\u201cList Open Files\u201d\uff0c\u6b64\u547d\u4ee4\u7528\u4e8e\u67e5\u770b\u6587\u4ef6\u88ab\u54ea\u4e9b\u8fdb\u7a0b\u5360\u7528\u3002\u4f8b\u5982\uff0c\u6267\u884c<code>lsof \/sys\/class\/gpio\/gpioGPIO8\/value<\/code>\u547d\u4ee4\uff0c\u53ef\u4ee5\u67e5\u770b\u5360\u7528GPIO8\u7684\u8fdb\u7a0b\u3002\u6267\u884c<code>kill -9 PID<\/code>\u547d\u4ee4\u6740\u6b7b\u8be5\u8fdb\u7a0b\uff0c\u5176\u4e2dPID\u4e3a\u8fdb\u7a0b\u53f7\u3002\u6ce8\u610f\uff0c\u4f7f\u7528 -9 \u9009\u9879\u5e94\u8c28\u614e\u5bf9\u5f85\uff0c\u56e0\u4e3a\u5b83\u4e0d\u5141\u8bb8\u8fdb\u7a0b\u6b63\u5e38\u6e05\u7406\u548c\u5173\u95ed\u3002\u53ea\u6709\u5728\u8fdb\u7a0b\u65e0\u6cd5\u6b63\u5e38\u7ec8\u6b62\u65f6\uff0c\u624d\u63a8\u8350\u4f7f\u7528\u8fd9\u4e2a\u9009\u9879\u3002<code>lsof<\/code>\u53ef\u80fd\u9700\u8981\u5355\u72ec\u5b89\u88c5\u3002<\/p>\n<ol start=\"2\">\n<li><code>Permission denied<\/code>\u9519\u8bef<\/li>\n<\/ol>\n<p>\u5982\u679c\u5728\/sys\/class\/gpio\/gpioGPIO8\/\u76ee\u5f55\u4e0b\u6267\u884c<code>echo 1 &gt; value<\/code>\u547d\u4ee4\uff0c\u5f97\u5230<code>Permission denied<\/code>\u7684\u9519\u8bef\u3002\u8fd9\u662f\u56e0\u4e3a\uff0cGPIO\u7684\u63a7\u5236\u9700\u8981root\u6743\u9650\uff0c\u56e0\u6b64\uff0c\u8981\u5728\u6b64\u76ee\u5f55\u4e0b\u6267\u884c\u547d\u4ee4\uff0c\u9700\u8981\u5148\u4f7f\u7528<code>sudo su<\/code>\u547d\u4ee4\u5207\u6362\u5230root\u7528\u6237\u3002\u6216\u8005\u4f7f\u7528\u4f7f\u7528 sudo \u547d\u4ee4\u5728\u63d0\u5347\u6743\u9650\u7684\u60c5\u51b5\u4e0b\u6267\u884c\u547d\u4ee4\uff0c\u5982\uff1a<\/p>\n<pre><code class=\"language-sh\">sudo sh -c &#039;echo 1 &gt; \/sys\/class\/gpio\/gpio8\/value&#039; \/\/\u4ee4 gpio8\u8f93\u51fa\u9ad8\u7535\u5e73<\/code><\/pre>\n<p>sh \u662f Bourne shell \u7684\u7b80\u5199\uff0c\u5b83\u662f\u8bb8\u591ashell\u7684\u524d\u8eab\uff0c\u5982 Bash\uff08Bourne Again shell\uff09\u7b49\u3002sh \u53ef\u4ee5\u6267\u884c\u547d\u4ee4\u548c\u7a0b\u5e8f\uff0c\u63d0\u4f9b\u7528\u6237\u754c\u9762\u6765\u4e0e\u64cd\u4f5c\u7cfb\u7edf\u4ea4\u4e92\u3002<\/p>\n<p>sh -c \u662f\u4f7f\u7528 Bourne shell \u6765\u6267\u884c\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u7684\u547d\u4ee4\u3002\u8fd9\u91cc\u7684 -c \u9009\u9879\u544a\u8bc9 sh\uff0c\u968f\u540e\u7684\u5b57\u7b26\u4e32\u53c2\u6570\u662f\u8981\u6267\u884c\u7684\u547d\u4ee4\u3002\u8fd9\u4e2a\u9009\u9879\u5e38\u5e38\u4e0e sudo \u7ed3\u5408\u4f7f\u7528\u6765\u6267\u884c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650\u7684\u547d\u4ee4\uff0c\u5c24\u5176\u662f\u5728\u547d\u4ee4\u4e2d\u6d89\u53ca\u91cd\u5b9a\u5411\u64cd\u4f5c\u65f6\uff0c\u5982\u8fd9\u91cc\u7684&quot;&gt;&quot;\u64cd\u4f5c\u7b26\u3002<\/p>\n<p>\u5982\u679c\u4e0d\u4f7f\u7528<code>sh -c<\/code>\uff0c\u800c\u662f\u76f4\u63a5\u8fd0\u884c\uff1a<\/p>\n<pre><code class=\"language-sh\">sudo echo 1 &gt; \/sys\/class\/gpio\/gpio8\/value<\/code><\/pre>\n<p>\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0csudo \u53ea\u4f1a\u63d0\u5347 echo 1 \u547d\u4ee4\u7684\u6743\u9650\uff0c\u800c\u4e0d\u4f1a\u63d0\u5347\u91cd\u5b9a\u5411\u7b26\u53f7 &gt; \u7684\u6743\u9650\u3002\u7531\u4e8e \/sys\/class\/gpio\/gpio8\/value \u6587\u4ef6\u901a\u5e38\u9700\u8981 root \u6743\u9650\u624d\u80fd\u5199\u5165\uff0c\u5c06\u4f1a\u6536\u5230 Permission denied \u9519\u8bef\u3002<\/p>\n<p>\u5982\u679c\u9047\u5230\u5176\u4ed6\u9519\u8bef\uff0c\u53ef\u4ee5\u901a\u8fc7<code>dmesg<\/code>\u547d\u4ee4\u67e5\u770b\u7cfb\u7edf\u65e5\u5fd7\uff0c\u4ee5\u4fbf\u627e\u5230\u9519\u8bef\u539f\u56e0\u3002<\/p>\n<p>\u5982\u679c\u8fd8\u6709\u5176\u4ed6\u95ee\u9898\uff0c\u53ef\u4ee5\u53c2\u8003<a href=\"https:\/\/openwrt.org\/docs\/\">OpenWRT\u5b98\u65b9\u6587\u6863<\/a><\/p>\n<p>\u901a\u8fc7\u8fd9\u4e9b\u57fa\u672c\u547d\u4ee4\uff0c\u53ef\u5feb\u901f\u4e0a\u624bGPIO\u63a7\u5236\uff0c\u5b9e\u73b0\u7b80\u5355\u7684\u786c\u4ef6\u4ea4\u4e92\u3002\u8fd9\u79cd\u7b80\u6d01\u7684\u547d\u4ee4\u884c\u63a7\u5236\u65b9\u6cd5\u4e0d\u4ec5\u65b9\u4fbf\u5b9e\u7528\uff0c\u800c\u4e14\u5728\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u53ef\u4ee5\u5feb\u901f\u9a8c\u8bc1\u786c\u4ef6\u529f\u80fd\uff0c\u662f\u786c\u4ef6\u8c03\u8bd5\u4e0d\u53ef\u6216\u7f3a\u7684\u5de5\u5177\u3002<\/p>\n<h1>3. \u5728C\/C++\u4e2d\u63a7\u5236GPIO<\/h1>\n<p>\u5728C++\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u6807\u51c6\u5e93\u4e2d\u7684\u6587\u4ef6\u6d41\u64cd\u4f5c\uff08fstream\uff09\u6765\u64cd\u4f5csysfs\u6587\u4ef6\u7cfb\u7edf\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9GPIO\u7684\u63a7\u5236\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u7a0b\uff0c\u5b83\u5c06GPIO8\u8bbe\u7f6e\u4e3a\u8f93\u51fa\uff0c\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff1a<\/p>\n<pre><code class=\"language-c++\">#include &lt;fstream&gt;\n#include &lt;string&gt;\n\nvoid exportGPIO(const std::string&amp; gpio) {\n    std::ofstream exportFile(&quot;\/sys\/class\/gpio\/export&quot;);\n    if (exportFile.is_open()) {\n        exportFile &lt;&lt; gpio;\n        exportFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\n    }\n}\n\nvoid unexportGPIO(const std::string&amp; gpio) {\n    std::ofstream unexportFile(&quot;\/sys\/class\/gpio\/unexport&quot;);\n    if (unexportFile.is_open()) {\n        unexportFile &lt;&lt; gpio;\n        unexportFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\n    }\n}\n\nvoid setGPIODirection(const std::string&amp; gpio, const std::string&amp; direction) {\n    std::ofstream directionFile(&quot;\/sys\/class\/gpio\/gpio&quot; + gpio + &quot;\/direction&quot;);\n    if (directionFile.is_open()) {\n        directionFile &lt;&lt; direction;\n        directionFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n    }\n}\n\nvoid setGPIOValue(const std::string&amp; gpio, const std::string&amp; value) {\n    std::ofstream valueFile(&quot;\/sys\/class\/gpio\/gpio&quot; + gpio + &quot;\/value&quot;);\n    if (valueFile.is_open()) {\n        valueFile &lt;&lt; value;\n        valueFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n    }\n}\n\nstd::string getGPIODirection(const std::string&amp; gpio) {\n    std::string direction;\n    std::ifstream directionFile(&quot;\/sys\/class\/gpio\/gpio&quot; + gpio + &quot;\/direction&quot;);\n    if (directionFile.is_open()) {\n        directionFile &gt;&gt; direction;\n        directionFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n    }\n    return direction;\n}\n\nstd::string getGPIOValue(const std::string&amp; gpio) {\n    std::string value;\n    std::ifstream valueFile(&quot;\/sys\/class\/gpio\/gpio&quot; + gpio + &quot;\/value&quot;);\n    if (valueFile.is_open()) {\n        valueFile &gt;&gt; value;\n        valueFile.close();\n    } else {\n        \/\/ \u6587\u4ef6\u6253\u5f00\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n    }\n    return value;\n}\n\nint main() { \n    std::string gpio = &quot;8&quot;; \/\/ \u8981\u64cd\u4f5c\u7684GPIO\u7f16\u53f7\n    exportGPIO(gpio); \/\/ \u5bfc\u51faGPIO\u5230\u7528\u6237\u7a7a\u95f4\n    setGPIODirection(gpio, &quot;out&quot;); \/\/ \u8bbe\u7f6e\u4e3a\u8f93\u51fa\n    setGPIOValue(gpio, &quot;1&quot;); \/\/ \u8f93\u51fa\u9ad8\u7535\u5e73\n    unexportGPIO(gpio);\/\/ \u53d6\u6d88\u5bfc\u51fa\n\n    std::string gpio = &quot;9&quot;; \/\/ \u8981\u64cd\u4f5c\u7684GPIO\u7f16\u53f7\n    exportGPIO(gpio);   \/\/ \u5bfc\u51faGPIO\u5230\u7528\u6237\u7a7a\u95f4\n    setGPIODirection(gpio, &quot;in&quot;); \/\/ \u8bbe\u7f6e\u4e3a\u8f93\u5165\n    std::string direction = getGPIODirection(gpio); \/\/ \u83b7\u53d6\u65b9\u5411\n    std::string value = getGPIOValue(gpio); \/\/ \u83b7\u53d6\u503c\n    std::cout &lt;&lt; &quot;GPIO&quot; &lt;&lt; gpio &lt;&lt; &quot; direction: &quot; &lt;&lt; direction &lt;&lt; &quot;, value: &quot; &lt;&lt; value &lt;&lt; std::endl;\n    unexportGPIO(gpio);\/\/ \u53d6\u6d88\u5bfc\u51fa\n    return 0;   \/\/ \u7a0b\u5e8f\u6b63\u5e38\u9000\u51fa\n}<\/code><\/pre>\n<p>\u8fd9\u6bb5\u7a0b\u5e8f\u662f\u7528C++\u7f16\u7a0b\u8bed\u8a00\u7f16\u5199\u7684\uff0c\u7528\u4e8e\u64cd\u4f5cLinux\u7cfb\u7edf\u4e2d\u7684GPIO\u8bbe\u5907\u3002\u7a0b\u5e8f\u4e2d\u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u51fd\u6570\uff0c\u901a\u8fc7sysfs\u6587\u4ef6\u7cfb\u7edf\u5bf9GPIO\u8bbe\u5907\u8fdb\u884c\u5bfc\u51fa\uff08export\uff09\u3001\u53d6\u6d88\u5bfc\u51fa\uff08unexport\uff09\u3001\u8bbe\u7f6e\u65b9\u5411\uff08setGPIODirection\uff09\u3001\u8bbe\u7f6e\u503c\uff08setGPIOValue\uff09\u3001\u83b7\u53d6\u65b9\u5411\uff08getGPIODirection\uff09\u548c\u83b7\u53d6\u503c\uff08getGPIOValue\uff09\u7b49\u64cd\u4f5c\u3002<\/p>\n<p>\u5728main\u51fd\u6570\u4e2d\uff0c\u7a0b\u5e8f\u9996\u5148\u5b9a\u4e49\u4e86\u8981\u64cd\u4f5c\u7684GPIO\u7f16\u53f7\uff08\u8fd9\u91cc\u662f&quot;8&quot;\uff09\uff0c\u7136\u540e\u6309\u7167\u987a\u5e8f\u8c03\u7528exportGPIO\u3001setGPIODirection\u3001setGPIOValue\u548cunexportGPIO\u51fd\u6570\uff0c\u5c06GPIO8\u5bfc\u51fa\u5230\u7528\u6237\u7a7a\u95f4\uff0c\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff0c\u7136\u540e\u5c06\u5176\u4ece\u7528\u6237\u7a7a\u95f4\u53d6\u6d88\u5bfc\u51fa\u3002<\/p>\n<p>\u63a5\u7740\uff0c\u7a0b\u5e8f\u5b9a\u4e49\u4e86\u53e6\u4e00\u4e2a\u8981\u64cd\u4f5c\u7684GPIO\u7f16\u53f7\uff08&quot;9&quot;\uff09\uff0c\u7136\u540e\u6309\u7167\u987a\u5e8f\u8c03\u7528exportGPIO\u3001setGPIODirection\u3001getGPIODirection\u3001getGPIOValue\u548cunexportGPIO\u51fd\u6570\uff0c\u5c06GPIO9\u5bfc\u51fa\u5230\u7528\u6237\u7a7a\u95f4\uff0c\u8bbe\u7f6e\u4e3a\u8f93\u5165\uff0c\u83b7\u53d6\u5176\u65b9\u5411\u548c\u503c\uff0c\u7136\u540e\u5c06\u5176\u4ece\u7528\u6237\u7a7a\u95f4\u53d6\u6d88\u5bfc\u51fa\u3002\u83b7\u53d6\u5230\u7684\u65b9\u5411\u548c\u503c\u88ab\u6253\u5370\u51fa\u6765\u3002<\/p>\n<p>\u8fd9\u4e2a\u7a0b\u5e8f\u9700\u8981\u4ee5root\u6743\u9650\u8fd0\u884c\uff0c\u56e0\u4e3a\u64cd\u4f5csysfs\u901a\u5e38\u9700\u8981root\u6743\u9650\u3002\u5982\u679c\u5728\u8fd0\u884c\u65f6\u9047\u5230\u6743\u9650\u95ee\u9898\uff0c\u53ef\u4ee5\u4f7f\u7528sudo\u547d\u4ee4\u8fd0\u884c\u8fd9\u4e2a\u7a0b\u5e8f\u3002<\/p>\n<p>\u5728\u4e0a\u9762\u7684C++ GPIO\u63a7\u5236\u7a0b\u5e8f\u4e2d\uff0c\u9009\u62e9\u4e86\u4f7f\u7528sysfs\u6587\u4ef6\u7cfb\u7edf\u6765\u5b9e\u73b0GPIO\u7684\u64cd\u4f5c\u3002\u8fd9\u79cd\u65b9\u6cd5\u6709\u5176\u72ec\u7279\u7684\u4f18\u70b9\uff0c\u4f46\u4e5f\u5b58\u5728\u4e00\u4e9b\u4e0d\u8db3\u3002\u8ba9\u6211\u4eec\u4e00\u8d77\u6765\u6df1\u5165\u4e86\u89e3\u4e00\u4e0b\u3002<\/p>\n<p>\u9996\u5148\uff0csysfs\u63a7\u5236\u65b9\u6cd5\u7684\u6700\u5927\u4f18\u70b9\u5c31\u662f\u5176\u7b80\u5355\u6613\u7528\u6027\u3002\u901a\u8fc7\u6587\u4ef6\u7cfb\u7edf\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u89c2\u5730\u8bbf\u95ee\u548c\u63a7\u5236GPIO\uff0c\u65e0\u9700\u6df1\u5165\u4e86\u89e3\u5e95\u5c42\u786c\u4ef6\u7684\u590d\u6742\u7ec6\u8282\u3002\u8fd9\u4f7f\u5f97\u6211\u4eec\u7684\u7a0b\u5e8f\u7f16\u5199\u8fc7\u7a0b\u53d8\u5f97\u66f4\u52a0\u8f7b\u677e\uff0c\u4e5f\u4f7f\u5f97\u4ee3\u7801\u66f4\u6613\u4e8e\u7406\u89e3\u548c\u7ef4\u62a4\u3002<\/p>\n<p>\u5176\u6b21\uff0csysfs\u63a7\u5236\u65b9\u6cd5\u5177\u6709\u826f\u597d\u7684\u8de8\u5e73\u53f0\u517c\u5bb9\u6027\u3002\u7531\u4e8esysfs\u662fLinux\u5185\u6838\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u6211\u4eec\u7684\u7a0b\u5e8f\u53ef\u4ee5\u5728\u5404\u79cdLinux\u53d1\u884c\u7248\u548c\u786c\u4ef6\u5e73\u53f0\u4e0a\u8fd0\u884c\uff0c\u8fd9\u5927\u5927\u589e\u52a0\u4e86\u6211\u4eec\u7a0b\u5e8f\u7684\u9002\u7528\u8303\u56f4\u3002<\/p>\n<p>\u6b64\u5916\uff0csysfs\u63a7\u5236\u65b9\u6cd5\u8fd8\u5177\u6709\u6613\u4e8e\u8c03\u8bd5\u7684\u4f18\u70b9\u3002\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u5728\u547d\u4ee4\u884c\u4e2d\u67e5\u770b\u548c\u4fee\u6539GPIO\u7684\u72b6\u6001\uff0c\u8fd9\u5bf9\u4e8e\u5feb\u901f\u9a8c\u8bc1\u6211\u4eec\u7684\u7a0b\u5e8f\u548c\u6392\u67e5\u95ee\u9898\u975e\u5e38\u6709\u5e2e\u52a9\u3002<\/p>\n<p>\u7136\u800c\uff0c\u5c3d\u7ba1sysfs\u63a7\u5236\u65b9\u6cd5\u6709\u8fd9\u4e48\u591a\u4f18\u70b9\uff0c\u4f46\u5b83\u4e5f\u5b58\u5728\u4e00\u4e9b\u4e0d\u8db3\u3002\u9996\u5148\uff0c\u7531\u4e8esysfs\u662f\u57fa\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7684\uff0c\u56e0\u6b64\u5728\u8fdb\u884cGPIO\u64cd\u4f5c\u65f6\uff0c\u9700\u8981\u8fdb\u884c\u6587\u4ef6\u8bfb\u5199\u64cd\u4f5c\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u6027\u80fd\u76f8\u5bf9\u4e8e\u76f4\u63a5\u8bbf\u95ee\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u65b9\u6cd5\u8981\u4f4e\u4e00\u4e9b\u3002\u5bf9\u4e8e\u5bf9\u5b9e\u65f6\u6027\u8981\u6c42\u8f83\u9ad8\u7684\u5e94\u7528\uff0c\u8fd9\u53ef\u80fd\u4f1a\u6210\u4e3a\u4e00\u4e2a\u95ee\u9898\u3002<\/p>\n<p>\u5176\u6b21\uff0c\u64cd\u4f5csysfs\u6587\u4ef6\u901a\u5e38\u9700\u8981root\u6743\u9650\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5e26\u6765\u5b89\u5168\u95ee\u9898\u3002\u867d\u7136\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u914d\u7f6eudev\u89c4\u5219\u6765\u6388\u6743\u7ed9\u7279\u5b9a\u7528\u6237\uff0c\u4f46\u8fd9\u4f1a\u589e\u52a0\u914d\u7f6e\u7684\u590d\u6742\u6027\u3002<\/p>\n<p>\u6700\u540e\uff0csysfs\u65b9\u6cd5\u4e0d\u518d\u88ab\u63a8\u8350\u4f7f\u7528\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u65b0\u7684\u5185\u6838\u7cfb\u7edf\u4e2d\uff0c4.8\u7248\u672c\u4e4b\u540e\uff0cGPIO Character Device API\u5df2\u7ecf\u53d6\u4ee3\u4e86sysfs\u65b9\u6cd5\uff0c\u6210\u4e3a\u4e86\u66f4\u52a0\u73b0\u4ee3\u3001\u66f4\u9ad8\u6548\u3001\u66f4\u7075\u6d3b\u7684GPIO\u63a7\u5236\u65b9\u6cd5\u3002<\/p>\n<p>\u603b\u7684\u6765\u8bf4\uff0csysfs\u63a7\u5236\u65b9\u6cd5\u5728\u7b80\u5355\u6613\u7528\u3001\u8de8\u5e73\u53f0\u517c\u5bb9\u6027\u548c\u6613\u4e8e\u8c03\u8bd5\u7b49\u3001\u8f83\u65e9\u7684linux\u7cfb\u7edf\u4e2d\u4f7f\u7528\u65b9\u9762\u5177\u6709\u4f18\u52bf\uff0c\u4f46\u5728\u6027\u80fd\u3001\u6743\u9650\u548c\u53ef\u79fb\u690d\u6027\u65b9\u9762\u5b58\u5728\u4e00\u5b9a\u7684\u4e0d\u8db3\u3002\u5728\u9009\u62e9\u4f7f\u7528\u8fd9\u79cd\u65b9\u6cd5\u65f6\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u5e94\u7528\u9700\u6c42\u548c\u573a\u666f\u8fdb\u884c\u6743\u8861\u3002<\/p>\n<h1>4. \u5728C\/C++\u4e2d\u63a7\u5236GPIO &#8211; GPIO Character Device API\u63a7\u5236\u65b9\u6cd5<\/h1>\n<p>\u5728\u4e0a\u4e00\u90e8\u5206\u4e2d\uff0c\u6211\u4eec\u8ba8\u8bba\u4e86\u5982\u4f55\u4f7f\u7528sysfs\u6587\u4ef6\u7cfb\u7edf\u5728C++\u4e2d\u63a7\u5236GPIO\uff0c\u4ee5\u53ca\u8fd9\u79cd\u65b9\u6cd5\u7684\u4f18\u70b9\u548c\u4e0d\u8db3\u3002\u73b0\u5728\uff0c\u6211\u4eec\u4f7f\u7528GPIO Character Device API\u6765\u63a7\u5236GPIO\u3002\u8fd9\u79cd\u65b0\u7684API\u63d0\u4f9b\u4e86\u4e00\u79cd\u66f4\u73b0\u4ee3\u3001\u66f4\u9ad8\u6548\u3001\u66f4\u7075\u6d3b\u7684\u65b9\u5f0f\u6765\u63a7\u5236GPIO\u3002\u662f\u5728Linux\u5185\u6838\u7248\u672c4.8\u4e4b\u540e\u5f15\u5165\u7684\uff0c\u56e0\u6b64\u5728\u8001\u7684\u7cfb\u7edf\u4e2d\u65e0\u6cd5\u4f7f\u7528\u3002\u4f7f\u7528\u4e4b\u524d\u8981\u67e5\u770b\u6240\u7528\u7cfb\u7edf\u7684\u5185\u6838\u7248\u672c\u662f\u5426\u652f\u6301\u3002<\/p>\n<p>\u8981\u4f7f\u7528GPIO Character Device API\uff0c\u9996\u5148\u9700\u8981\u5305\u542b<code>linux\/gpio.h<\/code>\u5934\u6587\u4ef6\u3002\u8fd9\u4e2a\u5934\u6587\u4ef6\u5305\u542b\u4e86\u6240\u6709\u4e0eGPIO\u64cd\u4f5c\u76f8\u5173\u7684API\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528\u8fd9\u4e9bAPI\u51fd\u6570\u6765\u5b9e\u73b0GPIO\u7684\u5bfc\u51fa\u3001\u8bbe\u7f6e\u65b9\u5411\u3001\u8bbe\u7f6e\u503c\u3001\u83b7\u53d6\u503c\u7b49\u64cd\u4f5c\u3002<\/p>\n<h2>4.1. \u6253\u5f00GPIO\u8bbe\u5907<\/h2>\n<p>\u5728\u4f7f\u7528GPIO Character Device API\u4e4b\u524d\uff0c\u9996\u5148\u9700\u8981\u6253\u5f00GPIO\u8bbe\u5907\u3002\u8fd9\u53ef\u4ee5\u901a\u8fc7<code>open<\/code>\u7cfb\u7edf\u8c03\u7528\u6765\u5b9e\u73b0\u3002\u4f8b\u5982\uff0c\u8981\u6253\u5f00GPIO\u8bbe\u5907<code>\/dev\/gpiochip0<\/code>\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-cpp\">#include &lt;fcntl.h&gt;\n#include &lt;unistd.h&gt;\n\nint gpio_fd = open(&quot;\/dev\/gpiochip0&quot;, O_RDWR);\nif (gpio_fd == -1) {\n    \/\/ \u6253\u5f00\u8bbe\u5907\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005\u8bbe\u5907\u4e0d\u5b58\u5728\n}<\/code><\/pre>\n<p>\u8fd9\u91cc\uff0c<code>O_RDWR<\/code>\u8868\u793a\u4ee5\u8bfb\u5199\u6a21\u5f0f\u6253\u5f00\u8bbe\u5907\u3002\u5982\u679c\u6253\u5f00\u6210\u529f\uff0c<code>open<\/code>\u51fd\u6570\u5c06\u8fd4\u56de\u4e00\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\uff0c\u7528\u4e8e\u540e\u7eed\u7684GPIO\u64cd\u4f5c\u3002\u5982\u679c\u6253\u5f00\u5931\u8d25\uff0c<code>open<\/code>\u51fd\u6570\u5c06\u8fd4\u56de-1\u3002<\/p>\n<h2>4.2. \u5bfc\u51faGPIO<\/h2>\n<p>\u5728\u4f7f\u7528GPIO\u4e4b\u524d\uff0c\u9700\u8981\u5c06\u5176\u5bfc\u51fa\u5230\u7528\u6237\u7a7a\u95f4\u3002\u8fd9\u53ef\u4ee5\u901a\u8fc7<code>ioctl<\/code>\u7cfb\u7edf\u8c03\u7528\u548c<code>GPIO_GET_LINEHANDLE_IOCTL<\/code>\u547d\u4ee4\u6765\u5b9e\u73b0\u3002\u4f8b\u5982\uff0c\u8981\u5bfc\u51faGPIO8\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-cpp\">#include &lt;linux\/gpio.h&gt;\n#include &lt;sys\/ioctl.h&gt;\n\nstruct gpiohandle_request req;\nreq.lineoffsets[0] = 8;\nreq.lines = 1;\nreq.flags = GPIOHANDLE_REQUEST_OUTPUT;\nstrcpy(req.consumer_label, &quot;my_gpio&quot;);\n\nif (ioctl(gpio_fd, GPIO_GET_LINEHANDLE_IOCTL, &amp;req) == -1) {\n    \/\/ \u5bfc\u51faGPIO\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n}<\/code><\/pre>\n<p>\u8fd9\u91cc\uff0c\u6211\u4eec\u9996\u5148\u5b9a\u4e49\u4e86\u4e00\u4e2a<code>gpiohandle_request<\/code>\u7ed3\u6784\u4f53\uff0c\u5e76\u8bbe\u7f6e\u4e86\u76f8\u5e94\u7684\u53c2\u6570\u3002<code>lineoffsets<\/code>\u6570\u7ec4\u8868\u793a\u8981\u5bfc\u51fa\u7684GPIO\u7f16\u53f7\uff0c<code>lines<\/code>\u8868\u793a\u8981\u5bfc\u51fa\u7684GPIO\u6570\u91cf\uff08\u8fd9\u91cc\u53ea\u5bfc\u51fa\u4e00\u4e2aGPIO\uff09\uff0c<code>flags<\/code>\u8868\u793aGPIO\u7684\u521d\u59cb\u65b9\u5411\uff08\u8fd9\u91cc\u8bbe\u7f6e\u4e3a\u8f93\u51fa\uff09\uff0c<code>consumer_label<\/code>\u8868\u793a\u4f7f\u7528\u8fd9\u4e2aGPIO\u7684\u5e94\u7528\u7a0b\u5e8f\u540d\u79f0\uff08\u53ef\u4ee5\u81ea\u5b9a\u4e49\uff09\u3002<\/p>\n<p>\u7136\u540e\uff0c\u6211\u4eec\u8c03\u7528<code>ioctl<\/code>\u51fd\u6570\uff0c\u4f20\u5165<code>GPIO_GET_LINEHANDLE_IOCTL<\/code>\u547d\u4ee4\u548c<code>gpiohandle_request<\/code>\u7ed3\u6784\u4f53\u3002\u5982\u679c\u5bfc\u51fa\u6210\u529f\uff0c<code>ioctl<\/code>\u51fd\u6570\u5c06\u8fd4\u56de0\uff0c\u5426\u5219\u8fd4\u56de-1\u3002<\/p>\n<h2>4.3. \u8bbe\u7f6eGPIO\u65b9\u5411\u548c\u503c<\/h2>\n<p>\u5728\u5bfc\u51faGPIO\u4e4b\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528<code>gpiohandle_data<\/code>\u7ed3\u6784\u4f53\u6765\u8bbe\u7f6eGPIO\u7684\u65b9\u5411\u548c\u503c\u3002\u4f8b\u5982\uff0c\u8981\u5c06GPIO8\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-cpp\">struct gpiohandle_data data;\ndata.values[0] = 1;\n\nif (ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &amp;data) == -1) {\n    \/\/ \u8bbe\u7f6eGPIO\u503c\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n}<\/code><\/pre>\n<p>\u8fd9\u91cc\uff0c\u6211\u4eec\u9996\u5148\u5b9a\u4e49\u4e86\u4e00\u4e2a<code>gpiohandle_data<\/code>\u7ed3\u6784\u4f53\uff0c\u5e76\u8bbe\u7f6e\u4e86\u76f8\u5e94\u7684\u53c2\u6570\u3002<code>values<\/code>\u6570\u7ec4\u8868\u793a\u8981\u8bbe\u7f6e\u7684GPIO\u503c\uff08\u8fd9\u91cc\u8bbe\u7f6e\u4e3a1\uff0c\u8868\u793a\u9ad8\u7535\u5e73\uff09\u3002<\/p>\n<p>\u7136\u540e\uff0c\u6211\u4eec\u8c03\u7528<code>ioctl<\/code>\u51fd\u6570\uff0c\u4f20\u5165<code>GPIOHANDLE_SET_LINE_VALUES_IOCTL<\/code>\u547d\u4ee4\u548c<code>gpiohandle_data<\/code>\u7ed3\u6784\u4f53\u3002\u5982\u679c\u8bbe\u7f6e\u6210\u529f\uff0c<code>ioctl<\/code>\u51fd\u6570\u5c06\u8fd4\u56de0\uff0c\u5426\u5219\u8fd4\u56de-1\u3002<\/p>\n<h2>4.4. \u83b7\u53d6GPIO\u65b9\u5411\u548c\u503c<\/h2>\n<p>\u8981\u83b7\u53d6GPIO\u7684\u65b9\u5411\u548c\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528<code>gpiohandle_data<\/code>\u7ed3\u6784\u4f53\u548c<code>ioctl<\/code>\u7cfb\u7edf\u8c03\u7528\u3002\u4f8b\u5982\uff0c\u8981\u83b7\u53d6GPIO8\u7684\u65b9\u5411\u548c\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-cpp\">struct gpiohandle_data data;\n\nif (ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &amp;data) == -1) {\n    \/\/ \u83b7\u53d6GPIO\u503c\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6743\u9650\u95ee\u9898\u6216\u8005GPIO\u7f16\u53f7\u9519\u8bef\n} else {\n    int value = data.values[0];\n    \/\/ \u5904\u7406\u83b7\u53d6\u5230\u7684GPIO\u503c\n}<\/code><\/pre>\n<p>\u8fd9\u91cc\uff0c\u6211\u4eec\u8c03\u7528<code>ioctl<\/code>\u51fd\u6570\uff0c\u4f20\u5165<code>GPIOHANDLE_GET_LINE_VALUES_IOCTL<\/code>\u547d\u4ee4\u548c<code>gpiohandle_data<\/code>\u7ed3\u6784\u4f53\u3002\u5982\u679c\u83b7\u53d6\u6210\u529f\uff0c<code>ioctl<\/code>\u51fd\u6570\u5c06\u8fd4\u56de0\uff0c\u5426\u5219\u8fd4\u56de-1\u3002\u83b7\u53d6\u5230\u7684GPIO\u503c\u5b58\u50a8\u5728<code>values<\/code>\u6570\u7ec4\u4e2d\u3002<\/p>\n<h2>4.5. \u53d6\u6d88\u5bfc\u51faGPIO<\/h2>\n<p>\u5728\u4f7f\u7528\u5b8cGPIO\u4e4b\u540e\uff0c\u9700\u8981\u5c06\u5176\u4ece\u7528\u6237\u7a7a\u95f4\u53d6\u6d88\u5bfc\u51fa\u3002\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5173\u95edGPIO\u8bbe\u5907\u6587\u4ef6\u6765\u5b9e\u73b0\u3002\u4f8b\u5982\uff0c\u8981\u53d6\u6d88\u5bfc\u51faGPIO8\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-cpp\">close(req.fd);<\/code><\/pre>\n<p>\u8fd9\u91cc\uff0c\u6211\u4eec\u8c03\u7528<code>close<\/code>\u51fd\u6570\uff0c\u4f20\u5165\u4e4b\u524d\u5bfc\u51faGPIO\u65f6\u83b7\u53d6\u5230\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u3002\u5982\u679c\u5173\u95ed\u6210\u529f\uff0c<code>close<\/code>\u51fd\u6570\u5c06\u8fd4\u56de0\uff0c\u5426\u5219\u8fd4\u56de-1\u3002<\/p>\n<h2>4.6. \u793a\u4f8b\u7a0b\u5e8f<\/h2>\n<p>\u4e0b\u9762\u662f\u4e00\u4e2a\u5b8c\u6574\u7684C++\u7a0b\u5e8f\uff0c\u4f7f\u7528GPIO Character Device API\u6765\u63a7\u5236GPIO8\uff1a<\/p>\n<pre><code class=\"language-cpp\">#include &lt;fcntl.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;linux\/gpio.h&gt;\n#include &lt;sys\/ioctl.h&gt;\n#include &lt;iostream&gt;\n\nint main() {\n    int gpio_fd = open(&quot;\/dev\/gpiochip0&quot;, O_RDWR);\n    if (gpio_fd == -1) {\n        std::cerr &lt;&lt; &quot;Failed to open GPIO device&quot; &lt;&lt; std::endl;\n        return 1;\n    }\n\n    struct gpiohandle_request req;\n    req.lineoffsets[0] = 8;\n    req.lines = 1;\n    req.flags = GPIOHANDLE_REQUEST_OUTPUT;\n    strcpy(req.consumer_label, &quot;my_gpio&quot;);\n\n    if (ioctl(gpio_fd, GPIO_GET_LINEHANDLE_IOCTL, &amp;req) == -1) {\n        std::cerr &lt;&lt; &quot;Failed to export GPIO&quot; &lt;&lt; std::endl;\n        close(gpio_fd);\n        return 1;\n    }\n\n    struct gpiohandle_data data;\n    data.values[0] = 1;\n\n    if (ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &amp;data) == -1) {\n        std::cerr &lt;&lt; &quot;Failed to set GPIO value&quot; &lt;&lt; std::endl;\n        close(req.fd);\n        close(gpio_fd);\n        return 1;\n    }\n\n    close(req.fd);\n    close(gpio_fd);\n    return 0;\n}<\/code><\/pre>\n<p>\u8fd9\u4e2a\u7a0b\u5e8f\u9996\u5148\u6253\u5f00GPIO\u8bbe\u5907\uff0c\u7136\u540e\u5bfc\u51faGPIO8\uff0c\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u5e76\u8f93\u51fa\u9ad8\u7535\u5e73\uff0c\u6700\u540e\u5c06\u5176\u4ece\u7528\u6237\u7a7a\u95f4\u53d6\u6d88\u5bfc\u51fa\u3002\u6ce8\u610f\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u9700\u8981\u4ee5root\u6743\u9650\u8fd0\u884c\uff0c\u56e0\u4e3a\u64cd\u4f5cGPIO\u8bbe\u5907\u901a\u5e38\u9700\u8981root\u6743\u9650\u3002\u5982\u679c\u5728\u8fd0\u884c\u65f6\u9047\u5230\u6743\u9650\u95ee\u9898\uff0c\u53ef\u4ee5\u4f7f\u7528<code>sudo<\/code>\u547d\u4ee4\u8fd0\u884c\u8fd9\u4e2a\u7a0b\u5e8f\u3002<\/p>\n<h1>5. \u5728C\/C++\u4e2d\u63a7\u5236GPIO &#8211; \u7f16\u5199\u5185\u6838\u7a0b\u5e8f\u7684\u63a7\u5236\u65b9\u6cd5<\/h1>\n<p>\u4e0a\u8ff0\u7684GPIO Character Device API\u662f\u5728linux\u5185\u6838\u7248\u672c4.8\u4e4b\u540e\u5f15\u5165\u7684\uff0c\u56e0\u6b64\u5728\u8001\u7684\u7cfb\u7edf\u4e2d\u65e0\u6cd5\u4f7f\u7528\u3002\u5982\u679c\u6240\u7528\u5185\u6838\u7248\u672c\u8f83\u8001\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7f16\u5199\u5185\u6838\u7a0b\u5e8f\u7684\u65b9\u6cd5\u6765\u63a7\u5236GPIO\u3002<\/p>\n<h2>5.1. \u5185\u6838\u7a0b\u5e8f<\/h2>\n<p>\u5185\u6838\u7a0b\u5e8f\u662f\u4f4d\u4e8e\u5185\u6838\u7a7a\u95f4\u7684\u8f6f\u4ef6\u7ec4\u4ef6\uff0c\u5b83\u63d0\u4f9b\u4e86\u5bf9GPIO\u5f15\u811a\u7684\u76f4\u63a5\u63a7\u5236\u3002\u8be5\u7a0b\u5e8f\u4f7f\u5f97\u64cd\u4f5c\u7cfb\u7edf\u80fd\u591f\u8bbe\u7f6eGPIO\u5f15\u811a\u7684\u6a21\u5f0f\uff08\u8f93\u5165\u3001\u8f93\u51fa\uff09\uff0c\u5e76\u5bf9\u5b83\u4eec\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c\u3002\u5728\u5d4c\u5165\u5f0fLinux\u7cfb\u7edf\u4e2d\uff0c\u5982OpenWrt\uff0c\u8fd9\u4e2a\u5185\u6838\u7a0b\u5e8f\u901a\u5e38\u4f5c\u4e3a\u5185\u6838\u6a21\u5757\u5b58\u5728\uff0c\u4f7f\u5f97\u7528\u6237\u53ef\u4ee5\u52a8\u6001\u5730\u52a0\u8f7d\u548c\u5378\u8f7d\u5b83\uff0c\u4ee5\u9002\u5e94\u4e0d\u540c\u7684\u786c\u4ef6\u548c\u9700\u6c42\u3002<\/p>\n<p>\u5728\u8fd9\u91cc\u501f\u7528\u522b\u4eba\u5199\u7684\u4e00\u4e2a\u4f8b\u5b50\uff0c\u6765\u8bf4\u660e\u5982\u4f55\u7f16\u5199\u5185\u6838\u7a0b\u5e8f\u6765\u63a7\u5236GPIO\u3002\u662f\u7528C\u8bed\u8a00\u5199\u7684\uff0c\u5934\u6587\u4ef6\u4e0e\u4ee3\u7801\u5982\u4e0b\u3002<\/p>\n<p>gpio_control_driver.h:<\/p>\n<pre><code class=\"language-c\">\/*\n * gpio_control_driver.h\n *\n *  Created on: 2017-9-10\n *      Author: robinson\n *\/\n\n#ifndef GPIO_CONTROL_DRIVER_H_\n#define GPIO_CONTROL_DRIVER_H_\n#include &lt;linux\/cdev.h&gt;\n#include &lt;linux\/ioctl.h&gt;\n#include &lt;linux\/kfifo.h&gt;\n#define GET_GPIO_NUM(arg1) (unsigned char)((arg1 &gt;&gt; 24) &amp; 0xff)\n#define GET_GPIO_VALUE(arg1) (unsigned char)((arg1 &gt;&gt; 16) &amp; 0xff)\n#define GPIO_CONTROL_MAJOR                  99\/\/device major number\n#define GPIO_CONTROL_DEV_NAME       &quot;gpio_control&quot;\n\/\/IOCTRL CMDs\n#define GPIO_CONTROL_SET_OUT            0x01\n#define GPIO_CONTROL_SET_IN         0x02\n\/\/#define GPIO_CONTROL_GET_DIRECTION        0x03\n#define GPIO_CONTROL_SET_VALUE          0x04\n#define GPIO_CONTROL_GET_VALUE          0x05\n#define GPIO_CONTROL_REQUEST_GPIO       0x06\n#define GPIO_CONTROL_FREE_GPIO          0x07\n#endif \/* GPIO_CONTROL_DRIVER_H_ *\/\n<\/code><\/pre>\n<p>gpio_control_driver.c\uff1a<\/p>\n<pre><code class=\"language-c\">\/*\n *  Gpio control driver\n *\n *  Copyright (C) 2017 (C) &lt;wurobinson@zhuotk.com&gt;\n *\n *  This program is free software; you can redistribute it and\/or modify\n *  it under the terms of the GNU General Public License version 2 as\n *  published by the Free Software Foundation.\n * \n * Description: This driver is written for JS9331 and JS7628 development board. You can use it\n *      to control gpios\n *\n *\/\n\n#include &lt;linux\/types.h&gt; \/\/\u8fd9\u4e2a\u5934\u6587\u4ef6\u5305\u542b\u4e86Linux\u5185\u6838\u4f7f\u7528\u7684\u4e00\u4e9b\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5b9a\u4e49\uff0c\u4f8b\u5982__u8, __u16, __u32\u7b49\u3002\n#include &lt;linux\/gpio.h&gt;   \/\/\u8fd9\u4e2a\u5934\u6587\u4ef6\u5305\u542b\u4e86GPIO\uff08General Purpose Input\/Output\uff09\u7cfb\u7edf\u7684\u76f8\u5173\u5b9a\u4e49\u548c\u51fd\u6570\uff0c\u5982gpio_direction_input(), gpio_direction_output(), gpio_set_value()\u7b49\u3002\n#include &lt;linux\/timer.h&gt;  \/\/\u63d0\u4f9b\u5b9a\u65f6\u5668\u76f8\u5173\u7684\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\uff0c\u5982timer_list\u7ed3\u6784\u4f53\uff0cadd_timer(), del_timer()\u7b49\u3002\n#include &lt;linux\/cdev.h&gt;   \/\/\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8\u5f00\u53d1\u7684\u76f8\u5173\u51fd\u6570\u548c\u7ed3\u6784\u4f53\uff0c\u5982cdev_init(), cdev_add()\u7b49\u3002\n#include &lt;linux\/fs.h&gt; \/\/\u5305\u542b\u4e86\u6587\u4ef6\u7cfb\u7edf\u76f8\u5173\u7684\u4e00\u4e9b\u57fa\u672c\u5b9a\u4e49\u548c\u51fd\u6570\uff0c\u5982\u6587\u4ef6\u64cd\u4f5c\u7684\u7ed3\u6784\u4f53file_operations\u3002\n#include &lt;linux\/module.h&gt; \/\/\u5305\u542b\u6a21\u5757\u76f8\u5173\u7684\u4e00\u4e9b\u51fd\u6570\u548c\u5b8f\uff0c\u5982MODULE_LICENSE, MODULE_AUTHOR, THIS_MODULE\u7b49\u3002\n#include &lt;linux\/init.h&gt;   \/\/\u63d0\u4f9b\u6a21\u5757\u521d\u59cb\u5316\u548c\u9000\u51fa\u7684\u5b8f\u5b9a\u4e49\uff0c\u5982module_init, module_exit\u3002\n#include &lt;linux\/irq.h&gt;    \/\/\u5e95\u5c42\u7684IRQ\u5904\u7406\uff0c\u4f8b\u5982IRQ\u5206\u914d\u3001\u91ca\u653e\u3001\u4f7f\u80fd\u548c\u7981\u6b62\u7b49\n#include &lt;linux\/hrtimer.h&gt;    \/\/\u9ad8\u5206\u8fa8\u7387\u5b9a\u65f6\u5668\uff08High Resolution Timer\uff09\u7684\u76f8\u5173\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\u3002\n#include &lt;linux\/stat.h&gt;   \/\/\u6587\u4ef6\u72b6\u6001\u7684\u76f8\u5173\u5b9a\u4e49\uff0c\u4f8b\u5982\u6587\u4ef6\u6743\u9650\u3002\n#include &lt;linux\/device.h&gt; \/\/\u8bbe\u5907\u6a21\u578b\u7684\u76f8\u5173\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982device_create()\uff0cdevice_destroy()\u7b49\u3002\n#include &lt;linux\/interrupt.h&gt;  \/\/\u5305\u542b\u4e2d\u65ad\u5904\u7406\u76f8\u5173\u7684\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982request_irq(), free_irq()\u7b49\u3002\n#include &lt;linux\/time.h&gt;   \/\/\u65f6\u95f4\u76f8\u5173\u7684\u51fd\u6570\u548c\u6570\u636e\u7ed3\u6784\uff0c\u5982\u7528\u4e8e\u83b7\u53d6\u7cfb\u7edf\u65f6\u95f4\u7684\u51fd\u6570\u7b49\u3002\n#include &lt;asm-generic\/errno-base.h&gt;   \/\/\u5b9a\u4e49\u4e86\u4e00\u4e9b\u57fa\u672c\u7684\u9519\u8bef\u53f7\uff0c\u5982EINTR, ENOMEM, EBUSY\u7b49\u3002\n#include &lt;linux\/miscdevice.h&gt; \/\/\u4e3a\u6742\u9879\u8bbe\u5907\u63d0\u4f9b\u7684\u63a5\u53e3\uff0c\u4f8b\u5982misc_register(), misc_deregister()\u7b49\u3002\n#include &quot;gpio_control_driver.h&quot; \/\/\u5305\u542b\u4e86GPIO\u63a7\u5236\u9a71\u52a8\u9700\u8981\u7684\u5404\u79cd\u5b9a\u4e49\u548c\u51fd\u6570\u539f\u578b\u3002\n\nstatic int gpio_control_open(struct inode *pinode, struct file *pfile) \/\/\u5b9a\u4e49\u8bbe\u5907\u6253\u5f00\u51fd\u6570\n{\n    printk(&quot;***%s***\\n&quot;,__func__);\n    \/\/initialize\n\n    return 0;\n}\n\nstatic int gpio_control_release(struct inode *pinode, struct file *pfile) \/\/\u5b9a\u4e49\u8bbe\u5907\u5173\u95ed\u51fd\u6570\n{\n    printk(&quot;***%s***\\n&quot;,__func__);\n\n    return 0;\n}\n\nstatic long gpio_control_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg) \/\/\u5b9a\u4e49IO\u63a7\u5236\u51fd\u6570\uff0cioctl\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u7cfb\u7edf\u8c03\u7528\uff0c\u5168\u79f0\u662f&quot;input\/output control&quot;\uff0c\u5373\u8f93\u5165\/\u8f93\u51fa\u63a7\u5236\u3002\u5b83\u63d0\u4f9b\u4e86\u4e00\u79cd\u4ece\u7528\u6237\u7a7a\u95f4\u5411\u5185\u6838\u7a7a\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u65b9\u5f0f\uff0c\u901a\u5e38\u7528\u4e8e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u4e2d\u3002\n{\n    int ret;\n    unsigned char gpio_number;\n    unsigned char gpio_value;\n\n    \/\/printk(&quot;***%s***\\n&quot;,__func__);\n    \/\/printk(&quot;cmd:0x%02X\\n&quot;, cmd);\n\n    gpio_number = GET_GPIO_NUM(arg);\n    gpio_value  = GET_GPIO_VALUE(arg);\n    \/\/printk(&quot;gpio number:%d\\n&quot;, gpio_number);\n    \/\/printk(&quot;gpio value:0x%02X\\n&quot;, gpio_value);\n\n    switch (cmd){\n    case GPIO_CONTROL_SET_OUT:\n        \/\/printk(&quot;command: GPIO_CONTROL_SET_OUT\\n&quot;);\n        ret = gpio_direction_output(gpio_number, gpio_value);\n        if (ret &lt; 0){\n            \/\/printk(&quot;###gpio_direction_output ERROR: can&#039;t set gpio %d output###\\n&quot;, gpio_number);\n            return -1;\n        }\n        \/\/printk(&quot;command: GPIO_CONTROL_SET_OUT done\\n&quot;);\n        break;\n\n    case GPIO_CONTROL_SET_IN:\n        ret = gpio_direction_input(gpio_number);\n        if (ret &lt; 0){\n            \/\/printk(&quot;###gpio_direction_input ERROR: can&#039;t set gpio %d input###\\n&quot;, gpio_number);\n            return -1;\n        }\n        \/\/printk(&quot;command: GPIO_CONTROL_SET_IN\\n&quot;);\n        break;\n#if 0\n    case GPIO_CONTROL_GET_DIRECTION:\n\n        printk(&quot;command: GPIO_CONTROL_GET_DIRECTION\\n&quot;);\n        break;\n#endif\n    case GPIO_CONTROL_SET_VALUE:\n        gpio_set_value(gpio_number, gpio_value);\n        \/\/printk(&quot;command: GPIO_CONTROL_SET_VALUE\\n&quot;);\n        break;\n\n    case GPIO_CONTROL_GET_VALUE:\n        ret = gpio_get_value(gpio_number);\n        if (ret &lt; 0){\n            printk(&quot;###gpio_get_value ERROR: can&#039;t get gpio %d value###\\n&quot;, gpio_number);\n            return -1;\n        }\n        \/\/printk(&quot;command: GPIO_CONTROL_GET_VALUE, value is %d\\n&quot;, ret);\n        break;\n\n    case GPIO_CONTROL_REQUEST_GPIO:\n        \/\/printk(&quot;command: GPIO_CONTROL_REQUEST_ONE\\n&quot;);\n        if (0 &gt; gpio_request(gpio_number, &quot;gpio_ctrl&quot;)){\n            \/\/printk(&quot;###gpio_request ERROR: can&#039;t request %d pin for output###\\n&quot;, gpio_number);\n            return -1;\n        }\n        \/\/printk(&quot;command: GPIO_CONTROL_REQUEST_GPIO done\\n&quot;);\n        break;\n\n    case GPIO_CONTROL_FREE_GPIO:\n        gpio_free(gpio_number);\n        \/\/printk(&quot;command: GPIO_CONTROL_FREE_GPIO done\\n&quot;);\n        break;\n\n    default:\n        printk(&quot;***Unknown command:0x%02X\\n***\\n&quot;, cmd);\n        break;\n\n    }\n\n    return ret;\n}\n\nstatic const struct file_operations gpio_control_ops = { \/\/\u5b9a\u4e49\u8bbe\u5907\u64cd\u4f5c\u51fd\u6570\n        .owner          = THIS_MODULE,  \/\/THIS_MODULE\u662f\u4e00\u4e2a\u5b8f\uff0c\u8868\u793a\u5f53\u524d\u6a21\u5757\u7684\u7ed3\u6784\u4f53\u6307\u9488\u3002\n        .open           = gpio_control_open,    \/\/open\u5b57\u6bb5\u662f\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u6307\u5411\u8bbe\u5907\u7684\u6253\u5f00\u51fd\u6570gpio_control_open\u3002\u8fd9\u4e2a\u51fd\u6570\u5728\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u6253\u5f00\u8bbe\u5907\u65f6\u88ab\u8c03\u7528\u3002\n        .release        = gpio_control_release, \/\/release\u5b57\u6bb5\u662f\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u6307\u5411\u8bbe\u5907\u7684\u91ca\u653e\u51fd\u6570gpio_control_release\u3002\u8fd9\u4e2a\u51fd\u6570\u5728\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u5173\u95ed\u8bbe\u5907\u65f6\u88ab\u8c03\u7528\u3002\n        .unlocked_ioctl = gpio_control_ioctl, \/\/unlocked_ioctl\u5b57\u6bb5\u662f\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u6307\u5411\u8bbe\u5907\u7684IO\u63a7\u5236\u51fd\u6570gpio_control_ioctl\u3002\u8fd9\u4e2a\u51fd\u6570\u5728\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u53d1\u9001IO\u63a7\u5236\u547d\u4ee4\u65f6\u88ab\u8c03\u7528\u3002\n};\n\nstatic struct miscdevice s_gpio_control_dev = { \/\/\u5b9a\u4e49\u8bbe\u5907\u7ed3\u6784\u4f53\n        .minor = MISC_DYNAMIC_MINOR,\n        .fops = &amp;gpio_control_ops,\n        .name = GPIO_CONTROL_DEV_NAME\n};\n\n\/\/module initialize function\nstatic int gpio_control_init(void) \/\/\u5b9a\u4e49\u6a21\u5757\u521d\u59cb\u5316\u51fd\u6570\n{\n    int result;\n    \/\/initialize and register device\n    result = misc_register(&amp;s_gpio_control_dev); \/\/misc_register()\u51fd\u6570\u7528\u4e8e\u6ce8\u518c\u4e00\u4e2amiscdevice\u7ed3\u6784\u4f53\uff0c\u4ece\u800c\u5c06\u8bbe\u5907\u6ce8\u518c\u5230\u5185\u6838\u4e2d\u3002\u5b83\u63a5\u6536\u4e00\u4e2a\u6307\u5411miscdevice\u7ed3\u6784\u4f53\u7684\u6307\u9488\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de0\u8868\u793a\u6210\u529f\uff0c\u8fd4\u56de\u8d1f\u6570\u8868\u793a\u5931\u8d25\u3002\n    if (result != 0) {\n        \/\/printk(&quot;###misc_register error###\\n&quot;);\n        return -1;\n    }\n\n    printk(&quot;**gpio_control module initiation OK**\\n&quot;);\n    return result;\n}\n\n\/\/module exit fuc\nvoid gpio_control_exit(void)\n{\n    \/\/unregister what we registered\n    misc_deregister(&amp;s_gpio_control_dev); \/\/misc_deregister()\u51fd\u6570\u7528\u4e8e\u6ce8\u9500\u4e00\u4e2amiscdevice\u7ed3\u6784\u4f53\uff0c\u4ece\u800c\u5c06\u8bbe\u5907\u4ece\u5185\u6838\u4e2d\u6ce8\u9500\u3002\u5b83\u63a5\u6536\u4e00\u4e2a\u6307\u5411miscdevice\u7ed3\u6784\u4f53\u7684\u6307\u9488\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de0\u8868\u793a\u6210\u529f\uff0c\u8fd4\u56de\u8d1f\u6570\u8868\u793a\u5931\u8d25\u3002\n\n    printk(&quot;**gpio_control module exit**\\n&quot;);\n}\n\nmodule_init(gpio_control_init); \/\/module_init()\u5b8f\u7528\u4e8e\u6307\u5b9a\u6a21\u5757\u521d\u59cb\u5316\u51fd\u6570\uff0c\u5373\u6a21\u5757\u52a0\u8f7d\u65f6\u88ab\u8c03\u7528\u7684\u51fd\u6570\u3002\nmodule_exit(gpio_control_exit); \/\/module_exit()\u5b8f\u7528\u4e8e\u6307\u5b9a\u6a21\u5757\u9000\u51fa\u51fd\u6570\uff0c\u5373\u6a21\u5757\u5378\u8f7d\u65f6\u88ab\u8c03\u7528\u7684\u51fd\u6570\u3002\n\nMODULE_VERSION(&quot;V1.0&quot;); \/\/MODULE_VERSION()\u5b8f\u7528\u4e8e\u6307\u5b9a\u6a21\u5757\u7684\u7248\u672c\u53f7\u3002\nMODULE_AUTHOR(&quot;wurobinson &lt;wurobinson@zhuotk.com&gt;&quot;); \/\/MODULE_AUTHOR()\u5b8f\u7528\u4e8e\u6307\u5b9a\u6a21\u5757\u7684\u4f5c\u8005\u3002\nMODULE_LICENSE(&quot;Dual BSD\/GPL&quot;); \/\/MODULE_LICENSE()\u5b8f\u7528\u4e8e\u6307\u5b9a\u6a21\u5757\u7684\u8bb8\u53ef\u8bc1\u3002\n<\/code><\/pre>\n<p>\u7a0b\u5e8f\u5e76\u4e0d\u590d\u6742\u6613\u4e8e\u7406\u89e3\uff0c\u5df2\u7ecf\u4e3a\u5927\u90e8\u5206\u7a0b\u5e8f\u6dfb\u52a0\u4e86\u6ce8\u91ca\u3002\u7a0b\u5e8f\u7684\u6838\u5fc3\u529f\u80fd\u662f\u901a\u8fc7IO\u63a7\u5236\u51fd\u6570\uff08gpio_control_ioctl\uff09\u6765\u5b9e\u73b0GPIO\u7684\u63a7\u5236\u3002\u8fd9\u4e2a\u51fd\u6570\u6839\u636e\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u53d1\u9001\u7684IO\u63a7\u5236\u547d\u4ee4\u6765\u6267\u884c\u76f8\u5e94\u7684GPIO\u64cd\u4f5c\uff0c\u5982\u8bbe\u7f6eGPIO\u7684\u8f93\u5165\/\u8f93\u51fa\u65b9\u5411\uff08gpio_direction_input\/gpio_direction_output\uff09\u3001\u8bbe\u7f6eGPIO\u7684\u503c\uff08gpio_set_value\uff09\u3001\u83b7\u53d6GPIO\u7684\u503c\uff08gpio_get_value\uff09\u3001\u8bf7\u6c42GPIO\uff08gpio_request\uff09\u548c\u91ca\u653eGPIO\uff08gpio_free\uff09\u3002<\/p>\n<p>\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u901a\u8fc7\u521b\u5efa\u4e00\u4e2a\u5b57\u7b26\u8bbe\u5907\u9a71\u52a8\uff0c\u4e3a\u7528\u6237\u7a7a\u95f4\u7684\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u63a5\u53e3\uff0c\u4f7f\u5f97\u7528\u6237\u7a7a\u95f4\u7684\u7a0b\u5e8f\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001IO\u63a7\u5236\u547d\u4ee4\u5230\u8fd9\u4e2a\u8bbe\u5907\u9a71\u52a8\uff0c\u6765\u5b9e\u73b0\u5bf9GPIO\u7684\u63a7\u5236\u3002\u7f16\u8bd1\u540e\u53ef\u4ee5\u5f97\u5230\u4e00\u4e2a\u5185\u6838\u6a21\u5757\uff0c\u53ef\u4ee5\u901a\u8fc7insmod\u547d\u4ee4\u52a0\u8f7d\u5230\u5185\u6838\u4e2d\uff0c\u901a\u8fc7rmmod\u547d\u4ee4\u5378\u8f7d\u3002<\/p>\n<h2>5.2. \u7528\u6237\u7a7a\u95f4\u7684GPIO\u63a7\u5236\u7a0b\u5e8f<\/h2>\n<p>\u4e0a\u9762\u7684gpio_control_driver\u5185\u6838\u7a0b\u5e8f\u4e3a\u7528\u6237\u7a7a\u95f4\u63d0\u4f9b\u4e86\u4e00\u4e2a\u63a5\u53e3\uff0c\u4f7f\u5f97\u7528\u6237\u7a7a\u95f4\u7684\u7a0b\u5e8f\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001IO\u63a7\u5236\u547d\u4ee4\u5230\u8fd9\u4e2a\u8bbe\u5907\u9a71\u52a8\uff0c\u6765\u5b9e\u73b0\u5bf9GPIO\u7684\u63a7\u5236\u3002\u4e0b\u9762\u6211\u4eec\u6765\u7f16\u5199\u4e00\u4e2a\u7528\u6237\u7a7a\u95f4\u7684GPIO\u63a7\u5236\u7a0b\u5e8f\uff0c\u6765\u5b9e\u73b0\u5bf9GPIO\u7684\u63a7\u5236\u3002<\/p>\n<p>\u8fd9\u4e2a\u7a0b\u5e8f\u662f\u7528C++\u7f16\u7a0b\u8bed\u8a00\u7f16\u5199\u7684\uff0c\u7528\u4e8e\u64cd\u4f5cLinux\u7cfb\u7edf\u4e2d\u7684GPIO\u8bbe\u5907\u3002\u7a0b\u5e8f\u4e2d\u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u51fd\u6570\uff0c\u901a\u8fc7\u5199\u5165\u5230\u7279\u5b9a\u7684\u8bbe\u5907\u6587\u4ef6\uff0c\u6216\u4f7f\u7528ioctl\u7b49\u7cfb\u7edf\u8c03\u7528\u4e0e\u9a71\u52a8\u7a0b\u5e8f\u901a\u4fe1\uff0c\u4ece\u800c\u8fbe\u5230\u63a7\u5236\u786c\u4ef6GPIO\u72b6\u6001\u7684\u76ee\u7684\u3002<\/p>\n<p>gpio_contrl_app.h:<\/p>\n<pre><code class=\"language-c\">#ifndef GPIO_CONTROL_APP_H_\n#define GPIO_CONTROL_APP_H_\n\n#define GPIO_CONTROL_DEVICE_PATH        &quot;\/dev\/gpio_control&quot;\n\n#define GPIO_IOCTL_PRAM(gpio_num, arg1) (((unsigned long)gpio_num &lt;&lt; 24) + ((unsigned long)arg1 &lt;&lt; 16)) \/\/\u5b9a\u4e49IO\u63a7\u5236\u547d\u4ee4\u7684\u53c2\u6570\uff0c\u7528\u4e8e\u5411\u9a71\u52a8\u7a0b\u5e8f\u53d1\u9001IO\u63a7\u5236\u547d\u4ee4\u3002\n#define GET_GPIO_NUM(arg1) (unsigned char)((arg1 &gt;&gt; 24) &amp; 0xff) \n#define GET_GPIO_VALUE(arg1) (unsigned char)((arg1 &gt;&gt; 16) &amp; 0xff) \n\n\/\/IOCTRL CMDs\n#define GPIO_CONTROL_SET_OUT            0x01\n#define GPIO_CONTROL_SET_IN         0x02\n\/\/#define GPIO_CONTROL_GET_DIRECTION        0x03\n#define GPIO_CONTROL_SET_VALUE          0x04\n#define GPIO_CONTROL_GET_VALUE          0x05\n#define GPIO_CONTROL_REQUEST_GPIO       0x06\n#define GPIO_CONTROL_FREE_GPIO          0x07\n\n#endif<\/code><\/pre>\n<p>gpio_control_app.cpp:<\/p>\n<pre><code class=\"language-cpp\">\/*\n * gpio_control_app\n *\n * Copyright (C) 2017 wurobinson &lt;wurobinson@zhuotk.com&gt;\n *\n * This program is free software; you can redistribute it and\/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version 2\n * of the License, or (at your option) any later version.\n *\n * This program is written for JS7628 and JS9331 development board ,\n * work with gpio_control_driver\n *\/\n\n#include &quot;gpio_control_app.hpp&quot;\n\nvoid GPIOControl::release_gpio()    \/\/\u5b9a\u4e49\u91ca\u653eGPIO\u7684\u51fd\u6570           \n{\n    ioctl(gpio_dev_fd, GPIO_CONTROL_SET_IN, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n}\n\nvoid GPIOControl::release_output_demo1(int signal_no) \/\/\u5b9a\u4e49\u91ca\u653eGPIO\u7684\u51fd\u6570\n{\n    release_gpio();\n    exit(0);\n}\n\nvoid GPIOControl::release_input_demo1(int signal_no) \/\/\u5b9a\u4e49\u91ca\u653eGPIO\u7684\u51fd\u6570\n{\n    release_gpio();\n    exit(0);\n}\n\nint GPIOControl::Set(int gpio_pin, int setvalue) \/\/ set gpio output level, return 0 or -1(error).\n{\n    \/\/ \u53d6\u6d88request\u6b64GPIO\n    \/\/ ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    \/\/ close(gpio_dev_fd);\n    int ret = 0;\n    gpio_dev_fd = open(GPIO_CONTROL_DEVICE_PATH, O_RDWR); \/\/ open gpio device\n    if (gpio_dev_fd &lt; 0)\n    {\n        printf(&quot;###open %s ERROR###\\n&quot;, GPIO_CONTROL_DEVICE_PATH);\n        return -1;\n    }\n    else\n    {\n        printf(&quot;***open %s success***\\n&quot;, GPIO_CONTROL_DEVICE_PATH);\n    }\n    printf(&quot;Use gpio:%d\\n&quot;, gpio_pin);\n\n    ret = ioctl(gpio_dev_fd, GPIO_CONTROL_REQUEST_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    if (ret &lt; 0)\n    {\n        perror(&quot;ioctl error&quot;);\n        printf(&quot;###request GPIO %d error###\\n&quot;, gpio_pin);\n        close(gpio_dev_fd);\n        return -1;\n    }\n    ret = ioctl(gpio_dev_fd, GPIO_CONTROL_SET_OUT, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    if (ret &lt; 0)\n    {\n        perror(&quot;ioctl error&quot;);\n        printf(&quot;###set GPIO %d error###\\n&quot;, gpio_pin);\n        \/\/ \u53d6\u6d88request\u6b64GPIO\n        ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n        close(gpio_dev_fd);\n        return -1;\n    }\n    \/\/ signal(SIGINT, output_fun);\n    printf(&quot;Set GPIO level: %d\\n&quot;, setvalue);\n    ioctl(gpio_dev_fd, GPIO_CONTROL_SET_VALUE, GPIO_IOCTL_PRAM(gpio_pin, setvalue));\n    \/\/ \u53d6\u6d88request\u6b64GPIO\n    ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    close(gpio_dev_fd);\n}\n\nint GPIOControl::Read(int gpio_pin) \/\/ get gpio input level, return 0, 1 or -1(error).\n{\n    int res = -1;\n    int ret = 0;\n    gpio_dev_fd = open(GPIO_CONTROL_DEVICE_PATH, O_RDWR); \/\/ open gpio device\n    if (gpio_dev_fd &lt; 0)\n    {\n        printf(&quot;###open %s ERROR###\\n&quot;, GPIO_CONTROL_DEVICE_PATH);\n        return -1;\n    }\n    else\n    {\n        printf(&quot;***open %s success***\\n&quot;, GPIO_CONTROL_DEVICE_PATH);\n    }\n    printf(&quot;Use gpio: %d\\n&quot;, gpio_pin);\n\n    ret = ioctl(gpio_dev_fd, GPIO_CONTROL_REQUEST_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    if (ret &lt; 0)\n    {\n        printf(&quot;###request GPIO %d error###&quot;, gpio_pin);\n        close(gpio_dev_fd);\n        return -1;\n    }\n    ret = ioctl(gpio_dev_fd, GPIO_CONTROL_SET_IN, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    if (ret &lt; 0)\n    {\n        printf(&quot;###set GPIO %d error###&quot;, gpio_pin);\n        ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n        close(gpio_dev_fd);\n        return -1;\n    }\n    res = ioctl(gpio_dev_fd, GPIO_CONTROL_GET_VALUE, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    printf(&quot;Get GPIO level: %d\\n&quot;, res);\n    ioctl(gpio_dev_fd, GPIO_CONTROL_FREE_GPIO, GPIO_IOCTL_PRAM(gpio_pin, 0));\n    close(gpio_dev_fd);\n    return res;\n}\n\nbool GPIOControl::Read_with_debounce(int gpio_pin, int debounce_time_ms = 50, int debounce_count_in = 5) \/\/debounce\u662f\u53bb\u6296\u52a8\uff0c\u53bb\u9664\u6296\u52a8\u7684\u610f\u601d\uff0c\u8fd9\u91cc\u662f\u53bb\u9664\u6296\u52a8\u7684\u8bfb\u51fd\u6570\u3002\n{\n    int debounce_count = debounce_count_in;\n    int stable_count = 0;\n\n    struct timespec originalSleepTime;                               \/\/ \u539f\u59cb\u65f6\u95f4\n    struct timespec remaining;                                       \/\/ \u5269\u4f59\u65f6\u95f4\n    originalSleepTime.tv_sec = debounce_time_ms \/ 1000;              \/\/ \u79d2\u6570\n    originalSleepTime.tv_nsec = (debounce_time_ms % 1000) * 1000000; \/\/ \u7eb3\u79d2\u6570\n\n    for (int i = 0; i &lt; debounce_count; i++)\n    {\n        struct timespec sleepTime = originalSleepTime; \/\/ \u4f7f\u7528\u9884\u5148\u8ba1\u7b97\u7684\u65f6\u95f4\n\n        int value = Read(gpio_pin); \/\/ \u8bfb\u53d6\u7535\u5e73\n        if (value == 1)\n        {\n            stable_count++; \/\/ \u7a33\u5b9a\u9ad8\u7535\u5e73\u8ba1\u6570\n        }\n        else\n        {\n            stable_count = 0;\n        }\n\n        if (stable_count &gt;= debounce_count)\n        {\n            return true; \/\/ \u7a33\u5b9a\u9ad8\u7535\u5e73\u8bfb\u53d6\n        }\n\n        while (nanosleep(&amp;sleepTime, &amp;remaining) == -1 &amp;&amp; errno == EINTR) \/\/ \u7b49\u5f85\u4e00\u6bb5\u65f6\u95f4\n        {\n            sleepTime = remaining; \/\/ \u5982\u679c\u88ab\u4fe1\u53f7\u4e2d\u65ad\uff0c\u5219\u7ee7\u7eed\u7b49\u5f85\u5269\u4f59\u65f6\u95f4\n        }\n    }\n    return false; \/\/ \u7a33\u5b9a\u4f4e\u7535\u5e73\u8bfb\u53d6\n}\n\nvoid GPIOControl::Get_gpio_list() \/\/\u83b7\u53d6GPIO\u5217\u8868\n{\n    struct gpiochip_info info;\n    struct gpioline_info line_info;\n    int fd, ret;\n    fd = open(GPIO_CONTROL_DEVICE_PATH, O_RDONLY);\n    if (fd &lt; 0)\n    {\n        printf(&quot;Unabled to open %s: %s&quot;, GPIO_CONTROL_DEVICE_PATH, strerror(errno));\n        return;\n    }\n    ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &amp;info);\n    if (ret == -1)\n    {\n        printf(&quot;Unable to get chip info from ioctl: %s&quot;, strerror(errno));\n        close(fd);\n        return;\n    }\n    printf(&quot;Chip name: %s\\n&quot;, info.name);\n    std::cout &lt;&lt; &quot;Chip name:&quot; &lt;&lt; info.name &lt;&lt; std::endl;\n    printf(&quot;Chip label: %s\\n&quot;, info.label);\n    printf(&quot;Number of lines: %d\\n&quot;, info.lines);\n\n    for (int i = 0; i &lt; info.lines; i++)\n    {\n        line_info.line_offset = i;\n        ret = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &amp;line_info);\n        if (ret == -1)\n        {\n            printf(&quot;Unable to get line info from offset %d: %s&quot;, i, strerror(errno));\n        }\n        else\n        {\n            printf(&quot;offset: %d, name: %s, consumer: %s. Flags:\\t[%s]\\t[%s]\\t[%s]\\t[%s]\\t[%s]\\n&quot;,\n                   i,\n                   line_info.name,\n                   line_info.consumer,\n                   (line_info.flags &amp; GPIOLINE_FLAG_IS_OUT) ? &quot;OUTPUT&quot; : &quot;INPUT&quot;,\n                   (line_info.flags &amp; GPIOLINE_FLAG_ACTIVE_LOW) ? &quot;ACTIVE_LOW&quot; : &quot;ACTIVE_HIGHT&quot;,\n                   (line_info.flags &amp; GPIOLINE_FLAG_OPEN_DRAIN) ? &quot;OPEN_DRAIN&quot; : &quot;...&quot;,\n                   (line_info.flags &amp; GPIOLINE_FLAG_OPEN_SOURCE) ? &quot;OPENSOURCE&quot; : &quot;...&quot;,\n                   (line_info.flags &amp; GPIOLINE_FLAG_KERNEL) ? &quot;KERNEL&quot; : &quot;&quot;);\n        }\n    }\n    close(fd);\n}\n<\/code><\/pre>\n<p>\u5b83\u4f7f\u7528\u4e86ioctl()\u51fd\u6570\u6765\u5b9e\u73b0\u5bf9GPIO\u7684\u5404\u79cd\u64cd\u4f5c\u3002\u5728release_gpio()\u51fd\u6570\u4e2d\uff0c\u5b83\u5c06GPIO\u8bbe\u7f6e\u4e3a\u8f93\u5165\u6a21\u5f0f\u5e76\u91ca\u653e\u5b83\u3002\u5728Set()\u51fd\u6570\u4e2d\uff0c\u5b83\u6253\u5f00GPIO\u8bbe\u5907\uff0c\u8bf7\u6c42GPIO\uff0c\u5c06\u5176\u8bbe\u7f6e\u4e3a\u8f93\u51fa\u6a21\u5f0f\uff0c\u8bbe\u7f6eGPIO\u7684\u7535\u5e73\u503c\uff0c\u7136\u540e\u91ca\u653eGPIO\u5e76\u5173\u95ed\u8bbe\u5907\u3002\u5728Read()\u51fd\u6570\u4e2d\uff0c\u5b83\u6253\u5f00GPIO\u8bbe\u5907\uff0c\u8bf7\u6c42GPIO\uff0c\u5c06\u5176\u8bbe\u7f6e\u4e3a\u8f93\u5165\u6a21\u5f0f\uff0c\u83b7\u53d6GPIO\u7684\u7535\u5e73\u503c\uff0c\u7136\u540e\u91ca\u653eGPIO\u5e76\u5173\u95ed\u8bbe\u5907\u3002\u5728Read_with_debounce()\u51fd\u6570\u4e2d\uff0c\u5b83\u901a\u8fc7\u591a\u6b21\u8bfb\u53d6GPIO\u7684\u7535\u5e73\u503c\u5e76\u5728\u6bcf\u6b21\u8bfb\u53d6\u4e4b\u95f4\u7b49\u5f85\u4e00\u6bb5\u65f6\u95f4\u6765\u5b9e\u73b0\u53bb\u6296\u52a8\u7684\u6548\u679c\u3002\u5728Get_gpio_list()\u51fd\u6570\u4e2d\uff0c\u5b83\u6253\u5f00GPIO\u8bbe\u5907\uff0c\u83b7\u53d6GPIO\u7684\u4fe1\u606f\u5e76\u6253\u5370\u51fa\u6765\uff0c\u7136\u540e\u5bf9\u6bcf\u4e00\u884c\u7684GPIO\u8fdb\u884c\u64cd\u4f5c\uff0c\u83b7\u53d6\u5e76\u6253\u5370\u51fa\u5176\u4fe1\u606f\uff0c\u6700\u540e\u5173\u95ed\u8bbe\u5907\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u901a\u8fc7\u4f7f\u7528ioctl()\u51fd\u6570\u6765\u63a7\u5236GPIO\uff0c\u5b9e\u73b0\u4e86GPIO\u7684\u8bbe\u7f6e\u3001\u8bfb\u53d6\u3001\u91ca\u653e\u548c\u83b7\u53d6\u5217\u8868\u7b49\u529f\u80fd\u3002<\/p>\n<p>\u53ef\u5c06\u8fd9\u4e2a\u7a0b\u5e8f\u5f15\u5165\u5230\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\uff0c\u7136\u540e\u8c03\u7528\u76f8\u5e94\u7684\u51fd\u6570\u6765\u5b9e\u73b0GPIO\u7684\u63a7\u5236\u3002\u6bd4\u5982\uff0c\u53ef\u4ee5\u8c03\u7528Set()\u51fd\u6570\u6765\u8bbe\u7f6eGPIO\u7684\u7535\u5e73\u503c\uff0c\u8c03\u7528Read()\u51fd\u6570\u6765\u83b7\u53d6GPIO\u7684\u7535\u5e73\u503c\uff0c\u8c03\u7528Read_with_debounce()\u51fd\u6570\u6765\u83b7\u53d6GPIO\u7684\u53bb\u6296\u52a8\u7535\u5e73\u503c\uff0c\u8c03\u7528Get_gpio_list()\u51fd\u6570\u6765\u83b7\u53d6GPIO\u7684\u5217\u8868\u3002<\/p>\n<h2>5.3. \u8c03\u7528\u793a\u4f8b<\/h2>\n<p>\u4ee5\u4e0b\u662f\u4e00\u4e2a\u7b80\u5355\u7684C++\u7a0b\u5e8f\uff0c\u5b83\u4f7f\u7528\u4e86\u4e0a\u8ff0\u7684GPIO\u63a7\u5236\u7c7bGPIOControl\u6765\u5b9e\u73b0GPIO\u7684\u8bfb\u5199\u64cd\u4f5c\u3002\u5728\u8fd9\u4e2a\u7a0b\u5e8f\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2aGPIOControl\u5bf9\u8c61\uff0c\u7136\u540e\u4f7f\u7528Set()\u51fd\u6570\u6765\u8bbe\u7f6eGPIO\u7684\u7535\u5e73\u503c\uff0c\u4f7f\u7528Read()\u51fd\u6570\u6765\u8bfb\u53d6GPIO\u7684\u7535\u5e73\u503c\u3002<\/p>\n<pre><code class=\"language-cpp\">#include &quot;gpio_control_app.h&quot;\n\nint main() {\n    GPIOControl gpioControl;  \/\/ \u521b\u5efaGPIOControl\u5bf9\u8c61\n    int gpio_pin = 4;  \/\/ GPIO\u5f15\u811a\u7f16\u53f7\n    int setvalue = 1;  \/\/ \u8bbe\u7f6e\u7684\u7535\u5e73\u503c\n\n    \/\/ \u8bbe\u7f6eGPIO\u7684\u7535\u5e73\u503c\n    if (gpioControl.Set(gpio_pin, setvalue) &lt; 0) {\n        printf(&quot;Set GPIO failed.\\n&quot;);\n        return -1;\n    }\n\n    \/\/ \u8bfb\u53d6GPIO\u7684\u7535\u5e73\u503c\n    int readvalue = gpioControl.Read(gpio_pin);\n    if (readvalue &lt; 0) {\n        printf(&quot;Read GPIO failed.\\n&quot;);\n        return -1;\n    }\n\n    printf(&quot;Read GPIO value: %d\\n&quot;, readvalue);\n\n    return 0;\n}\n<\/code><\/pre>\n<h1>6. \u5176\u5b83GPIO\u7684\u63a7\u5236\u65b9\u6cd5<\/h1>\n<p>\u672c\u6587\u662f\u4ee5openwrt\u7cfb\u7edf\u4e3a\u4f8b\u6765\u8bf4\u660eGPIO\u7684\u63a7\u5236\u65b9\u6cd5\uff0c\u7531\u4e8eopenwrt\u7cfb\u7edf\u662f\u57fa\u4e8eLinux\u7cfb\u7edf\u7684\uff0c\u56e0\u6b64\u672c\u6587\u4ecb\u7ecd\u7684\u65b9\u6cd5\u4e5f\u9002\u7528\u4e8e\u5176\u5b83Linux\u7cfb\u7edf\u3002\u5982\u679c\u4f60\u4f7f\u7528\u7684\u662f\u5176\u5b83\u7cfb\u7edf\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u53c2\u8003\u672c\u6587\u7684\u65b9\u6cd5\uff0c\u6765\u5b9e\u73b0GPIO\u7684\u63a7\u5236\u3002<\/p>\n<p>\u5982\u679c\u4f60\u4f7f\u7528\u6811\u8393\u6d3e\uff0c\u6709\u591a\u79cd\u5e93\u53ef\u4ee5\u7528\u4e8e\u63a7\u5236GPIO\u3002\u4ee5\u4e0b\u662f\u4e00\u4e9b\u5e38\u7528\u7684\u5e93\u53ca\u5176\u4f7f\u7528\u65b9\u6cd5\uff1a<\/p>\n<ol>\n<li>\n<p><strong>RPi.GPIO\u5e93<\/strong>\uff1a\u8fd9\u662fPython\u5bf9\u6811\u8393\u6d3e\u7684\u63a7\u5236\u5e93\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a\u51fd\u6570\u53ef\u4ee5\u8ba9\u6211\u4eec\u83b7\u53d6\u5f15\u811a\u4fe1\u606f\u3001\u4e0e\u5916\u90e8\u8bbe\u5907\u8fdb\u884c\u6570\u636e\u4ea4\u4e92\u7b49\u7b49\u3002\u4e00\u822c\u6765\u8bb2\uff0c\u6811\u8393\u6d3e\u5b98\u65b9\u955c\u50cf\u5df2\u7ecf\u9ed8\u8ba4\u5b89\u88c5\u4e86RPi.GPIO\u5e93\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u7528 <code>pip3 list<\/code> \u6765\u67e5\u770b\u4e00\u4e0b\u5df2\u5b89\u88c5\u5e93\u5217\u8868\u3002\u5982\u679c\u6ca1\u6709\u5b89\u88c5\u7684\u8bdd\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 <code>pip3 install rpi.gpio<\/code> \u6765\u5bf9\u5176\u8fdb\u884c\u5b89\u88c5\uff0c\u6216\u8005 <code>apt-get install python3-rpi.gpio<\/code> \u8fdb\u884c\u5b89\u88c5\u3002<\/p>\n<\/li>\n<li>\n<p><strong>WiringPi\u5e93<\/strong>\uff1a\u8fd9\u662f\u5e94\u7528\u4e8e\u6811\u8393\u6d3e\u5e73\u53f0\u7684GPIO\u63a7\u5236\u5e93\u51fd\u6570\uff0c\u5176\u4f7f\u7528C\u6216\u8005C++\u5f00\u53d1\u5e76\u4e14\u53ef\u4ee5\u88ab\u5176\u4ed6\u8bed\u8a00\u5305\u8f6c\uff0c\u4f8b\u5982python\u3001ruby\u7b49\u3002\u5b89\u88c5WiringPi\u5e93\u7684\u547d\u4ee4\u662f\uff1a<code>sudo apt-get install wiringpi<\/code>\u3002WiringPi\u5305\u62ec\u4e00\u5957gpio\u547d\u4ee4\uff0c\u4f7f\u7528gpio\u547d\u4ee4\u53ef\u4ee5\u63a7\u5236\u6811\u8393\u6d3e\u4e0a\u7684\u5404\u79cd\u63a5\u53e3\u3002<\/p>\n<\/li>\n<li>\n<p><strong>Bcm2835\u5e93<\/strong>\uff1a\u8fd9\u662f\u6811\u8393\u6d3ecpu\u82af\u7247\u7684\u5e93\u51fd\u6570\uff0c\u76f8\u5f53\u4e8estm32\u7684\u56fa\u4ef6\u5e93\u4e00\u6837\uff0c\u5e95\u5c42\u662f\u76f4\u63a5\u64cd\u4f5c\u5bc4\u5b58\u5668\u3002\u5b89\u88c5Bcm2835\u5e93\u7684\u547d\u4ee4\u662f\uff1a<code>tar zxvf bcm2835-1.xx.tar.gz<\/code>\uff0c\u7136\u540e\u8fdb\u5165\u89e3\u538b\u540e\u7684\u76ee\u5f55\uff0c\u6267\u884c<code>.\/configure<\/code>\uff0c<code>make<\/code>\uff0c<code>sudo make check<\/code>\uff0c<code>sudo make install<\/code>\u3002<\/p>\n<\/li>\n<li>\n<p><strong>Pi4J\u5e93<\/strong>\uff1a\u8fd9\u662f\u4e00\u4e2a\u53ef\u4ee5\u7528Java\u5f00\u63a7\u5236\u6811\u8393\u6d3e\u7684GPIO\u53e3\u7684\u5e93\u3002<\/p>\n<\/li>\n<\/ol>\n<p>\u4ee5\u4e0a\u8fd9\u4e9b\u5e93\u90fd\u53ef\u4ee5\u7528\u4e8e\u63a7\u5236\u6811\u8393\u6d3e\u7684GPIO\uff0c\u5177\u4f53\u9009\u62e9\u54ea\u4e2a\u5e93\uff0c\u53d6\u51b3\u4e8e\u4f60\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u5177\u4f53\u9700\u6c42\u3002<\/p>\n<h1>7. \u603b\u7ed3<\/h1>\n<p>\u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u63a7\u5236GPIO\u7684\u65b9\u6cd5\u6709\u591a\u79cd\uff0c\u6bcf\u79cd\u65b9\u6cd5\u90fd\u6709\u5176\u9002\u7528\u573a\u666f\u548c\u4f18\u7f3a\u70b9\u3002\u9996\u5148\uff0csysfs\u63a5\u53e3\uff0c\u8fd9\u662f\u4e00\u79cd\u901a\u8fc7\u6587\u4ef6\u7cfb\u7edf\u6765\u8bbf\u95ee\u548c\u63a7\u5236GPIO\u7684\u65b9\u6cd5\uff0c\u5b83\u901a\u8fc7\u7b80\u5355\u7684\u6587\u4ef6\u64cd\u4f5c\u63d0\u4f9bGPIO\u7684\u8bfb\u5199\u529f\u80fd\uff0c\u975e\u5e38\u76f4\u89c2\u4e14\u6613\u4e8e\u4f7f\u7528\uff0c\u4f46\u7531\u4e8e\u5176\u6027\u80fd\u9650\u5236\u4ee5\u53caLinux\u5185\u6838\u66f4\u65b0\u540e\u9010\u6e10\u88ab\u5f03\u7528\u7684\u8d8b\u52bf\uff0c\u5b83\u53ef\u80fd\u4e0d\u662f\u957f\u671f\u7684\u89e3\u51b3\u65b9\u6848\u3002<\/p>\n<p>\u7b2c\u4e8c\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528GPIO Character Device API\uff0c\u8fd9\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u4e00\u4e2a\u73b0\u4ee3\u7684\u7f16\u7a0b\u63a5\u53e3\uff0c\u5141\u8bb8\u7528\u6237\u901a\u8fc7\u7cfb\u7edf\u8c03\u7528\u5982ioctl\u6765\u9ad8\u6548\u5730\u63a7\u5236GPIO\u3002\u4e0esysfs\u76f8\u6bd4\uff0c\u8fd9\u4e2aAPI\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u529f\u80fd\u548c\u66f4\u597d\u7684\u6027\u80fd\uff0c\u662f\u63a8\u8350\u7684\u65b9\u6cd5\u3002<\/p>\n<p>\u7b2c\u4e09\u79cd\u662f\u76f4\u63a5\u5728\u5185\u6838\u7a7a\u95f4\u7f16\u5199\u7a0b\u5e8f\uff0c\u8fd9\u79cd\u65b9\u6cd5\u867d\u7136\u53ef\u4ee5\u63d0\u4f9b\u6700\u5927\u7684\u7075\u6d3b\u6027\u548c\u63a7\u5236\u80fd\u529b\uff0c\u4f46\u7f16\u7a0b\u590d\u6742\uff0c\u4e14\u9700\u8981\u6df1\u5165\u7684\u5185\u6838\u77e5\u8bc6\uff0c\u5bf9\u4e8e\u9a71\u52a8\u5f00\u53d1\u8005\u6765\u8bf4\u662f\u9002\u7528\u7684\uff0c\u4f46\u4e00\u822c\u5e94\u7528\u7a0b\u5e8f\u5f00\u53d1\u8005\u53ef\u80fd\u4e0d\u9700\u8981\u8fd9\u6837\u505a\u3002<\/p>\n<p>\u6b64\u5916\uff0c\u5bf9\u4e8e\u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u8fd8\u6709\u76f8\u5e94\u7684\u5e93\u6765\u7b80\u5316GPIO\u7684\u63a7\u5236\u3002\u4f8b\u5982\uff0c\u5728Python\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528RPi.GPIO\u6216WiringPi\u5e93\u6765\u63a7\u5236GPIO\uff0c\u8fd9\u4e24\u4e2a\u5e93\u63d0\u4f9b\u4e86\u4e00\u5957\u7b80\u5355\u7684API\u6765\u8fdb\u884cGPIO\u64cd\u4f5c\uff0c\u7279\u522b\u9002\u5408\u90a3\u4e9b\u9700\u8981\u5feb\u901f\u5f00\u53d1\u548c\u539f\u578b\u5236\u4f5c\u7684\u573a\u5408\u3002\u5c3d\u7ba1WiringPi\u5df2\u7ecf\u4e0d\u518d\u7ef4\u62a4\uff0c\u4f46\u5176\u7b80\u6d01\u7684\u8bbe\u8ba1\u4f7f\u5f97\u5b83\u5728\u5386\u53f2\u4e0a\u88ab\u5e7f\u6cdb\u4f7f\u7528\uff0c\u5c24\u5176\u662f\u5728\u6811\u8393\u6d3e\u8fd9\u7c7b\u5355\u677f\u8ba1\u7b97\u673a\u4e0a\u3002<\/p>\n<p>\u603b\u7684\u6765\u8bf4\uff0c\u9009\u62e9\u54ea\u79cd\u65b9\u6cd5\u548c\u5e93\u6765\u63a7\u5236GPIO\uff0c\u9700\u8981\u6839\u636e\u9879\u76ee\u7684\u5177\u4f53\u9700\u6c42\u3001\u5f00\u53d1\u8005\u7684\u6280\u672f\u80cc\u666f\u4ee5\u53ca\u6240\u4f7f\u7528\u7684\u786c\u4ef6\u5e73\u53f0\u6765\u51b3\u5b9a\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. \u4ec0\u4e48\u662fGPIO\u63a7\u5236\uff1f GPIO\uff08General-pur&#8230;<\/p>\n","protected":false},"author":1,"featured_media":531,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[8,7,9],"class_list":["post-133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-10","tag-c","tag-gpio","tag-openwrt"],"_links":{"self":[{"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/comments?post=133"}],"version-history":[{"count":4,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/posts\/133\/revisions"}],"predecessor-version":[{"id":145,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/posts\/133\/revisions\/145"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/media\/531"}],"wp:attachment":[{"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/media?parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/categories?post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xuzhe.tj.cn\/index.php\/wp-json\/wp\/v2\/tags?post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}