├── 7.定时器 ├── timer_test │ ├── timer_test.pro │ └── main.c ├── 7.定时器.pdf ├── ax-timer-dev │ ├── files │ │ ├── Makefile │ │ └── ax-timer-dev.c │ ├── ax-timer-dev.bb │ └── README └── system-user.dtsi ├── 6.gpio输入 ├── ax-key-test │ ├── ax-key-test.pro │ └── main.c ├── 6.gpio输入.pdf ├── ax-key-dev │ ├── files │ │ ├── Makefile │ │ └── ax-key-dev.c │ ├── ax-key-dev.bb │ └── README └── system-user.dtsi ├── 8.中断 ├── ax-key-test │ ├── ax-key-test.pro │ └── main.c ├── 8.中断.pdf ├── ax-irq-drv │ ├── files │ │ ├── Makefile │ │ ├── ax-irq-drv.c │ │ └── COPYING │ ├── ax-irq-drv.bb │ └── README └── system-user.dtsi ├── 9.阻塞IO ├── ax-key-test │ ├── ax-key-test.pro │ └── main.c ├── 9.阻塞IO.pdf ├── ax-bio-drv │ ├── files │ │ ├── Makefile │ │ └── ax-bio-drv.c │ ├── ax-bio-drv.bb │ └── README └── system-user.dtsi ├── 11.异步IO ├── ax_fasync_test │ ├── ax_fasync_test.pro │ └── main.c ├── 11.异步IO.pdf ├── ax-fasync-drv │ ├── files │ │ ├── Makefile │ │ └── ax-fasync-drv.c │ ├── ax-fasync-drv.bb │ └── README └── system-user.dtsi ├── 5.并发 ├── axledlong_test │ ├── axledlong_test.pro │ └── main.c ├── 5.并发.pdf ├── ax-concled-dev │ ├── files │ │ ├── Makefile │ │ └── ax-concled-dev.c │ ├── ax-concled-dev.bb │ └── README └── system-user.dtsi ├── 10.非阻塞IO ├── ax_nioled_test │ ├── ax_nioled_test.pro │ └── main.c ├── 10.非阻塞IO.pdf ├── ax-nio-drv │ ├── files │ │ ├── Makefile │ │ └── ax-nio-drv.c │ ├── ax-nio-drv.bb │ └── README └── system-user.dtsi ├── 1.字符设备 ├── axleddev_test │ ├── axleddev_test.pro │ └── main.c ├── 1.字符设备.pdf └── ax-led-drv │ ├── files │ ├── Makefile │ └── ax-led-drv.c │ ├── ax-led-drv.bb │ └── README ├── 2.字符设备的新写法 ├── axleddev_test │ ├── axleddev_test.pro │ └── main.c ├── 2.字符设备的新写法.pdf └── ax-newled-dev │ ├── files │ ├── Makefile │ └── ax-newled-dev.c │ ├── ax-newled-dev.bb │ └── README ├── 3.设备树与of函数 ├── axleddev_test │ ├── axleddev_test.pro │ └── main.c ├── 3.设备树与of函数.pdf ├── ax-dtled-dev │ ├── files │ │ ├── Makefile │ │ └── ax-dtled-dev.c │ ├── ax-dtled-dev.bb │ └── README └── system-user.dtsi ├── 12.platform平台设备 ├── axleddev_test │ ├── axleddev_test.pro │ └── main.c ├── 12.platform平台设备.pdf ├── ax-platform-dev │ ├── files │ │ ├── Makefile │ │ └── ax-platform-dev.c │ ├── ax-platform-dev.bb │ └── README └── ax-platform-drv │ ├── files │ ├── Makefile │ └── ax-platform-drv.c │ ├── ax-platform-drv.bb │ └── README ├── 4.pinctrl和gpio子系统 ├── axleddev_test │ ├── axleddev_test.pro │ └── main.c ├── 4.pinctrl和gpio子系统.pdf ├── ax-pinioled-dev │ ├── files │ │ ├── Makefile │ │ └── ax-pinioled-dev.c │ ├── ax-pinioled-dev.bb │ └── README └── system-user.dtsi ├── .gitignore └── README.md /7.定时器/timer_test/timer_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /6.gpio输入/ax-key-test/ax-key-test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /8.中断/ax-key-test/ax-key-test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /9.阻塞IO/ax-key-test/ax-key-test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /11.异步IO/ax_fasync_test/ax_fasync_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /5.并发/axledlong_test/axledlong_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /10.非阻塞IO/ax_nioled_test/ax_nioled_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | main.c 3 | -------------------------------------------------------------------------------- /1.字符设备/axleddev_test/axleddev_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | mian.c \ 3 | main.c 4 | -------------------------------------------------------------------------------- /2.字符设备的新写法/axleddev_test/axleddev_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | mian.c \ 3 | main.c 4 | -------------------------------------------------------------------------------- /3.设备树与of函数/axleddev_test/axleddev_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | mian.c \ 3 | main.c 4 | -------------------------------------------------------------------------------- /12.platform平台设备/axleddev_test/axleddev_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | mian.c \ 3 | main.c 4 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/axleddev_test/axleddev_test.pro: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | mian.c \ 3 | main.c 4 | -------------------------------------------------------------------------------- /5.并发/5.并发.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/5.并发/5.并发.pdf -------------------------------------------------------------------------------- /8.中断/8.中断.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/8.中断/8.中断.pdf -------------------------------------------------------------------------------- /7.定时器/7.定时器.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/7.定时器/7.定时器.pdf -------------------------------------------------------------------------------- /1.字符设备/1.字符设备.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/1.字符设备/1.字符设备.pdf -------------------------------------------------------------------------------- /9.阻塞IO/9.阻塞IO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/9.阻塞IO/9.阻塞IO.pdf -------------------------------------------------------------------------------- /11.异步IO/11.异步IO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/11.异步IO/11.异步IO.pdf -------------------------------------------------------------------------------- /10.非阻塞IO/10.非阻塞IO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/10.非阻塞IO/10.非阻塞IO.pdf -------------------------------------------------------------------------------- /6.gpio输入/6.gpio输入.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/6.gpio输入/6.gpio输入.pdf -------------------------------------------------------------------------------- /2.字符设备的新写法/2.字符设备的新写法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/2.字符设备的新写法/2.字符设备的新写法.pdf -------------------------------------------------------------------------------- /3.设备树与of函数/3.设备树与of函数.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/3.设备树与of函数/3.设备树与of函数.pdf -------------------------------------------------------------------------------- /12.platform平台设备/12.platform平台设备.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/12.platform平台设备/12.platform平台设备.pdf -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/4.pinctrl和gpio子系统.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy78963/ZYNQ7020-LinuxDrv-LearningRecord/HEAD/4.pinctrl和gpio子系统/4.pinctrl和gpio子系统.pdf -------------------------------------------------------------------------------- /8.中断/ax-irq-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-irq-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /1.字符设备/ax-led-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-led-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /10.非阻塞IO/ax-nio-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-nio-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /6.gpio输入/ax-key-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-key-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /7.定时器/ax-timer-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-timer-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /9.阻塞IO/ax-bio-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-bio-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /11.异步IO/ax-fasync-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-fasync-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /3.设备树与of函数/ax-dtled-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-dtled-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /5.并发/ax-concled-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-concled-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /2.字符设备的新写法/ax-newled-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-newled-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-platform-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-drv/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-platform-drv.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/ax-pinioled-dev/files/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := ax-pinioled-dev.o 2 | 3 | SRC := $(shell pwd) 4 | 5 | all: 6 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 7 | 8 | modules_install: 9 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 10 | 11 | clean: 12 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 13 | rm -f Module.markers Module.symvers modules.order 14 | rm -rf .tmp_versions Modules.symvers -------------------------------------------------------------------------------- /1.字符设备/ax-led-drv/ax-led-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-led-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-led-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /10.非阻塞IO/ax-nio-drv/ax-nio-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-nio-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-nio-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /6.gpio输入/ax-key-dev/ax-key-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-key-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-key-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /8.中断/ax-irq-drv/ax-irq-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-irq-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-irq-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /9.阻塞IO/ax-bio-drv/ax-bio-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-bio-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-bio-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /7.定时器/ax-timer-dev/ax-timer-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-timer-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-timer-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /3.设备树与of函数/ax-dtled-dev/ax-dtled-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-dtled-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-dtled-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /11.异步IO/ax-fasync-drv/ax-fasync-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-fasync-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-fasync-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /2.字符设备的新写法/ax-newled-dev/ax-newled-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-newled-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-newled-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /5.并发/ax-concled-dev/ax-concled-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-concled-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-concled-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-dev/ax-platform-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-platform-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-platform-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-drv/ax-platform-drv.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-platform-drv Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-platform-drv.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/ax-pinioled-dev/ax-pinioled-dev.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external ax-pinioled-dev Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://ax-pinioled-dev.c \ 10 | file://COPYING \ 11 | " 12 | 13 | S = "${WORKDIR}" 14 | 15 | # The inherit of module.bbclass will automatically name module packages with 16 | # "kernel-module-" prefix as required by the oe-core build environment. 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /1.字符设备/axleddev_test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int fd; 9 | char buf; 10 | 11 | if(3 != argc) 12 | { 13 | printf("none para\n"); 14 | return -1; 15 | } 16 | 17 | fd = open(argv[1], O_RDWR); 18 | if(fd < 0) 19 | { 20 | printf("Can't open file %s\r\n", argv[1]); 21 | return -1; 22 | } 23 | 24 | if(!strcmp("on",argv[2])) 25 | { 26 | printf("ps_led1 on\n"); 27 | buf = 1; 28 | write(fd, &buf, 1); 29 | } 30 | else if(!strcmp("off",argv[2])) 31 | { 32 | printf("ps_led1 off\n"); 33 | buf = 0; 34 | write(fd, &buf, 1); 35 | } 36 | else 37 | { 38 | printf("wrong para\n"); 39 | return -2; 40 | } 41 | 42 | close(fd); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /2.字符设备的新写法/axleddev_test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int fd; 9 | char buf; 10 | 11 | if(3 != argc) 12 | { 13 | printf("none para\n"); 14 | return -1; 15 | } 16 | 17 | fd = open(argv[1], O_RDWR); 18 | if(fd < 0) 19 | { 20 | printf("Can't open file %s\r\n", argv[1]); 21 | return -1; 22 | } 23 | 24 | if(!strcmp("on",argv[2])) 25 | { 26 | printf("ps_led1 on\n"); 27 | buf = 1; 28 | write(fd, &buf, 1); 29 | } 30 | else if(!strcmp("off",argv[2])) 31 | { 32 | printf("ps_led1 off\n"); 33 | buf = 0; 34 | write(fd, &buf, 1); 35 | } 36 | else 37 | { 38 | printf("wrong para\n"); 39 | return -2; 40 | } 41 | 42 | close(fd); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /3.设备树与of函数/axleddev_test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int fd; 9 | char buf; 10 | 11 | if(3 != argc) 12 | { 13 | printf("none para\n"); 14 | return -1; 15 | } 16 | 17 | fd = open(argv[1], O_RDWR); 18 | if(fd < 0) 19 | { 20 | printf("Can't open file %s\r\n", argv[1]); 21 | return -1; 22 | } 23 | 24 | if(!strcmp("on",argv[2])) 25 | { 26 | printf("ps_led1 on\n"); 27 | buf = 1; 28 | write(fd, &buf, 1); 29 | } 30 | else if(!strcmp("off",argv[2])) 31 | { 32 | printf("ps_led1 off\n"); 33 | buf = 0; 34 | write(fd, &buf, 1); 35 | } 36 | else 37 | { 38 | printf("wrong para\n"); 39 | return -2; 40 | } 41 | 42 | close(fd); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/axleddev_test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int fd; 9 | char buf; 10 | 11 | if(3 != argc) 12 | { 13 | printf("none para\n"); 14 | return -1; 15 | } 16 | 17 | fd = open(argv[1], O_RDWR); 18 | if(fd < 0) 19 | { 20 | printf("Can't open file %s\r\n", argv[1]); 21 | return -1; 22 | } 23 | 24 | if(!strcmp("on",argv[2])) 25 | { 26 | printf("ps_led1 on\n"); 27 | buf = 1; 28 | write(fd, &buf, 1); 29 | } 30 | else if(!strcmp("off",argv[2])) 31 | { 32 | printf("ps_led1 off\n"); 33 | buf = 0; 34 | write(fd, &buf, 1); 35 | } 36 | else 37 | { 38 | printf("wrong para\n"); 39 | return -2; 40 | } 41 | 42 | close(fd); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /5.并发/axledlong_test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int fd; 9 | char buf; 10 | int count; 11 | 12 | if(3 != argc) 13 | { 14 | printf("none para\n"); 15 | return -1; 16 | } 17 | 18 | fd = open(argv[1], O_RDWR); 19 | if(fd < 0) 20 | { 21 | printf("Can't open file %s\r\n", argv[1]); 22 | return -1; 23 | } 24 | 25 | if(!strcmp("on",argv[2])) 26 | { 27 | printf("ps_led1 on\n"); 28 | buf = 1; 29 | write(fd, &buf, 1); 30 | } 31 | else if(!strcmp("off",argv[2])) 32 | { 33 | printf("ps_led1 off\n"); 34 | buf = 0; 35 | write(fd, &buf, 1); 36 | } 37 | else 38 | { 39 | printf("wrong para\n"); 40 | return -2; 41 | } 42 | 43 | count = 20; 44 | while(count --) 45 | { 46 | sleep(1); 47 | } 48 | 49 | close(fd); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /7.定时器/timer_test/main.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "unistd.h" 3 | #include "sys/types.h" 4 | #include "sys/stat.h" 5 | #include "fcntl.h" 6 | #include "stdlib.h" 7 | #include "string.h" 8 | #include "linux/ioctl.h" 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | int fd, ret; 13 | char *filename; 14 | unsigned int interval_new, interval_old = 0; 15 | 16 | if(argc != 2) 17 | { 18 | printf("Error Usage!\r\n"); 19 | return -1; 20 | } 21 | 22 | filename = argv[1]; 23 | 24 | fd = open(filename, O_RDWR); 25 | if(fd < 0) 26 | { 27 | printf("can not open file %s\r\n", filename); 28 | return -1; 29 | } 30 | 31 | while(1) 32 | { 33 | printf("Input interval:"); 34 | scanf("%d", &interval_new); 35 | 36 | if(interval_new != interval_old) 37 | { 38 | interval_old = interval_new; 39 | ret = write(fd, &interval_new, sizeof(interval_new)); 40 | if(ret < 0) 41 | { 42 | printf("write failed\r\n"); 43 | } 44 | else 45 | { 46 | printf("interval refreshed!\r\n"); 47 | } 48 | } 49 | else 50 | { 51 | printf("same interval!"); 52 | } 53 | } 54 | close(fd); 55 | } 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /12.platform平台设备/axleddev_test/main.c: -------------------------------------------------------------------------------- 1 | /** ===================================================== ** 2 | *Author : ALINX Electronic Technology (Shanghai) Co., Ltd. 3 | *Website: http://www.alinx.com 4 | *Address: Room 202, building 18, 5 | No.518 xinbrick Road, 6 | Songjiang District, Shanghai 7 | *Created: 2020-3-2 8 | *Version: 1.0 9 | ** ===================================================== **/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int main(int argc, char **argv) 17 | { 18 | int fd; 19 | char buf; 20 | 21 | /* 验证输入参数个数 */ 22 | if(3 != argc) 23 | { 24 | printf("none para\n"); 25 | return -1; 26 | } 27 | 28 | /* 打开输入的设备文件, 获取文件句柄 */ 29 | fd = open(argv[1], O_RDWR); 30 | if(fd < 0) 31 | { 32 | /* 打开文件失败 */ 33 | printf("Can't open file %s\r\n", argv[1]); 34 | return -1; 35 | } 36 | 37 | /* 判断输入参数, on就点亮led, off则熄灭led */ 38 | if(!strcmp("on",argv[2])) 39 | { 40 | printf("ps_led1 on\n"); 41 | buf = 1; 42 | write(fd, &buf, 1); 43 | } 44 | else if(!strcmp("off",argv[2])) 45 | { 46 | printf("ps_led1 off\n"); 47 | buf = 0; 48 | write(fd, &buf, 1); 49 | } 50 | else 51 | { 52 | /* 输入参数错误 */ 53 | printf("wrong para\n"); 54 | return -2; 55 | } 56 | 57 | /* 操作结束后关闭文件 */ 58 | close(fd); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于ALINX-AX7020开发板的Linux驱动学习。 2 | -------------------------------------------- 3 | ## 暂停几周,有点忙。最近更新到了20章,还没来得及上传,回头看了一下前面的文档发现了一些错误,找机会修改后一起上传。 4 | ### 本篇是本人在ZYNQ上学习Linux驱动开发学习的笔记。 5 | ### ZYNQ上的Linux资料很少,毕竟本身也不是专门跑Linux的平台。不过借助Xilinx的一套开发工具,搭建板端的Linux系统还是很方便的。 6 | ### 主要涉及到工具有:PC端vivado、ubuntu端vivado、ubuntu端petalinux,vivado用来配置硬件资源,petalinux工具则用来快速搭建系统。具体操作,建议参考ALINX的教程,都是开源的资料,里面有详细的讲解。 7 | ------------------------------ 8 | ### 我使用的ubuntu系统是使用VM搭建的虚拟机,版本是16.04.6,尽量保证版本一致,否则很难保证不会出现奇怪的问题。 9 | ------------------------------ 10 | ### 会按项目持续更新,每个项目形式为:驱动程序(+设备树)+测试程序+实验教程。 11 | ### 若内容错误请务必不吝指正! 12 | -------------------------------------- 13 | <---------------已更新----------------> 14 | ======================================= 15 | ||==== 1.字符设备 16 | ======================================= 17 | ||==== 2.字符设备的新写法 18 | ======================================= 19 | ||==== 3.设备树与of函数 20 | ======================================= 21 | ||==== 4.pinctrl和gpio子系统 22 | ======================================= 23 | ||==== 5.并发 24 | ======================================= 25 | ||==== 6.gpio输入 26 | ======================================= 27 | ||==== 7.定时器 28 | ======================================= 29 | ||==== 8.中断 30 | ======================================= 31 | ||==== 9.阻塞IO 32 | ======================================= 33 | ||==== 10.非阻塞IO 34 | ======================================= 35 | ||==== 11.异步IO 36 | ======================================= 37 | ||==== 12.platform平台设备 38 | ======================================= 39 | -------------------------------------------------------------------------------- /8.中断/ax-key-test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | int fd, fd_l ,ret; 9 | char *filename, led_value = 0; 10 | unsigned int key_value; 11 | 12 | if(argc != 2) 13 | { 14 | printf("Error Usage\r\n"); 15 | return -1; 16 | } 17 | 18 | filename = argv[1]; 19 | fd = open(filename, O_RDWR); 20 | if(fd < 0) 21 | { 22 | printf("file %s open failed\r\n", argv[1]); 23 | return -1; 24 | } 25 | 26 | while(1) 27 | { 28 | ret = read(fd, &key_value, sizeof(key_value)); 29 | if(ret < 0) 30 | { 31 | printf("read failed\r\n"); 32 | break; 33 | } 34 | if(1 == key_value) 35 | { 36 | printf("ps_key1 press\r\n"); 37 | led_value = !led_value; 38 | 39 | fd_l = open("/dev/gpio_leds", O_RDWR); 40 | if(fd_l < 0) 41 | { 42 | printf("file /dev/gpio_leds open failed\r\n"); 43 | break; 44 | } 45 | 46 | ret = write(fd_l, &led_value, sizeof(led_value)); 47 | if(ret < 0) 48 | { 49 | printf("write failed\r\n"); 50 | break; 51 | } 52 | 53 | ret = close(fd_l); 54 | if(ret < 0) 55 | { 56 | printf("file /dev/gpio_leds close failed\r\n"); 57 | break; 58 | } 59 | } 60 | } 61 | 62 | ret = close(fd); 63 | if(ret < 0) 64 | { 65 | printf("file %s close failed\r\n", argv[1]); 66 | return -1; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /9.阻塞IO/ax-key-test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | int fd, fd_l ,ret; 9 | char *filename, led_value = 0; 10 | unsigned int key_value; 11 | 12 | if(argc != 2) 13 | { 14 | printf("Error Usage\r\n"); 15 | return -1; 16 | } 17 | 18 | filename = argv[1]; 19 | fd = open(filename, O_RDWR); 20 | if(fd < 0) 21 | { 22 | printf("file %s open failed\r\n", argv[1]); 23 | return -1; 24 | } 25 | 26 | while(1) 27 | { 28 | ret = read(fd, &key_value, sizeof(key_value)); 29 | if(ret < 0) 30 | { 31 | printf("read failed\r\n"); 32 | break; 33 | } 34 | if(1 == key_value) 35 | { 36 | printf("ps_key1 press\r\n"); 37 | led_value = !led_value; 38 | 39 | fd_l = open("/dev/gpio_leds", O_RDWR); 40 | if(fd_l < 0) 41 | { 42 | printf("file /dev/gpio_leds open failed\r\n"); 43 | break; 44 | } 45 | 46 | ret = write(fd_l, &led_value, sizeof(led_value)); 47 | if(ret < 0) 48 | { 49 | printf("write failed\r\n"); 50 | break; 51 | } 52 | 53 | ret = close(fd_l); 54 | if(ret < 0) 55 | { 56 | printf("file /dev/gpio_leds close failed\r\n"); 57 | break; 58 | } 59 | } 60 | } 61 | 62 | ret = close(fd); 63 | if(ret < 0) 64 | { 65 | printf("file %s close failed\r\n", argv[1]); 66 | return -1; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /6.gpio输入/ax-key-test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | int fd, fd_l ,ret; 9 | char *filename, led_value = 0; 10 | unsigned int key_value; 11 | 12 | if(argc != 2) 13 | { 14 | printf("Error Usage\r\n"); 15 | return -1; 16 | } 17 | 18 | filename = argv[1]; 19 | fd = open(filename, O_RDWR); 20 | if(fd < 0) 21 | { 22 | printf("file %s open failed\r\n", argv[1]); 23 | return -1; 24 | } 25 | 26 | while(1) 27 | { 28 | ret = read(fd, &key_value, sizeof(key_value)); 29 | if(ret < 0) 30 | { 31 | printf("read failed\r\n"); 32 | break; 33 | } 34 | if(1 == key_value) 35 | { 36 | printf("ps_key1 press\r\n"); 37 | led_value = !led_value; 38 | 39 | fd_l = open("/dev/gpio_leds", O_RDWR); 40 | if(fd_l < 0) 41 | { 42 | printf("file /dev/gpio_leds open failed\r\n"); 43 | break; 44 | } 45 | 46 | ret = write(fd_l, &led_value, sizeof(led_value)); 47 | if(ret < 0) 48 | { 49 | printf("write failed\r\n"); 50 | break; 51 | } 52 | 53 | ret = close(fd_l); 54 | if(ret < 0) 55 | { 56 | printf("file /dev/gpio_leds close failed\r\n"); 57 | break; 58 | } 59 | } 60 | } 61 | 62 | ret = close(fd); 63 | if(ret < 0) 64 | { 65 | printf("file %s close failed\r\n", argv[1]); 66 | return -1; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /3.设备树与of函数/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | alinxled { 20 | compatible = "alinxled"; 21 | reg = < 22 | 0xE000A204 0x04 /* gpio方向寄存器 */ 23 | 0xE000A208 0x04 /* gpio使能寄存器 */ 24 | 0xE000A040 0x04 /* gpio控制寄存器 */ 25 | 0xF800012C 0x04 /* AMBA外设时钟使能寄存器 */ 26 | >; 27 | }; 28 | 29 | }; 30 | 31 | &i2c0 { 32 | clock-frequency = <100000>; 33 | }; 34 | 35 | &usb0 { 36 | dr_mode = "host"; 37 | usb-phy = <&usb_phy0>; 38 | }; 39 | 40 | &sdhci0 { 41 | u-boot,dm-pre-reloc; 42 | }; 43 | 44 | &uart1 { 45 | u-boot,dm-pre-reloc; 46 | }; 47 | 48 | &flash0 { 49 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 50 | }; 51 | 52 | &gem0 { 53 | phy-handle = <ðernet_phy>; 54 | ethernet_phy: ethernet-phy@1 { 55 | reg = <1>; 56 | device_type = "ethernet-phy"; 57 | }; 58 | }; 59 | 60 | &amba_pl { 61 | hdmi_encoder_0:hdmi_encoder { 62 | compatible = "digilent,drm-encoder"; 63 | digilent,edid-i2c = <&i2c0>; 64 | }; 65 | 66 | xilinx_drm { 67 | compatible = "xlnx,drm"; 68 | xlnx,vtc = <&v_tc_0>; 69 | xlnx,connector-type = "HDMIA"; 70 | xlnx,encoder-slave = <&hdmi_encoder_0>; 71 | clocks = <&axi_dynclk_0>; 72 | dglnt,edid-i2c = <&i2c0>; 73 | planes { 74 | xlnx,pixel-format = "rgb888"; 75 | plane0 { 76 | dmas = <&axi_vdma_0 0>; 77 | dma-names = "dma"; 78 | }; 79 | }; 80 | }; 81 | }; 82 | 83 | &axi_dynclk_0 { 84 | compatible = "digilent,axi-dynclk"; 85 | #clock-cells = <0>; 86 | clocks = <&clkc 15>; 87 | }; 88 | 89 | &v_tc_0 { 90 | compatible = "xlnx,v-tc-5.01.a"; 91 | }; 92 | -------------------------------------------------------------------------------- /11.异步IO/ax_fasync_test/main.c: -------------------------------------------------------------------------------- 1 | /** ===================================================== ** 2 | *Author : ALINX Electronic Technology (Shanghai) Co., Ltd. 3 | *Website: http://www.alinx.com 4 | *Address: Room 202, building 18, 5 | No.518 xinbrick Road, 6 | Songjiang District, Shanghai 7 | *Created: 2020-3-2 8 | *Version: 1.0 9 | ** ===================================================== **/ 10 | 11 | #include "stdio.h" 12 | #include "unistd.h" 13 | #include "sys/types.h" 14 | #include "sys/stat.h" 15 | #include "fcntl.h" 16 | #include "stdlib.h" 17 | #include "string.h" 18 | #include "poll.h" 19 | #include "sys/select.h" 20 | #include "sys/time.h" 21 | #include "linux/ioctl.h" 22 | #include "signal.h" 23 | 24 | static int fd = 0, fd_l = 0; 25 | 26 | static void sigio_signal_func() 27 | { 28 | int ret = 0; 29 | static char led_value = 0; 30 | unsigned int key_value; 31 | 32 | /* 获取按键状态 */ 33 | ret = read(fd, &key_value, sizeof(key_value)); 34 | if(ret < 0) 35 | { 36 | printf("read failed\r\n"); 37 | } 38 | 39 | /* 判断按键状态 */ 40 | if(1 == key_value) 41 | { 42 | /* 按键被按下,改变吗led状态 */ 43 | printf("ps_key1 press\r\n"); 44 | led_value = !led_value; 45 | 46 | fd_l = open("/dev/gpio_leds", O_RDWR); 47 | if(fd_l < 0) 48 | { 49 | printf("file /dev/gpio_leds open failed\r\n"); 50 | } 51 | 52 | ret = write(fd_l, &led_value, sizeof(led_value)); 53 | if(ret < 0) 54 | { 55 | printf("write failed\r\n"); 56 | } 57 | 58 | ret = close(fd_l); 59 | if(ret < 0) 60 | { 61 | printf("file /dev/gpio_leds close failed\r\n"); 62 | } 63 | } 64 | } 65 | 66 | int main(int argc, char *argv[]) 67 | { 68 | int flags = 0; 69 | char *filename; 70 | 71 | if(argc != 2) 72 | { 73 | printf("wrong para\n"); 74 | return -1; 75 | } 76 | 77 | filename = argv[1]; 78 | fd = open(filename, O_RDWR); 79 | if(fd < 0) 80 | { 81 | printf("can not open file %s\r\n", filename); 82 | return -1; 83 | } 84 | 85 | /* 指定信号SIGIO,并绑定处理函数 */ 86 | signal(SIGIO, sigio_signal_func); 87 | /* 把当前线程指定为将接收信号的进程 */ 88 | fcntl(fd, F_SETOWN, getpid()); 89 | /* 获取当前线程状态 */ 90 | flags = fcntl(fd, F_GETFD); 91 | /* 设置当前线程为FASYNC状态 */ 92 | fcntl(fd, F_SETFL, flags | FASYNC); 93 | 94 | while(1) 95 | { 96 | sleep(2); 97 | } 98 | 99 | close(fd); 100 | return 0; 101 | } 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /5.并发/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | gpio@e000a000 { 21 | compatible = "xlnx,zynq-gpio-1.0"; 22 | #gpio-cells = <0x2>; 23 | clocks = <0x1 0x2a>; 24 | gpio-controller; 25 | interrupt-controller; 26 | #interrupt-cells = <0x2>; 27 | interrupt-parent = <0x4>; 28 | interrupts = <0x0 0x14 0x4>; 29 | reg = <0xe000a000 0x1000>; 30 | }; 31 | 32 | slcr@f8000000 { 33 | pinctrl@700 { 34 | pinctrl_led_default: led-default { 35 | mux { 36 | groups = "gpio0_0_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO0"; 42 | io-standard = <1>; 43 | bias-disable; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | }; 50 | 51 | alinxled { 52 | compatible = "alinx-led"; 53 | pinctrl-names = "default"; 54 | pinctrl-0 = <&pinctrl_led_default>; 55 | alinxled-gpios = <&gpio0 0 0>; 56 | }; 57 | }; 58 | 59 | &i2c0 { 60 | clock-frequency = <100000>; 61 | }; 62 | 63 | &usb0 { 64 | dr_mode = "host"; 65 | usb-phy = <&usb_phy0>; 66 | }; 67 | 68 | &sdhci0 { 69 | u-boot,dm-pre-reloc; 70 | }; 71 | 72 | &uart1 { 73 | u-boot,dm-pre-reloc; 74 | }; 75 | 76 | &flash0 { 77 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 78 | }; 79 | 80 | &gem0 { 81 | phy-handle = <ðernet_phy>; 82 | ethernet_phy: ethernet-phy@1 { 83 | reg = <1>; 84 | device_type = "ethernet-phy"; 85 | }; 86 | }; 87 | 88 | &amba_pl { 89 | hdmi_encoder_0:hdmi_encoder { 90 | compatible = "digilent,drm-encoder"; 91 | digilent,edid-i2c = <&i2c0>; 92 | }; 93 | 94 | xilinx_drm { 95 | compatible = "xlnx,drm"; 96 | xlnx,vtc = <&v_tc_0>; 97 | xlnx,connector-type = "HDMIA"; 98 | xlnx,encoder-slave = <&hdmi_encoder_0>; 99 | clocks = <&axi_dynclk_0>; 100 | dglnt,edid-i2c = <&i2c0>; 101 | planes { 102 | xlnx,pixel-format = "rgb888"; 103 | plane0 { 104 | dmas = <&axi_vdma_0 0>; 105 | dma-names = "dma"; 106 | }; 107 | }; 108 | }; 109 | }; 110 | 111 | &axi_dynclk_0 { 112 | compatible = "digilent,axi-dynclk"; 113 | #clock-cells = <0>; 114 | clocks = <&clkc 15>; 115 | }; 116 | 117 | &v_tc_0 { 118 | compatible = "xlnx,v-tc-5.01.a"; 119 | }; 120 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | gpio@e000a000 { 21 | compatible = "xlnx,zynq-gpio-1.0"; 22 | #gpio-cells = <0x2>; 23 | clocks = <0x1 0x2a>; 24 | gpio-controller; 25 | interrupt-controller; 26 | #interrupt-cells = <0x2>; 27 | interrupt-parent = <0x4>; 28 | interrupts = <0x0 0x14 0x4>; 29 | reg = <0xe000a000 0x1000>; 30 | }; 31 | 32 | slcr@f8000000 { 33 | pinctrl@700 { 34 | pinctrl_led_default: led-default { 35 | mux { 36 | groups = "gpio0_0_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO0"; 42 | io-standard = <1>; 43 | bias-disable; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | }; 50 | 51 | alinxled { 52 | compatible = "alinx-led"; 53 | pinctrl-names = "default"; 54 | pinctrl-0 = <&pinctrl_led_default>; 55 | alinxled-gpios = <&gpio0 0 0>; 56 | }; 57 | }; 58 | 59 | &i2c0 { 60 | clock-frequency = <100000>; 61 | }; 62 | 63 | &usb0 { 64 | dr_mode = "host"; 65 | usb-phy = <&usb_phy0>; 66 | }; 67 | 68 | &sdhci0 { 69 | u-boot,dm-pre-reloc; 70 | }; 71 | 72 | &uart1 { 73 | u-boot,dm-pre-reloc; 74 | }; 75 | 76 | &flash0 { 77 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 78 | }; 79 | 80 | &gem0 { 81 | phy-handle = <ðernet_phy>; 82 | ethernet_phy: ethernet-phy@1 { 83 | reg = <1>; 84 | device_type = "ethernet-phy"; 85 | }; 86 | }; 87 | 88 | &amba_pl { 89 | hdmi_encoder_0:hdmi_encoder { 90 | compatible = "digilent,drm-encoder"; 91 | digilent,edid-i2c = <&i2c0>; 92 | }; 93 | 94 | xilinx_drm { 95 | compatible = "xlnx,drm"; 96 | xlnx,vtc = <&v_tc_0>; 97 | xlnx,connector-type = "HDMIA"; 98 | xlnx,encoder-slave = <&hdmi_encoder_0>; 99 | clocks = <&axi_dynclk_0>; 100 | dglnt,edid-i2c = <&i2c0>; 101 | planes { 102 | xlnx,pixel-format = "rgb888"; 103 | plane0 { 104 | dmas = <&axi_vdma_0 0>; 105 | dma-names = "dma"; 106 | }; 107 | }; 108 | }; 109 | }; 110 | 111 | &axi_dynclk_0 { 112 | compatible = "digilent,axi-dynclk"; 113 | #clock-cells = <0>; 114 | clocks = <&clkc 15>; 115 | }; 116 | 117 | &v_tc_0 { 118 | compatible = "xlnx,v-tc-5.01.a"; 119 | }; 120 | -------------------------------------------------------------------------------- /1.字符设备/ax-led-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-led-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-led-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-led-drv_instance: ax-led-drv@XXXXXXXX { 42 | compatible = "vendor,ax-led-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-led-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-led-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /10.非阻塞IO/ax-nio-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-nio-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-nio-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-nio-drv_instance: ax-nio-drv@XXXXXXXX { 42 | compatible = "vendor,ax-nio-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-nio-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-nio-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /6.gpio输入/ax-key-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-key-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-key-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-key-dev_instance: ax-key-dev@XXXXXXXX { 42 | compatible = "vendor,ax-key-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-key-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-key-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /8.中断/ax-irq-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-irq-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-irq-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-irq-drv_instance: ax-irq-drv@XXXXXXXX { 42 | compatible = "vendor,ax-irq-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-irq-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-irq-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /9.阻塞IO/ax-bio-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-bio-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-bio-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-bio-drv_instance: ax-bio-drv@XXXXXXXX { 42 | compatible = "vendor,ax-bio-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-bio-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-bio-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /7.定时器/ax-timer-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-timer-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-timer-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-timer-dev_instance: ax-timer-dev@XXXXXXXX { 42 | compatible = "vendor,ax-timer-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-timer-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-timer-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /3.设备树与of函数/ax-dtled-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-dtled-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-dtled-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-dtled-dev_instance: ax-dtled-dev@XXXXXXXX { 42 | compatible = "vendor,ax-dtled-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-dtled-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-dtled-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /11.异步IO/ax-fasync-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-fasync-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-fasync-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-fasync-drv_instance: ax-fasync-drv@XXXXXXXX { 42 | compatible = "vendor,ax-fasync-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-fasync-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-fasync-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /2.字符设备的新写法/ax-newled-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-newled-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-newled-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-newled-dev_instance: ax-newled-dev@XXXXXXXX { 42 | compatible = "vendor,ax-newled-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-newled-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-newled-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /5.并发/ax-concled-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-concled-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-concled-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-concled-dev_instance: ax-concled-dev@XXXXXXXX { 42 | compatible = "vendor,ax-concled-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-concled-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-concled-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-platform-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-platform-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-platform-dev_instance: ax-platform-dev@XXXXXXXX { 42 | compatible = "vendor,ax-platform-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-platform-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-platform-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-drv/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-platform-drv.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-platform-drv" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-platform-drv_instance: ax-platform-drv@XXXXXXXX { 42 | compatible = "vendor,ax-platform-drv"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-platform-drv@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-platform-drv@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/ax-pinioled-dev/README: -------------------------------------------------------------------------------- 1 | PetaLinux User Module Template 2 | =================================== 3 | 4 | This directory contains a PetaLinux kernel module created from a template. 5 | 6 | If you are developing your module from scratch, simply start editing the 7 | file ax-pinioled-dev.c. 8 | 9 | You can easily import any existing module code by copying it into this 10 | directory, and editing the automatically generated Makefile as described below. 11 | 12 | The "all:" target in the Makefile template will compile compile the module. 13 | 14 | Modify the "install" target in Makefile to use $(TARGETROOTINST) to install your 15 | module to the host copy of the target file system referring to the 16 | comments of the "install" target. 17 | 18 | Before building the module, you will need to enable the module from 19 | PetaLinux menuconfig by running: 20 | "petalinux-config -c rootfs" 21 | You will see your module in the "Kernel Modules --->" submenu. 22 | 23 | To compile and install your module to the target file system copy on the host, 24 | simply run the 25 | "petalinux-build -c kernel" to build kernel first, and then run 26 | "petalinux-build -c ax-pinioled-dev" to build the module 27 | command. 28 | 29 | You will also need to rebuild PetaLinux bootable images so that the images 30 | is updated with the updated target filesystem copy, run this command: 31 | "petalinux-build -x package" 32 | 33 | You can also run one PetaLinux command to compile the module, install it 34 | to the target filesystem host copy and update the bootable images as follows: 35 | "petalinux-build" 36 | 37 | If OF(OpenFirmware) is configured, you need to add the device node to the 38 | DTS(Device Tree Source) file so that the device can be probed when the module is 39 | loaded. Here is an example of the device node in the device tree: 40 | 41 | ax-pinioled-dev_instance: ax-pinioled-dev@XXXXXXXX { 42 | compatible = "vendor,ax-pinioled-dev"; 43 | reg = ; 44 | interrupt-parent = <&INTR_CONTROLLER_INSTANCE>; 45 | interrupts = < INTR_NUM INTR_SENSITIVITY >; 46 | }; 47 | Notes: 48 | * "ax-pinioled-dev@XXXXXXXX" is the label of the device node, it is usually the "DEVICE_TYPE@PHYSICAL_START_ADDRESS". E.g. "ax-pinioled-dev@89000000". 49 | * "compatible" needs to match one of the the compatibles in the module's compatible list. 50 | * "reg" needs to be pair(s) of the physical start address of the device and the address range. 51 | * If the device has interrupt, the "interrupt-parent" needs to be the interrupt controller which the interrupt connects to. and the "interrupts" need to be pair(s) of the interrupt ID and the interrupt sensitivity. 52 | 53 | For more information about the the DTS file, please refer to this document in the Linux kernel: linux-2.6.x/Documentation/powerpc/booting-without-of.txt 54 | 55 | 56 | To add extra source code files (for example, to split a large module into 57 | multiple source files), add the relevant .o files to the list in the local 58 | Makefile where indicated. 59 | -------------------------------------------------------------------------------- /7.定时器/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /8.中断/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /10.非阻塞IO/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /11.异步IO/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /6.gpio输入/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /9.阻塞IO/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | model = "Zynq ALINX Development Board"; 4 | compatible = "alinx,zynq", "xlnx,zynq-7000"; 5 | 6 | aliases { 7 | ethernet0 = "&gem0"; 8 | serial0 = "&uart1"; 9 | }; 10 | 11 | usb_phy0: usb_phy@0 { 12 | compatible = "ulpi-phy"; 13 | #phy-cells = <0>; 14 | reg = <0xe0002000 0x1000>; 15 | view-port = <0x0170>; 16 | drv-vbus; 17 | }; 18 | 19 | amba { 20 | slcr@f8000000 { 21 | pinctrl_led_default: led-default { 22 | mux { 23 | groups = "gpio0_0_grp"; 24 | function = "gpio0"; 25 | }; 26 | 27 | conf { 28 | pins = "MIO0"; 29 | io-standard = <1>; 30 | bias-disable; 31 | slew-rate = <0>; 32 | }; 33 | }; 34 | pinctrl_key_default: key-default { 35 | mux { 36 | groups = "gpio0_50_grp"; 37 | function = "gpio0"; 38 | }; 39 | 40 | conf { 41 | pins = "MIO50"; 42 | io-standard = <1>; 43 | bias-high-impedance; 44 | slew-rate = <0>; 45 | }; 46 | }; 47 | }; 48 | }; 49 | 50 | alinxled { 51 | compatible = "alinx-led"; 52 | pinctrl-names = "default"; 53 | pinctrl-0 = <&pinctrl_led_default>; 54 | alinxled-gpios = <&gpio0 0 0>; 55 | }; 56 | 57 | alinxkey { 58 | compatible = "alinx-key"; 59 | pinctrl-names = "default"; 60 | pinctrl-0 = <&pinctrl_key_default>; 61 | alinxkey-gpios = <&gpio0 50 0>; 62 | }; 63 | }; 64 | 65 | &i2c0 { 66 | clock-frequency = <100000>; 67 | }; 68 | 69 | &usb0 { 70 | dr_mode = "host"; 71 | usb-phy = <&usb_phy0>; 72 | }; 73 | 74 | &sdhci0 { 75 | u-boot,dm-pre-reloc; 76 | }; 77 | 78 | &uart1 { 79 | u-boot,dm-pre-reloc; 80 | }; 81 | 82 | &flash0 { 83 | compatible = "micron,m25p80", "w25q256", "spi-flash"; 84 | }; 85 | 86 | &gem0 { 87 | phy-handle = <ðernet_phy>; 88 | ethernet_phy: ethernet-phy@1 { 89 | reg = <1>; 90 | device_type = "ethernet-phy"; 91 | }; 92 | }; 93 | 94 | &amba_pl { 95 | hdmi_encoder_0:hdmi_encoder { 96 | compatible = "digilent,drm-encoder"; 97 | digilent,edid-i2c = <&i2c0>; 98 | }; 99 | 100 | xilinx_drm { 101 | compatible = "xlnx,drm"; 102 | xlnx,vtc = <&v_tc_0>; 103 | xlnx,connector-type = "HDMIA"; 104 | xlnx,encoder-slave = <&hdmi_encoder_0>; 105 | clocks = <&axi_dynclk_0>; 106 | dglnt,edid-i2c = <&i2c0>; 107 | planes { 108 | xlnx,pixel-format = "rgb888"; 109 | plane0 { 110 | dmas = <&axi_vdma_0 0>; 111 | dma-names = "dma"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | 117 | &axi_dynclk_0 { 118 | compatible = "digilent,axi-dynclk"; 119 | #clock-cells = <0>; 120 | clocks = <&clkc 15>; 121 | }; 122 | 123 | &v_tc_0 { 124 | compatible = "xlnx,v-tc-5.01.a"; 125 | }; 126 | -------------------------------------------------------------------------------- /10.非阻塞IO/ax_nioled_test/main.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "unistd.h" 3 | #include "sys/types.h" 4 | #include "sys/stat.h" 5 | #include "fcntl.h" 6 | #include "stdlib.h" 7 | #include "string.h" 8 | #include "poll.h" 9 | #include "sys/select.h" 10 | #include "sys/time.h" 11 | #include "linux/ioctl.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | 16 | /* ret获取返回值, fd获取文件句柄 */ 17 | int ret, fd, fd_l; 18 | /* 定义一个监视文件读变化的描述符合集 */ 19 | fd_set readfds; 20 | /* 定义一个超时时间结构体 */ 21 | struct timeval timeout; 22 | 23 | char *filename, led_value = 0; 24 | unsigned int key_value; 25 | 26 | if(argc != 2) 27 | { 28 | printf("Error Usage\r\n"); 29 | return -1; 30 | } 31 | 32 | filename = argv[1]; 33 | /* 获取文件句柄, O_NONBLOCK表示非阻塞访问 */ 34 | fd = open(filename, O_RDWR | O_NONBLOCK); 35 | if(fd < 0) 36 | { 37 | printf("can not open file %s\r\n", filename); 38 | return -1; 39 | } 40 | 41 | while(1) 42 | { 43 | /* 初始化描述符合集 */ 44 | FD_ZERO(&readfds); 45 | /* 把文件句柄fd指向的文件添加到描述符 */ 46 | FD_SET(fd, &readfds); 47 | 48 | /* 超时时间初始化为1.5秒 */ 49 | timeout.tv_sec = 1; 50 | timeout.tv_usec = 500000; 51 | 52 | /* 调用select, 注意第一个参数为fd+1 */ 53 | ret = select(fd + 1, &readfds, NULL, NULL, &timeout); 54 | switch (ret) 55 | { 56 | case 0: 57 | { 58 | /* 超时 */ 59 | break; 60 | } 61 | case -1: 62 | { 63 | /* 出错 */ 64 | break; 65 | } 66 | default: 67 | { 68 | /* 监视的文件可操作 */ 69 | /* 判断可操作的文件是不是文件句柄fd指向的文件 */ 70 | if(FD_ISSET(fd, &readfds)) 71 | { 72 | /* 操作文件 */ 73 | ret = read(fd, &key_value, sizeof(key_value)); 74 | if(ret < 0) 75 | { 76 | printf("read failed\r\n"); 77 | break; 78 | } 79 | printf("key_value = %d\r\n", key_value); 80 | if(1 == key_value) 81 | { 82 | printf("ps_key1 press\r\n"); 83 | led_value = !led_value; 84 | 85 | fd_l = open("/dev/gpio_leds", O_RDWR); 86 | if(fd_l < 0) 87 | { 88 | printf("file /dev/gpio_leds open failed\r\n"); 89 | break; 90 | } 91 | 92 | ret = write(fd_l, &led_value, sizeof(led_value)); 93 | if(ret < 0) 94 | { 95 | printf("write failed\r\n"); 96 | break; 97 | } 98 | 99 | ret = close(fd_l); 100 | if(ret < 0) 101 | { 102 | printf("file /dev/gpio_leds close failed\r\n"); 103 | break; 104 | } 105 | } 106 | } 107 | break; 108 | } 109 | } 110 | } 111 | close(fd); 112 | return ret; 113 | } 114 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-dev/files/ax-platform-dev.c: -------------------------------------------------------------------------------- 1 | /** ===================================================== ** 2 | *Author : ALINX Electronic Technology (Shanghai) Co., Ltd. 3 | *Website: http://www.alinx.com 4 | *Address: Room 202, building 18, 5 | No.518 xinbrick Road, 6 | Songjiang District, Shanghai 7 | *Created: 2020-3-2 8 | *Version: 1.0 9 | ** ===================================================== **/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* 寄存器首地址 */ 31 | /* gpio方向寄存器 */ 32 | #define GPIO_DIRM_0 0xE000A204 33 | /* gpio使能寄存器 */ 34 | #define GPIO_OEN_0 0xE000A208 35 | /* gpio控制寄存器 */ 36 | #define GPIO_DATA_0 0xE000A040 37 | /* AMBA外设时钟使能寄存器 */ 38 | #define APER_CLK_CTRL 0xF800012C 39 | /* 寄存器大小 */ 40 | #define REGISTER_LENGTH 4 41 | 42 | /* 删除设备时会执行此函数 */ 43 | static void led_release(struct device *dev) 44 | { 45 | printk("led device released\r\n"); 46 | } 47 | 48 | /* 初始化LED的设备信息, 即寄存器信息 */ 49 | static struct resource led_resources[] = 50 | { 51 | { 52 | .start = GPIO_DIRM_0, 53 | .end = GPIO_DIRM_0 + REGISTER_LENGTH - 1, 54 | /* 寄存器当作内存处理 */ 55 | .flags = IORESOURCE_MEM, 56 | }, 57 | { 58 | .start = GPIO_OEN_0, 59 | .end = GPIO_OEN_0 + REGISTER_LENGTH - 1, 60 | .flags = IORESOURCE_MEM, 61 | }, 62 | { 63 | .start = GPIO_DATA_0, 64 | .end = GPIO_DATA_0 + REGISTER_LENGTH - 1, 65 | .flags = IORESOURCE_MEM, 66 | }, 67 | { 68 | .start = APER_CLK_CTRL, 69 | .end = APER_CLK_CTRL + REGISTER_LENGTH - 1, 70 | .flags = IORESOURCE_MEM, 71 | }, 72 | }; 73 | 74 | /* 声明并初始化platform_device */ 75 | static struct platform_device led_device = 76 | { 77 | /* 名字和driver中的name一致 */ 78 | .name = "alinx-led", 79 | /* 只有一个设备 */ 80 | .id = -1, 81 | .dev = { 82 | /* 设置release函数 */ 83 | .release = &led_release, 84 | }, 85 | /* 设置资源个数 */ 86 | .num_resources = ARRAY_SIZE(led_resources), 87 | /* 设置资源信息 */ 88 | .resource = led_resources, 89 | }; 90 | 91 | /* 入口函数 */ 92 | static int __init led_device_init(void) 93 | { 94 | /* 在入口函数中调用platform_driver_register, 注册platform驱动 */ 95 | return platform_device_register(&led_device); 96 | } 97 | 98 | /* 出口函数 */ 99 | static void __exit led_device_exit(void) 100 | { 101 | /* 在出口函数中调用platform_driver_register, 卸载platform驱动 */ 102 | platform_device_unregister(&led_device); 103 | } 104 | 105 | /* 标记加载、卸载函数 */ 106 | module_init(led_device_init); 107 | module_exit(led_device_exit); 108 | 109 | /* 驱动描述信息 */ 110 | MODULE_AUTHOR("Alinx"); 111 | MODULE_ALIAS("gpio_led"); 112 | MODULE_DESCRIPTION("PLATFORM LED device"); 113 | MODULE_VERSION("v1.0"); 114 | MODULE_LICENSE("GPL"); 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /1.字符设备/ax-led-drv/files/ax-led-drv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* 驱动名称 */ 9 | #define DEVICE_NAME "gpio_leds" 10 | /* 驱动主设备号 */ 11 | #define GPIO_LED_MAJOR 200 12 | 13 | /* gpio寄存器虚拟地址 */ 14 | static unsigned int gpio_add_minor; 15 | /* gpio寄存器物理基地址 */ 16 | #define GPIO_BASE 0xE000A000 17 | /* gpio寄存器所占空间大小 */ 18 | #define GPIO_SIZE 0x1000 19 | /* gpio方向寄存器 */ 20 | #define GPIO_DIRM_0 (unsigned int *)(0xE000A204 - GPIO_BASE + gpio_add_minor) 21 | /* gpio使能寄存器 */ 22 | #define GPIO_OEN_0 (unsigned int *)(0xE000A208 - GPIO_BASE + gpio_add_minor) 23 | /* gpio控制寄存器 */ 24 | #define GPIO_DATA_0 (unsigned int *)(0xE000A040 - GPIO_BASE + gpio_add_minor) 25 | 26 | /* 时钟使能寄存器虚拟地址 */ 27 | static unsigned int clk_add_minor; 28 | /* 时钟使能寄存器物理基地址 */ 29 | #define CLK_BASE 0xF8000000 30 | /* 时钟使能寄存器所占空间大小 */ 31 | #define CLK_SIZE 0x1000 32 | /* AMBA外设时钟使能寄存器 */ 33 | #define APER_CLK_CTRL (unsigned int *)(0xF800012C - CLK_BASE + clk_add_minor) 34 | 35 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 36 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 37 | { 38 | /* 把需要修改的物理地址映射到虚拟地址 */ 39 | gpio_add_minor = (unsigned int)ioremap(GPIO_BASE, GPIO_SIZE); 40 | clk_add_minor = (unsigned int)ioremap(CLK_BASE, CLK_SIZE); 41 | 42 | /* MIO_0时钟使能 */ 43 | *APER_CLK_CTRL |= 0x00400000; 44 | /* MIO_0设置成输出 */ 45 | *GPIO_DIRM_0 |= 0x00000001; 46 | /* MIO_0使能 */ 47 | *GPIO_OEN_0 |= 0x00000001; 48 | 49 | printk("gpio_test module open\n"); 50 | 51 | return 0; 52 | } 53 | 54 | 55 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 56 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 57 | { 58 | int rst; 59 | char writeBuf[5] = {0}; 60 | 61 | printk("gpio_test module write\n"); 62 | 63 | rst = copy_from_user(writeBuf, buf, len); 64 | if(0 != rst) 65 | { 66 | return -1; 67 | } 68 | 69 | if(1 != len) 70 | { 71 | printk("gpio_test len err\n"); 72 | return -2; 73 | } 74 | if(1 == writeBuf[0]) 75 | { 76 | *GPIO_DATA_0 &= 0xFFFFFFFE; 77 | printk("gpio_test ON\n"); 78 | } 79 | else if(0 == writeBuf[0]) 80 | { 81 | *GPIO_DATA_0 |= 0x00000001; 82 | printk("gpio_test OFF\n"); 83 | } 84 | else 85 | { 86 | printk("gpio_test para err\n"); 87 | return -3; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 94 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 95 | { 96 | /* MIO_0时钟失能 */ 97 | *APER_CLK_CTRL |= 0xFFBFFFFF; 98 | /* MIO_0失能 */ 99 | *GPIO_OEN_0 &= 0xFFFFFFFE; 100 | 101 | /* 释放对虚拟地址的占用 */ 102 | iounmap((unsigned int *)gpio_add_minor); 103 | iounmap((unsigned int *)clk_add_minor); 104 | 105 | printk("gpio_test module release\n"); 106 | return 0; 107 | } 108 | 109 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 110 | static struct file_operations gpio_leds_fops = { 111 | .owner = THIS_MODULE, 112 | .open = gpio_leds_open, 113 | .write = gpio_leds_write, 114 | .release = gpio_leds_release, 115 | }; 116 | 117 | /* 模块加载时会调用的函数 */ 118 | static int __init gpio_led_init(void) 119 | { 120 | int ret; 121 | 122 | /* 通过模块主设备号、名称、模块带有的功能函数(及file_operations结构体)来注册模块 */ 123 | ret = register_chrdev(GPIO_LED_MAJOR, DEVICE_NAME, &gpio_leds_fops); 124 | if (ret < 0) 125 | { 126 | printk("gpio_led_dev_init_ng\n"); 127 | return ret; 128 | } 129 | else 130 | { 131 | /* 注册成功 */ 132 | printk("gpio_led_dev_init_ok\n"); 133 | } 134 | return 0; 135 | } 136 | 137 | /* 卸载模块 */ 138 | static void __exit gpio_led_exit(void) 139 | { 140 | /* 注销模块, 释放模块对这个设备号和名称的占用 */ 141 | unregister_chrdev(GPIO_LED_MAJOR, DEVICE_NAME); 142 | 143 | printk("gpio_led_dev_exit_ok\n"); 144 | } 145 | 146 | /* 标记加载、卸载函数 */ 147 | module_init(gpio_led_init); 148 | module_exit(gpio_led_exit); 149 | 150 | /* 驱动描述信息 */ 151 | MODULE_AUTHOR("Alinx"); 152 | MODULE_ALIAS("gpio_led"); 153 | MODULE_DESCRIPTION("GPIO LED driver"); 154 | MODULE_VERSION("v1.0"); 155 | MODULE_LICENSE("GPL"); 156 | 157 | -------------------------------------------------------------------------------- /2.字符设备的新写法/ax-newled-dev/files/ax-newled-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 设备节点名称 */ 13 | #define DEVICE_NAME "gpio_leds" 14 | /* 设备号个数 */ 15 | #define DEVID_COUNT 1 16 | /* 驱动个数 */ 17 | #define DRIVE_COUNT 1 18 | /* 主设备号 */ 19 | #define MAJOR 20 | /* 次设备号 */ 21 | #define MINOR 0 22 | 23 | /* gpio寄存器虚拟地址 */ 24 | static unsigned int gpio_add_minor; 25 | /* gpio寄存器物理基地址 */ 26 | #define GPIO_BASE 0xE000A000 27 | /* gpio寄存器所占空间大小 */ 28 | #define GPIO_SIZE 0x1000 29 | /* gpio方向寄存器 */ 30 | #define GPIO_DIRM_0 (unsigned int *)(0xE000A204 - GPIO_BASE + gpio_add_minor) 31 | /* gpio使能寄存器 */ 32 | #define GPIO_OEN_0 (unsigned int *)(0xE000A208 - GPIO_BASE + gpio_add_minor) 33 | /* gpio控制寄存器 */ 34 | #define GPIO_DATA_0 (unsigned int *)(0xE000A040 - GPIO_BASE + gpio_add_minor) 35 | 36 | /* 时钟使能寄存器虚拟地址 */ 37 | static unsigned int clk_add_minor; 38 | /* 时钟使能寄存器物理基地址 */ 39 | #define CLK_BASE 0xF8000000 40 | /* 时钟使能寄存器所占空间大小 */ 41 | #define CLK_SIZE 0x1000 42 | /* AMBA外设时钟使能寄存器 */ 43 | #define APER_CLK_CTRL (unsigned int *)(0xF800012C - CLK_BASE + clk_add_minor) 44 | 45 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 46 | struct alinx_char_dev{ 47 | dev_t devid; //设备号 48 | struct cdev cdev; //字符设备 49 | struct class *class; //类 50 | struct device *device; //设备节点 51 | }; 52 | /* 声明设备结构体 */ 53 | static struct alinx_char_dev alinx_char = { 54 | .cdev = { 55 | .owner = THIS_MODULE, 56 | }, 57 | }; 58 | 59 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 60 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 61 | { 62 | /* 把需要修改的物理地址映射到虚拟地址 */ 63 | gpio_add_minor = (unsigned int)ioremap(GPIO_BASE, GPIO_SIZE); 64 | clk_add_minor = (unsigned int)ioremap(CLK_BASE, CLK_SIZE); 65 | 66 | /* MIO_0时钟使能 */ 67 | *APER_CLK_CTRL |= 0x00400000; 68 | /* MIO_0设置成输出 */ 69 | *GPIO_DIRM_0 |= 0x00000001; 70 | /* MIO_0使能 */ 71 | *GPIO_OEN_0 |= 0x00000001; 72 | 73 | printk("gpio_test module open\n"); 74 | 75 | return 0; 76 | } 77 | 78 | 79 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 80 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 81 | { 82 | int rst; 83 | char writeBuf[5] = {0}; 84 | 85 | printk("gpio_test module write\n"); 86 | 87 | rst = copy_from_user(writeBuf, buf, len); 88 | if(0 != rst) 89 | { 90 | return -1; 91 | } 92 | 93 | if(1 != len) 94 | { 95 | printk("gpio_test len err\n"); 96 | return -2; 97 | } 98 | if(1 == writeBuf[0]) 99 | { 100 | *GPIO_DATA_0 &= 0xFFFFFFFE; 101 | printk("gpio_test ON\n"); 102 | } 103 | else if(0 == writeBuf[0]) 104 | { 105 | *GPIO_DATA_0 |= 0x00000001; 106 | printk("gpio_test OFF\n"); 107 | } 108 | else 109 | { 110 | printk("gpio_test para err\n"); 111 | return -3; 112 | } 113 | 114 | return 0; 115 | } 116 | 117 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 118 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 119 | { 120 | /* 释放对虚拟地址的占用 */ 121 | iounmap((unsigned int *)gpio_add_minor); 122 | iounmap((unsigned int *)clk_add_minor); 123 | 124 | printk("gpio_test module release\n"); 125 | return 0; 126 | } 127 | 128 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 129 | static struct file_operations ax_char_fops = { 130 | .owner = THIS_MODULE, 131 | .open = gpio_leds_open, 132 | .write = gpio_leds_write, 133 | .release = gpio_leds_release, 134 | }; 135 | 136 | /* 模块加载时会调用的函数 */ 137 | static int __init gpio_led_init(void) 138 | { 139 | 140 | /* 注册设备号 */ 141 | alloc_chrdev_region(&alinx_char.devid, MINOR, DEVID_COUNT, DEVICE_NAME); 142 | 143 | /* 初始化字符设备结构体 */ 144 | cdev_init(&alinx_char.cdev, &ax_char_fops); 145 | 146 | /* 注册字符设备 */ 147 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 148 | 149 | /* 创建类 */ 150 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 151 | if(IS_ERR(alinx_char.class)) 152 | { 153 | return PTR_ERR(alinx_char.class); 154 | } 155 | 156 | /* 创建设备节点 */ 157 | alinx_char.device = device_create(alinx_char.class, NULL, 158 | alinx_char.devid, NULL, 159 | DEVICE_NAME); 160 | if (IS_ERR(alinx_char.device)) 161 | { 162 | return PTR_ERR(alinx_char.device); 163 | } 164 | 165 | return 0; 166 | } 167 | 168 | /* 卸载模块 */ 169 | static void __exit gpio_led_exit(void) 170 | { 171 | /* 注销字符设备 */ 172 | cdev_del(&alinx_char.cdev); 173 | 174 | /* 注销设备号 */ 175 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 176 | 177 | /* 删除设备节点 */ 178 | device_destroy(alinx_char.class, alinx_char.devid); 179 | 180 | /* 删除类 */ 181 | class_destroy(alinx_char.class); 182 | 183 | 184 | printk("gpio_led_dev_exit_ok\n"); 185 | } 186 | 187 | /* 标记加载、卸载函数 */ 188 | module_init(gpio_led_init); 189 | module_exit(gpio_led_exit); 190 | 191 | /* 驱动描述信息 */ 192 | MODULE_AUTHOR("Alinx"); 193 | MODULE_ALIAS("gpio_led"); 194 | MODULE_DESCRIPTION("NEW GPIO LED driver"); 195 | MODULE_VERSION("v1.0"); 196 | MODULE_LICENSE("GPL"); 197 | 198 | -------------------------------------------------------------------------------- /3.设备树与of函数/ax-dtled-dev/files/ax-dtled-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* 设备节点名称 */ 14 | #define DEVICE_NAME "gpio_leds" 15 | /* 设备号个数 */ 16 | #define DEVID_COUNT 1 17 | /* 驱动个数 */ 18 | #define DRIVE_COUNT 1 19 | /* 主设备号 */ 20 | #define MAJOR 21 | /* 次设备号 */ 22 | #define MINOR 0 23 | 24 | /* gpio寄存器虚拟地址 */ 25 | static u32 *GPIO_DIRM_0; 26 | /* gpio使能寄存器 */ 27 | static u32 *GPIO_OEN_0; 28 | /* gpio控制寄存器 */ 29 | static u32 *GPIO_DATA_0; 30 | /* AMBA外设时钟使能寄存器 */ 31 | static u32 *APER_CLK_CTRL; 32 | 33 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 34 | struct alinx_char_dev{ 35 | dev_t devid; //设备号 36 | struct cdev cdev; //字符设备 37 | struct class *class; //类 38 | struct device *device; //设备 39 | struct device_node *nd; //设备树的设备节点 40 | }; 41 | /* 声明设备结构体 */ 42 | static struct alinx_char_dev alinx_char = { 43 | .cdev = { 44 | .owner = THIS_MODULE, 45 | }, 46 | }; 47 | 48 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 49 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 50 | { 51 | /* MIO_0时钟使能 */ 52 | *APER_CLK_CTRL |= 0x00400000; 53 | /* MIO_0设置成输出 */ 54 | *GPIO_DIRM_0 |= 0x00000001; 55 | /* MIO_0使能 */ 56 | *GPIO_OEN_0 |= 0x00000001; 57 | 58 | printk("gpio_test module open\n"); 59 | 60 | return 0; 61 | } 62 | 63 | 64 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 65 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 66 | { 67 | int rst; 68 | char writeBuf[5] = {0}; 69 | 70 | printk("gpio_test module write\n"); 71 | 72 | rst = copy_from_user(writeBuf, buf, len); 73 | if(0 != rst) 74 | { 75 | return -1; 76 | } 77 | 78 | if(1 != len) 79 | { 80 | printk("gpio_test len err\n"); 81 | return -2; 82 | } 83 | if(1 == writeBuf[0]) 84 | { 85 | *GPIO_DATA_0 &= 0xFFFFFFFE; 86 | printk("gpio_test ON\n"); 87 | } 88 | else if(0 == writeBuf[0]) 89 | { 90 | *GPIO_DATA_0 |= 0x00000001; 91 | printk("gpio_test OFF\n"); 92 | } 93 | else 94 | { 95 | printk("gpio_test para err\n"); 96 | return -3; 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 103 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 104 | { 105 | printk("gpio_test module release\n"); 106 | return 0; 107 | } 108 | 109 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 110 | static struct file_operations ax_char_fops = { 111 | .owner = THIS_MODULE, 112 | .open = gpio_leds_open, 113 | .write = gpio_leds_write, 114 | .release = gpio_leds_release, 115 | }; 116 | 117 | /* 模块加载时会调用的函数 */ 118 | static int __init gpio_led_init(void) 119 | { 120 | /* 用于接受返回值 */ 121 | u32 ret = 0; 122 | /* 存放reg数据的数组 */ 123 | u32 reg_data[10]; 124 | 125 | /* 通过节点名称获取节点 */ 126 | alinx_char.nd = of_find_node_by_name(NULL, "alinxled"); 127 | /* 4、获取 reg 属性内容 */ 128 | ret = of_property_read_u32_array(alinx_char.nd, "reg", reg_data, 8); 129 | if(ret < 0) 130 | { 131 | printk("get reg failed!\r\n"); 132 | return -1; 133 | } 134 | else 135 | { 136 | /* do nothing */ 137 | } 138 | 139 | /* 把需要修改的物理地址映射到虚拟地址 */ 140 | GPIO_DIRM_0 = ioremap(reg_data[0], reg_data[1]); 141 | GPIO_OEN_0 = ioremap(reg_data[2], reg_data[3]); 142 | GPIO_DATA_0 = ioremap(reg_data[4], reg_data[5]); 143 | APER_CLK_CTRL = ioremap(reg_data[6], reg_data[7]); 144 | 145 | /* 注册设备号 */ 146 | alloc_chrdev_region(&alinx_char.devid, MINOR, DEVID_COUNT, DEVICE_NAME); 147 | 148 | /* 初始化字符设备结构体 */ 149 | cdev_init(&alinx_char.cdev, &ax_char_fops); 150 | 151 | /* 注册字符设备 */ 152 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 153 | 154 | /* 创建类 */ 155 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 156 | if(IS_ERR(alinx_char.class)) 157 | { 158 | return PTR_ERR(alinx_char.class); 159 | } 160 | 161 | /* 创建设备节点 */ 162 | alinx_char.device = device_create(alinx_char.class, NULL, 163 | alinx_char.devid, NULL, 164 | DEVICE_NAME); 165 | if (IS_ERR(alinx_char.device)) 166 | { 167 | return PTR_ERR(alinx_char.device); 168 | } 169 | 170 | return 0; 171 | } 172 | 173 | /* 卸载模块 */ 174 | static void __exit gpio_led_exit(void) 175 | { 176 | /* 注销字符设备 */ 177 | cdev_del(&alinx_char.cdev); 178 | 179 | /* 注销设备号 */ 180 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 181 | 182 | /* 删除设备节点 */ 183 | device_destroy(alinx_char.class, alinx_char.devid); 184 | 185 | /* 删除类 */ 186 | class_destroy(alinx_char.class); 187 | 188 | /* 释放对虚拟地址的占用 */ 189 | iounmap(GPIO_DIRM_0); 190 | iounmap(GPIO_OEN_0); 191 | iounmap(GPIO_DATA_0); 192 | iounmap(APER_CLK_CTRL); 193 | 194 | printk("gpio_led_dev_exit_ok\n"); 195 | } 196 | 197 | /* 标记加载、卸载函数 */ 198 | module_init(gpio_led_init); 199 | module_exit(gpio_led_exit); 200 | 201 | /* 驱动描述信息 */ 202 | MODULE_AUTHOR("Alinx"); 203 | MODULE_ALIAS("gpio_led"); 204 | MODULE_DESCRIPTION("DEVICE TREE GPIO LED driver"); 205 | MODULE_VERSION("v1.0"); 206 | MODULE_LICENSE("GPL"); 207 | 208 | -------------------------------------------------------------------------------- /4.pinctrl和gpio子系统/ax-pinioled-dev/files/ax-pinioled-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* 设备节点名称 */ 21 | #define DEVICE_NAME "gpio_leds" 22 | /* 设备号个数 */ 23 | #define DEVID_COUNT 1 24 | /* 驱动个数 */ 25 | #define DRIVE_COUNT 1 26 | /* 主设备号 */ 27 | #define MAJOR1 28 | /* 次设备号 */ 29 | #define MINOR1 0 30 | /* LED点亮时输入的值 */ 31 | #define ALINX_LED_ON 1 32 | /* LED熄灭时输入的值 */ 33 | #define ALINX_LED_OFF 0 34 | 35 | 36 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 37 | struct alinx_char_dev{ 38 | dev_t devid; //设备号 39 | struct cdev cdev; //字符设备 40 | struct class *class; //类 41 | struct device *device; //设备 42 | struct device_node *nd; //设备树的设备节点 43 | int alinx_led_gpio; //gpio号 44 | }; 45 | /* 声明设备结构体 */ 46 | static struct alinx_char_dev alinx_char = { 47 | .cdev = { 48 | .owner = THIS_MODULE, 49 | }, 50 | }; 51 | 52 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 53 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 54 | { 55 | /* 设置私有数据 */ 56 | file_p->private_data = &alinx_char; 57 | printk("gpio_test module open\n"); 58 | return 0; 59 | } 60 | 61 | 62 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 63 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 64 | { 65 | int retvalue; 66 | unsigned char databuf[1]; 67 | /* 获取私有数据 */ 68 | struct alinx_char_dev *dev = file_p->private_data; 69 | 70 | retvalue = copy_from_user(databuf, buf, len); 71 | if(retvalue < 0) 72 | { 73 | printk("alinx led write failed\r\n"); 74 | return -EFAULT; 75 | } 76 | 77 | if(databuf[0] == ALINX_LED_ON) 78 | { 79 | gpio_set_value(dev->alinx_led_gpio, !!0); 80 | } 81 | else if(databuf[0] == ALINX_LED_OFF) 82 | { 83 | gpio_set_value(dev->alinx_led_gpio, !!1); 84 | } 85 | else 86 | { 87 | printk("gpio_test para err\n"); 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 94 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 95 | { 96 | printk("gpio_test module release\n"); 97 | return 0; 98 | } 99 | 100 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 101 | static struct file_operations ax_char_fops = { 102 | .owner = THIS_MODULE, 103 | .open = gpio_leds_open, 104 | .write = gpio_leds_write, 105 | .release = gpio_leds_release, 106 | }; 107 | 108 | /* 模块加载时会调用的函数 */ 109 | static int __init gpio_led_init(void) 110 | { 111 | /* 用于接受返回值 */ 112 | u32 ret = 0; 113 | 114 | /* 获取设备节点 */ 115 | alinx_char.nd = of_find_node_by_path("/alinxled"); 116 | if(alinx_char.nd == NULL) 117 | { 118 | printk("alinx_char node not find\r\n"); 119 | return -EINVAL; 120 | } 121 | else 122 | { 123 | printk("alinx_char node find\r\n"); 124 | } 125 | 126 | /* 获取节点中gpio标号 */ 127 | alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0); 128 | if(alinx_char.alinx_led_gpio < 0) 129 | { 130 | printk("can not get alinxled-gpios"); 131 | return -EINVAL; 132 | } 133 | printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio); 134 | 135 | /* 申请gpio标号对应的引脚 */ 136 | ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled"); 137 | if(ret != 0) 138 | { 139 | printk("can not request gpio\r\n"); 140 | } 141 | 142 | /* 把这个io设置为输出 */ 143 | ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1); 144 | if(ret < 0) 145 | { 146 | printk("can not set gpio\r\n"); 147 | } 148 | 149 | /* 注册设备号 */ 150 | alloc_chrdev_region(&alinx_char.devid, MINOR1, DEVID_COUNT, DEVICE_NAME); 151 | 152 | /* 初始化字符设备结构体 */ 153 | cdev_init(&alinx_char.cdev, &ax_char_fops); 154 | 155 | /* 注册字符设备 */ 156 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 157 | 158 | /* 创建类 */ 159 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 160 | if(IS_ERR(alinx_char.class)) 161 | { 162 | return PTR_ERR(alinx_char.class); 163 | } 164 | 165 | /* 创建设备节点 */ 166 | alinx_char.device = device_create(alinx_char.class, NULL, 167 | alinx_char.devid, NULL, 168 | DEVICE_NAME); 169 | if (IS_ERR(alinx_char.device)) 170 | { 171 | return PTR_ERR(alinx_char.device); 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | /* 卸载模块 */ 178 | static void __exit gpio_led_exit(void) 179 | { 180 | /* 释放gpio */ 181 | gpio_free(alinx_char.alinx_led_gpio); 182 | 183 | /* 注销字符设备 */ 184 | cdev_del(&alinx_char.cdev); 185 | 186 | /* 注销设备号 */ 187 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 188 | 189 | /* 删除设备节点 */ 190 | device_destroy(alinx_char.class, alinx_char.devid); 191 | 192 | /* 删除类 */ 193 | class_destroy(alinx_char.class); 194 | 195 | printk("gpio_led_dev_exit_ok\n"); 196 | } 197 | 198 | /* 标记加载、卸载函数 */ 199 | module_init(gpio_led_init); 200 | module_exit(gpio_led_exit); 201 | 202 | /* 驱动描述信息 */ 203 | MODULE_AUTHOR("Alinx"); 204 | MODULE_ALIAS("gpio_led"); 205 | MODULE_DESCRIPTION("PINCTRL AND GPIO LED driver"); 206 | MODULE_VERSION("v1.0"); 207 | MODULE_LICENSE("GPL"); 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /6.gpio输入/ax-key-dev/files/ax-key-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | /* 设备节点名称 */ 22 | #define DEVICE_NAME "gpio_key" 23 | /* 设备号个数 */ 24 | #define DEVID_COUNT 1 25 | /* 驱动个数 */ 26 | #define DRIVE_COUNT 1 27 | /* 主设备号 */ 28 | #define MAJOR1 29 | /* 次设备号 */ 30 | #define MINOR1 0 31 | 32 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 33 | struct alinx_char_dev{ 34 | dev_t devid; //设备号 35 | struct cdev cdev; //字符设备 36 | struct class *class; //类 37 | struct device *device; //设备 38 | struct device_node *nd; //设备树的设备节点 39 | int alinx_key_gpio; //gpio号 40 | }; 41 | /* 声明设备结构体 */ 42 | static struct alinx_char_dev alinx_char = { 43 | .cdev = { 44 | .owner = THIS_MODULE, 45 | }, 46 | }; 47 | 48 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 49 | static int gpio_key_open(struct inode *inode_p, struct file *file_p) 50 | { 51 | /* 设置私有数据 */ 52 | file_p->private_data = &alinx_char; 53 | printk("gpio_test module open\n"); 54 | return 0; 55 | } 56 | 57 | 58 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 59 | static ssize_t gpio_key_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) 60 | { 61 | int ret = 0; 62 | /* 返回按键的值 */ 63 | unsigned int key_value = 0; 64 | /* 获取私有数据 */ 65 | struct alinx_char_dev *dev = file_p->private_data; 66 | 67 | /* 检查按键是否被按下 */ 68 | if(0 == gpio_get_value(dev->alinx_key_gpio)) 69 | { 70 | /* 按键被按下 */ 71 | /* 防抖 */ 72 | mdelay(50); 73 | /* 等待按键抬起 */ 74 | while(!gpio_get_value(dev->alinx_key_gpio)); 75 | key_value = 1; 76 | } 77 | else 78 | { 79 | /* 按键未被按下 */ 80 | } 81 | /* 返回按键状态 */ 82 | ret = copy_to_user(buf, &key_value, sizeof(key_value)); 83 | 84 | return ret; 85 | } 86 | 87 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 88 | static int gpio_key_release(struct inode *inode_p, struct file *file_p) 89 | { 90 | printk("gpio_test module release\n"); 91 | return 0; 92 | } 93 | 94 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 95 | static struct file_operations ax_char_fops = { 96 | .owner = THIS_MODULE, 97 | .open = gpio_key_open, 98 | .read = gpio_key_read, 99 | .release = gpio_key_release, 100 | }; 101 | 102 | /* 模块加载时会调用的函数 */ 103 | static int __init gpio_key_init(void) 104 | { 105 | /* 用于接受返回值 */ 106 | u32 ret = 0; 107 | 108 | /* 获取设备节点 */ 109 | alinx_char.nd = of_find_node_by_path("/alinxkey"); 110 | if(alinx_char.nd == NULL) 111 | { 112 | printk("alinx_char node not find\r\n"); 113 | return -EINVAL; 114 | } 115 | else 116 | { 117 | printk("alinx_char node find\r\n"); 118 | } 119 | 120 | /* 获取节点中gpio标号 */ 121 | alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); 122 | if(alinx_char.alinx_key_gpio < 0) 123 | { 124 | printk("can not get alinxkey-gpios"); 125 | return -EINVAL; 126 | } 127 | printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); 128 | 129 | /* 申请gpio标号对应的引脚 */ 130 | ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); 131 | if(ret != 0) 132 | { 133 | printk("can not request gpio\r\n"); 134 | return -EINVAL; 135 | } 136 | 137 | /* 把这个io设置为输入 */ 138 | ret = gpio_direction_input(alinx_char.alinx_key_gpio); 139 | if(ret < 0) 140 | { 141 | printk("can not set gpio\r\n"); 142 | return -EINVAL; 143 | } 144 | 145 | /* 注册设备号 */ 146 | alloc_chrdev_region(&alinx_char.devid, MINOR1, DEVID_COUNT, DEVICE_NAME); 147 | 148 | /* 初始化字符设备结构体 */ 149 | cdev_init(&alinx_char.cdev, &ax_char_fops); 150 | 151 | /* 注册字符设备 */ 152 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 153 | 154 | /* 创建类 */ 155 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 156 | if(IS_ERR(alinx_char.class)) 157 | { 158 | return PTR_ERR(alinx_char.class); 159 | } 160 | 161 | /* 创建设备节点 */ 162 | alinx_char.device = device_create(alinx_char.class, NULL, 163 | alinx_char.devid, NULL, 164 | DEVICE_NAME); 165 | if (IS_ERR(alinx_char.device)) 166 | { 167 | return PTR_ERR(alinx_char.device); 168 | } 169 | 170 | return 0; 171 | } 172 | 173 | /* 卸载模块 */ 174 | static void __exit gpio_key_exit(void) 175 | { 176 | /* 释放gpio */ 177 | gpio_free(alinx_char.alinx_key_gpio); 178 | 179 | /* 注销字符设备 */ 180 | cdev_del(&alinx_char.cdev); 181 | 182 | /* 注销设备号 */ 183 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 184 | 185 | /* 删除设备节点 */ 186 | device_destroy(alinx_char.class, alinx_char.devid); 187 | 188 | /* 删除类 */ 189 | class_destroy(alinx_char.class); 190 | 191 | printk("gpio_key_dev_exit_ok\n"); 192 | } 193 | 194 | /* 标记加载、卸载函数 */ 195 | module_init(gpio_key_init); 196 | module_exit(gpio_key_exit); 197 | 198 | /* 驱动描述信息 */ 199 | MODULE_AUTHOR("Alinx"); 200 | MODULE_ALIAS("gpio_key"); 201 | MODULE_DESCRIPTION("GPIO OUT driver"); 202 | MODULE_VERSION("v1.0"); 203 | MODULE_LICENSE("GPL"); 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /7.定时器/ax-timer-dev/files/ax-timer-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* 设备节点名称 */ 23 | #define DEVICE_NAME "timer_led" 24 | /* 设备号个数 */ 25 | #define DEVID_COUNT 1 26 | /* 驱动个数 */ 27 | #define DRIVE_COUNT 1 28 | /* 主设备号 */ 29 | #define MAJOR_U 30 | /* 次设备号 */ 31 | #define MINOR_U 0 32 | 33 | 34 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 35 | struct alinx_char_dev{ 36 | dev_t devid; //设备号 37 | struct cdev cdev; //字符设备 38 | struct class *class; //类 39 | struct device *device; //设备 40 | struct device_node *nd; //设备树的设备节点 41 | int alinx_led_gpio; //gpio号 42 | char led_status; //gpio状态 43 | unsigned int time_count; //定时器时间 44 | struct timer_list timer; //定时器 45 | }; 46 | /* 声明设备结构体 */ 47 | static struct alinx_char_dev alinx_char = { 48 | .cdev = { 49 | .owner = THIS_MODULE, 50 | }, 51 | }; 52 | 53 | void timer_function(unsigned long data) 54 | { 55 | /* 反转led状态 */ 56 | alinx_char.led_status = !alinx_char.led_status; 57 | /* 设置led */ 58 | gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status); 59 | /* 重新开始计时 */ 60 | mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count)); 61 | } 62 | 63 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 64 | static int timer_led_open(struct inode *inode_p, struct file *file_p) 65 | { 66 | printk("gpio_test module open\n"); 67 | return 0; 68 | } 69 | 70 | 71 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 72 | static ssize_t timer_led_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 73 | { 74 | int retvalue; 75 | /* 获取用户数据 */ 76 | retvalue = copy_from_user(&alinx_char.time_count, buf, len); 77 | /* 设置好timer后先点亮led */ 78 | alinx_char.led_status = 1; 79 | gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status); 80 | /* 开启timer */ 81 | mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count)); 82 | 83 | return 0; 84 | } 85 | 86 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 87 | static int timer_led_release(struct inode *inode_p, struct file *file_p) 88 | { 89 | printk("gpio_test module release\n"); 90 | /* 删除定时器 */ 91 | del_timer_sync(&alinx_char.timer); 92 | return 0; 93 | } 94 | 95 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 96 | static struct file_operations ax_char_fops = { 97 | .owner = THIS_MODULE, 98 | .open = timer_led_open, 99 | .write = timer_led_write, 100 | .release = timer_led_release, 101 | }; 102 | 103 | /* 模块加载时会调用的函数 */ 104 | static int __init timer_led_init(void) 105 | { 106 | /* 用于接受返回值 */ 107 | u32 ret = 0; 108 | 109 | /* 获取led设备节点 */ 110 | alinx_char.nd = of_find_node_by_path("/alinxled"); 111 | if(alinx_char.nd == NULL) 112 | { 113 | printk("alinx_char node not find\r\n"); 114 | return -EINVAL; 115 | } 116 | else 117 | { 118 | printk("alinx_char node find\r\n"); 119 | } 120 | 121 | /* 获取节点中gpio标号 */ 122 | alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0); 123 | if(alinx_char.alinx_led_gpio < 0) 124 | { 125 | printk("can not get alinxled-gpios"); 126 | return -EINVAL; 127 | } 128 | printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio); 129 | 130 | /* 申请gpio标号对应的引脚 */ 131 | ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled"); 132 | if(ret != 0) 133 | { 134 | printk("can not request gpio\r\n"); 135 | } 136 | 137 | /* 把这个io设置为输出 */ 138 | ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1); 139 | if(ret < 0) 140 | { 141 | printk("can not set gpio\r\n"); 142 | } 143 | 144 | /* 注册设备号 */ 145 | alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); 146 | 147 | /* 初始化字符设备结构体 */ 148 | cdev_init(&alinx_char.cdev, &ax_char_fops); 149 | 150 | /* 注册字符设备 */ 151 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 152 | 153 | /* 创建类 */ 154 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 155 | if(IS_ERR(alinx_char.class)) 156 | { 157 | return PTR_ERR(alinx_char.class); 158 | } 159 | 160 | /* 创建设备节点 */ 161 | alinx_char.device = device_create(alinx_char.class, NULL, 162 | alinx_char.devid, NULL, 163 | DEVICE_NAME); 164 | if (IS_ERR(alinx_char.device)) 165 | { 166 | return PTR_ERR(alinx_char.device); 167 | } 168 | 169 | /* 设置定时器回掉函数 */ 170 | alinx_char.timer.function = timer_function; 171 | /* 初始化定时器 */ 172 | init_timer(&alinx_char.timer); 173 | return 0; 174 | } 175 | 176 | /* 卸载模块 */ 177 | static void __exit timer_led_exit(void) 178 | { 179 | /* 释放gpio */ 180 | gpio_free(alinx_char.alinx_led_gpio); 181 | 182 | /* 注销字符设备 */ 183 | cdev_del(&alinx_char.cdev); 184 | 185 | /* 注销设备号 */ 186 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 187 | 188 | /* 删除设备节点 */ 189 | device_destroy(alinx_char.class, alinx_char.devid); 190 | 191 | /* 删除类 */ 192 | class_destroy(alinx_char.class); 193 | 194 | printk("timer_led_dev_exit_ok\n"); 195 | } 196 | 197 | /* 标记加载、卸载函数 */ 198 | module_init(timer_led_init); 199 | module_exit(timer_led_exit); 200 | 201 | /* 驱动描述信息 */ 202 | MODULE_AUTHOR("Alinx"); 203 | MODULE_ALIAS("gpio_led"); 204 | MODULE_DESCRIPTION("TIMER LED driver"); 205 | MODULE_VERSION("v1.0"); 206 | MODULE_LICENSE("GPL"); 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /12.platform平台设备/ax-platform-drv/files/ax-platform-drv.c: -------------------------------------------------------------------------------- 1 | /** ===================================================== ** 2 | *Author : ALINX Electronic Technology (Shanghai) Co., Ltd. 3 | *Website: http://www.alinx.com 4 | *Address: Room 202, building 18, 5 | No.518 xinbrick Road, 6 | Songjiang District, Shanghai 7 | *Created: 2020-3-2 8 | *Version: 1.0 9 | ** ===================================================== **/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /* 设备节点名称 */ 35 | #define DEVICE_NAME "gpio_leds" 36 | /* 设备号个数 */ 37 | #define DEVID_COUNT 1 38 | /* 驱动个数 */ 39 | #define DRIVE_COUNT 1 40 | /* 主设备号 */ 41 | #define MAJOR 42 | /* 次设备号 */ 43 | #define MINOR 0 44 | 45 | /* gpio寄存器虚拟地址 */ 46 | static u32 *GPIO_DIRM_0; 47 | /* gpio使能寄存器 */ 48 | static u32 *GPIO_OEN_0; 49 | /* gpio控制寄存器 */ 50 | static u32 *GPIO_DATA_0; 51 | /* AMBA外设时钟使能寄存器 */ 52 | static u32 *APER_CLK_CTRL; 53 | 54 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 55 | struct alinx_char_dev{ 56 | dev_t devid; //设备号 57 | struct cdev cdev; //字符设备 58 | struct class *class; //类 59 | struct device *device; //设备 60 | }; 61 | /* 声明设备结构体 */ 62 | static struct alinx_char_dev alinx_char = { 63 | .cdev = { 64 | .owner = THIS_MODULE, 65 | }, 66 | }; 67 | 68 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 69 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 70 | { 71 | /* 设置私有数据 */ 72 | file_p->private_data = &alinx_char; 73 | 74 | return 0; 75 | } 76 | 77 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 78 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 79 | { 80 | int rst; 81 | char writeBuf[5] = {0}; 82 | 83 | rst = copy_from_user(writeBuf, buf, len); 84 | if(0 != rst) 85 | { 86 | return -1; 87 | } 88 | 89 | if(1 != len) 90 | { 91 | printk("gpio_test len err\n"); 92 | return -2; 93 | } 94 | if(1 == writeBuf[0]) 95 | { 96 | *GPIO_DATA_0 &= 0xFFFFFFFE; 97 | } 98 | else if(0 == writeBuf[0]) 99 | { 100 | *GPIO_DATA_0 |= 0x00000001; 101 | } 102 | else 103 | { 104 | printk("gpio_test para err\n"); 105 | return -3; 106 | } 107 | 108 | return 0; 109 | } 110 | 111 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 112 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 113 | { 114 | return 0; 115 | } 116 | 117 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 118 | static struct file_operations ax_char_fops = { 119 | .owner = THIS_MODULE, 120 | .open = gpio_leds_open, 121 | .write = gpio_leds_write, 122 | .release = gpio_leds_release, 123 | }; 124 | 125 | /* probe函数实现, 驱动和设备匹配时会被调用 */ 126 | static int gpio_leds_probe(struct platform_device *dev) 127 | { 128 | /* 资源大小 */ 129 | int regsize[4]; 130 | /* 资源信息 */ 131 | struct resource *led_source[4]; 132 | 133 | int i; 134 | for(i = 0; i < 4; i ++) 135 | { 136 | /* 获取dev中的IORESOURCE_MEM资源 */ 137 | led_source[i] = platform_get_resource(dev, IORESOURCE_MEM, i); 138 | /* 返回NULL获取资源失败 */ 139 | if(!led_source[i]) 140 | { 141 | dev_err(&dev->dev, "get resource %d failed\r\n", i); 142 | return -ENXIO; 143 | } 144 | /* 获取当前资源大小 */ 145 | regsize[i] = resource_size(led_source[i]); 146 | } 147 | 148 | /* 把需要修改的物理地址映射到虚拟地址 */ 149 | GPIO_DIRM_0 = ioremap(led_source[0]->start, regsize[0]); 150 | GPIO_OEN_0 = ioremap(led_source[1]->start, regsize[1]); 151 | GPIO_DATA_0 = ioremap(led_source[2]->start, regsize[2]); 152 | APER_CLK_CTRL = ioremap(led_source[3]->start, regsize[3]); 153 | 154 | /* MIO_0时钟使能 */ 155 | *APER_CLK_CTRL |= 0x00400000; 156 | /* MIO_0设置成输出 */ 157 | *GPIO_DIRM_0 |= 0x00000001; 158 | /* MIO_0使能 */ 159 | *GPIO_OEN_0 |= 0x00000001; 160 | 161 | /* 注册设备号 */ 162 | alloc_chrdev_region(&alinx_char.devid, MINOR, DEVID_COUNT, DEVICE_NAME); 163 | 164 | /* 初始化字符设备结构体 */ 165 | cdev_init(&alinx_char.cdev, &ax_char_fops); 166 | 167 | /* 注册字符设备 */ 168 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 169 | 170 | /* 创建类 */ 171 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 172 | if(IS_ERR(alinx_char.class)) 173 | { 174 | return PTR_ERR(alinx_char.class); 175 | } 176 | 177 | /* 创建设备节点 */ 178 | alinx_char.device = device_create(alinx_char.class, NULL, 179 | alinx_char.devid, NULL, 180 | DEVICE_NAME); 181 | if (IS_ERR(alinx_char.device)) 182 | { 183 | return PTR_ERR(alinx_char.device); 184 | } 185 | 186 | return 0; 187 | } 188 | 189 | static int gpio_leds_remove(struct platform_device *dev) 190 | { 191 | /* 注销字符设备 */ 192 | cdev_del(&alinx_char.cdev); 193 | 194 | /* 注销设备号 */ 195 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 196 | 197 | /* 删除设备节点 */ 198 | device_destroy(alinx_char.class, alinx_char.devid); 199 | 200 | /* 删除类 */ 201 | class_destroy(alinx_char.class); 202 | 203 | /* 释放对虚拟地址的占用 */ 204 | iounmap(GPIO_DIRM_0); 205 | iounmap(GPIO_OEN_0); 206 | iounmap(GPIO_DATA_0); 207 | return 0; 208 | } 209 | 210 | /* 声明并初始化platform驱动 */ 211 | static struct platform_driver led_driver = { 212 | .driver = { 213 | /* 将会用name字段和设备匹配, 这里name命名为alinx-led */ 214 | .name = "alinx-led", 215 | }, 216 | .probe = gpio_leds_probe, 217 | .remove = gpio_leds_remove, 218 | }; 219 | 220 | /* 驱动入口函数 */ 221 | static int __init gpio_led_drv_init(void) 222 | { 223 | /* 在入口函数中调用platform_driver_register, 注册platform驱动 */ 224 | return platform_driver_register(&led_driver); 225 | } 226 | 227 | /* 驱动出口函数 */ 228 | static void __exit gpio_led_dev_exit(void) 229 | { 230 | /* 在出口函数中调用platform_driver_register, 卸载platform驱动 */ 231 | platform_driver_unregister(&led_driver); 232 | } 233 | 234 | /* 标记加载、卸载函数 */ 235 | module_init(gpio_led_drv_init); 236 | module_exit(gpio_led_dev_exit); 237 | 238 | /* 驱动描述信息 */ 239 | MODULE_AUTHOR("Alinx"); 240 | MODULE_ALIAS("gpio_led"); 241 | MODULE_DESCRIPTION("PLATFORM LED driver"); 242 | MODULE_VERSION("v1.0"); 243 | MODULE_LICENSE("GPL"); 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /8.中断/ax-irq-drv/files/ax-irq-drv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /* 设备节点名称 */ 24 | #define DEVICE_NAME "interrupt_led" 25 | /* 设备号个数 */ 26 | #define DEVID_COUNT 1 27 | /* 驱动个数 */ 28 | #define DRIVE_COUNT 1 29 | /* 主设备号 */ 30 | #define MAJOR_U 31 | /* 次设备号 */ 32 | #define MINOR_U 0 33 | 34 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 35 | struct alinx_char_dev { 36 | /** 字符设备框架 **/ 37 | dev_t devid; //设备号 38 | struct cdev cdev; //字符设备 39 | struct class *class; //类 40 | struct device *device; //设备 41 | struct device_node *nd; //设备树的设备节点 42 | /** 并发处理 **/ 43 | spinlock_t lock; //自旋锁变量 44 | /** gpio **/ 45 | int alinx_key_gpio; //gpio号 46 | int key_sts; //记录按键状态, 为1时被按下 47 | /** 中断 **/ 48 | unsigned int irq; //中断号 49 | /** 定时器 **/ 50 | struct timer_list timer; //定时器 51 | }; 52 | /* 声明设备结构体 */ 53 | static struct alinx_char_dev alinx_char = { 54 | .cdev = { 55 | .owner = THIS_MODULE, 56 | }, 57 | }; 58 | 59 | /** 回掉 **/ 60 | /* 中断服务函数 */ 61 | static irqreturn_t key_handler(int irq, void *dev) 62 | { 63 | /* 按键按下或抬起时会进入中断 */ 64 | /* 开启50毫秒的定时器用作防抖动 */ 65 | mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(50)); 66 | return IRQ_RETVAL(IRQ_HANDLED); 67 | } 68 | 69 | /* 定时器服务函数 */ 70 | void timer_function(unsigned long arg) 71 | { 72 | unsigned long flags; 73 | /* 获取锁 */ 74 | spin_lock_irqsave(&alinx_char.lock, flags); 75 | 76 | /* value用于获取按键值 */ 77 | unsigned char value; 78 | /* 获取按键值 */ 79 | value = gpio_get_value(alinx_char.alinx_key_gpio); 80 | if(value == 0) 81 | { 82 | /* 按键按下, 状态置1 */ 83 | alinx_char.key_sts = 1; 84 | } 85 | else 86 | { 87 | /* 按键抬起 */ 88 | } 89 | 90 | /* 释放锁 */ 91 | spin_unlock_irqrestore(&alinx_char.lock, flags); 92 | } 93 | 94 | /** 系统调用实现 **/ 95 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 96 | static int char_drv_open(struct inode *inode_p, struct file *file_p) 97 | { 98 | printk("gpio_test module open\n"); 99 | return 0; 100 | } 101 | 102 | 103 | /* read函数实现, 对应到Linux系统调用函数的write函数 */ 104 | static ssize_t char_drv_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) 105 | { 106 | unsigned long flags; 107 | int ret; 108 | /* 获取锁 */ 109 | spin_lock_irqsave(&alinx_char.lock, flags); 110 | 111 | /* keysts用于读取按键状态 */ 112 | /* 返回按键状态值 */ 113 | ret = copy_to_user(buf, &alinx_char.key_sts, sizeof(alinx_char.key_sts)); 114 | /* 清除按键状态 */ 115 | alinx_char.key_sts = 0; 116 | 117 | /* 释放锁 */ 118 | spin_unlock_irqrestore(&alinx_char.lock, flags); 119 | return 0; 120 | } 121 | 122 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 123 | static int char_drv_release(struct inode *inode_p, struct file *file_p) 124 | { 125 | printk("gpio_test module release\n"); 126 | return 0; 127 | } 128 | 129 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 130 | static struct file_operations ax_char_fops = { 131 | .owner = THIS_MODULE, 132 | .open = char_drv_open, 133 | .read = char_drv_read, 134 | .release = char_drv_release, 135 | }; 136 | 137 | /* 模块加载时会调用的函数 */ 138 | static int __init char_drv_init(void) 139 | { 140 | /* 用于接受返回值 */ 141 | u32 ret = 0; 142 | 143 | /** 并发处理 **/ 144 | /* 初始化自旋锁 */ 145 | spin_lock_init(&alinx_char.lock); 146 | 147 | /** gpio框架 **/ 148 | /* 获取设备节点 */ 149 | alinx_char.nd = of_find_node_by_path("/alinxkey"); 150 | if(alinx_char.nd == NULL) 151 | { 152 | printk("alinx_char node not find\r\n"); 153 | return -EINVAL; 154 | } 155 | else 156 | { 157 | printk("alinx_char node find\r\n"); 158 | } 159 | 160 | /* 获取节点中gpio标号 */ 161 | alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); 162 | if(alinx_char.alinx_key_gpio < 0) 163 | { 164 | printk("can not get alinxkey-gpios"); 165 | return -EINVAL; 166 | } 167 | printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); 168 | 169 | /* 申请gpio标号对应的引脚 */ 170 | ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); 171 | if(ret != 0) 172 | { 173 | printk("can not request gpio\r\n"); 174 | return -EINVAL; 175 | } 176 | 177 | /* 把这个io设置为输入 */ 178 | ret = gpio_direction_input(alinx_char.alinx_key_gpio); 179 | if(ret < 0) 180 | { 181 | printk("can not set gpio\r\n"); 182 | return -EINVAL; 183 | } 184 | 185 | /** 中断 **/ 186 | /* 获取中断号 */ 187 | alinx_char.irq = gpio_to_irq(alinx_char.alinx_key_gpio); 188 | /* 申请中断 */ 189 | ret = request_irq(alinx_char.irq, 190 | key_handler, 191 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 192 | "alinxkey", 193 | NULL); 194 | if(ret < 0) 195 | { 196 | printk("irq %d request failed\r\n", alinx_char.irq); 197 | return -EFAULT; 198 | } 199 | 200 | /** 定时器 **/ 201 | alinx_char.timer.function = timer_function; 202 | init_timer(&alinx_char.timer); 203 | 204 | /** 字符设备框架 **/ 205 | /* 注册设备号 */ 206 | alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); 207 | 208 | /* 初始化字符设备结构体 */ 209 | cdev_init(&alinx_char.cdev, &ax_char_fops); 210 | 211 | /* 注册字符设备 */ 212 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 213 | 214 | /* 创建类 */ 215 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 216 | if(IS_ERR(alinx_char.class)) 217 | { 218 | return PTR_ERR(alinx_char.class); 219 | } 220 | 221 | /* 创建设备节点 */ 222 | alinx_char.device = device_create(alinx_char.class, NULL, 223 | alinx_char.devid, NULL, 224 | DEVICE_NAME); 225 | if (IS_ERR(alinx_char.device)) 226 | { 227 | return PTR_ERR(alinx_char.device); 228 | } 229 | 230 | return 0; 231 | } 232 | 233 | /* 卸载模块 */ 234 | static void __exit char_drv_exit(void) 235 | { 236 | /** gpio **/ 237 | /* 释放gpio */ 238 | gpio_free(alinx_char.alinx_key_gpio); 239 | 240 | /** 中断 **/ 241 | /* 释放中断 */ 242 | free_irq(alinx_char.irq, NULL); 243 | 244 | /** 定时器 **/ 245 | /* 删除定时器 */ 246 | del_timer_sync(&alinx_char.timer); 247 | 248 | /** 字符设备框架 **/ 249 | /* 注销字符设备 */ 250 | cdev_del(&alinx_char.cdev); 251 | 252 | /* 注销设备号 */ 253 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 254 | 255 | /* 删除设备节点 */ 256 | device_destroy(alinx_char.class, alinx_char.devid); 257 | 258 | /* 删除类 */ 259 | class_destroy(alinx_char.class); 260 | 261 | printk("timer_led_dev_exit_ok\n"); 262 | } 263 | 264 | /* 标记加载、卸载函数 */ 265 | module_init(char_drv_init); 266 | module_exit(char_drv_exit); 267 | 268 | /* 驱动描述信息 */ 269 | MODULE_AUTHOR("Alinx"); 270 | MODULE_ALIAS("alinx char"); 271 | MODULE_DESCRIPTION("INTERRUPT LED driver"); 272 | MODULE_VERSION("v1.0"); 273 | MODULE_LICENSE("GPL"); 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /5.并发/ax-concled-dev/files/ax-concled-dev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* 设备节点名称 */ 21 | #define DEVICE_NAME "gpio_leds" 22 | /* 设备号个数 */ 23 | #define DEVID_COUNT 1 24 | /* 驱动个数 */ 25 | #define DRIVE_COUNT 1 26 | /* 主设备号 */ 27 | #define MAJOR1 28 | /* 次设备号 */ 29 | #define MINOR1 0 30 | /* LED点亮时输入的值 */ 31 | #define ALINX_LED_ON 1 32 | /* LED熄灭时输入的值 */ 33 | #define ALINX_LED_OFF 0 34 | 35 | /* 原子变量开关 */ 36 | #define ATOMIC_T_ON 37 | /* 自旋锁开关 */ 38 | //#define SPINKLOCK_T_ON 39 | /* 信号量开关 */ 40 | //#define SEMAPHORE_ON 41 | 42 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 43 | struct alinx_char_dev{ 44 | dev_t devid; //设备号 45 | struct cdev cdev; //字符设备 46 | struct class *class; //类 47 | struct device *device; //设备 48 | struct device_node *nd; //设备树的设备节点 49 | int alinx_led_gpio; //gpio号 50 | 51 | #ifdef ATOMIC_T_ON 52 | atomic_t lock; //原子变量 53 | #endif 54 | 55 | #ifdef SPINKLOCK_T_ON 56 | spinlock_t lock; //自旋锁变量 57 | int source_status; //资源占用状态 58 | #endif 59 | 60 | #ifdef SEMAPHORE_ON 61 | struct semaphore lock; 62 | #endif 63 | }; 64 | /* 声明设备结构体 */ 65 | static struct alinx_char_dev alinx_char = { 66 | .cdev = { 67 | .owner = THIS_MODULE, 68 | }, 69 | }; 70 | 71 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 72 | static int gpio_leds_open(struct inode *inode_p, struct file *file_p) 73 | { 74 | /* 应用程序调用了open函数表示需要调用共享资源 */ 75 | #ifdef ATOMIC_T_ON 76 | /* 通过判断原子变量的值来判断资源的占用状态 */ 77 | if (!atomic_read(&alinx_char.lock)) 78 | { 79 | /* 若原子变量值为0, 则资源没有被占用, 80 | 此时把原子变量加1, 表示之后资源就被占用了 */ 81 | atomic_inc(&alinx_char.lock); 82 | } 83 | else 84 | { 85 | /* 否则资源被占用, 返回忙碌 */ 86 | return -EBUSY; 87 | } 88 | #endif 89 | 90 | #ifdef SPINKLOCK_T_ON 91 | /* 获取自旋锁 */ 92 | spin_lock(&alinx_char.lock); 93 | /* 判断资源占用状态 */ 94 | if(!alinx_char.source_status) 95 | { 96 | /* 为0则未被占用, 97 | 此时把状态值加1, 表示之后资源就被占用了 */ 98 | alinx_char.source_status ++; 99 | /* 释放锁 */ 100 | spin_unlock(&alinx_char.lock); 101 | } 102 | else 103 | { 104 | /* 释放锁 */ 105 | spin_unlock(&alinx_char.lock); 106 | /* 否则资源被占用, 返回忙碌 */ 107 | return -EBUSY; 108 | } 109 | #endif 110 | 111 | #ifdef SEMAPHORE_ON 112 | /* 获取信号量 */ 113 | down(&alinx_char.lock); 114 | #endif 115 | 116 | /* 设置私有数据 */ 117 | file_p->private_data = &alinx_char; 118 | printk("gpio_test module open\n"); 119 | return 0; 120 | } 121 | 122 | 123 | /* write函数实现, 对应到Linux系统调用函数的write函数 */ 124 | static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) 125 | { 126 | int retvalue; 127 | unsigned char databuf[1]; 128 | /* 获取私有数据 */ 129 | struct alinx_char_dev *dev = file_p->private_data; 130 | 131 | retvalue = copy_from_user(databuf, buf, len); 132 | if(retvalue < 0) 133 | { 134 | printk("alinx led write failed\r\n"); 135 | return -EFAULT; 136 | } 137 | 138 | if(databuf[0] == ALINX_LED_ON) 139 | { 140 | gpio_set_value(dev->alinx_led_gpio, !!0); 141 | } 142 | else if(databuf[0] == ALINX_LED_OFF) 143 | { 144 | gpio_set_value(dev->alinx_led_gpio, !!1); 145 | } 146 | else 147 | { 148 | printk("gpio_test para err\n"); 149 | } 150 | 151 | return 0; 152 | } 153 | 154 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 155 | static int gpio_leds_release(struct inode *inode_p, struct file *file_p) 156 | { 157 | /* 应用程序调用close函数, 宣布资源已使用完毕 */ 158 | #ifdef ATOMIC_T_ON 159 | /* 原子变量恢复为0, 表示资源已使用完毕 */ 160 | atomic_set(&alinx_char.lock, 0); 161 | #endif 162 | 163 | #ifdef SPINKLOCK_T_ON 164 | /* 获取自旋锁 */ 165 | spin_lock(&alinx_char.lock); 166 | /* 资源占用状态恢复为0, 表示资源已使用完毕 */ 167 | alinx_char.source_status = 0; 168 | /* 释放锁 */ 169 | spin_unlock(&alinx_char.lock); 170 | #endif 171 | 172 | #ifdef SEMAPHORE_ON 173 | /* 释放信号量 */ 174 | up(&alinx_char.lock); 175 | #endif 176 | 177 | printk("gpio_test module release\n"); 178 | return 0; 179 | } 180 | 181 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 182 | static struct file_operations ax_char_fops = { 183 | .owner = THIS_MODULE, 184 | .open = gpio_leds_open, 185 | .write = gpio_leds_write, 186 | .release = gpio_leds_release, 187 | }; 188 | 189 | /* 模块加载时会调用的函数 */ 190 | static int __init gpio_led_init(void) 191 | { 192 | /* 用于接受返回值 */ 193 | u32 ret = 0; 194 | 195 | #ifdef ATOMIC_T_ON 196 | /* 设置原子变量为0, 即资源为未被占用的状态 */ 197 | atomic_set(&alinx_char.lock, 0); 198 | #endif 199 | 200 | #ifdef SPINKLOCK_T_ON 201 | /* 初始化自旋锁 */ 202 | spin_lock_init(&alinx_char.lock); 203 | /* 初始化资源占用状态为0, 意为资源没有被占用 */ 204 | alinx_char.source_status = 0; 205 | #endif 206 | 207 | #ifdef SEMAPHORE_ON 208 | /* 初始化信号量 */ 209 | sema_init(alinx_char.lock, 1); 210 | #endif 211 | 212 | /* 获取设备节点 */ 213 | alinx_char.nd = of_find_node_by_path("/alinxled"); 214 | if(alinx_char.nd == NULL) 215 | { 216 | printk("alinx_char node not find\r\n"); 217 | return -EINVAL; 218 | } 219 | else 220 | { 221 | printk("alinx_char node find\r\n"); 222 | } 223 | 224 | /* 获取节点中gpio标号 */ 225 | alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0); 226 | if(alinx_char.alinx_led_gpio < 0) 227 | { 228 | printk("can not get alinxled-gpios"); 229 | return -EINVAL; 230 | } 231 | printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio); 232 | 233 | /* 申请gpio标号对应的引脚 */ 234 | ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled"); 235 | if(ret != 0) 236 | { 237 | printk("can not request gpio\r\n"); 238 | } 239 | 240 | /* 把这个io设置为输出 */ 241 | ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1); 242 | if(ret < 0) 243 | { 244 | printk("can not set gpio\r\n"); 245 | } 246 | 247 | /* 注册设备号 */ 248 | alloc_chrdev_region(&alinx_char.devid, MINOR1, DEVID_COUNT, DEVICE_NAME); 249 | 250 | /* 初始化字符设备结构体 */ 251 | cdev_init(&alinx_char.cdev, &ax_char_fops); 252 | 253 | /* 注册字符设备 */ 254 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 255 | 256 | /* 创建类 */ 257 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 258 | if(IS_ERR(alinx_char.class)) 259 | { 260 | return PTR_ERR(alinx_char.class); 261 | } 262 | 263 | /* 创建设备节点 */ 264 | alinx_char.device = device_create(alinx_char.class, NULL, 265 | alinx_char.devid, NULL, 266 | DEVICE_NAME); 267 | if (IS_ERR(alinx_char.device)) 268 | { 269 | return PTR_ERR(alinx_char.device); 270 | } 271 | 272 | return 0; 273 | } 274 | 275 | /* 卸载模块 */ 276 | static void __exit gpio_led_exit(void) 277 | { 278 | /* 释放gpio */ 279 | gpio_free(alinx_char.alinx_led_gpio); 280 | 281 | /* 注销字符设备 */ 282 | cdev_del(&alinx_char.cdev); 283 | 284 | /* 注销设备号 */ 285 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 286 | 287 | /* 删除设备节点 */ 288 | device_destroy(alinx_char.class, alinx_char.devid); 289 | 290 | /* 删除类 */ 291 | class_destroy(alinx_char.class); 292 | 293 | printk("gpio_led_dev_exit_ok\n"); 294 | } 295 | 296 | /* 标记加载、卸载函数 */ 297 | module_init(gpio_led_init); 298 | module_exit(gpio_led_exit); 299 | 300 | /* 驱动描述信息 */ 301 | MODULE_AUTHOR("Alinx"); 302 | MODULE_ALIAS("gpio_led"); 303 | MODULE_DESCRIPTION("CONCURRENT driver"); 304 | MODULE_VERSION("v1.0"); 305 | MODULE_LICENSE("GPL"); 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /9.阻塞IO/ax-bio-drv/files/ax-bio-drv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /* 设备节点名称 */ 24 | #define DEVICE_NAME "bio_led" 25 | /* 设备号个数 */ 26 | #define DEVID_COUNT 1 27 | /* 驱动个数 */ 28 | #define DRIVE_COUNT 1 29 | /* 主设备号 */ 30 | #define MAJOR_U 31 | /* 次设备号 */ 32 | #define MINOR_U 0 33 | 34 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 35 | struct alinx_char_dev { 36 | /** 字符设备框架 **/ 37 | dev_t devid; //设备号 38 | struct cdev cdev; //字符设备 39 | struct class *class; //类 40 | struct device *device; //设备 41 | struct device_node *nd; //设备树的设备节点 42 | /** gpio **/ 43 | int alinx_key_gpio; //gpio号 44 | /** 并发处理 **/ 45 | atomic_t key_sts; //记录按键状态, 为1时被按下 46 | /** 中断 **/ 47 | unsigned int irq; //中断号 48 | /** 定时器 **/ 49 | struct timer_list timer; //定时器 50 | /** 等待队列 **/ 51 | wait_queue_head_t wait_q_h; //等待队列头 52 | }; 53 | /* 声明设备结构体 */ 54 | static struct alinx_char_dev alinx_char = { 55 | .cdev = { 56 | .owner = THIS_MODULE, 57 | }, 58 | }; 59 | 60 | /** 回掉 **/ 61 | /* 中断服务函数 */ 62 | static irqreturn_t key_handler(int irq, void *dev) 63 | { 64 | /* 按键按下或抬起时会进入中断 */ 65 | /* 开启50毫秒的定时器用作防抖动 */ 66 | mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(50)); 67 | return IRQ_RETVAL(IRQ_HANDLED); 68 | } 69 | 70 | /* 定时器服务函数 */ 71 | void timer_function(unsigned long arg) 72 | { 73 | /* value用于获取按键值 */ 74 | unsigned char value; 75 | /* 获取按键值 */ 76 | value = gpio_get_value(alinx_char.alinx_key_gpio); 77 | if(value == 0) 78 | { 79 | /* 按键按下, 状态置1 */ 80 | atomic_set(&alinx_char.key_sts, 1); 81 | /** 等待队列 **/ 82 | /* 唤醒进程 */ 83 | wake_up_interruptible(&alinx_char.wait_q_h); 84 | } 85 | else 86 | { 87 | /* 按键抬起 */ 88 | } 89 | } 90 | 91 | /** 系统调用实现 **/ 92 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 93 | static int char_drv_open(struct inode *inode_p, struct file *file_p) 94 | { 95 | printk("gpio_test module open\n"); 96 | return 0; 97 | } 98 | 99 | 100 | /* read函数实现, 对应到Linux系统调用函数的write函数 */ 101 | static ssize_t char_drv_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) 102 | { 103 | unsigned int keysts = 0; 104 | int ret; 105 | 106 | /* 读取key的状态 */ 107 | keysts = atomic_read(&alinx_char.key_sts); 108 | /* 判断当前按键状态 */ 109 | if(!keysts) 110 | { 111 | /* 按键未被按下(数据未准备好) */ 112 | /* 以当前进程创建并初始化为队列项 */ 113 | DECLARE_WAITQUEUE(queue_mem, current); 114 | /* 把当前进程的队列项添加到队列头 */ 115 | add_wait_queue(&alinx_char.wait_q_h, &queue_mem); 116 | /* 设置当前进成为可被信号打断的状态 */ 117 | __set_current_state(TASK_INTERRUPTIBLE); 118 | /* 切换进程, 是当前进程休眠 */ 119 | schedule(); 120 | 121 | /* 被唤醒, 修改当前进程状态为RUNNING */ 122 | set_current_state(TASK_RUNNING); 123 | /* 把当前进程的队列项从队列头中删除 */ 124 | remove_wait_queue(&alinx_char.wait_q_h, &queue_mem); 125 | 126 | /* 判断是否是被信号唤醒 */ 127 | if(signal_pending(current)) 128 | { 129 | /* 如果是直接返回错误 */ 130 | return -ERESTARTSYS; 131 | } 132 | else 133 | { 134 | /* 被按键唤醒 */ 135 | } 136 | } 137 | else 138 | { 139 | /* 按键被按下(数据准备好了) */ 140 | } 141 | 142 | /* 读取key的状态 */ 143 | keysts = atomic_read(&alinx_char.key_sts); 144 | /* 返回按键状态值 */ 145 | ret = copy_to_user(buf, &keysts, sizeof(keysts)); 146 | /* 清除按键状态 */ 147 | atomic_set(&alinx_char.key_sts, 0); 148 | return 0; 149 | } 150 | 151 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 152 | static int char_drv_release(struct inode *inode_p, struct file *file_p) 153 | { 154 | printk("gpio_test module release\n"); 155 | return 0; 156 | } 157 | 158 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 159 | static struct file_operations ax_char_fops = { 160 | .owner = THIS_MODULE, 161 | .open = char_drv_open, 162 | .read = char_drv_read, 163 | .release = char_drv_release, 164 | }; 165 | 166 | /* 模块加载时会调用的函数 */ 167 | static int __init char_drv_init(void) 168 | { 169 | /* 用于接受返回值 */ 170 | u32 ret = 0; 171 | 172 | /** 并发处理 **/ 173 | /* 初始化原子变量 */ 174 | atomic_set(&alinx_char.key_sts, 0); 175 | 176 | /** gpio框架 **/ 177 | /* 获取设备节点 */ 178 | alinx_char.nd = of_find_node_by_path("/alinxkey"); 179 | if(alinx_char.nd == NULL) 180 | { 181 | printk("alinx_char node not find\r\n"); 182 | return -EINVAL; 183 | } 184 | else 185 | { 186 | printk("alinx_char node find\r\n"); 187 | } 188 | 189 | /* 获取节点中gpio标号 */ 190 | alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); 191 | if(alinx_char.alinx_key_gpio < 0) 192 | { 193 | printk("can not get alinxkey-gpios"); 194 | return -EINVAL; 195 | } 196 | printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); 197 | 198 | /* 申请gpio标号对应的引脚 */ 199 | ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); 200 | if(ret != 0) 201 | { 202 | printk("can not request gpio\r\n"); 203 | return -EINVAL; 204 | } 205 | 206 | /* 把这个io设置为输入 */ 207 | ret = gpio_direction_input(alinx_char.alinx_key_gpio); 208 | if(ret < 0) 209 | { 210 | printk("can not set gpio\r\n"); 211 | return -EINVAL; 212 | } 213 | 214 | /** 中断 **/ 215 | /* 获取中断号 */ 216 | alinx_char.irq = gpio_to_irq(alinx_char.alinx_key_gpio); 217 | /* 申请中断 */ 218 | ret = request_irq(alinx_char.irq, 219 | key_handler, 220 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 221 | "alinxkey", 222 | NULL); 223 | if(ret < 0) 224 | { 225 | printk("irq %d request failed\r\n", alinx_char.irq); 226 | return -EFAULT; 227 | } 228 | 229 | /** 定时器 **/ 230 | alinx_char.timer.function = timer_function; 231 | init_timer(&alinx_char.timer); 232 | 233 | /** 等待队列 **/ 234 | init_waitqueue_head(&alinx_char.wait_q_h); 235 | 236 | /** 字符设备框架 **/ 237 | /* 注册设备号 */ 238 | alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); 239 | 240 | /* 初始化字符设备结构体 */ 241 | cdev_init(&alinx_char.cdev, &ax_char_fops); 242 | 243 | /* 注册字符设备 */ 244 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 245 | 246 | /* 创建类 */ 247 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 248 | if(IS_ERR(alinx_char.class)) 249 | { 250 | return PTR_ERR(alinx_char.class); 251 | } 252 | 253 | /* 创建设备节点 */ 254 | alinx_char.device = device_create(alinx_char.class, NULL, 255 | alinx_char.devid, NULL, 256 | DEVICE_NAME); 257 | if (IS_ERR(alinx_char.device)) 258 | { 259 | return PTR_ERR(alinx_char.device); 260 | } 261 | 262 | return 0; 263 | } 264 | 265 | /* 卸载模块 */ 266 | static void __exit char_drv_exit(void) 267 | { 268 | /** gpio **/ 269 | /* 释放gpio */ 270 | gpio_free(alinx_char.alinx_key_gpio); 271 | 272 | /** 中断 **/ 273 | /* 释放中断 */ 274 | free_irq(alinx_char.irq, NULL); 275 | 276 | /** 定时器 **/ 277 | /* 删除定时器 */ 278 | del_timer_sync(&alinx_char.timer); 279 | 280 | /** 字符设备框架 **/ 281 | /* 注销字符设备 */ 282 | cdev_del(&alinx_char.cdev); 283 | 284 | /* 注销设备号 */ 285 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 286 | 287 | /* 删除设备节点 */ 288 | device_destroy(alinx_char.class, alinx_char.devid); 289 | 290 | /* 删除类 */ 291 | class_destroy(alinx_char.class); 292 | 293 | printk("timer_led_dev_exit_ok\n"); 294 | } 295 | 296 | /* 标记加载、卸载函数 */ 297 | module_init(char_drv_init); 298 | module_exit(char_drv_exit); 299 | 300 | /* 驱动描述信息 */ 301 | MODULE_AUTHOR("Alinx"); 302 | MODULE_ALIAS("alinx char"); 303 | MODULE_DESCRIPTION("BIO LED driver"); 304 | MODULE_VERSION("v1.0"); 305 | MODULE_LICENSE("GPL"); 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | -------------------------------------------------------------------------------- /10.非阻塞IO/ax-nio-drv/files/ax-nio-drv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /* 设备节点名称 */ 26 | #define DEVICE_NAME "nio_led" 27 | /* 设备号个数 */ 28 | #define DEVID_COUNT 1 29 | /* 驱动个数 */ 30 | #define DRIVE_COUNT 1 31 | /* 主设备号 */ 32 | #define MAJOR_U 33 | /* 次设备号 */ 34 | #define MINOR_U 0 35 | 36 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 37 | struct alinx_char_dev { 38 | /** 字符设备框架 **/ 39 | dev_t devid; //设备号 40 | struct cdev cdev; //字符设备 41 | struct class *class; //类 42 | struct device *device; //设备 43 | struct device_node *nd; //设备树的设备节点 44 | /** gpio **/ 45 | int alinx_key_gpio; //gpio号 46 | /** 并发处理 **/ 47 | atomic_t key_sts; //记录按键状态, 为1时被按下 48 | /** 中断 **/ 49 | unsigned int irq; //中断号 50 | /** 定时器 **/ 51 | struct timer_list timer; //定时器 52 | /** 等待队列 **/ 53 | wait_queue_head_t wait_q_h; //等待队列头 54 | }; 55 | /* 声明设备结构体 */ 56 | static struct alinx_char_dev alinx_char = { 57 | .cdev = { 58 | .owner = THIS_MODULE, 59 | }, 60 | }; 61 | 62 | /** 回掉 **/ 63 | /* 中断服务函数 */ 64 | static irqreturn_t key_handler(int irq, void *dev) 65 | { 66 | /* 按键按下或抬起时会进入中断 */ 67 | /* 开启50毫秒的定时器用作防抖动 */ 68 | mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(50)); 69 | return IRQ_RETVAL(IRQ_HANDLED); 70 | } 71 | 72 | /* 定时器服务函数 */ 73 | void timer_function(unsigned long arg) 74 | { 75 | /* value用于获取按键值 */ 76 | unsigned char value; 77 | /* 获取按键值 */ 78 | value = gpio_get_value(alinx_char.alinx_key_gpio); 79 | if(value == 0) 80 | { 81 | /* 按键按下, 状态置1 */ 82 | atomic_set(&alinx_char.key_sts, 1); 83 | /** 等待队列 **/ 84 | /* 唤醒进程 */ 85 | wake_up_interruptible(&alinx_char.wait_q_h); 86 | } 87 | else 88 | { 89 | /* 按键抬起 */ 90 | } 91 | } 92 | 93 | /** 系统调用实现 **/ 94 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 95 | static int char_drv_open(struct inode *inode_p, struct file *file_p) 96 | { 97 | printk("gpio_test module open\n"); 98 | return 0; 99 | } 100 | 101 | /* read函数实现, 对应到Linux系统调用函数的write函数 */ 102 | static ssize_t char_drv_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) 103 | { 104 | unsigned int keysts = 0; 105 | int ret; 106 | 107 | /* 读取key的状态 */ 108 | keysts = atomic_read(&alinx_char.key_sts); 109 | /* 判断文件打开方式 */ 110 | if(file_p->f_flags & O_NONBLOCK) 111 | { 112 | /* 如果是非阻塞访问, 说明以满足读取条件 */ 113 | } 114 | /* 判断当前按键状态 */ 115 | else if(!keysts) 116 | { 117 | /* 按键未被按下(数据未准备好) */ 118 | /* 以当前进程创建并初始化为队列项 */ 119 | DECLARE_WAITQUEUE(queue_mem, current); 120 | /* 把当前进程的队列项添加到队列头 */ 121 | add_wait_queue(&alinx_char.wait_q_h, &queue_mem); 122 | /* 设置当前进成为可被信号打断的状态 */ 123 | __set_current_state(TASK_INTERRUPTIBLE); 124 | /* 切换进程, 是当前进程休眠 */ 125 | schedule(); 126 | 127 | /* 被唤醒, 修改当前进程状态为RUNNING */ 128 | set_current_state(TASK_RUNNING); 129 | /* 把当前进程的队列项从队列头中删除 */ 130 | remove_wait_queue(&alinx_char.wait_q_h, &queue_mem); 131 | 132 | /* 判断是否是被信号唤醒 */ 133 | if(signal_pending(current)) 134 | { 135 | /* 如果是直接返回错误 */ 136 | return -ERESTARTSYS; 137 | } 138 | else 139 | { 140 | /* 被按键唤醒 */ 141 | } 142 | } 143 | else 144 | { 145 | /* 按键被按下(数据准备好了) */ 146 | } 147 | 148 | /* 读取key的状态 */ 149 | keysts = atomic_read(&alinx_char.key_sts); 150 | /* 返回按键状态值 */ 151 | ret = copy_to_user(buf, &keysts, sizeof(keysts)); 152 | /* 清除按键状态 */ 153 | atomic_set(&alinx_char.key_sts, 0); 154 | return 0; 155 | } 156 | 157 | /* poll函数实现 */ 158 | unsigned int char_drv_poll(struct file *filp, struct poll_table_struct *wait) 159 | { 160 | unsigned int ret = 0; 161 | 162 | /* 将应用程序添添加到等待队列中 */ 163 | poll_wait(filp, &alinx_char.wait_q_h, wait); 164 | 165 | /* 判断key的状态 */ 166 | if(atomic_read(&alinx_char.key_sts)) 167 | { 168 | /* key准备好了, 返回数据可读 */ 169 | ret = POLLIN; 170 | } 171 | else 172 | { 173 | 174 | } 175 | 176 | return ret; 177 | } 178 | 179 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 180 | static int char_drv_release(struct inode *inode_p, struct file *file_p) 181 | { 182 | printk("gpio_test module release\n"); 183 | return 0; 184 | } 185 | 186 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 187 | static struct file_operations ax_char_fops = { 188 | .owner = THIS_MODULE, 189 | .open = char_drv_open, 190 | .read = char_drv_read, 191 | .poll = char_drv_poll, 192 | .release = char_drv_release, 193 | }; 194 | 195 | /* 模块加载时会调用的函数 */ 196 | static int __init char_drv_init(void) 197 | { 198 | /* 用于接受返回值 */ 199 | u32 ret = 0; 200 | 201 | /** 并发处理 **/ 202 | /* 初始化原子变量 */ 203 | atomic_set(&alinx_char.key_sts, 0); 204 | 205 | /** gpio框架 **/ 206 | /* 获取设备节点 */ 207 | alinx_char.nd = of_find_node_by_path("/alinxkey"); 208 | if(alinx_char.nd == NULL) 209 | { 210 | printk("alinx_char node not find\r\n"); 211 | return -EINVAL; 212 | } 213 | else 214 | { 215 | printk("alinx_char node find\r\n"); 216 | } 217 | 218 | /* 获取节点中gpio标号 */ 219 | alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); 220 | if(alinx_char.alinx_key_gpio < 0) 221 | { 222 | printk("can not get alinxkey-gpios"); 223 | return -EINVAL; 224 | } 225 | printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); 226 | 227 | /* 申请gpio标号对应的引脚 */ 228 | ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); 229 | if(ret != 0) 230 | { 231 | printk("can not request gpio\r\n"); 232 | return -EINVAL; 233 | } 234 | 235 | /* 把这个io设置为输入 */ 236 | ret = gpio_direction_input(alinx_char.alinx_key_gpio); 237 | if(ret < 0) 238 | { 239 | printk("can not set gpio\r\n"); 240 | return -EINVAL; 241 | } 242 | 243 | /** 中断 **/ 244 | /* 获取中断号 */ 245 | alinx_char.irq = gpio_to_irq(alinx_char.alinx_key_gpio); 246 | /* 申请中断 */ 247 | ret = request_irq(alinx_char.irq, 248 | key_handler, 249 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 250 | "alinxkey", 251 | NULL); 252 | if(ret < 0) 253 | { 254 | printk("irq %d request failed\r\n", alinx_char.irq); 255 | return -EFAULT; 256 | } 257 | 258 | /** 定时器 **/ 259 | alinx_char.timer.function = timer_function; 260 | init_timer(&alinx_char.timer); 261 | 262 | /** 等待队列 **/ 263 | init_waitqueue_head(&alinx_char.wait_q_h); 264 | 265 | /** 字符设备框架 **/ 266 | /* 注册设备号 */ 267 | alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); 268 | 269 | /* 初始化字符设备结构体 */ 270 | cdev_init(&alinx_char.cdev, &ax_char_fops); 271 | 272 | /* 注册字符设备 */ 273 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 274 | 275 | /* 创建类 */ 276 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 277 | if(IS_ERR(alinx_char.class)) 278 | { 279 | return PTR_ERR(alinx_char.class); 280 | } 281 | 282 | /* 创建设备节点 */ 283 | alinx_char.device = device_create(alinx_char.class, NULL, 284 | alinx_char.devid, NULL, 285 | DEVICE_NAME); 286 | if (IS_ERR(alinx_char.device)) 287 | { 288 | return PTR_ERR(alinx_char.device); 289 | } 290 | 291 | return 0; 292 | } 293 | 294 | /* 卸载模块 */ 295 | static void __exit char_drv_exit(void) 296 | { 297 | /** gpio **/ 298 | /* 释放gpio */ 299 | gpio_free(alinx_char.alinx_key_gpio); 300 | 301 | /** 中断 **/ 302 | /* 释放中断 */ 303 | free_irq(alinx_char.irq, NULL); 304 | 305 | /** 定时器 **/ 306 | /* 删除定时器 */ 307 | del_timer_sync(&alinx_char.timer); 308 | 309 | /** 字符设备框架 **/ 310 | /* 注销字符设备 */ 311 | cdev_del(&alinx_char.cdev); 312 | 313 | /* 注销设备号 */ 314 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 315 | 316 | /* 删除设备节点 */ 317 | device_destroy(alinx_char.class, alinx_char.devid); 318 | 319 | /* 删除类 */ 320 | class_destroy(alinx_char.class); 321 | 322 | printk("timer_led_dev_exit_ok\n"); 323 | } 324 | 325 | /* 标记加载、卸载函数 */ 326 | module_init(char_drv_init); 327 | module_exit(char_drv_exit); 328 | 329 | /* 驱动描述信息 */ 330 | MODULE_AUTHOR("Alinx"); 331 | MODULE_ALIAS("alinx char"); 332 | MODULE_DESCRIPTION("NIO LED driver"); 333 | MODULE_VERSION("v1.0"); 334 | MODULE_LICENSE("GPL"); 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | -------------------------------------------------------------------------------- /11.异步IO/ax-fasync-drv/files/ax-fasync-drv.c: -------------------------------------------------------------------------------- 1 | /** ===================================================== ** 2 | *Author : ALINX Electronic Technology (Shanghai) Co., Ltd. 3 | *Website: http://www.alinx.com 4 | *Address: Room 202, building 18, 5 | No.518 xinbrick Road, 6 | Songjiang District, Shanghai 7 | *Created: 2020-3-2 8 | *Version: 1.0 9 | ** ===================================================== **/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | /* 设备节点名称 */ 37 | #define DEVICE_NAME "fasync_led" 38 | /* 设备号个数 */ 39 | #define DEVID_COUNT 1 40 | /* 驱动个数 */ 41 | #define DRIVE_COUNT 1 42 | /* 主设备号 */ 43 | #define MAJOR_U 44 | /* 次设备号 */ 45 | #define MINOR_U 0 46 | 47 | /* 把驱动代码中会用到的数据打包进设备结构体 */ 48 | struct alinx_char_dev { 49 | dev_t devid; //设备号 50 | struct cdev cdev; //字符设备 51 | struct class *class; //类 52 | struct device *device; //设备 53 | struct device_node *nd; //设备树的设备节点 54 | int alinx_key_gpio; //gpio号 55 | atomic_t key_sts; //记录按键状态, 为1时被按下 56 | unsigned int irq; //中断号 57 | struct timer_list timer; //定时器 58 | wait_queue_head_t wait_q_h; //等待队列头 59 | struct fasync_struct *fasync; //异步信号 60 | }; 61 | /* 声明设备结构体 */ 62 | static struct alinx_char_dev alinx_char = { 63 | .cdev = { 64 | .owner = THIS_MODULE, 65 | }, 66 | }; 67 | 68 | /* 中断服务函数 */ 69 | static irqreturn_t key_handler(int irq, void *dev_in) 70 | { 71 | /* 按键按下或抬起时会进入中断 */ 72 | struct alinx_char_dev *dev = (struct alinx_char_dev *)dev_in; 73 | /* 开启50毫秒的定时器用作防抖动 */ 74 | dev->timer.data = (volatile long)dev_in; 75 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(50)); 76 | return IRQ_RETVAL(IRQ_HANDLED); 77 | } 78 | 79 | /* 定时器服务函数 */ 80 | void timer_function(unsigned long arg) 81 | { 82 | struct alinx_char_dev *dev = (struct alinx_char_dev *)arg; 83 | /* value用于获取按键值 */ 84 | unsigned char value; 85 | /* 获取按键值 */ 86 | value = gpio_get_value(dev->alinx_key_gpio); 87 | if(value == 0) 88 | { 89 | /* 按键按下, 状态置1 */ 90 | atomic_set(&dev->key_sts, 1); 91 | /* fasync有没有初始化过 */ 92 | if(dev->fasync) 93 | { 94 | /* 初始化过说明应用程序调用过 */ 95 | kill_fasync(&dev->fasync, SIGIO, POLL_OUT); 96 | } 97 | else if((current->state & TASK_INTERRUPTIBLE) != 0) 98 | { 99 | /* 是等待队列,需要唤醒进程 */ 100 | wake_up_interruptible(&dev->wait_q_h); 101 | } 102 | else 103 | { 104 | /* do nothing */ 105 | } 106 | } 107 | else 108 | { 109 | /* 按键抬起 */ 110 | } 111 | } 112 | 113 | /* open函数实现, 对应到Linux系统调用函数的open函数 */ 114 | static int char_drv_open(struct inode *inode_p, struct file *file_p) 115 | { 116 | printk("gpio_test module open\n"); 117 | file_p->private_data = &alinx_char; 118 | return 0; 119 | } 120 | 121 | /* read函数实现, 对应到Linux系统调用函数的write函数 */ 122 | static ssize_t char_drv_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) 123 | { 124 | unsigned int keysts = 0; 125 | int ret; 126 | 127 | struct alinx_char_dev *dev = (struct alinx_char_dev *)file_p->private_data; 128 | 129 | /* 读取key的状态 */ 130 | keysts = atomic_read(&dev->key_sts); 131 | /* 判断文件打开方式 */ 132 | if(file_p->f_flags & O_NONBLOCK) 133 | { 134 | /* 如果是非阻塞访问, 说明已满足读取条件 */ 135 | } 136 | /* 判断当前按键状态 */ 137 | else if(!keysts) 138 | { 139 | /* 按键未被按下(数据未准备好) */ 140 | /* 以当前进程创建并初始化为队列项 */ 141 | DECLARE_WAITQUEUE(queue_mem, current); 142 | /* 把当前进程的队列项添加到队列头 */ 143 | add_wait_queue(&dev->wait_q_h, &queue_mem); 144 | /* 设置当前进成为可被信号打断的状态 */ 145 | __set_current_state(TASK_INTERRUPTIBLE); 146 | /* 切换进程, 是当前进程休眠 */ 147 | schedule(); 148 | 149 | /* 被唤醒, 修改当前进程状态为RUNNING */ 150 | set_current_state(TASK_RUNNING); 151 | /* 把当前进程的队列项从队列头中删除 */ 152 | remove_wait_queue(&dev->wait_q_h, &queue_mem); 153 | 154 | /* 判断是否是被信号唤醒 */ 155 | if(signal_pending(current)) 156 | { 157 | /* 如果是直接返回错误 */ 158 | return -ERESTARTSYS; 159 | } 160 | else 161 | { 162 | /* 被按键唤醒 */ 163 | } 164 | } 165 | else 166 | { 167 | /* 按键被按下(数据准备好了) */ 168 | } 169 | 170 | /* 读取key的状态 */ 171 | keysts = atomic_read(&dev->key_sts); 172 | /* 返回按键状态值 */ 173 | ret = copy_to_user(buf, &keysts, sizeof(keysts)); 174 | /* 清除按键状态 */ 175 | atomic_set(&dev->key_sts, 0); 176 | return 0; 177 | } 178 | 179 | /* poll函数实现 */ 180 | unsigned int char_drv_poll(struct file *file_p, struct poll_table_struct *wait) 181 | { 182 | unsigned int ret = 0; 183 | 184 | struct alinx_char_dev *dev = (struct alinx_char_dev *)file_p->private_data; 185 | 186 | /* 将应用程序添添加到等待队列中 */ 187 | poll_wait(file_p, &dev->wait_q_h, wait); 188 | 189 | /* 判断key的状态 */ 190 | if(atomic_read(&dev->key_sts)) 191 | { 192 | /* key准备好了, 返回数据可读 */ 193 | ret = POLLIN; 194 | } 195 | else 196 | { 197 | 198 | } 199 | 200 | return ret; 201 | } 202 | 203 | /* fasync函数实现 */ 204 | static int char_drv_fasync(int fd,struct file *file_p, int mode) 205 | { 206 | struct alinx_char_dev *dev = (struct alinx_char_dev *)file_p->private_data; 207 | return fasync_helper(fd, file_p, mode, &dev->fasync); 208 | } 209 | 210 | /* release函数实现, 对应到Linux系统调用函数的close函数 */ 211 | static int char_drv_release(struct inode *inode_p, struct file *file_p) 212 | { 213 | printk("gpio_test module release\n"); 214 | return char_drv_fasync(-1, file_p, 0); 215 | } 216 | 217 | /* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */ 218 | static struct file_operations ax_char_fops = { 219 | .owner = THIS_MODULE, 220 | .open = char_drv_open, 221 | .read = char_drv_read, 222 | .poll = char_drv_poll, 223 | .fasync = char_drv_fasync, 224 | .release = char_drv_release, 225 | }; 226 | 227 | /* 模块加载时会调用的函数 */ 228 | static int __init char_drv_init(void) 229 | { 230 | /* 用于接受返回值 */ 231 | u32 ret = 0; 232 | 233 | /* 初始化原子变量 */ 234 | atomic_set(&alinx_char.key_sts, 0); 235 | 236 | /* 获取设备节点 */ 237 | alinx_char.nd = of_find_node_by_path("/alinxkey"); 238 | if(alinx_char.nd == NULL) 239 | { 240 | printk("alinx_char node not find\r\n"); 241 | return -EINVAL; 242 | } 243 | else 244 | { 245 | printk("alinx_char node find\r\n"); 246 | } 247 | 248 | /* 获取节点中gpio标号 */ 249 | alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); 250 | if(alinx_char.alinx_key_gpio < 0) 251 | { 252 | printk("can not get alinxkey-gpios"); 253 | return -EINVAL; 254 | } 255 | printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); 256 | 257 | /* 申请gpio标号对应的引脚 */ 258 | ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); 259 | if(ret != 0) 260 | { 261 | printk("can not request gpio\r\n"); 262 | return -EINVAL; 263 | } 264 | 265 | /* 把这个io设置为输入 */ 266 | ret = gpio_direction_input(alinx_char.alinx_key_gpio); 267 | if(ret < 0) 268 | { 269 | printk("can not set gpio\r\n"); 270 | return -EINVAL; 271 | } 272 | 273 | /* 获取中断号 */ 274 | alinx_char.irq = gpio_to_irq(alinx_char.alinx_key_gpio); 275 | /* 申请中断 */ 276 | ret = request_irq(alinx_char.irq, 277 | key_handler, 278 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 279 | "alinxkey", 280 | &alinx_char); 281 | if(ret < 0) 282 | { 283 | printk("irq %d request failed\r\n", alinx_char.irq); 284 | return -EFAULT; 285 | } 286 | 287 | alinx_char.timer.function = timer_function; 288 | init_timer(&alinx_char.timer); 289 | 290 | init_waitqueue_head(&alinx_char.wait_q_h); 291 | 292 | /* 注册设备号 */ 293 | alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); 294 | 295 | /* 初始化字符设备结构体 */ 296 | cdev_init(&alinx_char.cdev, &ax_char_fops); 297 | 298 | /* 注册字符设备 */ 299 | cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); 300 | 301 | /* 创建类 */ 302 | alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); 303 | if(IS_ERR(alinx_char.class)) 304 | { 305 | return PTR_ERR(alinx_char.class); 306 | } 307 | 308 | /* 创建设备节点 */ 309 | alinx_char.device = device_create(alinx_char.class, NULL, 310 | alinx_char.devid, NULL, 311 | DEVICE_NAME); 312 | if (IS_ERR(alinx_char.device)) 313 | { 314 | return PTR_ERR(alinx_char.device); 315 | } 316 | 317 | return 0; 318 | } 319 | 320 | /* 卸载模块 */ 321 | static void __exit char_drv_exit(void) 322 | { 323 | /* 释放gpio */ 324 | gpio_free(alinx_char.alinx_key_gpio); 325 | 326 | /* 释放中断 */ 327 | free_irq(alinx_char.irq, NULL); 328 | 329 | /* 删除定时器 */ 330 | del_timer_sync(&alinx_char.timer); 331 | 332 | /* 注销字符设备 */ 333 | cdev_del(&alinx_char.cdev); 334 | 335 | /* 注销设备号 */ 336 | unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); 337 | 338 | /* 删除设备节点 */ 339 | device_destroy(alinx_char.class, alinx_char.devid); 340 | 341 | /* 删除类 */ 342 | class_destroy(alinx_char.class); 343 | 344 | printk("timer_led_dev_exit_ok\n"); 345 | } 346 | 347 | /* 标记加载、卸载函数 */ 348 | module_init(char_drv_init); 349 | module_exit(char_drv_exit); 350 | 351 | /* 驱动描述信息 */ 352 | MODULE_AUTHOR("Alinx"); 353 | MODULE_ALIAS("alinx char"); 354 | MODULE_DESCRIPTION("FASYNC LED driver"); 355 | MODULE_VERSION("v1.0"); 356 | MODULE_LICENSE("GPL"); 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | -------------------------------------------------------------------------------- /8.中断/ax-irq-drv/files/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | --------------------------------------------------------------------------------