diff --git a/18_dtsplatform/.vscode/c_cpp_properties.json b/18_dtsplatform/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..8b7002dfca4f245cb25afb668dd0097b7144a49b --- /dev/null +++ b/18_dtsplatform/.vscode/c_cpp_properties.json @@ -0,0 +1,51 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "/usr/bin/g++", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64", + "browse": { + "path": [ + "${workspaceFolder}", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ] + } + }, + { + "name": "Win32", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "C:/Qt/Qt5.12.9/Tools/mingw730_64/bin/gcc.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64" + } + ], + "version": 4 +} + diff --git a/18_dtsplatform/.vscode/settings.json b/18_dtsplatform/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..1a2a04ac7a2d6b080404235adcd34b94bc581cb4 --- /dev/null +++ b/18_dtsplatform/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + } +} \ No newline at end of file diff --git a/18_dtsplatform/Makefile b/18_dtsplatform/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..895dfb164df26fd347b4c195289a959f7be9d97d --- /dev/null +++ b/18_dtsplatform/Makefile @@ -0,0 +1,13 @@ +KERNELDIR := ../../../linux-imx-rel_imx_4.1.15_2.1.0_ga +CURRENT_PATH := $(shell pwd) +obj-m := leddriver.o + +build: kernel_modules + +kernel_modules: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules + +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean + + diff --git a/18_dtsplatform/dtsplatform.code-workspace b/18_dtsplatform/dtsplatform.code-workspace new file mode 100644 index 0000000000000000000000000000000000000000..a563c858bedf0385cd9bbd6d0395651af865f705 --- /dev/null +++ b/18_dtsplatform/dtsplatform.code-workspace @@ -0,0 +1,41 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "gpio.h": "c", + "*.tcc": "c", + "ioctl.h": "c", + "fstream": "c", + "types.h": "c", + "kernel.h": "c", + "ide.h": "c", + "uaccess.h": "c", + "atomic.h": "c", + "interrupt.h": "c", + "hardirq.h": "c", + "irq.h": "c", + "delay.h": "c", + "init.h": "c", + "module.h": "c", + "cdev.h": "c", + "of_address.h": "c", + "of_gpio.h": "c", + "errno.h": "c", + "device.h": "c", + "of.h": "c", + "of_irq.h": "c", + "timer.h": "c", + "stdlib.h": "c", + "stdio.h": "c", + "driver.h": "c", + "select.h": "c", + "fcntl.h": "c", + "signal.h": "c" + } + + } +} \ No newline at end of file diff --git a/18_dtsplatform/ledApp.c b/18_dtsplatform/ledApp.c new file mode 100644 index 0000000000000000000000000000000000000000..05b1adcc81378cf278a2a8161ba082a9f986b5c6 --- /dev/null +++ b/18_dtsplatform/ledApp.c @@ -0,0 +1,46 @@ +#include "stdio.h" +#include "unistd.h" +#include "sys/types.h" +#include "fcntl.h" +#include "stdlib.h" +#include "string.h" + +#define LEDOFF 0 +#define LEDOON 0 + +int main(int argc,char *argv[]) +{ + int fd, retvalue; + char *filename; + unsigned char databuf[3]; + if (argc != 3) + { + printf("Error Usage!\r\n"); + return -1; + } + + filename = argv[1]; + + /* 打开led驱动 */ + fd = open(filename, O_RDWR); + if(fd < 0){ + printf("file %s open failed!\r\n", argv[1]); + return -1; + } + + databuf[0] = atoi(argv[2]); + retvalue = write(fd, databuf, sizeof(databuf)); + if(retvalue < 0 ){ + printf("LED Control Failed!\r\n"); + close(fd); + return -1; + } + + retvalue = close(fd); + if(retvalue < 0){ + printf("file %s close failed!\r\n", argv[1]); + return -1; + } + + return 0; +} diff --git a/18_dtsplatform/leddevice.c b/18_dtsplatform/leddevice.c new file mode 100644 index 0000000000000000000000000000000000000000..9e3091fd862e4c35959be5e8f5af911e434793e0 --- /dev/null +++ b/18_dtsplatform/leddevice.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +* 寄存器地址定义 +*/ +#define CCM_CCGR1_BASE (0X020C406C) +#define SW_MUX_GPIO1_IO03_BASE (0X020E0068) +#define SW_PAD_GPIO1_IO03_BASE (0X020E02F4) +#define GPIO1_DR_BASE (0X0209C000) +#define GPIO1_GDIR_BASE (0X0209C004) +#define REGISTER_LENGTH 4 + +/* + @description : 释放 flatform 设备模块的时候此函数会执行 +* @param - dev : 要释放的设备 + +* @return 无 +*/ +static void led_release(struct device *dev) +{ + printk("led device released!\r\n"); +} + +static struct resource led_resources[] = { + [0] = { + .start = CCM_CCGR1_BASE, + .end = (CCM_CCGR1_BASE + REGISTER_LENGTH - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SW_MUX_GPIO1_IO03_BASE, + .end = (SW_MUX_GPIO1_IO03_BASE + REGISTER_LENGTH - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = SW_PAD_GPIO1_IO03_BASE, + .end = (SW_PAD_GPIO1_IO03_BASE + REGISTER_LENGTH - 1), + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = GPIO1_DR_BASE, + .end = (GPIO1_DR_BASE + REGISTER_LENGTH - 1), + .flags = IORESOURCE_MEM, + }, + [4] = { + .start = GPIO1_GDIR_BASE, + .end = (GPIO1_GDIR_BASE + REGISTER_LENGTH - 1), + .flags = IORESOURCE_MEM, + }, +}; + + + +/* +* platform 设备结构体 +*/ + static struct platform_device leddevice = { + .name = "imx6ul-led", + .id = -1, + .dev = { + .release = &led_release, + }, + .num_resources = ARRAY_SIZE(led_resources), + .resource = led_resources, +}; + + +/* +* @description: 设备模块加载 +* @param : 无 +* @return : 无 +*/ +static int __init leddevice_init(void) +{ + return platform_device_register(&leddevice); +} + +/* +* @description : 设备模块注销 +* @param : 无 +* @return : 无 +*/ +static void __exit leddevice_exit(void) +{ + platform_device_unregister(&leddevice); +} + +module_init(leddevice_init); +module_exit(leddevice_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("chaoliang"); \ No newline at end of file diff --git a/18_dtsplatform/leddriver.c b/18_dtsplatform/leddriver.c new file mode 100644 index 0000000000000000000000000000000000000000..f4fb2f7175c8d9a6b2355e32da632132faa55f4e --- /dev/null +++ b/18_dtsplatform/leddriver.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LEDDEV_CNT 1 /* 设备号长度 */ +#define LEDDEV_NAME "dtsplatled" /* 设备名字 */ +#define LEDOFF 0 +#define LEDON 1 + +/* leddev设备结构体 */ +struct leddev_dev +{ + dev_t devid; /* 设备号 */ + int major; /* 主设备号 */ + struct cdev cdev; + struct class *class; + struct device *device; /* 设备 */ + + struct device_node *node; /* LED设备节点 */ + int led0; /* LED灯GPIO标号 */ +}; + +struct leddev_dev leddev; /* led设备 */ + +void led0_switch(u8 sta) +{ + if (sta == LEDON) + { + gpio_set_value(leddev.led0, 0); + }else if (sta == LEDOFF) + { + gpio_set_value(leddev.led0, 1); + } +} + + +static int led_open(struct inode* inode, struct file* filp) +{ + filp->private_data = &leddev; + return 0; +} + +static ssize_t led_write(struct file* filp, const char __user* buf, size_t cnt, loff_t* offt) +{ + int retvalue; + unsigned char databuf[2]; + unsigned char ledstat; + + retvalue = copy_from_user(databuf, buf, cnt); + if (retvalue<0) + { + printk("kernel write failed! \r\n"); + return -EFAULT; + } + ledstat = databuf[0]; + if (ledstat == LEDON) + { + led0_switch(LEDON); + }else if (ledstat == LEDOFF) + { + led0_switch(LEDOFF); + } + return 0; +} + + + +struct file_operations led_fops = { + .owner = THIS_MODULE, + .open = led_open, + .write = led_write, +}; + + +static int led_probe(struct platform_device *dev) +{ + printk("led driver and device was matched!\r\n"); + /* 1、设置设备号 */ + if(leddev.major){ + leddev.devid = MKDEV(leddev.major, 0); + register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME); + }else{ + alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME); + leddev.major = MAJOR(leddev.devid); + } + + /* 2、注册设备 */ + cdev_init(&leddev.cdev, &led_fops); + cdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT); + + /* 创建类 */ + leddev.class = class_create(THIS_MODULE, LEDDEV_NAME); + if (IS_ERR(leddev.class)) + { + return PTR_ERR(leddev.class); + } + + /* 4、创建设备 */ + leddev.device = device_create(leddev.class, NULL, leddev.devid, NULL, + LEDDEV_NAME); + if (IS_ERR(leddev.device)) + { + return PTR_ERR(leddev.device); + } + + /* 5、初始化IO */ + leddev.node = of_find_node_by_path("/gpioled"); + if (leddev.node == NULL) { + printk("gpioled node nost find!\r\n"); + return -EINVAL; + } + leddev.led0 = of_get_named_gpio(leddev.node, "led-gpio", 0); + if (leddev.led0 < 0) { + printk("can't get led-gpio\r\n"); + return -EINVAL; + } + gpio_request(leddev.led0, "led0"); + gpio_direction_output(leddev.led0, 1); /* 设置为输出,默认高电平 */ + return 0; +} + + +static int led_remove(struct platform_device* dev) +{ + gpio_set_value(leddev.led0, 1); + cdev_del(&leddev.cdev); + unregister_chrdev_region(leddev.devid, LEDDEV_CNT); + device_destroy(leddev.class, leddev.devid); + class_destroy(leddev.class); + return 0; +} + +static struct of_device_id led_of_match[] = { + {.compatible = "atkalpha-gpioled"}, + {/* 空 */} +}; + +static struct platform_driver led_driver = { + .driver = { + .name = "imx6ul-led", + .of_match_table = led_of_match, + }, + .probe = led_probe, + .remove = led_remove, +}; + +static int __init leddriver_init(void) +{ + return platform_driver_register(&led_driver); +} + +static __exit leddriver_exit(void) +{ + platform_driver_unregister(&led_driver); +} + +module_init(leddriver_init); +module_exit(leddriver_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("chaoliang"); \ No newline at end of file