linux PWM蜂鸣器移植以及驱动程序分析【转】
本文转载自:https://blog.csdn.net/lxllinux/article/details/80885331
通过S3C2440底板原理图可知蜂鸣器接2440的GPB0/TOUT0.即我们的蜂鸣器是通过GPB0 IO口使用PWM信号驱动工作的,而且GPB0口是一个复用的IO口,要使用它得把他设置成TOUT0 PWM输出模式。
蜂鸣器可以发声,靠的不仅仅是蜂鸣器硬件的驱动,还有Linux下的PWM(脉冲宽度调制)这种变频技术,靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。通过改变频率可以使蜂鸣器发出不同的声音。
二、修改设备树
- beeper {
- compatible = "pwm-beeper";
- pwms = <&pwm 0 1000000 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pwm0_pin>;
- };
四、修改配置文件:
- /*********************************************************************************
- * Copyright: (C) 2017 qicheng
- * All rights reserved.
- *
- * Filename: beer_test.c
- * Description: This file
- *
- * Version: 1.0.0(04/19/2017)
- * Author: yangni <497049229@qq.com>
- * ChangeLog: 1, Release initial version on "04/19/2017 11:44:58 AM"
- *
- ********************************************************************************/
- #include<stdint.h>
- #include<string.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include<stdio.h>
- #include<linux/input.h>
- #include<unistd.h>
- int main(int argc, char *argv[])
- {
- int fd, version, ret;
- int i;
- struct input_event event;
- if ((fd = open("/dev/event1", O_RDWR)) < 0) {
- perror("beep test");
- return 1;
- }
- event.type = EV_SND;
- event.code = SND_TONE;
- if(!strcmp (argv[1],"1"))
- {
- for(i=0;i<=7;i++)
- {
- event.value = 2000; //打开蜂鸣器
- ret = write(fd, &event, sizeof(struct input_event));
- sleep(0.5);
- event.value = 0; //关闭蜂鸣器
- ret = write(fd, &event, sizeof(struct input_event));
- }
- }
- else if(!strcmp (argv[1],"0"))
- {
- event.value = 0;
- ret = write(fd, &event, sizeof(struct input_event));
- }
- close(fd);
- return 0;
- }
从应用程序中得到的input_event.code只能为SND_BELL或SND_TONE,否则退出。
- /* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- * PWM beeper driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
- #include <linux/input.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/platform_device.h>
- #include <linux/pwm.h>
- #include <linux/slab.h>
- struct pwm_beeper {
- struct input_dev *input;
- struct pwm_device *pwm;
- unsigned long period;
- };
- #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
- //事件处理函数
- static int pwm_beeper_event(struct input_dev *input,
- unsigned int type, unsigned int code, int value)
- {
- int ret = 0;
- struct pwm_beeper *beeper = input_get_drvdata(input);
- unsigned long period;
- if (type != EV_SND || value < 0)
- return -EINVAL; //若input_event.type不是EV_SND或input_event.value小于0,则退出
- switch (code) {
- case SND_BELL:
- value = value ? 1000 : 0;
- break;
- case SND_TONE:
- break;
- default:
- return -EINVAL;
- }
- if (value == 0) {
- pwm_config(beeper->pwm, 0, 0); //配置PWM函数
- pwm_disable(beeper->pwm); //关闭PWM函数
- } else {
- period = HZ_TO_NANOSECONDS(value);
- ret = pwm_config(beeper->pwm, period / 2, period);
- if (ret)
- return ret;
- ret = pwm_enable(beeper->pwm);
- if (ret)
- return ret;
- beeper->period = period;
- }
- return 0;
- }
- static int __devinit pwm_beeper_probe(struct platform_device *pdev)
- {
- unsigned long pwm_id = (unsigned long)pdev->dev.platform_data;
- struct pwm_beeper *beeper;
- int error;
- //为蜂鸣器设备开辟一段内存空间,并清零
- beeper = kzalloc(sizeof(*beeper), GFP_KERNEL);
- if (!beeper)
- return -ENOMEM;
- beeper->pwm = pwm_request(pwm_id, "pwm beeper"); //申请一个PWM设备
- if (IS_ERR(beeper->pwm)) {
- error = PTR_ERR(beeper->pwm);
- dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error);
- goto err_free;
- }
- beeper->input = input_allocate_device(); //为输入设备结构体分配一个空间,并对其主要的成员进行了初始化.
- if (!beeper->input) {
- dev_err(&pdev->dev, "Failed to allocate input device\n");
- error = -ENOMEM;
- goto err_pwm_free;
- }
- beeper->input->dev.parent = &pdev->dev; //将输入信息赋值到输入子系统
- beeper->input->name = "pwm-beeper";
- beeper->input->phys = "pwm/input0";
- beeper->input->id.bustype = BUS_HOST;
- beeper->input->id.vendor = 0x001f;
- beeper->input->id.product = 0x0001;
- beeper->input->id.version = 0x0100;
- beeper->input->evbit[0] = BIT(EV_SND);
- beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
- beeper->input->event = pwm_beeper_event; //给出 事件处理函数
- input_set_drvdata(beeper->input, beeper);
- error = input_register_device(beeper->input);
- if (error)
- {
- dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
- goto err_input_free;
- }
- platform_set_drvdata(pdev, beeper);
- return 0;
- err_input_free: input_free_device(beeper->input);
- err_pwm_free: pwm_free(beeper->pwm);
- err_free: kfree(beeper); return error;
- }
- //移除pwm设备
- static int __devexit pwm_beeper_remove(struct platform_device *pdev)
- {
- struct pwm_beeper *beeper = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
- input_unregister_device(beeper->input); //卸载输入子系统
- pwm_disable(beeper->pwm);
- pwm_free(beeper->pwm);
- kfree(beeper);
- return 0;
- }
- #ifdef CONFIG_PM
- static int pwm_beeper_suspend(struct device *dev)
- {
- struct pwm_beeper *beeper = dev_get_drvdata(dev);
- if (beeper->period)
- pwm_disable(beeper->pwm);
- return 0;
- }
- static int pwm_beeper_resume(struct device *dev)
- {
- struct pwm_beeper *beeper = dev_get_drvdata(dev);
- if (beeper->period)
- { pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
- pwm_enable(beeper->pwm);
- }
- return 0;
- }
- static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, pwm_beeper_suspend, pwm_beeper_resume);
- #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops)
- #else
- #define PWM_BEEPER_PM_OPS NULL
- #endif
- //创建平台驱动,此处name与上面我们在mach-smdk2440.c添加的名字相同,用于匹配
- static struct platform_driver pwm_beeper_driver = {
- .probe = pwm_beeper_probe,
- .remove = __devexit_p(pwm_beeper_remove),
- .driver = { .name = "pwm-beeper",
- .owner = THIS_MODULE,
- .pm = PWM_BEEPER_PM_OPS,
- },
- };
- //驱动入口
- static int __init pwm_beeper_init(void)
- {
- return platform_driver_register(&pwm_beeper_driver); //注册平台驱动
- }
- module_init(pwm_beeper_init);
- static void __exit pwm_beeper_exit(void)
- {
- platform_driver_unregister(&pwm_beeper_driver);
- }
- module_exit(pwm_beeper_exit);
- MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
- MODULE_DESCRIPTION("PWM beeper driver");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:pwm-beeper");
内核使能的是驱动,而设备是我们自己添加的。该驱动程序工作流程与之前的类似:
- beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
- PWM蜂鸣器的事件类型为EV_SND,声音的类型为SND_TONE或SND_BELL
- 这两项内容就是我们在应用程序中要用到的input_event中的type和code
- static int pwm_beeper_event(struct input_dev *input,
- unsigned int type, unsigned int code, int value)
- {
- int ret = 0;
- struct pwm_beeper *beeper = input_get_drvdata(input);
- unsigned long period;
- if (type != EV_SND || value < 0)
- return -EINVAL;
- switch (code) {
- case SND_BELL:
- value = value ? 1000 : 0;
- break;
- case SND_TONE:
- break;
- default:
- return -EINVAL;
- }
- if (value == 0) {
- pwm_config(beeper->pwm, 0, 0); //配置PWM函数
- pwm_disable(beeper->pwm); //关闭PWM函数
- } else {
- period = HZ_TO_NANOSECONDS(value);
- ret = pwm_config(beeper->pwm, period / 2, period);
- if (ret)
- return ret;
- ret = pwm_enable(beeper->pwm);
- if (ret)
- return ret;
- beeper->period = period;
- }
- return 0;
- }
- 如果code为SND_BELL,不管input_event.value为多少,最终的value只能为1000或0,即不能改变蜂鸣器的频率。0表示关闭。
- 如果code为SND_TONE,则可以通过改变input_event.value的值来调整蜂鸣器的频率,从而发出各种不同的音调。
Linux输入子系统包括三个层次:事件处理层(Event Handler)、核心层(Input Core)和驱动层(Input Driver)。
1.事件处理层负责与用户程序打交道,将核心层传来的事件报告给用户程序。
2.核心层是链接其他两个层之间的纽带与桥梁,向下提供驱动层的接口,向上提供事件处理层的接口。
3.驱动层负责操作具体的硬件设备,这层的代码是针对具体的驱动程序的,键盘、鼠标、触摸屏等字符设备驱动功能的实现工作主要就在这层。
输入子系统有三个核心结构体:input_dev,input_handle和input_handler。input_dev表示一个输入设备,包含输入设备的一些相关信息;input_handler表示对输入事件的具体处理,它为输入设备的功能实现了一个接口;input_handle是用来连接输入设备和输入事件。输入子系统主要的任务就是把这三个结构体连接在一起。
总结:
通过S3C2440底板原理图可知蜂鸣器接2440的GPB0/TOUT0.即我们的蜂鸣器是通过GPB0 IO口使用PWM信号驱动工作的,而且GPB0口是一个复用的IO口,要使用它得把他设置成TOUT0 PWM输出模式。
蜂鸣器可以发声,靠的不仅仅是蜂鸣器硬件的驱动,还有Linux下的PWM(脉冲宽度调制)这种变频技术,靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。通过改变频率可以使蜂鸣器发出不同的声音。
二、修改设备树
- beeper {
- compatible = "pwm-beeper";
- pwms = <&pwm 0 1000000 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pwm0_pin>;
- };
四、修改配置文件:
- /*********************************************************************************
- * Copyright: (C) 2017 qicheng
- * All rights reserved.
- *
- * Filename: beer_test.c
- * Description: This file
- *
- * Version: 1.0.0(04/19/2017)
- * Author: yangni <497049229@qq.com>
- * ChangeLog: 1, Release initial version on "04/19/2017 11:44:58 AM"
- *
- ********************************************************************************/
- #include<stdint.h>
- #include<string.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include<stdio.h>
- #include<linux/input.h>
- #include<unistd.h>
- int main(int argc, char *argv[])
- {
- int fd, version, ret;
- int i;
- struct input_event event;
- if ((fd = open("/dev/event1", O_RDWR)) < 0) {
- perror("beep test");
- return 1;
- }
- event.type = EV_SND;
- event.code = SND_TONE;
- if(!strcmp (argv[1],"1"))
- {
- for(i=0;i<=7;i++)
- {
- event.value = 2000; //打开蜂鸣器
- ret = write(fd, &event, sizeof(struct input_event));
- sleep(0.5);
- event.value = 0; //关闭蜂鸣器
- ret = write(fd, &event, sizeof(struct input_event));
- }
- }
- else if(!strcmp (argv[1],"0"))
- {
- event.value = 0;
- ret = write(fd, &event, sizeof(struct input_event));
- }
- close(fd);
- return 0;
- }
从应用程序中得到的input_event.code只能为SND_BELL或SND_TONE,否则退出。
- /* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- * PWM beeper driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
- #include <linux/input.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/platform_device.h>
- #include <linux/pwm.h>
- #include <linux/slab.h>
- struct pwm_beeper {
- struct input_dev *input;
- struct pwm_device *pwm;
- unsigned long period;
- };
- #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
- //事件处理函数
- static int pwm_beeper_event(struct input_dev *input,
- unsigned int type, unsigned int code, int value)
- {
- int ret = 0;
- struct pwm_beeper *beeper = input_get_drvdata(input);
- unsigned long period;
- if (type != EV_SND || value < 0)
- return -EINVAL; //若input_event.type不是EV_SND或input_event.value小于0,则退出
- switch (code) {
- case SND_BELL:
- value = value ? 1000 : 0;
- break;
- case SND_TONE:
- break;
- default:
- return -EINVAL;
- }
- if (value == 0) {
- pwm_config(beeper->pwm, 0, 0); //配置PWM函数
- pwm_disable(beeper->pwm); //关闭PWM函数
- } else {
- period = HZ_TO_NANOSECONDS(value);
- ret = pwm_config(beeper->pwm, period / 2, period);
- if (ret)
- return ret;
- ret = pwm_enable(beeper->pwm);
- if (ret)
- return ret;
- beeper->period = period;
- }
- return 0;
- }
- static int __devinit pwm_beeper_probe(struct platform_device *pdev)
- {
- unsigned long pwm_id = (unsigned long)pdev->dev.platform_data;
- struct pwm_beeper *beeper;
- int error;
- //为蜂鸣器设备开辟一段内存空间,并清零
- beeper = kzalloc(sizeof(*beeper), GFP_KERNEL);
- if (!beeper)
- return -ENOMEM;
- beeper->pwm = pwm_request(pwm_id, "pwm beeper"); //申请一个PWM设备
- if (IS_ERR(beeper->pwm)) {
- error = PTR_ERR(beeper->pwm);
- dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error);
- goto err_free;
- }
- beeper->input = input_allocate_device(); //为输入设备结构体分配一个空间,并对其主要的成员进行了初始化.
- if (!beeper->input) {
- dev_err(&pdev->dev, "Failed to allocate input device\n");
- error = -ENOMEM;
- goto err_pwm_free;
- }
- beeper->input->dev.parent = &pdev->dev; //将输入信息赋值到输入子系统
- beeper->input->name = "pwm-beeper";
- beeper->input->phys = "pwm/input0";
- beeper->input->id.bustype = BUS_HOST;
- beeper->input->id.vendor = 0x001f;
- beeper->input->id.product = 0x0001;
- beeper->input->id.version = 0x0100;
- beeper->input->evbit[0] = BIT(EV_SND);
- beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
- beeper->input->event = pwm_beeper_event; //给出 事件处理函数
- input_set_drvdata(beeper->input, beeper);
- error = input_register_device(beeper->input);
- if (error)
- {
- dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
- goto err_input_free;
- }
- platform_set_drvdata(pdev, beeper);
- return 0;
- err_input_free: input_free_device(beeper->input);
- err_pwm_free: pwm_free(beeper->pwm);
- err_free: kfree(beeper); return error;
- }
- //移除pwm设备
- static int __devexit pwm_beeper_remove(struct platform_device *pdev)
- {
- struct pwm_beeper *beeper = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
- input_unregister_device(beeper->input); //卸载输入子系统
- pwm_disable(beeper->pwm);
- pwm_free(beeper->pwm);
- kfree(beeper);
- return 0;
- }
- #ifdef CONFIG_PM
- static int pwm_beeper_suspend(struct device *dev)
- {
- struct pwm_beeper *beeper = dev_get_drvdata(dev);
- if (beeper->period)
- pwm_disable(beeper->pwm);
- return 0;
- }
- static int pwm_beeper_resume(struct device *dev)
- {
- struct pwm_beeper *beeper = dev_get_drvdata(dev);
- if (beeper->period)
- { pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
- pwm_enable(beeper->pwm);
- }
- return 0;
- }
- static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, pwm_beeper_suspend, pwm_beeper_resume);
- #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops)
- #else
- #define PWM_BEEPER_PM_OPS NULL
- #endif
- //创建平台驱动,此处name与上面我们在mach-smdk2440.c添加的名字相同,用于匹配
- static struct platform_driver pwm_beeper_driver = {
- .probe = pwm_beeper_probe,
- .remove = __devexit_p(pwm_beeper_remove),
- .driver = { .name = "pwm-beeper",
- .owner = THIS_MODULE,
- .pm = PWM_BEEPER_PM_OPS,
- },
- };
- //驱动入口
- static int __init pwm_beeper_init(void)
- {
- return platform_driver_register(&pwm_beeper_driver); //注册平台驱动
- }
- module_init(pwm_beeper_init);
- static void __exit pwm_beeper_exit(void)
- {
- platform_driver_unregister(&pwm_beeper_driver);
- }
- module_exit(pwm_beeper_exit);
- MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
- MODULE_DESCRIPTION("PWM beeper driver");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:pwm-beeper");
内核使能的是驱动,而设备是我们自己添加的。该驱动程序工作流程与之前的类似:
- beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
- PWM蜂鸣器的事件类型为EV_SND,声音的类型为SND_TONE或SND_BELL
- 这两项内容就是我们在应用程序中要用到的input_event中的type和code
- static int pwm_beeper_event(struct input_dev *input,
- unsigned int type, unsigned int code, int value)
- {
- int ret = 0;
- struct pwm_beeper *beeper = input_get_drvdata(input);
- unsigned long period;
- if (type != EV_SND || value < 0)
- return -EINVAL;
- switch (code) {
- case SND_BELL:
- value = value ? 1000 : 0;
- break;
- case SND_TONE:
- break;
- default:
- return -EINVAL;
- }
- if (value == 0) {
- pwm_config(beeper->pwm, 0, 0); //配置PWM函数
- pwm_disable(beeper->pwm); //关闭PWM函数
- } else {
- period = HZ_TO_NANOSECONDS(value);
- ret = pwm_config(beeper->pwm, period / 2, period);
- if (ret)
- return ret;
- ret = pwm_enable(beeper->pwm);
- if (ret)
- return ret;
- beeper->period = period;
- }
- return 0;
- }
- 如果code为SND_BELL,不管input_event.value为多少,最终的value只能为1000或0,即不能改变蜂鸣器的频率。0表示关闭。
- 如果code为SND_TONE,则可以通过改变input_event.value的值来调整蜂鸣器的频率,从而发出各种不同的音调。
Linux输入子系统包括三个层次:事件处理层(Event Handler)、核心层(Input Core)和驱动层(Input Driver)。
1.事件处理层负责与用户程序打交道,将核心层传来的事件报告给用户程序。
2.核心层是链接其他两个层之间的纽带与桥梁,向下提供驱动层的接口,向上提供事件处理层的接口。
3.驱动层负责操作具体的硬件设备,这层的代码是针对具体的驱动程序的,键盘、鼠标、触摸屏等字符设备驱动功能的实现工作主要就在这层。
输入子系统有三个核心结构体:input_dev,input_handle和input_handler。input_dev表示一个输入设备,包含输入设备的一些相关信息;input_handler表示对输入事件的具体处理,它为输入设备的功能实现了一个接口;input_handle是用来连接输入设备和输入事件。输入子系统主要的任务就是把这三个结构体连接在一起。
总结:
linux PWM蜂鸣器移植以及驱动程序分析【转】的更多相关文章
- [S5PV210 Linux字符驱动之PWM蜂鸣器驱动
在SMDK210.C中添加如下beeper_device 结构体 static struct platform_device beeper_device = { .name = "pwm_b ...
- 【驱动】linux下I2C驱动架构全面分析
I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...
- 【转载】帧缓冲驱动程序分析及其在BSP上的添加
原文地址:(四)帧缓冲驱动程序分析及其在BSP上的添加 作者:gfvvz 一.BSP修改及其分析 1. BSP中直接配置的四个寄存器 S3C6410数据手册的第14.5部分是显示控制器的编程模型部 ...
- linux下I2C驱动架构全面分析【转】
本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...
- 嵌入式linux应用程序移植方法总结
嵌入式linux应用程序移植方法总结 前段时间一直在做openCapwap的移植和调试工作,现在工作已接近尾声,编写本文档对前段工作进行一个总结,分享下openCapwap移植过程中的经验和感悟.江浩 ...
- 转: 关于Linux与JVM的内存关系分析
转自: http://tech.meituan.com/linux-jvm-memory.html Linux与JVM的内存关系分析 葛吒2014-08-29 10:00 引言 在一些物理内存为8g的 ...
- 戴文的Linux内核专题:03驱动程序
转自Linux中国 驱动程序是使内核能够沟通和操作硬件或协议(规则和标准)的小程序.没有驱动程序,内核不知道如何与硬件沟通或者处理协议(内核实际上先发送指令给BIOS,然后BIOS传给硬件). Lin ...
- Linux与Windows中动态链接库的分析与对比
摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...
- android 电容屏(三):驱动调试之驱动程序分析篇
平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...
随机推荐
- Java模版方法的另一种实现
面试荔枝FM杯具,遂死磕AQS途中发现一个有趣的模版用法,记下来. 模版方法是很重要的设计模式,在数据访问层.众多的插件接口都可见其影子,一般的实现都是在模版中定义抽象方法并使用其方法进行算法,让具体 ...
- python3中报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'
reload(sys) sys.setdefaultencoding("utf-8") f = open('.\\24.novel.txt','rb') str = f.read( ...
- python学习之旅(三)
Python基础知识(2):运算符 一.算术运算符 加 +,减 -,乘 *,除 /,幂 **,求余 %,取整 // 二.成员运算符 in,not in 判断一个字符是否在字符串中 name = &qu ...
- RFID系统 免费开源代码 开发,分享[申明:来源于网络]
RFID系统 免费开源代码 开发,分享[申明:来源于网络] 地址:http://www.codeforge.cn/s/0/RFID%E7%B3%BB%E7%BB%9F
- Saltstack如何修改主机名或者minion id
参考:http://www.mamicode.com/info-detail-2241784.html 在生产维护的过程中,由于某种需要,可能需要给一些服务器改名,比如根据服务器的用途重新进行定义主机 ...
- linux --- 部署前后端分离项目
vue + uwsgi +nginx 部署前后端分离项目 准备项目 1.将前端vue项目包和后端django项目包上传服务器,通过lrzsz,直接从windows拖进linux中 2.解压缩操作 前端 ...
- 基于 ASP.NET Core 2.1 的 Razor Class Library 实现自定义错误页面的公用类库
注意:文中使用的是 razor pages ,建议使用 razor views ,使用 razor pages 有一个小坑,razor pages 会用到 {page} 路由参数,如果应用中也用到了这 ...
- Socket 的网络编程
socket 网络编程的服务端: 1) 创建socket 套接字. 2) 和socket绑定主机地址和端口 3) socket 主动监听端口,看又没有来连接. 4) 当执行到 accept() 时, ...
- (一)juc线程高级特性——volatile / CAS算法 / ConcurrentHashMap
1. volatile 关键字与内存可见性 原文地址: https://www.cnblogs.com/zjfjava/category/979088.html 内存可见性(Memory Visibi ...
- 【Python全栈-后端开发】Django进阶1-分页
Django[进阶篇-1 ]分页 分页 一.Django内置分页 from django.core.paginator import Paginator, EmptyPage, PageNotAnIn ...