IMX6ULL linux4.x RS485配置

文章目录

  • IMX6ULL linux4.x RS485配置
    • 使用IMX6ULL硬件流控
      • 设备树
    • 使用普通IO口做软件流控
      • 串口驱动补丁
      • 设备树
    • rs485测试程序
      • 使用效果

IMX6ULL linux4.x RS485配置

使用IMX6ULL硬件流控

设备树

pinctrl_485r1: 485r1grp {fsl,pins = <MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1MX6UL_PAD_UART2_CTS_B__GPIO1_IO22       0x1b0b1 /* RS485 RE/DE */>;};&uart2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_485r1>;              //使用的引脚组uart-has-rtscts;                           //使用引硬件流rts-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;  //设置rst引脚linux,rs485-enabled-at-boot-time;          //启用rs485status = "okay";
};

使用普通IO口做软件流控

串口驱动补丁

gpio-rs485.patch

diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
index 35ae1fb..9a0e120 100644
--- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
@@ -6,6 +6,7 @@ Required properties:- interrupts : Should contain uart interruptOptional properties:
+- fsl,rs485-gpio-txen : Indicate a GPIO is used as TXEN instead of RTS- fsl,uart-has-rtscts : Indicate the uart has rts and cts- fsl,irda-mode : Indicate the uart supports irda mode- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index c9bd603..0390990 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -21,6 +21,7 @@#define SUPPORT_SYSRQ#endif+#include <linux/gpio.h>#include <linux/module.h>#include <linux/ioport.h>#include <linux/init.h>
@@ -37,6 +38,7 @@#include <linux/slab.h>#include <linux/of.h>#include <linux/of_device.h>
+#include <linux/of_gpio.h>#include <linux/io.h>#include <linux/dma-mapping.h>@@ -224,6 +226,7 @@ struct imx_port {unsigned short		trcv_delay; /* transceiver delay */struct clk		*clk_ipg;struct clk		*clk_per;
+	int			txen_gpio;const struct imx_uart_data *devdata;/* DMA fields */
@@ -393,16 +396,38 @@ static void imx_stop_tx(struct uart_port *port)temp = readl(port->membase + UCR1);writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1);+	if(sport->txen_gpio != -1 && readl(port->membase + USR2) & USR2_TXDC){
+		//mdelay(5);
+		//while(!(readl(sport->port.membase + uts_reg(sport)) & UTS_TXEMPTY)){
+		//    udelay(1);
+		//}
+		gpio_set_value(sport->txen_gpio, 0);
+
+		/* disable shifter empty irq */
+		temp = readl(port->membase + UCR4);
+		temp &= ~UCR4_TCEN;
+		writel(temp, port->membase + UCR4);
+	}
+/* in rs485 mode disable transmitter if shifter is empty */if (port->rs485.flags & SER_RS485_ENABLED &&readl(port->membase + USR2) & USR2_TXDC) {
-		temp = readl(port->membase + UCR2);
-		if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
-			temp &= ~UCR2_CTS;
-		else
-			temp |= UCR2_CTS;
-		writel(temp, port->membase + UCR2);
+		if(sport->txen_gpio != -1){
+		    if(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+			    gpio_set_value(sport->txen_gpio, 1);
+		    else
+			    gpio_set_value(sport->txen_gpio, 0);
+
+		}else{
+		    temp = readl(port->membase + UCR2);
+		    if(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+			    temp &= ~UCR2_CTS;
+		    else
+			    temp |= UCR2_CTS;
+		    writel(temp, port->membase + UCR2);
+		}+		/* disable shifter empty irq */temp = readl(port->membase + UCR4);temp &= ~UCR4_TCEN;writel(temp, port->membase + UCR4);
@@ -595,15 +620,32 @@ static void imx_start_tx(struct uart_port *port)struct imx_port *sport = (struct imx_port *)port;unsigned long temp;+	if(sport->txen_gpio != -1){
+		gpio_set_value(sport->txen_gpio, 1);
+
+		/*enable shifter empty irq */
+		temp = readl(port->membase + UCR4);
+		temp |= UCR4_TCEN;
+		writel(temp, port->membase + UCR4);
+	}if (port->rs485.flags & SER_RS485_ENABLED) {
-		/* enable transmitter and shifter empty irq */
-		temp = readl(port->membase + UCR2);
-		if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
+		/* enable transmitter */
+		if(sport->txen_gpio != -1){
+		    if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
+			gpio_set_value(sport->txen_gpio, 1);
+		    else
+			gpio_set_value(sport->txen_gpio, 0);
+		}
+		else{
+		    temp = readl(port->membase + UCR2);
+		    if (port->rs485.flags & SER_RS485_RTS_ON_SEND)temp &= ~UCR2_CTS;
-		else
+		    elsetemp |= UCR2_CTS;
-		writel(temp, port->membase + UCR2);
+		    writel(temp, port->membase + UCR2);
+		}+		/*enable shifter empty irq */temp = readl(port->membase + UCR4);temp |= UCR4_TCEN;writel(temp, port->membase + UCR4);
@@ -653,6 +695,9 @@ static irqreturn_t imx_txint(int irq, void *dev_id)unsigned long flags;spin_lock_irqsave(&sport->port.lock, flags);
+	
+	//if(sport->txen_gpio != -1)
+	  //  printk("bkq%d\n", __LINE__);imx_transmit_buffer(sport);spin_unlock_irqrestore(&sport->port.lock, flags);return IRQ_HANDLED;
@@ -1326,7 +1371,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,if (sport->have_rtscts) {ucr2 &= ~UCR2_IRTS;-			if (port->rs485.flags & SER_RS485_ENABLED) {
+			if ((port->rs485.flags & SER_RS485_ENABLED) &&
+			    (sport->txen_gpio == -1))		
+			{/** RTS is mandatory for rs485 operation, so keep* it under manual control and keep transmitter
@@ -1341,7 +1388,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,} else {termios->c_cflag &= ~CRTSCTS;}
-	} else if (port->rs485.flags & SER_RS485_ENABLED)
+	} else if (port->rs485.flags & SER_RS485_ENABLED && 
+		    sport->txen_gpio == -1)/* disable transmitter */if (!(port->rs485.flags & SER_RS485_RTS_AFTER_SEND))ucr2 |= UCR2_CTS;
@@ -1587,20 +1635,27 @@ static int imx_rs485_config(struct uart_port *port,rs485conf->flags |= SER_RS485_RX_DURING_TX;/* RTS is required to control the transmitter */
-	if (!sport->have_rtscts)
+	if (sport->txen_gpio == -1 && !sport->have_rtscts)rs485conf->flags &= ~SER_RS485_ENABLED;if (rs485conf->flags & SER_RS485_ENABLED) {
-		unsigned long temp;
-/* disable transmitter */
-		temp = readl(sport->port.membase + UCR2);
-		temp &= ~UCR2_CTSC;
-		if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
+		if(sport->txen_gpio != -1){
+		    if(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+			    gpio_set_value(sport->txen_gpio, 1);
+		    else
+			    gpio_set_value(sport->txen_gpio, 0);
+		}else{
+		    unsigned long temp;
+
+		    temp = readl(sport->port.membase + UCR2);
+		    temp &= ~UCR2_CTSC;
+		    if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)temp &= ~UCR2_CTS;
-		else
+		    elsetemp |= UCR2_CTS;
-		writel(temp, sport->port.membase + UCR2);
+		    writel(temp, sport->port.membase + UCR2);
+		}}port->rs485 = *rs485conf;
@@ -1939,6 +1994,15 @@ static int serial_imx_probe_dt(struct imx_port *sport,if (of_get_property(np, "fsl,dte-mode", NULL))sport->dte_mode = 1;+	if (of_find_property(np, "fsl,rs485-gpio-txen", NULL))
+		sport->txen_gpio = of_get_named_gpio(np, "fsl,rs485-gpio-txen", 0);
+	else
+		sport->txen_gpio = -1;
+	if (gpio_is_valid(sport->txen_gpio))
+		devm_gpio_request_one(&pdev->dev, sport->txen_gpio,
+				    GPIOF_OUT_INIT_LOW, "rs485-txen");
+	else
+		sport->txen_gpio = -1;sport->devdata = of_id->data;return 0;
patch -p1 < gpio-rs485.patch

设备树

pinctrl_485r1: 485r1grp {fsl,pins = <MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1>;};
pinctrl_uart4_txen: uart4_txengpr {fsl,pins = <MX6UL_PAD_JTAG_TCK__GPIO1_IO14        0x17059 /* TXEN */>;
};&uart2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_485r1  &pinctrl_uart4_txen>;dmas = <>;dma-names = "";fsl,rs485-gpio-txen = <&gpio1 18 0>;status = "okay";
};

rs485测试程序

uart_test.c

#include <stdio.h>
#include <termios.h>
#include <linux/ioctl.h>
#include <linux/serial.h>
#include <asm-generic/ioctls.h> /* TIOCGRS485 + TIOCSRS485 ioctl definitions */
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>/*** @brief: set the properties of serial port* @Param: fd: file descriptor* @Param: nSpeed: Baud Rate* @Param: nBits: character size* @Param: nEvent: parity of serial port* @Param: nStop: stop bits*/
typedef enum {DISABLE = 0, ENABLE} RS485_ENABLE_t;int set_port(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{struct termios newtio, oldtio;memset(&oldtio, 0, sizeof(oldtio));/* save the old serial port configuration */if(tcgetattr(fd, &oldtio) != 0) {perror("set_port/tcgetattr");return -1;}memset(&newtio, 0, sizeof(newtio));/* ignore modem control lines and enable receiver */newtio.c_cflag = newtio.c_cflag |= CLOCAL | CREAD;newtio.c_cflag &= ~CSIZE;/* set character size */switch (nBits) {case 8:newtio.c_cflag |= CS8;break;case 7:newtio.c_cflag |= CS7;break;case 6:newtio.c_cflag |= CS6;break;case 5:newtio.c_cflag |= CS5;break;default:newtio.c_cflag |= CS8;break;}/* set the parity */switch (nEvent) {case 'o':case 'O':newtio.c_cflag |= PARENB;newtio.c_cflag |= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);break;case 'e':case 'E':newtio.c_cflag |= PARENB;newtio.c_cflag &= ~PARODD;newtio.c_iflag |= (INPCK | ISTRIP);break;case 'n':case 'N':newtio.c_cflag &= ~PARENB;break;default:newtio.c_cflag &= ~PARENB;break;}/* set the stop bits */switch (nStop) {case 1:newtio.c_cflag &= ~CSTOPB;break;case 2:newtio.c_cflag |= CSTOPB;break;default:newtio.c_cflag &= ~CSTOPB;break;}/* set output and input baud rate */switch (nSpeed) {case 0:cfsetospeed(&newtio, B0);cfsetispeed(&newtio, B0);break;case 50:cfsetospeed(&newtio, B50);cfsetispeed(&newtio, B50);break;case 75:cfsetospeed(&newtio, B75);cfsetispeed(&newtio, B75);break;case 110:cfsetospeed(&newtio, B110);cfsetispeed(&newtio, B110);break;case 134:cfsetospeed(&newtio, B134);cfsetispeed(&newtio, B134);break;case 150:cfsetospeed(&newtio, B150);cfsetispeed(&newtio, B150);break;case 200:cfsetospeed(&newtio, B200);cfsetispeed(&newtio, B200);break;case 300:cfsetospeed(&newtio, B300);cfsetispeed(&newtio, B300);break;case 600:cfsetospeed(&newtio, B600);cfsetispeed(&newtio, B600);break;case 1200:cfsetospeed(&newtio, B1200);cfsetispeed(&newtio, B1200);break;case 1800:cfsetospeed(&newtio, B1800);cfsetispeed(&newtio, B1800);break;case 2400:cfsetospeed(&newtio, B2400);cfsetispeed(&newtio, B2400);break;case 4800:cfsetospeed(&newtio, B4800);cfsetispeed(&newtio, B4800);break;case 9600:cfsetospeed(&newtio, B9600);cfsetispeed(&newtio, B9600);break;case 19200:cfsetospeed(&newtio, B19200);cfsetispeed(&newtio, B19200);break;case 38400:cfsetospeed(&newtio, B38400);cfsetispeed(&newtio, B38400);break;case 57600:cfsetospeed(&newtio, B57600);cfsetispeed(&newtio, B57600);break;case 115200:cfsetospeed(&newtio, B115200);cfsetispeed(&newtio, B115200);break;case 230400:cfsetospeed(&newtio, B230400);cfsetispeed(&newtio, B230400);break;default:cfsetospeed(&newtio, B115200);cfsetispeed(&newtio, B115200);break;}/* set timeout in deciseconds for non-canonical read */newtio.c_cc[VTIME] = 0;/* set minimum number of characters for non-canonical read */newtio.c_cc[VMIN] = 0;/* flushes data received but not read */tcflush(fd, TCIFLUSH);/* set the parameters associated with the terminal fromthe termios structure and the change occurs immediately */if((tcsetattr(fd, TCSANOW, &newtio))!=0){perror("set_port/tcsetattr");return -1;}return 0;
}/*** @brief: open serial port* @Param: dir: serial device path*/
int open_port(char *dir)
{int fd ;fd = open(dir, O_RDWR);if(fd < 0) {perror("open_port");}return fd;
}/*** @brief: print usage message* @Param: stream: output device* @Param: exit_code: error code which want to exit*/
void print_usage (FILE *stream, int exit_code)
{fprintf(stream, "Usage: option [ dev... ] \n");fprintf(stream,"\t-h  --help     Display this usage information.\n""\t-d  --device   The device ttyS[0-3] or ttySCMA[0-1]\n""\t-b  --baudrate Set the baud rate you can select\n""\t               [230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300]\n""\t-s  --string   Write the device data\n""\t-e  --1 or 0 , Write 1 to enable rs485_mode(only at atmel)\n");exit(exit_code);
}/*** @brief: main function* @Param: argc: number of parameters* @Param: argv: parameters list*/
int rs485_enable(const int fd, const RS485_ENABLE_t enable)
{struct serial_rs485 rs485conf;int res;/* Get configure from device */res = ioctl(fd, TIOCGRS485, &rs485conf);if (res < 0) {perror("Ioctl error on getting 485 configure:");close(fd);return res;}/* Set enable/disable to configure */if (enable) {   // Enable rs485 moders485conf.flags |= SER_RS485_ENABLED;} else {        // Disable rs485 moders485conf.flags &= ~(SER_RS485_ENABLED);}rs485conf.delay_rts_before_send = 0x00000004;/* Set configure to device */res = ioctl(fd, TIOCSRS485, &rs485conf);if (res < 0) {perror("Ioctl error on setting 485 configure:");close(fd);}return res;
}int main(int argc, char *argv[])
{char *write_buf = "0123456789";char read_buf[100];int fd, i, len, nread,r;pid_t pid;int next_option;extern struct termios oldtio;int speed ;char *device;int spee_flag = 0, device_flag = 0;const char *const short_options = "hd:s:b:e:";const struct option long_options[] = {{ "help",   0, NULL, 'h'},{ "device", 1, NULL, 'd'},{ "string", 1, NULL, 's'},{ "baudrate", 1, NULL, 'b'},{ NULL,     0, NULL, 0  }};if (argc < 2) {print_usage (stdout, 0);exit(0);}while (1) {next_option = getopt_long (argc, argv, short_options, long_options, NULL);if (next_option < 0)break;switch (next_option) {case 'h':print_usage (stdout, 0);break;case 'd':device = optarg;device_flag = 1;break;case 'b':speed = atoi(optarg);spee_flag = 1;break;case 's':write_buf = optarg;break;case 'e':r = atoi(optarg);break;case '?':print_usage (stderr, 1);break;default:abort ();}}if ((!device_flag)||(!spee_flag)) {print_usage (stderr, 1);exit(0);}/* open serial port */fd = open_port(device);if (fd < 0) {perror("open failed");return -1;}if(r){rs485_enable(fd,ENABLE);}/* set serial port */i = set_port(fd, speed, 8, 'N', 1);if (i < 0) {perror("set_port failed");return -1;}while (1) {/* if new data is available on the serial port, read and print it out */nread = read(fd ,read_buf ,sizeof(read_buf));if (nread > 0) {printf("RECV[%3d]: ", nread);for(i = 0; i < nread; i++)printf("0x%02x ", read_buf[i]);printf("\n");write(fd, read_buf, nread);//自己添加}else{printf("read error\n");sleep(1);}}/* restore the old configuration */tcsetattr(fd, TCSANOW, &oldtio);close(fd);return 0;
}

使用效果

uart_test -d /dev/ttymxc2 -b 115200

image-20240709093233509

image-20240709093303992

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/44126.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【鸿蒙学习笔记】UIAbility组件概述

官方文档&#xff1a;UIAbility组件 目录标题 UIAbility组件概述 [Q&A] 什么是UIAbility&#xff1f;声明周期UIAbility组件-启动模式UIAbility组件-与UI的数据同步 UIAbility组件概述 [Q&A] 什么是UIAbility&#xff1f; UIAbility组件是一种包含UI界面的应用组件&a…

防火墙组网

一、实验拓扑图 二、实验要求 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9&#xff1a;00-18&#xff1a;00&#xff09;可以访问&#xff0c; 生产区的设备全天可以访问。 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网。 3、办…

Sora模型:释放创意产业文本到视频AI的潜力

Sora&#xff0c;这个由OpenAI在2024年推出的文本到视频生成模型&#xff0c;不仅能够将文字描述转化为生动的视频内容&#xff0c;而且还能保持视频一分钟之久的连贯性和高质量&#xff0c;这在之前是难以想象的。 尽管AI在图像和文本理解上已取得巨大进步&#xff0c;但将这…

飞猪惹怒12306,一张火车票让第三方平台耍尽手段……

小柴已经记不清铁路12306是多少次发出提醒&#xff0c;似乎每一次出行高峰&#xff0c;都会提醒一次。 比如一再强调&#xff0c;购买加速包、付费成为会员就能优先出票&#xff0c;找朋友助力砍一刀&#xff0c;就能获得更高的出票概率……都是假的。‍‍ 因为&#xff0c;铁…

Win-ARM联盟的端侧AI技术分析

Win-ARM联盟&#xff0c;端侧AI大幕将起 微软震撼发布全球首款AI定制Windows PC——Copilot PC&#xff0c;搭载全新NPU与重塑的Windows 11系统&#xff0c;纳德拉盛赞其为史上最快、最强、最智能的Windows PC。该设备算力需求高达40TOPS&#xff0c;支持语音翻译、实时绘画、文…

PHP同城多商户多行业系统小程序源码

同城新生态&#xff0c;解锁多商户多行业系统的无限魅力&#x1f306;&#x1f680; &#x1f308; 开篇&#xff1a;同城新纪元&#xff0c;多商户多行业系统引领潮流&#xff01; 想象一下&#xff0c;在同一个城市内&#xff0c;无论是美食探索、购物狂欢&#xff0c;还是…

滥用云服务进行传播的恶意软件越来越多

由于云服务提供了传统方式所不具备的可扩展性、匿名性和容错性&#xff0c;攻击者越来越多地开始利用云服务来存储、分发和建立 C&C 信道&#xff0c;例如 VCRUM 存储在 AWS 上或 SYK Cryptor 通过 DriveHQ 进行分发。 过去的一个月内&#xff0c;研究人员一直在监控使用这…

css看见彩虹,吃定彩虹

css彩虹 .f111 {width: 200px;height: 200px;border-radius: 50%;box-shadow: 0 0 0 5px inset red, 0 0 0 10px inset orange, 0 0 0 15px inset yellow, 0 0 0 20px inset lime, 0 0 0 25px inset aqua, 0 0 0 30px inset blue, 0 0 0 35px inset magenta;clip-path: polygo…

文件上传漏洞:upload-labs靶场安装和实践

一、upload-labs靶场安装 安装&#xff1a;Windows下的Upload-labs环境搭建(Upload文件夹不存在报错&#xff09;_upload-labs文件夹不存在-CSDN博客 当安装好phpstudy之后&#xff0c;在网址栏输入&#xff1a;localhost或127.0.0.1&#xff0c;如果没问题&#xff0c;就将下…

【NLP学习笔记】transformers中的tokenizer切词时是否返回token_type_ids

结论 先说结论&#xff1a; 是否返回token_type_ids&#xff0c;可以在切词时通过 return_token_type_idsTrue/False指定&#xff0c;指定了True就肯定会返回&#xff0c;指定False&#xff0c;不一定就不返回。 分析 Doc地址 https://huggingface.co/docs/transformers/main…

springboot通江银耳销售管理系统-计算机毕业设计源码15998

摘要 随着人们健康意识的增强&#xff0c;银耳这种传统的中药食材备受关注。而通江银耳是四川省通江县特产&#xff0c;中国国家地理标志产品。四川省通江县是银耳的发源地&#xff0c;中国银耳之乡&#xff0c;通江银耳因主产于此而得名&#xff0c;以其独到的质厚、肉嫩、易炖…

【Python专栏】Python的历史及背景介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Python专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Python的背景介绍 关键词&#xff1a;Python、优缺点、领域 目录 …

自定义指令实现Element Plus分页组件内容样式修改

改之前是这样的 改之后是这样的 因为之前我也有写过文章讲解Vue2-ElementUI分页组件的样式修改。 ElementUI 分页组件内容样式修改https://blog.csdn.net/qq_54548545/article/details/139728064且通常情况下&#xff0c;一个项目若是大量使用到分页组件&#xff0c;咱们也不可…

Mac怎么录屏带声音,学会这2种方法,轻松解决

在数字化时代&#xff0c;录屏已经成为我们工作、学习和娱乐中不可或缺的一部分。对于Mac用户来说&#xff0c;Mac怎么录屏带声音是一个非常实用又重要的操作&#xff0c;无论是为了保存会议内容、制作教学视频还是为了录制游戏视频&#xff0c;这一功能都能为我们提供极大的便…

会员运营体系设计及SOP梳理

一些做会员的经验和方法分享给大家&#xff0c;包括顶层思考、流程的梳理、组织的建立&#xff0c;后续会做成系列&#xff0c;最近几期主要围绕顶层策略方面&#xff0c;以下是核心内容的整理&#xff1a; 1、会员运营体系设计 顶层设计与关键业务定位&#xff1a;建立客户运营…

Web学习day03

maven&Mybatis 目录 maven&Mybatis 文章目录 一、maven 1.1作用 1.2仓库 1.3命令 1.4依赖范围 1.5生命周期 二、MyBatis 2.1简介 2.2API 2.3增删改的实现&案例 总结 一、maven 1.1作用 统一项目结构&#xff1b;项目构建&#xff1a;通过简单命令&a…

GitHub 站点打不开

遇到的问题 您是否遇到过GitHub网站打不开的情况&#xff0c;正如下图所示&#xff1a; 解决方案 以下是一些常见的解决方案&#xff1a; 1. 检查网络连接 确保你的设备已连接到互联网。尝试访问其他网站&#xff0c;确保不是你的网络问题。 C:\Vinca>ping github.…

Vue+SpringBoot实现仿网盘项目

目录 一、效果展示 二、前端代码 三、后端代码及核心解释 四、进阶开发与思路 一、效果展示 1.1读取文件夹内的文件 1.2删除功能 1.3 上传文件 1.4 文件下载 对应的网盘实际地址与对应下载内容&#xff1a; 二、前端代码 2.1 创建vue项目&#xff08;需要有vuex与router&…

C++笔试真题

可变分区管理方案 最佳适应&#xff1a;空闲区按容量递增最坏适应&#xff1a;空闲区按容量递减首先适应&#xff1a;空闲区按地址递增 C的结构体中有构造函数。 Linux新建用户或组 useradd&#xff1a;命令用于建立用户账号usermod&#xff1a;修改用户账号groupadd&#…

【模块化与包管理】:解锁【Python】编程的高效之道

目录 1.什么是模块&#xff1f; 2. 模块的导入过程 3. 理解命名空间 4. import语句的多种形式 5. 模块的执行与重新导入 6. 包&#xff08;Package&#xff09; 7. sys模块和os模块 sys模块 常用属性 示例&#xff1a;使用sys模块 os模块 常用功能 示例&#xff1…