inux應用開發基礎知識——串口應用編程(十一)

前言:

在Linux系統中,串口設備以文件的形式存在,通常位于/dev目錄下,如ttyS0、ttyUSB0等。這些設備文件可以用于讀取和寫入數據。要使用串口設備,需要打開相應的設備文件。在打開串口時,可以使用O_RDWR選項標志進行讀寫操作,同時使用O_NOCTTY選項標志告訴Linux“本程序不作為串口的‘控制終端’”,以避免一些輸入字符影響進程運行。下面讓我們對串口應用編程進行一個簡單的入門學習吧。

目錄

?一、串口的作用

二、UART硬件介紹

1.使用串口

2. mini2440:

3. JZ2440:?

三、TTY體系中設備節點的差別

1.什么是TTY?

2.各類設備節點的差別

?四、TTY驅動程序的框架

五、回環?

1.串口API

2.串口收發實驗

六、GPS 模塊

1.GPS 模塊硬件

2.GPS 模塊數據格式


?一、串口的作用

UART:通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter),簡稱串口。

????????調試:移植u-boot、內核、應用程序時,主要使用串口查看打印信息

????????外接各種模塊

串口因為結構簡單、穩定可靠,廣受歡迎。

通過三根線即可,發送、接收、地線
?

二、UART硬件介紹

1.使用串口

(1)波特率

(2)格式:數據位,停止位,校驗位,流量控制

怎么樣發送1Byte,比如‘A’????????

????????'A' = 0x41 = 0100 0001

(1) 雙方約定波特率: 每一位占據的時間,假設為1秒

(2) 邏輯電平

?如果TTL想轉化為RS-232的話需要電平轉化芯片

2. mini2440:

3. JZ2440:?

波特率為115200格式為8n1時每秒可以傳輸的字節為:11520 byte

三、TTY體系中設備節點的差別

/dev/ttySo、/dev/ttySACO、/dev/tty.ldev/tty0、/dev/tty1、/devlconsole,

它們有什么差別?

TTYTerminal/ConsolE/UART,

它們有什么差別?

1.什么是TTY?

????????teletype,更準確地說是teleprinter,是一種通信設備,可以用來發送、接收文本信息

????????teletype是一家公司的名字,它生產的teleprinter實在太有名,結果公司名變成了這類產品的名字:teleprinter都被稱為teletype了。

teletype被用來傳輸商業電報,想象一下:

????????把兩臺teletype的線纜接在一起,或者使用無線技術連接兩臺telety這邊打字,另一邊就可以接收到信息并誦過紙張打印出來。

將?teletype 的另一端直接與電腦連接起來,這樣TTY就與計算機關聯起來了。

????????以前的計算機非常的昂貴,可能會有很多地方是共用一臺電腦,通過終端進行操作計算機,一個系統存在多個終端。

Terminal和Console的差別
????????Terminal含有遠端的意思,中文為:終端。Console翻譯為控制臺,可以理解為權限更大、能查看更多信息。比如我們可以在Console上看到內核的打印信息,從這個角度上看:

????????Console是某一個Terminal

????????Terminal并不都是Console。

????????我們可以從多個Terminal中選擇某一個作為Console

????????很多時候,兩個概念混用,并無明確的、官方的定義

????????隨著時代的發展又出現了新的設備。

????????隨著時代的發展個人電腦和虛擬終端也進入了人們的生活中

在Ubuntu上演示:
按住鍵盤:Ctrl+Alt+F3啟動一個虛擬終端,Ctrl+Alt+F4再啟動一個虛擬終端。在里面切換為root用戶:
sudo passwd root //如果su root不成功,就先設置root密碼su root

2.各類設備節點的差別

?/devlconsole

比如: coisole=ttyS0 console=tty
不想去分辨這個設備是串口還是虛擬端,有沒有辦法得到這個設備?
有!通過/devlconsole!
console=ttyS0時: /devlconsole就是ttyso
console=tty時:/devlconsole就是前臺程序的虛擬終端

console=tty0時: /devlconsole就是前臺程序的虛擬終端

console=ttyN時:/devlconsole就是/dev/ttyN
console有多個取值時,使用最后一個取值來判斷

?四、TTY驅動程序的框架

????????大多數用戶都會在輸入時犯錯,所以退格鍵會很有用。這當然可以由應用程序本身來實現,但是根據UNIX設計"哲學",應用程序應盡可能保持簡單。為了方便起見,操作系統提供了一個編輯緩沖區和一些基本的編輯命令(退格清除單個單詞,清除行,重新打印),這些命令在行規范((line discipline)內默認啟用。高級應用程序可以通過將行規范設置為原姓模式(raw mode)而不是默認的成熟或準則模式(cooked and canonical)來禁用這些功能。

五、回環?

1.串口API

????????在Linux系統中,操作設備的統一接口就是: open/ioctl/read/write

????????對于UART,又在ioctl之上封裝了很多函數,主要是用來設置行規程。所以對于UART,編程的套路就是:
?????????????????open
????????????????設置行規程,比如波特率、數據位、停止位、檢驗位、RAW模式、一有數據就返回? ? ? ? ? ? ? ? ? ? ? ? read/write

????????怎么設置行規程??

????????行規程的參數用結構體 termios 來表示,可以參考 Linux 串口—struct termios 結構體:

https://blog.csdn.net/yemingzhu163/article/details/5897156

這些函數在名稱上有一些慣例:

?tc:terminal contorl

?cf: control flag

????????主要是需要設置好 termios 中的參數,這些參數很復雜,可以參考 Linux 串口—struct termios 結構體。?

   1 #include <stdio.h>2 #include <string.h>3 #include <sys/types.h>4 #include <errno.h>5 #include <sys/stat.h>6 #include <fcntl.h>7 #include <unistd.h>8 #include <termios.h>9 #include <stdlib.h>1011 /* set_opt(fd,115200,8,'N',1) */12 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)13 {14     struct termios newtio,oldtio;1516     if ( tcgetattr( fd,&oldtio) != 0) {17         perror("SetupSerial 1");18         return -1;19     }2021     bzero( &newtio, sizeof( newtio ) );22     newtio.c_cflag |= CLOCAL | CREAD;23     newtio.c_cflag &= ~CSIZE;2425     newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/26     newtio.c_oflag  &= ~OPOST;   /*Output*/2728     switch( nBits )29     {30     case 7:31         newtio.c_cflag |= CS7;32     break;33     case 8:34         newtio.c_cflag |= CS8;35     break;36     }3738     switch( nEvent )39     {40     case 'O':41         newtio.c_cflag |= PARENB;42         newtio.c_cflag |= PARODD;43         newtio.c_iflag |= (INPCK | ISTRIP);44     break;45     case 'E':46         newtio.c_iflag |= (INPCK | ISTRIP);47         newtio.c_cflag |= PARENB;48         newtio.c_cflag &= ~PARODD;49     break;50     case 'N':51         newtio.c_cflag &= ~PARENB;52     break;53     }5455     switch( nSpeed )56     {57     case 2400:58         cfsetispeed(&newtio, B2400);59         cfsetospeed(&newtio, B2400);60     break;61     case 4800:62         cfsetispeed(&newtio, B4800);63         cfsetospeed(&newtio, B4800);64     break;65     case 9600:66         cfsetispeed(&newtio, B9600);67         cfsetospeed(&newtio, B9600);68     break;69     case 115200:70         cfsetispeed(&newtio, B115200);71         cfsetospeed(&newtio, B115200);72     break;73     default:74         cfsetispeed(&newtio, B9600);75         cfsetospeed(&newtio, B9600);76     break;77     }7879     if( nStop == 1 )80         newtio.c_cflag &= ~CSTOPB;81     else if ( nStop == 2 )82         newtio.c_cflag |= CSTOPB;8384     newtio.c_cc[VMIN]  = 1;  /* 讀數據時的最小字節數: 沒讀到這些數據我就不返回! */85     newtio.c_cc[VTIME] = 0; /* 等待第1個數據的時間:86                              * 比如VMIN設為10表示至少讀到10個數據才返回,87                              * 但是沒有數據總不能一直等吧? 可以設置VTIME(單位是10秒)88                              * 假設VTIME=1,表示:89                              *    10秒內一個數據都沒有的話就返回90                              *    如果10秒內至少讀到了1個字節,那就繼續等待,完全讀到VMIN個數據再返回91                              */9293     tcflush(fd,TCIFLUSH);9495     if((tcsetattr(fd,TCSANOW,&newtio))!=0)96     {97         perror("com set error");98         return -1;99     }                                                                                                                                                                                                                                                                                                                                     
100     //printf("set done!\n");
101     return 0;
102 }
103
104 int open_port(char *com)
105 {
106     int fd;
107     //fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);
108     fd = open(com, O_RDWR|O_NOCTTY);
109     if (-1 == fd){
110         return(-1);
111     }
112
113       if(fcntl(fd, F_SETFL, 0)<0) /* 設置串口為阻塞狀態*/
114       {
115             printf("fcntl failed!\n");
116             return -1;
117       }
118
119       return fd;
120 }
121
122
123 /*
124  * ./serial_send_recv <dev>
125  */
126 int main(int argc, char **argv)
127 {
128     int fd;
129     int iRet;
130     char c;
131
132     /* 1. open */
133
134     /* 2. setup
135      * 115200,8N1
136      * RAW mode
137      * return data immediately
138      */
139
140     /* 3. write and read */
141
142     if (argc != 2)
143     {
144         printf("Usage: \n");
145         printf("%s </dev/ttySAC1 or other>\n", argv[0]);
146         return -1;
147     }
148
149     fd = open_port(argv[1]);
150     if (fd < 0)
151     {
152         printf("open %s err!\n", argv[1]);
153         return -1;
154     }
155
156     iRet = set_opt(fd, 115200, 8, 'N', 1);
157     if (iRet)
158     {
159         printf("set port err!\n");
160         return -1;
161     }
162
163     printf("Enter a char: ");
164     while (1)
165     {
166         scanf("%c", &c);
167         iRet = write(fd, &c, 1);
168         iRet = read(fd, &c, 1);
169         if (iRet == 1)
170             printf("get: %02x %c\n", c, c);
171         else
172             printf("can not get data\n");
173     }
174
175     return 0;
176 }

第152行: 打開設備節點

第156行:設置波特率和格式

164     while (1)
165     {
166         scanf("%c", &c);
167         iRet = write(fd, &c, 1);
168         iRet = read(fd, &c, 1);
169         if (iRet == 1)
170             printf("get: %02x %c\n", c, c);
171         else
172             printf("can not get data\n");
173     }

第164~173行: 進入循環后等待用戶輸入數據,得到數據后發給指定的串口,再讀取指定串口上的數據,讀到后在命令行中打印出來??

104 int open_port(char *com)

?第104~120行:打開設備節點

?第113行:

? ? ? ? ? ? ? ?1.fcntl (fd,FSETFL,FNDELAY);讀數據時不等待,沒有數據就返回0

???????????????2.fcntl (fd, F_SETFL,0);讀數據時,沒有數據阻塞

12 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

第12~102行:?設置波特率和格式

?

2.串口收發實驗

????????通過把串口的發送、接收引腳短接,實現自發自收:使用 write 函數 發出字符,使用 read 函數讀取字符。

1. Ubuntu 上
arm-buildroot-linux-gnueabihf-gcc -o serial_send_recv serial_send_recv.c
2. 板子上
/mnt/serial_send_recv /dev/ttymxc5

六、GPS 模塊

????????全球定位系統(Global Positioning System,GPS)是一種以空中衛星為 基礎的高精度無線電導航的定位系統,它在全球任何地方以及近地空間都能夠提 供準確的地理位置、車行速度及精確的時間信息。GPS 主要由三大組成部分:空 間部分、地面監控部分和用戶設備部分。GPS 系統具有高精度、全天候、用廣泛 等特點。

1.GPS 模塊硬件

????????GPS 模塊與外部控制器的通訊接口有多種方式,這里我們使用串口進行通訊, 波特率為 9600bps,1bit 停止位,無校驗位,無流控,默認每秒輸出一次標準格式數據。

2.GPS 模塊數據格式

????????GPS 使用多種標準數據格式,目前最通用的 GNSS 格式是 NMEA0183 格式。 NMEA0183 是最終定位格式,即將二進制定位格式轉為統一標準定位格式,與衛星類型無關。這是一套定義接收機輸出的標準信息,有幾種不同的格式,每種都是獨立相關的 ASCII 格式,逗點隔開數據流,數據流長度從 30-100 字符不等, 通常以每秒間隔持續輸出。

????????我們使用串口接收數據,收到的數據包含:$GPGGA(GPS 定位數據)、$GPGLL (地理定位信息)、$GPGSA(當前衛星信息)、$GPGSV(可見衛星狀態信息)、 $GPRMC(推薦最小定位信息)、$GPVTG(地面速度信息)。

???????? 這里我們只分析$GPGGA (Global Positioning System Fix Data)即可, 它包含了 GPS 定位經緯度、質量因子、HDOP、高程、參考站號等字段。其標準格式如下:

$XXGGA 語句各字段的含義和取值范圍各字段的含義和取值范圍見下表所示, XX 取值有: ? ????????GPGGA:單 GPS

????????BDGGA:單北斗

????????GLGGA:單 GLONASS

????????GNGGA:多星聯合定位

例子:$GPGGA,074529.82,2429.6717,N,11804.6973,E,1,8,1.098, 42.110,,,M,,*76。

  1 #include <stdio.h>2 #include <string.h>3 #include <sys/types.h>4 #include <errno.h>5 #include <sys/stat.h>6 #include <fcntl.h>7 #include <unistd.h>8 #include <termios.h>9 #include <stdlib.h>1011 /* set_opt(fd,115200,8,'N',1) */12 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)13 {14     struct termios newtio,oldtio;1516     if ( tcgetattr( fd,&oldtio) != 0) {17         perror("SetupSerial 1");18         return -1;19     }2021     bzero( &newtio, sizeof( newtio ) );22     newtio.c_cflag |= CLOCAL | CREAD;23     newtio.c_cflag &= ~CSIZE;2425     newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/26     newtio.c_oflag  &= ~OPOST;   /*Output*/2728     switch( nBits )29     {30     case 7:31         newtio.c_cflag |= CS7;32     break;33     case 8:34         newtio.c_cflag |= CS8;35     break;36     }3738     switch( nEvent )39     {40     case 'O':41         newtio.c_cflag |= PARENB;42         newtio.c_cflag |= PARODD;43         newtio.c_iflag |= (INPCK | ISTRIP);44     break;45     case 'E':46         newtio.c_iflag |= (INPCK | ISTRIP);47         newtio.c_cflag |= PARENB;48         newtio.c_cflag &= ~PARODD;49     break;50     case 'N':51         newtio.c_cflag &= ~PARENB;52     break;53     }5455     switch( nSpeed )56     {57     case 2400:58         cfsetispeed(&newtio, B2400);59         cfsetospeed(&newtio, B2400);60     break;61     case 4800:62         cfsetispeed(&newtio, B4800);63         cfsetospeed(&newtio, B4800);64     break;65     case 9600:66         cfsetispeed(&newtio, B9600);67         cfsetospeed(&newtio, B9600);68     break;69     case 115200:70         cfsetispeed(&newtio, B115200);71         cfsetospeed(&newtio, B115200);72     break;73     default:74         cfsetispeed(&newtio, B9600);75         cfsetospeed(&newtio, B9600);76     break;77     }7879     if( nStop == 1 )80         newtio.c_cflag &= ~CSTOPB;81     else if ( nStop == 2 )82         newtio.c_cflag |= CSTOPB;8384     newtio.c_cc[VMIN]  = 1;  /* 讀數據時的最小字節數: 沒讀到這些數據我就不返回! */85     newtio.c_cc[VTIME] = 0; /* 等待第1個數據的時間:86                              * 比如VMIN設為10表示至少讀到10個數據才返回,87                              * 但是沒有數據總不能一直等吧? 可以設置VTIME(單位是10秒)88                              * 假設VTIME=1,表示:89                              *    10秒內一個數據都沒有的話就返回90                              *    如果10秒內至少讀到了1個字節,那就繼續等待,完全讀到VMIN個數據再返回91                              */9293     tcflush(fd,TCIFLUSH);9495     if((tcsetattr(fd,TCSANOW,&newtio))!=0)96     {97         perror("com set error");98         return -1;99     }
100     //printf("set done!\n");
101     return 0;
102 }
103
104 int open_port(char *com)
105 {
106     int fd;
107     //fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);
108     fd = open(com, O_RDWR|O_NOCTTY);
109     if (-1 == fd){
110         return(-1);
111     }
112
113       if(fcntl(fd, F_SETFL, 0)<0) /* 設置串口為阻塞狀態*/
114       {
115             printf("fcntl failed!\n");
116             return -1;
117       }
118
119       return fd;
120 }
121
122
123 int read_gps_raw_data(int fd, char *buf)
124 {
125     int i = 0;
126     int iRet;
127     char c;
128     int start = 0;
129
130     while (1)
131     {
132         iRet = read(fd, &c, 1);
133         if (iRet == 1)
134         {
135             if (c == '$')
136                 start = 1;
137             if (start)
138             {
139                 buf[i++] = c;
140             }
141             if (c == '\n' || c == '\r')
142                 return 0;
143         }
144         else
145         {
146             return -1;
147         }
148     }
149 }
150
151 /* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"<CR><LF> */
152 int parse_gps_raw_data(char *buf, char *time, char *lat, char *ns, char *lng, char *ew)
153 {
154     char tmp[10];
155
156     if (buf[0] != '$')
157         return -1;
158     else if (strncmp(buf+3, "GGA", 3) != 0)
159         return -1;
160     else if (strstr(buf, ",,,,,"))
161     {
162         printf("Place the GPS to open area\n");
163         return -1;
164     }
165     else {
166         //printf("raw data: %s\n", buf);
167         sscanf(buf, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]", tmp, time, lat, ns, lng, ew);
168         return 0;
169     }
170 }
171
172
173 /*
174  * ./serial_send_recv <dev>
175  */
176 int main(int argc, char **argv)
177 {
178     int fd;
179     int iRet;
180     char c;
181     char buf[1000];
182     char time[100];
183     char Lat[100];
184     char ns[100];
185     char Lng[100];
186     char ew[100];
187
188     float fLat, fLng;
189
190     /* 1. open */
191
192     /* 2. setup
193      * 115200,8N1
194      * RAW mode
195      * return data immediately
196      */
197
198     /* 3. write and read */
199
200     if (argc != 2)
201     {
202         printf("Usage: \n");
203         printf("%s </dev/ttySAC1 or other>\n", argv[0]);
204         return -1;
205     }
206
207     fd = open_port(argv[1]);
208     if (fd < 0)
209     {
210         printf("open %s err!\n", argv[1]);
211         return -1;
212     }
213
214     iRet = set_opt(fd, 9600, 8, 'N', 1);
215     if (iRet)
216     {
217         printf("set port err!\n");
218         return -1;
219     }
220
221     while (1)
222     {
223         /* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"<CR><LF>*/
224         /* read line */
225         iRet = read_gps_raw_data(fd, buf);
226
227         /* parse line */
228         if (iRet == 0)
229         {
230             iRet = parse_gps_raw_data(buf, time, Lat, ns, Lng, ew);
231         }
232
233         /* printf */
234         if (iRet == 0)
235         {
236             printf("Time : %s\n", time);
237             printf("ns   : %s\n", ns);
238             printf("ew   : %s\n", ew);
239             printf("Lat  : %s\n", Lat);
240             printf("Lng  : %s\n", Lng);
241
242             /* 緯度格式: ddmm.mmmm */
243             sscanf(Lat+2, "%f", &fLat);
244             fLat = fLat / 60;
245             fLat += (Lat[0] - '0')*10 + (Lat[1] - '0');
246
247             /* 經度格式: dddmm.mmmm */
248             sscanf(Lng+3, "%f", &fLng);
249             fLng = fLng / 60;
250             fLng += (Lng[0] - '0')*100 + (Lng[1] - '0')*10 + (Lng[2] - '0');
251             printf("Lng,Lat: %.06f,%.06f\n", fLng, fLat);
252         }
253     }
254
255     return 0;
256 }
257
123 int read_gps_raw_data(int fd, char *buf)

?第123行對應到255行:GPS原始數據,讀取一行數據

152 int parse_gps_raw_data(char *buf, char *time, char *lat, char *ns, char *lng, char *ew)

?第151~170行:進行數據解析

?

167 sscanf(buf, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]", tmp, time, lat, ns, lng, ew);

?注:%[^] 剔除不包含符合

?第181~186 :定義這五個數據?

?第228行:iRet == 0表明讀到數據

?第234~252行:讀到數據并進行數據解析,如果解析成功則將這些信息打印出來

第181~186行 :定義這五個數據。

第242~251行:將經緯度轉變并且打印出來。

1. Ubuntu 上
arm-buildroot-linux-gnueabihf-gcc -o gps_read gps_read.c
2. 板子上
/mnt/gps_read /dev/ttymxc5

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161050.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

哈夫曼樹你需要了解一下

哈夫曼樹介紹哈夫曼數特點哈夫曼應用場景哈夫曼構建過程哈夫曼樹示例拓展 哈夫曼樹介紹 哈夫曼樹&#xff08;Huffman Tree&#xff09;是一種特殊的二叉樹&#xff0c;也被稱為最優二叉樹。在計算機科學中&#xff0c;它是由權值作為葉子節點構造出來的一種二叉樹。哈夫曼樹的…

05 取樣器(BeanShell和JSR223 Sampler)

一、取樣器作用 1、取樣器可以理解為Jmeter的橋梁&#xff0c;或者是Jmeter的加工廠&#xff1b; 2、Jmeter使用過程中&#xff0c;經常有些數據不能直接使用&#xff0c;需要加工后才能使用&#xff1b;這樣就用到了取樣器&#xff1b;但是這里存在問題&#xff0c;Jmeter中的…

Differences between package.json and pnpm-lock.yaml

1.pnpm-lock.yaml 是pnpm包管理工具生成的確保依賴包的版本在所有的環境里面都相同對依賴包的任何操作都會更新在該文件中&#xff0c;因此&#xff0c;需要確保提交到代碼倉庫中。包含了解析的依賴項和版本號。如下圖&#xff1a; 2.package.json 列出應用所需的依賴和元數…

批量修改文件名

原理&#xff1a; 利用 bat 的 REN 舊名字 新名字 命令 第一步&#xff1a; 【CtrlA】選中所有文件&#xff0c;按下【Shift】鍵右鍵任一文件夾彈出窗口選擇【復制為路徑】 第二步&#xff1a; 使用Excel技巧構造出 REN 舊名字 新名字 第三步&#xff1a; 用拼接好的命令…

【黑馬甄選離線數倉day01_項目介紹與環境準備】

1. 行業背景 1.1 電商發展歷史 電商1.0: 初創階段20世紀90年代&#xff0c;電商行業剛剛興起&#xff0c;主要以B2C模式為主&#xff0c;如亞馬遜、eBay等 ? 電商2.0: 發展階段21世紀初&#xff0c;電商行業進入了快速發展階段&#xff0c;出現了淘寶、京東等大型電商平臺&a…

(swjtu西南交大)數據庫實驗(數據庫需求分析):音樂軟件數據管理系統

實驗內容&#xff1a; 數據庫需求分析&#xff1a;各用戶組需求描述&#xff0c;繪出數據流圖&#xff08;詳細案例參見教材p333~p337&#xff0c;陶宏才&#xff0c;數據庫原理及設計&#xff0c;第三版&#xff09;&#xff1b; 一、選題背景 近年來&#xff0c;“聽歌”逐…

Ajax入門-Express框架介紹和基本使用

電腦實在忒垃圾了&#xff0c;出現問題耗費了至少一刻鐘time&#xff0c;然后才搞出來正常的效果&#xff1b; 效果鎮樓 另外重新安裝了VScode軟件&#xff0c;原來的老是報錯&#xff0c;bug。。&#xff1b; 2個必要的安裝命令&#xff1b; 然后建立必要的文件夾和文件&…

雷軍:我的程序人生路

今天有朋友發給我一篇我在20年前在BBS上寫的帖子。那還是1996年&#xff0c;我們通過電話線撥號連接到西點BBS上飆帖子玩的年代。那是一個互聯網混沌初開的年代&#xff0c;那是一個BBS和Email幾乎主宰了全部互聯網的年代&#xff0c;那是一個青春的理想和熱血沸騰的年代。 我…

新能源車將突破2000萬輛,漢威科技為電池安全保駕護航

近年來&#xff0c;我國新能源汽車銷量持續突破新高。據中汽協數據&#xff0c;1~10月&#xff0c;國內新能源汽車銷量達728萬輛&#xff0c;同比增長37.8%&#xff0c;市場占有率達到30.4%。隨著第四季度車市傳統旺季的到來&#xff0c;新能源消費需求將進一步釋放&#xff0c…

Python小灰灰

系列文章 序號文章目錄直達鏈接表白系列1浪漫520表白代碼https://want595.blog.csdn.net/article/details/1306668812滿屏表白代碼https://want595.blog.csdn.net/article/details/1297945183跳動的愛心https://want595.blog.csdn.net/article/details/1295031234漂浮愛心htt…

【軟件工程師從0到1】- 封裝 (知識匯總)

前言 介紹&#xff1a;大家好啊&#xff0c;我是hitzaki辰。 社區&#xff1a;&#xff08;完全免費、歡迎加入&#xff09;日常打卡、學習交流、資源共享的知識星球。 自媒體&#xff1a;我會在b站/抖音更新視頻講解 或 一些純技術外的分享&#xff0c;賬號同名&#xff1a;hi…

藍橋等考C++組別八級005

第一部分:選擇題 1、C++ L8 (15分) 以下關于break的說法正確的是( )。 A. 只有循環結構里面才可以使用break語句。 B. 程序運行到break語句的時候會暫停,直到用戶按下任意鍵才會繼續執行。 C. 嵌套循環的內層循環里面遇到break的時候,整個嵌套循環結構會立即停止,…

Jenkins擴展篇-流水線腳本語法

JenkinsFile可以通過兩種語法來聲明流水線結構&#xff0c;一種是聲明式語法&#xff0c;另一種是腳本式語法。 腳本式語法以Groovy語言為基礎&#xff0c;語法結構同Groovy相同。 由于Groovy學習不適合所有初學者&#xff0c;所以Jenkins團隊為編寫Jenkins流水線提供一種更簡…

kubernetes學習-概念5

服務&#xff08;Service&#xff09; Kubernetes 中 Service 是 將運行在一個或一組 Pod 上的網絡應用程序公開為網絡服務的方法。 Kubernetes 中 Service 的一個關鍵目標是讓你無需修改現有應用以使用某種不熟悉的服務發現機制。 你可以在 Pod 集合中運行代碼&#xff0c;無…

nginx使用詳解:轉發規則、負載均衡、server_name

文章目錄 一、nginx常用的轉發規則location 指令說明location轉發使用 二、upstream負載均衡使用三、server_name使用四、其他常用配置限制請求類型處理靜態資源目錄遍歷問題限制客戶端使用的ip或者域名 五、需要注意的地方location /api1 探討location ~ /api1 探討&#xff0…

DataFunSummit:2023年OLAP引擎架構峰會-核心PPT資料下載

一、峰會簡介 OLAP技術是當前大數據領域的熱門方向&#xff0c;該領域在各個行業都有廣泛的使用場景&#xff0c;對OLAP引擎的功能有豐富多樣的需求。同時&#xff0c;在性能、穩定性和成本方面&#xff0c;也有諸多挑戰。目前&#xff0c;OLAP技術沒有形成統一的事實標準&…

redis性能管理

redis的數據庫是存放在內存當中&#xff0c;所以對內存的監控至關重要 redis內存監控和解析 1.如何查看redis內存使用情況 [rootlocalhost utils]# redis-cli -h 20.0.0.170 -p 6379 20.0.0.170:6379> info memory used_memory:853336 //redis中數據占用的內存 use…

觸發設備離線

業務場景 業務開發過程中&#xff0c;我們經常會需要判斷遠程終端是否在線&#xff0c;當終端離線的時候我們需要發送消息告知相應的系統&#xff0c; 環形隊列 1.創建一個index從0到30的環形隊列&#xff08;本質是個數組&#xff09; 2.環上每一個slot是一個Set&#xf…

python 執行系統命令

subprocess 模塊和 os.system 或 os.popen 等函數相比&#xff0c;功能更為強大和靈活&#xff0c;是 Python 官方推薦的執行系統命令的方法。主要的優勢包括&#xff1a; 更強的錯誤處理&#xff1a;subprocess 模塊可以更精細地控制錯誤輸出和錯誤代碼&#xff0c;而 os.syst…

自定義springboot的生命周期函數在項目啟動完成后去取配置文件中的值

主要是實現smartLifecycle類 package com.ruoyi.workflow.util;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springfr…