{"id":1403,"date":"2024-07-24T10:04:38","date_gmt":"2024-07-24T02:04:38","guid":{"rendered":"https:\/\/swordofmorning.com\/?p=1403"},"modified":"2025-10-09T13:55:01","modified_gmt":"2025-10-09T05:55:01","slug":"rv1126-03","status":"publish","type":"post","link":"https:\/\/swordofmorning.com\/index.php\/2024\/07\/24\/rv1126-03\/","title":{"rendered":"RV1126 \u4e3aLinux\u6dfb\u52a0\u4e00\u4e2a\u9a71\u52a8"},"content":{"rendered":"<p><div class=\"has-toc have-toc\"><\/div><\/p>\n<p>&emsp;&emsp;\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u8bd5\u56fe\u5728<code>kernel\/driver\/misc<\/code>\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u81ea\u5df1\u7684\u9a71\u52a8\u7a0b\u5e8f\uff0c\u5e76\u5c06\u5176<code>build-in<\/code>\u5230\u7cfb\u7edf\u4e2d\u3002<\/p>\n<p>&emsp;&emsp;\u6211\u4eec\u5728<code>kernel\/driver\/misc<\/code>\u4e0b\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5939<code>my_driver<\/code>\uff0c\u5e76\u6dfb\u52a0<code>.c<\/code>\u3001<code>Makefile<\/code>\u548c<code>Kconfig<\/code><\/p>\n<h2>\u4e00\u3001hello.c<\/h2>\n<p>&emsp;&emsp;\u6211\u4eec\u8fd9\u4e2a\u5e94\u7528\u7a0b\u5e8f\u662f\u4e00\u4e2a\u6700\u7b80\u5355\u7684\u9a71\u52a8\uff0c\u5b83\u53ef\u4ee5\u4ece\u7528\u6237\u7a7a\u95f4\u8bfb\u53d6\u5b57\u7b26\u4e32\u3001\u5411\u7528\u6237\u7a7a\u95f4\u53d1\u9001\u5b57\u7b26\u4e32\uff0c\u9664\u6b64\u4e4b\u5916\u5b83\u6ca1\u6709\u5176\u4ed6\u7684\u529f\u80fd\u3002\u8fd9\u4e2a\u9a71\u52a8\u7684\u6587\u4ef6\u540d\u662f<code>hello.c<\/code>\uff0c\u8bbe\u5907\u540d\u662f<code>my_driver<\/code>\u3002<\/p>\n<pre><code class=\"language-c\">#include &lt;linux\/module.h&gt;\n#include &lt;linux\/fs.h&gt;\n#include &lt;linux\/uaccess.h&gt;\n#include &lt;linux\/init.h&gt;\n#include &lt;linux\/miscdevice.h&gt;\n\n#define DEVICE_NAME &quot;my_driver&quot;\n\nstatic ssize_t my_driver_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)\n{\n    const char *hello_world = &quot;Hello world&quot;;\n    size_t len = strlen(hello_world);\n\n    if (*ppos &gt;= len)\n        return 0;\n\n    if (count &gt; len - *ppos)\n        count = len - *ppos;\n\n    if (copy_to_user(buf, hello_world + *ppos, count))\n        return -EFAULT;\n\n    *ppos += count;\n    return count;\n}\n\nstatic ssize_t my_driver_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)\n{\n    char input_str[256];\n\n    if (count &gt; sizeof(input_str) - 1)\n        count = sizeof(input_str) - 1;\n\n    if (copy_from_user(input_str, buf, count))\n        return -EFAULT;\n\n    input_str[count] = &#039;\\0&#039;;\n    pr_info(&quot;Received string: %s\\n&quot;, input_str);\n\n    return count;\n}\n\nstatic const struct file_operations my_driver_fops = {\n    .owner = THIS_MODULE,\n    .read = my_driver_read,\n    .write = my_driver_write,\n};\n\nstatic struct miscdevice my_driver_device = {\n    .minor = MISC_DYNAMIC_MINOR,\n    .name = DEVICE_NAME,\n    .fops = &amp;my_driver_fops,\n};\n\nstatic int __init my_driver_init(void)\n{\n    int ret;\n\n    ret = misc_register(&amp;my_driver_device);\n    if (ret)\n        pr_err(&quot;Failed to register misc device\\n&quot;);\n\n    return ret;\n}\n\nstatic void __exit my_driver_exit(void)\n{\n    misc_deregister(&amp;my_driver_device);\n}\n\nmodule_init(my_driver_init);\nmodule_exit(my_driver_exit);\n\nMODULE_LICENSE(&quot;GPL&quot;);\nMODULE_AUTHOR(&quot;Your Name&quot;);\nMODULE_DESCRIPTION(&quot;A simple driver example&quot;);<\/code><\/pre>\n<h2>\u4e8c\u3001Makefile &amp; Kconfig<\/h2>\n<p>&emsp;&emsp;\u6211\u4eec\u5728<code>Makefile<\/code>\u4e2d\u6dfb\u52a0\u5982\u4e0b\u5185\u5bb9\uff1a<\/p>\n<pre><code class=\"language-makefile\">obj-$(CONFIG_MYDRIVER) += hello.o<\/code><\/pre>\n<p><code>Kconfig<\/code>\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-kconfig\">config ChooseMyDriver\n    tristate &quot;description&quot;\n    select MYDRIVER\n    default y\n    help\n      Enable support for the my_driver device.<\/code><\/pre>\n<h2>\u4e09\u3001\u5176\u4ed6\u914d\u7f6e<\/h2>\n<p>&emsp;&emsp;\u6211\u4eec\u5728<code>misc\/Kconfig<\/code>\u4e2d\u6dfb\u52a0\uff1a<\/p>\n<pre><code class=\"language-Kconfig\">config MYDRIVER\n    tristate &quot;description&quot;\n    default y\n    help\n      Say Sth.<\/code><\/pre>\n<p>\u548c\uff1a<\/p>\n<pre><code class=\"language-Kconfig\">source &quot;drivers\/misc\/my_driver\/Kconfig&quot;<\/code><\/pre>\n<p>\u540c\u65f6\uff0c\u6211\u4eec\u5728<code>misc\/Makefile<\/code>\u4e2d\u6dfb\u52a0\uff1a<\/p>\n<pre><code class=\"language-makefile\">obj-$(CONFIG_MYDRIVER)      += my_driver\/<\/code><\/pre>\n<p>\u6211\u4eec\u8fd8\u9700\u8981\u5728<code>kernel<\/code>\u7684<code>.config<\/code>\u6587\u4ef6(\u8fd9\u91cc\u7528\u7684\u662f<code>rv1126_defconfig<\/code>)\u4e2d\u6dfb\u52a0\uff1a<\/p>\n<pre><code class=\"language-config\">CONFIG_ChooseMyDriver=y<\/code><\/pre>\n<p>&emsp;&emsp;\u5b8c\u6210\u4e4b\u540e\uff0c\u6211\u4eec\u53ef\u4ee5\u7f16\u8bd1\u7cfb\u7edf\u3002\u6211\u4eec\u53ef\u4ee5\u5728<code>\/dev\/<\/code>\u4e0b\u53d1\u73b0<code>dev\/my_driver<\/code>\u8bbe\u5907\uff0c\u8bc1\u660e\u5176\u88ab\u52a0\u8f7d\u6210\u529f\u3002<\/p>\n<h2>\u56db\u3001\u9a8c\u8bc1\u7a0b\u5e8f<\/h2>\n<p>&emsp;&emsp;\u6211\u4eec\u5199\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u9a71\u52a8\uff0c\u6587\u4ef6\u76ee\u5f55\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-sh\">.\n\u251c\u2500\u2500 build\n\u251c\u2500\u2500 CMakeLists.txt\n\u2514\u2500\u2500 src\n    \u251c\u2500\u2500 CMakeLists.txt\n    \u2514\u2500\u2500 main.cpp<\/code><\/pre>\n<p>\u5176\u4e2d\uff0c\u6211\u4eec\u5728<code>.\/build<\/code>\u4e2d\u6784\u5efa\u7a0b\u5e8f\uff1b<code>src<\/code>\u7528\u6765\u5b58\u653e\u6e90\u7801\u3002<\/p>\n<p>&emsp;&emsp;\u5728<code>.\/CMakeLists.txt<\/code>\u4e2d\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-cmake\">PROJECT(Test_Driver_Application)\n\nCMAKE_MINIMUM_REQUIRED(VERSION 3.5)\n\nSET(COMPILER_PATH &quot;\/home\/xjt\/_Workspace_\/RV1126\/RV1126_RV1109_LINUX_SDK_V2.2.5.1_20230530\/buildroot\/output\/rockchip_rv1126_rv1109\/host\/bin\/&quot;)\n\nSET(CMAKE_C_COMPILER ${COMPILER_PATH}arm-linux-gnueabihf-gcc)\nSET(CMAKE_CXX_COMPILER ${COMPILER_PATH}arm-linux-gnueabihf-g++)\n\nSET(CMAKE_C_FLAGS &quot;${CMAKE_C_FLAGS} -s -O3 -lrt&quot;)\nSET(CMAKE_CXX_FLAGS &quot;${CMAKE_CXX_FLAGS} -s -O3 -lrt&quot;)\n\nADD_SUBDIRECTORY(src bin)<\/code><\/pre>\n<p>&emsp;&emsp;\u5728<code>.\/src\/CMakeLists.txt<\/code>\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-cmake\">FILE(\n    GLOB_RECURSE SRC_LIST \n    .\/*.c\n    .\/*.cpp\n)\n\n# Exe output path\nSET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR\/bin})\n\nADD_EXECUTABLE(demo ${SRC_LIST})\n\n# Link lib and so\nTARGET_LINK_LIBRARIES(\n    demo\n)<\/code><\/pre>\n<p>&emsp;&emsp;<code>main.c<\/code>\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-c\">#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;fcntl.h&gt;\n#include &lt;unistd.h&gt;\n\n#define DEVICE_PATH &quot;\/dev\/my_driver&quot;\n\nint main(void)\n{\n    int fd;\n    char buffer[256];\n    ssize_t bytes_read, bytes_written;\n\n    fd = open(DEVICE_PATH, O_RDWR);\n    if (fd == -1) {\n        perror(&quot;Failed to open device&quot;);\n        exit(EXIT_FAILURE);\n    }\n\n    bytes_read = read(fd, buffer, sizeof(buffer));\n    if (bytes_read == -1) {\n        perror(&quot;Failed to read from device&quot;);\n        close(fd);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(&quot;Read from device: %.*s\\n&quot;, (int)bytes_read, buffer);\n\n    strcpy(buffer, &quot;Hello from user space&quot;);\n    bytes_written = write(fd, buffer, strlen(buffer));\n    if (bytes_written == -1) {\n        perror(&quot;Failed to write to device&quot;);\n        close(fd);\n        exit(EXIT_FAILURE);\n    }\n\n    close(fd);\n    return 0;\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u6211\u4eec\u5728<code>.\/build<\/code>\u4e0b\u6267\u884c<code>cmake ..<\/code>\uff0c\u4e4b\u540e\u518d\u76f4\u63a5<code>make<\/code>\u3002\u5373\u53ef\u5728<code>.\/build\/bin<\/code>\u4e0b\u627e\u5230\u6700\u7ec8\u7684\u7a0b\u5e8f<code>demo<\/code>\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&emsp;&emsp;\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u8bd5\u56fe\u5728kernel\/driver\/misc\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u81ea\u5df1\u7684\u9a71\u52a8\u7a0b\u5e8f\uff0c\u5e76\u5c06\u5176build-in\u5230 &#8230;<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46],"tags":[303],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/1403"}],"collection":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/comments?post=1403"}],"version-history":[{"count":3,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/1403\/revisions"}],"predecessor-version":[{"id":1406,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/1403\/revisions\/1406"}],"wp:attachment":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/media?parent=1403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/categories?post=1403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/tags?post=1403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}