Repository navigation
Expand file tree
/
Copy pathsearch.xml
More file actions
844 lines (816 loc) · 136 KB
/
Copy pathsearch.xml
File metadata and controls
844 lines (816 loc) · 136 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>INTRO</title>
<url>/2018/05/13/INTRO/</url>
<content><![CDATA[<p>业精于勤,荒于嬉;行成于思,毁于随</p>
]]></content>
<tags>
<tag>INTRO</tag>
</tags>
</entry>
<entry>
<title>无线充电</title>
<url>/2018/05/14/%E6%97%A0%E7%BA%BF%E5%85%85%E7%94%B5/</url>
<content><![CDATA[<p>不成熟的东西</p>
<span id="more"></span>
<p><img src="https://i.imgur.com/tHyaexi.png" alt="Imgur"><br>首先交流电经过电能发送端的整流电路和逆变电路变成高频的交流电,然后传递给线圈,将能量传送到电能的接收端,最后电能的接收端再经过整流或逆变得到直流电或交流电供给负载使用</p>
<p>#发射端<br><img src="https://i.imgur.com/qDB3Xck.png" alt="Imgur"><br>&emsp;&emsp;5V的直流电传递给给高频逆变电路,然后再传递给谐振网络,让系统频率变成 llOKHz至205KHz的高频交流电。高频率的交流电传递给后而的线圈,磁场会发生变化,手机系统能鼠的接收端线会感应到这种变化。反馈信号电路和控制器是对发射线圈电流的俭测.</p>
<!-- more -->
<p>&emsp;&emsp;当系统进行工作时,如果电流出现大的波动,表示系统正在进行不正常的充电或者系统遭到了破坏,那么反馈信号电路就会将信息传递给控制器,然后做出相应的调节,一方而保护了系统,另一方而也让系统能够更加精确.高效的工作。控制器接收反馈信号电路的信号,然后判断该系统足否能够正常工作.并对当前线圈的电流值进行相应计算。<br>频率的变化对系统非常重要,选择逆变电路的时候,要保证某一频率下,效率不会很低。从内部驱动的电路组成来看,大致可以分为全桥逆变电路。半桥逆变电路,单端式逆变电路。<br><img src="https://i.imgur.com/Pt9NRIz.png" alt="Imgur"><br>由上图可知,在全桥逆变的电路结构中4个开关管是一样的,通过控制这四 个管子的快速开通和关断来形成高频交流电,从而能够将电能传递给线圈的副边。<br>工作原理为:当Q1和Q4导通时,另外两个管子是关断的,电流经过Q1后流过 线圈,然后经过Q4流回电源负极;<br>同理,在下一时刻,Q2和Q3导通时,Q1和Q4是关断的,电流经过Q3后流过线圈,然后经Q2流回电源负极。其中二极管 作用为续流,这两个过程中流经线圈的电流方向相反,改变4个开关管的频率就可以改变交流线圈的电流频率.<br>本电路实现软开关变得控制比较容易。缺点是开关管的控制比较复杂。不过转换效率高,功率大。所以应用广泛。</p>
<p>#接收端<br><img src="https://i.imgur.com/op7EfSK.png" alt="Imgur"><br>AC- DC整流变换电路将手机接 端线圈中高频率的交流电转换成直流电 ,<br>此将转换成系统所需要的5 V直流电 ,然 后传递给负载 。反馈信号电路负<br>责 检 测 AC- DC变 换 电 路 的 输 出 电 值 ,并传送给控制器 ,然 后 让 控 制 器 能 够 及时的了解到当前传输功率的大小,这样可以及时的 将误差信息传递到发射端。在这里,控制器是很重要的组成部分,它能够监视用电设备的充电状态 ,比如充电 是否完成,充电是否异常等。 </p>
<p>前面分析得知,系统能量的输入端采用全桥逆变电路,然后经过耦合线圈将能量传递到输电到输出端。系统的主电路如下图所示。<br><img src="https://i.imgur.com/UjCLlBe.png" alt="Imgur"></p>
]]></content>
<categories>
<category>电力电子</category>
</categories>
<tags>
<tag>无线充电</tag>
</tags>
</entry>
<entry>
<title>linux入门操作</title>
<url>/2018/06/25/linux%E5%85%A5%E9%97%A8%E6%93%8D%E4%BD%9C/</url>
<content><![CDATA[<p>linux 命令记录</p>
<span id="more"></span>
<p>使用环境:ubuntu 16.04 LTS</p>
<ul>
<li>终端<br>打开终端的方式有两种<br>直接寻找程序打开<br>使用快捷键 <code>ctrl +alt +T</code></li>
</ul>
<p>&emsp;&emsp;进入终端后,如果是默认设置的话,则会进入该用户的当前的家用户目录中<br>&emsp;&emsp;在终端中输入ls 就可以看到家目录下所有的内容<br>&emsp;&emsp;当输入<code>ls -l</code><br>&emsp;&emsp;就会显示当前目录下所有的内容的详细列表<br>&emsp;&emsp;这里的<code>-l</code> 是附加命令,是针对ls 这个命令进行的更多功能设置</p>
<p>当使用 ls 指令后我们看到 家目录下有一个downloads文件夹 我们进入这个文件夹,输入<code>cd downloads/ </code></p>
<p>使用ls 指令会看到ls 至指令下 downloads 文件夹下有一个Ubuntu1.pdf </p>
<p>下面是几个基础知识,<br>首先linux的根目录是”/ “</p>
<!-- more -->
<p><code>cd /</code> 就可以进入到根目录<br>当前用户家目录则用~ 代替<br><code>cd ~</code> 就可以进入家目录文件夹</p>
<p>一般来说,以根目录”/“ 开始的路径 就被称为是绝对路径.<br>而当前用户的家目录的绝对路径则一般为<code>/home/用户名</code><br>使用<code>cd /home /用户名</code> 和使用<code>cd ~</code> 是一样的意思</p>
<p>使用tab 键可以自动补全需要的文件名 使用方法是输入文件夹名字的前几个字母,点击<code>TAB</code>键</p>
<p>双点代表上一级目录,单点代表当前目录<br><code>cd ..</code> 是返回上级目录<br><code>./ </code>是当前科执行程序</p>
<p>新建文件夹 mkdir<br><code>mkdir test</code><br><code>cd test/</code></p>
<p>删除文件夹 rmdir<br><code>rmdir 文件夹名 </code><br>这个指令要求这个文件夹必须是空的才能删除</p>
<p>删除文件(夹) rm<br><code>rm 文件名</code> 删除文件<br><code>rm -rf</code> 文件夹名删除目标文件夹及其下的所有文件</p>
<p>在根目录下 mkdir 一般用户是不能使用的必须是root 用户才可以<br>使用<code>sudo mkdir</code> 才能实现新建</p>
<p>复制 cp<br> 源文件路径 目标路径<br><code>cp -rf 源文件路径 目标文件夹路径</code></p>
<p>移动 mv<br><code>mv 文件名 移动路径</code><br>mv不需要添加-rf命令</p>
<p>这个指令可以用来修改文件名<br>mv 文件名</p>
]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>CURRENT AND VOLTAGE</title>
<url>/2018/10/15/Professional-English-1/</url>
<content><![CDATA[<p>一些专业术语的中英对照</p>
<span id="more"></span>
<p>current n.电流</p>
<p>voltage n.电压</p>
<p>variable n.变量</p>
<p>charge n.电荷;v.充电,带电,起电</p>
<p>coulomb n.库仑(电荷的单位)</p>
<p>circuit n.电路</p>
<p>underlying a.①基本的,根本的②潜在的,下伏的</p>
<p>electron n.电子</p>
<p>positive charge 正电荷</p>
<p>negative charge 负电荷</p>
<p>magnitude n.大小,尺寸,数量,数值</p>
<p>electromotive a.电动的,起电的</p>
<p>electromotive force电动势</p>
<p>ampere n.安,安培(电流的单位)</p>
<p>integrate v.积分,求积分</p>
<p>work n.功</p>
<p>potential difference n.电位差</p>
<p>rectangular a.矩形的,直角的,正交的</p>
<p>joule n.焦尔(能量、热量、功的单位)</p>
<p>volt n.伏特(电压、电位、电势的单位)</p>
<p>voltaic battery 伏达电池</p>
<p>convention n.习惯,惯例,常规</p>
<p>reference direction 参考方向</p>
<p>polarity n.极性</p>
<p>power n.①功率,效率②动力,电力,能力,电源③乘方,幂</p>
<p>watt n.瓦特(功率的单位)</p>
<p>time-varying a.时变的</p>
<p>instantaneous power 瞬时功率</p>
<p>passive a.①无源的②消极的,被动的;</p>
<p>algebraic n.无源 a.代数的</p>
<p>instant n.瞬间,瞬时,即刻,时,时刻</p>
<hr>
<p>Current</p>
<p>current situation 现状,目前形势;现况</p>
<p>current status 当前状态;目前状况</p>
<p>current state 现行状态;初速电流状态</p>
<p>electric current 电流</p>
<p>direct current 直流;[电]直流电</p>
<p>alternating current (AC) 交流电</p>
<p>current density 电流密度;扩散(弥漫)流密度</p>
<p>eddy current 涡流;[电学]涡电流</p>
<p>tidal current 潮流</p>
<p>constant current 恒定电流</p>
<p>current transformer n. 电流变换器</p>
<p>leakage current [电]泄漏电流</p>
<p>high current 电流过高;高强度电流</p>
<p>current control 电流控制;日常检查</p>
<p>welding current 焊接电流</p>
<hr>
<p>voltage</p>
<p>low voltage 低电压</p>
<p>output voltage 输出电压</p>
<p>voltage stability 电压稳定;电压稳定度</p>
<p>input voltage 输入电压;工作电压</p>
<p>dc voltage 直流电压;直羚压</p>
<p>rated voltage [化]额定电压</p>
<p>voltage control 电压控制</p>
<p>voltage regulator 稳压器;调压器</p>
<p>voltage source n. 电压电源</p>
<p>supply voltage 电源电压;供给电压</p>
<p>voltage drop 电压降落</p>
<p>ac voltage 交流电压;交羚压</p>
<p>voltage transformer 电压互感器;电压变量器</p>
<p>constant voltage 恒定电压;定压</p>
<p>voltage regulation 稳压;电压调整;电压变动率</p>
<p>working voltage 工作电压;工诅压;操作电压</p>
<p>breakdown voltage [电]击穿电压</p>
<p>medium voltage 中压</p>
<p>applied voltage 外加电压</p>
]]></content>
<categories>
<category>English</category>
</categories>
<tags>
<tag>Electrical Professional English</tag>
</tags>
</entry>
<entry>
<title>linux C编程 一站式学习</title>
<url>/2018/09/10/%E5%B5%8C%E5%85%A5%E5%BC%8FC/</url>
<content><![CDATA[<p>《linux C编程 一站式学习》</p>
<span id="more"></span>
<p>&emsp;&emsp;《linux C编程 一站式学习》<br>&emsp;&emsp;再学一次C语言。<br>&emsp;&emsp;从大学一年纪学习C语言。一直都是在windows平台下。</p>
]]></content>
<categories>
<category>Linux C</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>网络通讯协议(1)</title>
<url>/2018/10/25/TCP-IP-part1/</url>
<content><![CDATA[<p>网络通信协议基本介绍</p>
<span id="more"></span>
<p>&emsp;&emsp;互联网的实现分为好几层,每一层都有自己的功能,就好比盖房子,每一层都是依靠下一层的支持. 用户接触到的是最上面的一层.</p>
<p>&emsp;&emsp;用户接触到的是最上面的一层, 根本没有感觉到下面的层.而要理解互联网就必须要从下层开始, 自下而上的理解每一层的含义. 而如何分层,有不同的模型.</p>
<p>&emsp;&emsp;有的是七层模型, 有的分为五层. 我们一般倾向于五层协议, 这里给大家阐述的也都是五层协议.<br><br/><br><img src="https://i.imgur.com/AYYE2WB.png" alt="GitHub Logo"></p>
<p>&emsp;&emsp;这个图中我们看见一个主机A和一主机B相互发送数据.而他们的底层支持就包含了这五层协议.</p>
<p><img src="https://i.imgur.com/OW22j94.png" alt="GitHub Logo"></p>
<p>自下而上</p>
<ul>
<li>Physcial Layer, 物理层 </li>
<li>Data Link Layer (MAC), 数据链路层 </li>
<li>Network Layer (IP), 网路层 </li>
<li>Transport Layer (TCP UDP), 传输层</li>
<li>Application Layer, 应用层</li>
</ul>
<p>&emsp;&emsp;越底层离物理硬件越近,越高层和用户越近.每一层都是完成某一种功能.<br>为了实现这些功能,需要遵守共同的规则,我们叫做协议(protocol)<br ><br>&emsp;&emsp;在互联网中,每一层都定义了非常多的协议,而这些协议的总称就叫互联网协议,它是互联网的核心.</p>
<p><img src="https://i.imgur.com/tQWzvtg.png" alt="Imgur"></p>
<p>上图是对五层协议的概述:<br>&emsp;&emsp;应用层(Application Layer) : web服务器做交互<br>&emsp;&emsp;传输层(Transport Layer) : 两个远程主机建立连接<br>&emsp;&emsp;网路层(Network Layer) : 通过IP笛子传输数据包<br>&emsp;&emsp;数据链层(Data Link Layer) : 通过MAC地址交换帧数据<br>&emsp;&emsp;物理层(Physcial Layer) : 帧中的比特进行编码和解&emsp;&emsp;码,并包括在网络上驱动和接收信号的收发器。</p>
<p><img src="https://i.imgur.com/Vp3Cswb.jpg" alt="Imgur"></p>
<p>比方说 下载一个网页的话<br>&emsp;&emsp;应用层: 输一个IP地址192.168.1.102 默认输入80端口,下载他们<br>&emsp;&emsp;传输层: 它需要告诉服务器:客户端端口是31244,要连接的服务端端口是80<br>&emsp;&emsp;网路层: 两台主机的IP和端口在互相通讯<br>&emsp;&emsp;网络链路层: 添加包含MAC地址信息的标头以创建帧。然后将帧发送到物理层以发送比特</p>
<p>#物理层</p>
<p>&emsp;&emsp;电脑组网需要用电缆,光缆,无线电波把电脑连接起来.他们就是把电脑连接起来的物理手段.主要规定了网络中的电气特性,作用是负责传输0和1这样的电信号.</p>
<p>#数据链路<br>&emsp;&emsp;但是单纯的传输0和1,没有什么意义.所以,出现了数据链路层<br>&emsp;&emsp;多少个电信号算一组,一个信号位又有什么意义,数据链路层就解决了这个问题<br>&emsp;&emsp;他在物理层的上方确定了0和1的分组方式.也就是常说的以太网协议.<br>&emsp;&emsp;以太网协议规定一组电信号构成了一个数据包,我们把他叫做帧<br>&emsp;&emsp;每一个帧又分成两个部分,head 和 data </p>
<table>
<thead>
<tr>
<th>head</th>
<th>……..data………..</th>
</tr>
</thead>
<tbody><tr>
<td>&emsp;&emsp;head:表头, 包含数据包的说明项 比方说发送者是谁,接受者是谁,数据类型等等</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;head在以太网协议中有一个长度的定义,他的固定长度是18个字节</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;data的长度最短是46字节,最长是1500字节</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;所以帧的最短长度是64字节,最长是1518字节</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;但是某些情况下,数据非常长,就需要被分割成多个帧进行发送</td>
<td></td>
</tr>
</tbody></table>
<p>MAC地址:以太网的数据包的head包含了发送者和接受者的信息,MAC地址就是每一块网卡都有唯一的地址.长度是48个二进制位,通常是12个十六进制数去表示.有了这个MAC地址,就可以定位网卡和数据包的路径.为数据传输做了夯实的基础.</p>
<p>#广播<br>一个网卡为什么会知道另一块网卡的地址.这个时候在以太网中,有一个ARP协议,他可以解决这个问题.这个在后面会有所涉及.<br>我们需要知道,以太网数据包必须知道接收方的MAC地址才能够发送,<br>其次就算有了MAC地址,系统怎么样才能把数据包准确的发送到接受方.<br>在以太网中采用了一种非常原始的方式,他不是准确的把数据包发送到接受方<br>而是向本网络内的所有计算机房发送,让每一台计算机自己去判断自己是不是接受方.</p>
<p>假设1,2,3,4,5计算机在同一个网络中</p>
<ul>
<li>广播 1号计算机向处于同一网络中的所有计算机发送数据包</li>
<li>2,3,4,5号计算机都收到这个包,读取数据包head部分,找到接收方的MAC地址,与自身MAC地址比较</li>
<li>MAC地址相同的话就接受这个包,然后做进一步处理,否则丢弃这个包.</li>
</ul>
]]></content>
<categories>
<category>网络通信协议</category>
</categories>
<tags>
<tag>网络通信协议</tag>
</tags>
</entry>
<entry>
<title>在Linux终端中写文件</title>
<url>/2018/10/26/linux%E5%85%A5%E9%97%A8%E6%93%8D%E4%BD%9C2/</url>
<content><![CDATA[<p>linux终端vim写文件</p>
<span id="more"></span>
<p>在终端中写文件</p>
<p>sublime text</p>
<p>vim 不要乱按键盘</p>
<p>新建 vim helloVIM.txt</p>
<p>在普通模式下 ,<br>输入冒号后,然后便可以输入字母并回车,来执行保存,退出<br>w:保存 q是退出</p>
<p>在普通模式下 按下 i 进入插入模式<br>esc按键是退出插入模式</p>
<p>上下左右键可以移动光标 没有上下左右键 hjkl</p>
<p>连续摁下两次D 即dd 删除行</p>
<p>shell文件<br>shell想要变成可执行文件的话 第一行一定是#!/bin/sh<br>先去一个名字 echo_ex.sh 后缀名一定是sh 代表是shell文件<br>代码:<br><code>#!/bin/sh</code><br><code>echo "i am so smart"</code><br><code>echo "you are so smart too"</code><br><code>echo "i love you "</code><br><code>echo "i like your idea"</code><br><code>echo "i like studying and researching"</code></p>
<p>然后退出并且保存</p>
<p>但是还是不能执行 信息需要把他变成可执行模式</p>
<p>sudo chmod 777 echo_ex.sh</p>
<p>然后再输入<code>./echo_ex.sh</code></p>
<p>编写shell 文件说法</p>
]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>ros系统catkin文件</title>
<url>/2018/11/07/ros%E7%B3%BB%E7%BB%9Fcatkin%E6%96%87%E4%BB%B6/</url>
<content><![CDATA[<p>一些不成熟的介绍</p>
<span id="more"></span>
<p>catkin 是用来编译ros程序的<br>catkin 工作空间就是一个文件夹<br>组织和管理功能包的文件<br>用catkin工具编译</p>
<p>各种ros代码放在catkin workpace 文件夹中<br>如何:创建一个catkin的文件空间<br>指令:catkin_make 帮助我们初始化工作空间</p>
<p>$mkdir ~p ~/catkin_ws/src<br>$cd ~/catkin_ws/<br>$catkin_make<br>其实catkin_make的主要功能是编译</p>
<p>编译<br>$cd -/catkin_ws #回到工作空间<br>$catkin_make<br>$source -/catkin_ws/devel/setup.bash<br>#编译完成之后要source刷新环境</p>
<p>注意:<br>catkin_make 之前一定要回到catkin workspace<br>catkin_make 之后一定要devel/setup.bash这句话是把刚刚编译的worksapce 刷新到环境里面</p>
<p>catkin workspace 里的<br>src文件 package源代码<br> build文件夹 cmake& catkin 缓存文件和中间文件<br>devel文件夹: 生成的目标文件 包括 1.头文件 2.动态链接库 3.静态链接库 4.可执行文件<br>bulid 和devel 初学者不用掌握</p>
<p>注意::ros build 是旧的版本 看到资料直接忽略</p>
<p>src里面到底有什么<br>src 里面有许多package<br>package 是catkin编译的基本单元<br>catkin的编译对象就是一个又一个package</p>
]]></content>
<categories>
<category>ROS</category>
</categories>
<tags>
<tag>ROS</tag>
</tags>
</entry>
<entry>
<title>网络通信(2)</title>
<url>/2018/11/07/%E7%BD%91%E7%BB%9C%E9%80%9A%E4%BF%A12/</url>
<content><![CDATA[<p>网络层和传输层</p>
<span id="more"></span>
<p>&emsp;&emsp;之前说的是以太网协议,这里我们看网络层和传输层.<br>&emsp;&emsp;我们知道以太网是依靠MAC地址来发送数据的,理论上单单依靠MAC地址,上海的网卡就可以找到在北京的网卡,这在理论上是可以实现的.</p>
<p>&emsp;&emsp;但是它有一个严重的缺点,以太网采用广播的方式去发送一个数据包,如果每个程序员人手一个包的话,这样不仅效率低,而且发送者和接受者局限在子网当中.</p>
<p>&emsp;&emsp;也就是说,如果两个主机不在同一子网当中,广播是没有办法传输的.这种设计是比较合理的.否则互联网上每一台计算机都要收到这个包,这将是一场灾难.</p>
<p>&emsp;&emsp;互联网是由无数个子网组成的巨型网络.如果北京和上海在同一个子网络中,这几乎是不可能的.所以我们需要寻找以这个方法来区分哪些MAC地址是同一子网络的,哪些不是.<br>&emsp;&emsp;如果是同一子网的话,就使用广播的方式去发送数据,否则就选择路由的方式发送.<br>&emsp;&emsp;而路由的意思是如何向不同的子网分发数据包,这个是一个非常庞大的主题.我们这里不展开说.<br>&emsp;&emsp;非常遗憾的是MAC地址本身是不能做到这一点的,MAC地址只和厂商有关,和网络环境无关,这就导致了网络层的诞生.<br><br/><br>#网络层<br>&emsp;&emsp;网络层的作用是引进了一套新的地址,让我们能够区分出不同的计算机是否处于同一个子网内.这一套地址就叫网络地址,简称网址.<br>&emsp;&emsp;网络层出现后,每一台计算机都有两个地址,一个是MAC地址,一个是网络地址.这两个地址是没有关系的.MAC地址是和网卡绑定的.而网络地址是由管理员分配的.他们只是随机的组合在一起.</p>
<p>&emsp;&emsp;网络地址帮助我们确定计算机所在的子网络.<br>&emsp;&emsp;MAC地址将我们的数据包发送到子网络中的目标网卡.<br>&emsp;&emsp;所以从逻辑上,我们判断是先处理网络地址,再处理MAC地址.</p>
<p> 由此引出IP协议,IP协议是指规定网络地址的额协议,他所定义的地址就是IP地址.目前广泛采用的是ipv4协议.这里不涉及ipv6的内容.<br>Ipv4是由32个二进制数组成的.我们习惯的把它分成4段的10进制数字.</p>
<blockquote>
<p>192.168.1.30<br>11000000- 10101000- 00000001- 00011110</p>
</blockquote>
<p>&emsp;&emsp;他的范围是0.0.0.0-255.255.255.255<br>&emsp;&emsp;在互联网上,每一台计算机都被分配一个IP地址,这个地址成两部分.<br>&emsp;&emsp;前三段(如 192.168.1)为一部分,代表网络<br>&emsp;&emsp;最后一段(如 30),代表主机,用这个30来确定这个主机<br>&emsp;&emsp;同一子网的计算机,他们的网络部分应该是一样的.</p>
<blockquote>
<p>192.168.1.1 和192.168.1.2<br>假设上面的IP地址的网络部分是前面的24位,也就是前三段,因为他们的网络部分相同,所以他们处于同一子网.</p>
</blockquote>
<p>&emsp;&emsp;但是有一个问题,单单从IP地址的话,我们是没有办法判断网络部分的.刚刚我们能判断,有一个前提.我们假定前三段是网络部分,但实际上,IP地址的网络部分到底是前面的24位还是16位,从IP地址本身是看不出来的.<br>那么如何从IP地址上判断两个计算机是不是处于同一子网.</p>
<p>&emsp;&emsp;这就引出了另外一个参数,子网掩码.所谓的子网掩码就是表示子网络特征的一个参数.它在形式上也是类似一个IP地址,同时也是一个32位的2进制数字,它的网络部分全是1,主机部分全是0.</p>
<blockquote>
<p>如 192.168.1.3<br>假设前面24位是网络部分,后面8位是主机部分.那么它的子网掩码就是255.255.255.0.<br>这个数字换算成2进制,前面24位都是1,后八位都是0.<br>当我们真的子网掩码之后,我们就可以判断任意的两个IP地址是否处于同一子网,方法是将这两个IP地址与子网掩码分别进行AND运算.然后比较他们的的结果是否一致.相同则表明在同一子网.反之,这不在.</p>
</blockquote>
<p>#总结<br>IP协议的主要作用是</p>
<ul>
<li>为每一台计算机分配一个IP地址</li>
<li>确定哪些地址再同一子网内</li>
</ul>
<p>IP数据包</p>
<table>
<thead>
<tr>
<th>head</th>
<th>———data———</th>
</tr>
</thead>
<tbody><tr>
<td>&emsp;&emsp;根据IP协议发送的数据包就叫做IP数据包,那其中必然包含了IP的地址信息</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;我们之前说过,以太网的数据包只包含一个MAC地址,并且没有IP地址的栏位,我们不需要修改数据包的定义,增加数据包的栏位.在说到以太网额那节课,我们说到:发送一个帧,帧里面有一个表头和数据.</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;实际上我们不必要去添加一个栏位去存储IP数据包.我们可以把IP的数据包直接放进以太网数据包中的data部分.所以不用修改以太网的规格.这就是互联网分层结构的好处.上层的变动完全不会下层的结构.</td>
<td></td>
</tr>
<tr>
<td>&emsp;&emsp;在程序开发的时候,也是一个道理.假设设计一个接口,用一个对象把参数封装起来.只要给对象添加一个内部属性,避免了一次次的添加参数.</td>
<td></td>
</tr>
</tbody></table>
<p>&emsp;&emsp;具体到IP数据包,它也是有head和data两个部分,* head主要包含版本号,长度,IP地址这样的信息.</p>
<ul>
<li>data是IP数据包的具体内容.<br>IP数据包被放入以太网数据包内后,数据包就会变成</li>
</ul>
<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>data</th>
</tr>
</thead>
</table>
<p>&emsp;&emsp;在这个结构中,IP head 在20-60字节之间 整个IP数据包长度为65535字节,所以理论上一个IP数据包的数据部分最长是65515.<br>我们前面提到,以太网的数据部分最长只有1500字节,所以ip数据包已经超过了1500字节,那么它就要分割成多个以太网数据包分开发送.</p>
<p>&emsp;&emsp;有一点值得一提,因为IP数据包是放在以太网数据包里发送的,所以我们必须同时知道两个地址.一个是对方的MAC地址,另一个是对方的IP地址.通常情况下,对方的IP地址是已知的,但是却不知道对方的MAC地址.</p>
<p>&emsp;&emsp;这个时候就涉及到ARP协议.我们假设存在两台计算机,这两台计算机就会分成两种情况.</p>
<ul>
<li><p>两台计算机不在同一子网 所以他没有办法知道对方的MAC地址,只能把数据包传输到两个子网连接的网关进行处理.</p>
</li>
<li><p>两台计算机在同一子网,这个时候就可以使用ARP协议,得到对方的IP地址.</p>
</li>
</ul>
<p>&emsp;&emsp;ARP协议也是发送一个数据包,这个包也是包含在以太网的数据包中,他包含了目标主机的IP地址,MAC地址.<br>&emsp;&emsp;他知道对方的IP地址,但是不知道地方的MAC地址,所以他零时用了6组16进制的数字去表示这是一个广播的地址,他所在子网的每一个主机都会收到这个数据包.<br>&emsp;&emsp;当这些主机收到这些数据包之后,他们把IP地址提取出来和自己的IP地址进行比较.如果都是相同的就做一个回复.告诉对方我就是你要找的目标主机,并且把自己的MAC地址上报上去.如果不相同则丢弃这个包.</p>
<p>&emsp;&emsp;总之,有了ARP协议之后,我们就有了同一子网内的主机的MAC地址,然后把数据包发送给任意一台主机.</p>
<p>&emsp;&emsp;我们有了MAC地址和IP地址,我们可以在两台主机上建立通信.现在的问题是同一台主机上有许多的程序都需要网络,比方说一边看网页,一边打开聊天软件.当一个数据包从互联网上发过来的时候,你怎么知道他是表示网页还是聊天内容.</p>
<p>&emsp;&emsp;也就是说,我们还需要一个参数,来表示数据包到底被哪一个进程使用.这个参数就叫端口(Port),他其实每一个使用网卡的进程的编号,每一个数据包都会发送到计算机的特定端口上.所以不同的进程就会获取到自己所需要的数据.</p>
<p>&emsp;&emsp;这个端口号是0-65535之间的整数.真好是16个2进制位.0-1023的端口被系统占用.所以我们在本地启动80或者443的时候会提示我们权限不够.用户一般只能选择在1023以上的端口.</p>
<p>&emsp;&emsp;不管是浏览网页还是在线聊天,程序都会随机选择一个端口与服务器的端口做一个联系.</p>
<p>#传输层<br>&emsp;&emsp;传输层的功能就是建立端口到端口之间的通讯.相比之下,网络层是建立主机到主机之间的通讯.只要确定了主机和端口,我们就可以实现程序和程序之间的交流.所以unix系统把主机加端口叫做套接字(Socket).有了他之后就可以进行网络编程了.</p>
<p>说到传输层不得不说,两个重要的协议<br>&emsp;&emsp;UDP和TCP<br>而他的格式几乎就是数据前面加上端口号<br>UDP的数据包也是由head和data组成.</p>
<table>
<thead>
<tr>
<th>head</th>
<th><em><strong><strong>data</strong></strong></em>__</th>
</tr>
</thead>
<tbody><tr>
<td>head部分定义 send port 和receive port</td>
<td></td>
</tr>
<tr>
<td>数据部分就是要发送的数据</td>
<td></td>
</tr>
</tbody></table>
<p>然后把UDP数据包放到IP数据包的data部分<br>我们前面又说到IP数据包又是放在Ethernet协议的data部分<br>所以现在来看的话 Ethernet数据包变成现在这样</p>
<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>UDP head</th>
<th>__<em><strong><strong>UDP data</strong></strong></em></th>
</tr>
</thead>
<tbody><tr>
<td>&emsp;&emsp;UDP的head部分只有8个字节,总长度不会超过65535字节,刚好可以放进一个IP数据包.</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>&emsp;&emsp;这种协议的优点是简单,容易实现.但是缺点是可靠性差.数据包发送之后,不知道对方是不是已经收到了.为了解决这个问题,TCP协议应运而生.</p>
<p>&emsp;&emsp;TCP协议相对比较复杂,可以粗略的认为是有确认机制的UDP协议.每发送一次数据包都要进行确认.如果有一个数据包有遗失的话就收不到确认.那么发送的一方就知道,需要重新发送这个数据包.</p>
<p>&emsp;&emsp;关于TCP的三次握手,相对比较复杂.以后研究之后分享给大家<br><br/><br>&emsp;&emsp;TCP的优点是内容不容易丢失,缺点是过程复杂,实现困难会消耗比较多的资源.<br>&emsp;&emsp;TCP数据包和UDP数据包一样都是内嵌在IP数据包中的.TCPd的数据包没有长度限制,理论上可以无线长的.但是为了保证网络的效率,TCP的数据包长度不会超过IP数据包的长度.这样会确保当个TCP的数据包不会再分割.</p>
<p>TCP</p>
<ul>
<li>面向连接</li>
<li>提供可靠资源</li>
<li>点对点 </li>
<li>资源消耗高<br>UDP</li>
<li>无连接 (在发送数据前不需要建立连接)</li>
<li>不保证可靠</li>
<li>实时性很强</li>
<li>一对一 ,多对一,多对多</li>
<li>资源消耗少</li>
</ul>
]]></content>
<categories>
<category>网络通信协议</category>
</categories>
<tags>
<tag>网络通信协议</tag>
</tags>
</entry>
<entry>
<title>网络通信协议(3)</title>
<url>/2018/11/07/%E7%BD%91%E7%BB%9C%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE3/</url>
<content><![CDATA[<p>应用层</p>
<span id="more"></span>
<p>应用层<br>&emsp;&emsp;由于互联网是开放的架构, 数据来源是五花八门.所以事先必须规定一些格式,否则根本没有办法解读.<br>&emsp;&emsp;现在讲的应用层就是规定应用程序的数据格式.<br>&emsp;&emsp;举个例子, TCP协议可以为各式各样的程序传递数据, 比如EMAIL,www,FTP等等, 那么必须有不同的协议规定电子邮件, 网页, FTP的数据格式.这些应用程序的协议就构成了一个应用层, 这就是我们说的五层协议里面最高的一层, 是面对用户的.</p>
<p>他的数据就放在TCP协议的data部分,所以以太网数据包就会变成以下的样子.</p>
<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>TCP head</th>
<th>–Application Layer data–</th>
</tr>
</thead>
<tbody><tr>
<td><br/></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><br/></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><img src="https://i.imgur.com/46b9CAd.png" alt="Imgur"></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>&emsp;&emsp; 在这幅图中, 有4台主机.1和2处于一个子网,3和4处于同一子网.<br>&emsp; &emsp; 如果1给4发送数据包.然后4告诉1, 收到了数据包.这样就可以实现两台计算机之间的通讯.<br>&emsp; &emsp; 而发送这个数据包就必须需要两个地址. MAC地址和IP地址, 有了这两个地址之后, 数据包才能够准确的送到接受者的手中.<br>&emsp; &emsp; 但是MAC地址是有局限的, 如果两台主机不在同一子网, 就没有办法知道彼此的MAC地址.<br><br/></p>
<p>&emsp;&emsp; 所以出现了网关(gateway), 它实现转发的功能. 主机1给主机4发送数据包.他先判断主机4是否处于同一子网.如果不是, 主机1把数据包发给他的网关(A).<br>&emsp; &emsp; 这网关通过路由协议, 发现了主机4处于另一个网关内(B). A网关把数据发送给了B网关, B网关又把数据转发给了主机4.</p>
<p>&emsp; &emsp; 主机1想要把数据发送给A网关, 需要知道A网关的MAC地址.<br>&emsp; &emsp; 所以数据包的目标地址实际上分为两种情况.</p>
<table>
<thead>
<tr>
<th>场景</th>
<th>数据包地址</th>
</tr>
</thead>
<tbody><tr>
<td>目标主机同一子网</td>
<td>对方的MAC地址,对方的IP地址</td>
</tr>
<tr>
<td>目标主机非同一子网</td>
<td>网关的MAC地址,对方的IP地址</td>
</tr>
<tr>
<td><br/></td>
<td></td>
</tr>
</tbody></table>
<p>我们在windows中连接网络,可能会看到静态IP和动态IP的选项<br><img src="https://i.imgur.com/sMXDp9F.png" alt="Imgur"></p>
<p>我们给电脑插上网线开机之后,不能立刻上网.我们必须要给电脑</p>
<ul>
<li>设置本机IP</li>
<li>设置子网掩码</li>
<li>设置网关的IP地址</li>
<li>设置DNS的IP地址</li>
</ul>
<p>静态IP<br>&emsp; 首先它设置比较专业<br>&emsp; 其次设置静态IP后这个IP不能被其他计算机使用处于这两点, 大部分用户都是使用动态IP地址上网.</p>
<p>动态IP<br>&emsp; 所谓的动态IP就是指计算机开机以后会自动分配一个ip地址, 这个IP地址不会被别人设定.</p>
<p>动态IP使用的协议是DHCP协议</p>
<p>&emsp;&emsp; 这个协议规定了,在每一个子网中, 有一台计算机作为DHCP服务器.它专门去负责这个网络内的所有IP地址的自动分配.<br>&emsp; &emsp; 所有新的计算机加入这个网络之后,必须向DHCP服务器发送一个DHCP请求数据包.以此来申请IP地址和相关的网络参数.</p>
<p>&emsp; &emsp; 之前提到,两个主机在同一子网时,必须知道对方的MAC地址IP地址,才能发送数据包.</p>
<p>&emsp; &emsp;<br>但是问题来了<br>新加入的主机不知道这两个地址.<br><br/></p>
<p>DHCP协议做了一些比较巧妙的设定,首先它是应用层的协议,建立在UDP协议之上.<br>所以数据包是这样的</p>
<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>UDP head</th>
<th>DHCP data</th>
</tr>
</thead>
<tbody><tr>
<td>&emsp; &emsp; 最前面的Ethernet head设置发出方,比如本机的MAC地和接受方DHCP服务器的MAC地址.</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>&emsp; &emsp; 发射方的MAC地址就是本机网卡的MAC地址,DHCP服务器的MAC地址是不知道的.</p>
<p>&emsp; &emsp; 这个时候就会填入广播的地址,有一个默认的6组16进制数组成. FF:FF:FF:FF:FF:FF</p>
<p>&emsp; &emsp; 后面的IP head 设置了发出方的IP地址和接受方的IP地址.对于两个主机而言,他们本机都不知道.于是发出方的IP设为0.0.0.0,接收方的IP设为255.255.255.255.</p>
<p>&emsp; &emsp; 最后的UDP head设置发出方的端口和接受方的端口.这部分是由DHCP协议规定好的,发出方是68端口,接受方式67端口.</p>
<p>&emsp; &emsp; 数据包构造完成之后就可以发送了.以太网是以广播发送的,在同一子网内的每一台主机都会收到这个包.因为接收方的地址是FF:FF:FF:FF:FF:FF所以看不出来是发给谁的.收到这个包的主机会分析这个包的IP地址,确定是不是发给自己的.之前讲ARP协议的时候,已经有接触.</p>
<p>&emsp; &emsp; 当看到发出方的IP地址是0.0.0.0,接收方IP地址是255.255.255.255.于是DHCP服务器就知道这个包是发给我的.其他主机就会丢弃这个包.</p>
<p>&emsp; &emsp; 接下来DHCP服务器会读出这个包的数据内容,然后分配好一个IP地址,发送回去一个DHCP响应数据包.</p>
<p>&emsp; &emsp; DHCP响应数据包.它的格式和DHCP数据包类似.分配给请求方的IP地址和其他网络参数都会包含在data这部分.新加入的主机就知道了自己的IP地址,子网掩码,网关地址. 有了这个之后就可以上网冲浪了.</p>
<p>下面举一个实例<br>#当访问一个网页的时候,互联网协议是怎么运作的?<br>在浏览器地址栏输入google.com<br>意味着浏览器要向google服务器发送一个请求的数据包.当从本地请求一个网络地址的时候.</p>
<ul>
<li>第一步要走的是DNS的协议<br>我们知道发送数据包必须要知道对方的IP地址,但是我们现在只知道<a href="http://www.google.com.不知道他的ip地址/">www.google.com.不知道他的IP地址</a>.</li>
</ul>
<p>&emsp; &emsp;DNS协议就能够实现这样的功能,他可以将网址转换成IP地址<br>&emsp; &emsp;假设DNS服务器是8.8.8.8,于是向这个地址发送一个DNS数据包,使用53的端口.而DNS数据包的格式是这样的.</p>
<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>UDP head</th>
<th>DNS data</th>
</tr>
</thead>
<tbody><tr>
<td>&emsp; &emsp;我们发送这个数据包之后,DNS数据包会做出一个响应,他会告诉主机Google的IP地址.</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><br/></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<ul>
<li>知道IP地址之后,就需要判断是否和本地处于同一个子网,就需要用到子网掩码.主机对本地的IP地址和从DNS服务器获取的IP地址进行二进制AND运算.由此判断是否在同一网络.</li>
</ul>
<p>&emsp; &emsp;因为不处于同一个子网,所以要向Google发送数据包就必须要经过网关(gateway).也就是路由器192.168.1.1. 进行转发.<br>接收方的MAC地址是网关的MAC地址.</p>
<ul>
<li>而浏览网页使用的是http协议,它的数据包结构是<table>
<thead>
<tr>
<th>Ethernet head</th>
<th>IP head</th>
<th>TCP head</th>
<th>http data</th>
</tr>
</thead>
<tbody><tr>
<td>假设http请求数据包的长度是4960字节,它会被嵌在TCP的数据包当中.</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
</li>
</ul>
<p>&emsp; &emsp;TCP协议<br>&emsp; &emsp;TCP的数据包需要设置一个端口,接收方(也就是google),他们的默认的http端口是80.<br>&emsp; &emsp;而发送方,也就是本机.它的端口是随机生成的1024-65535之间的整数.假设是12345.</p>
<p>&emsp; &emsp;TCP协议的标头(head)是20字节,加上嵌入http的数据包,总长度是4980字节.</p>
<ul>
<li>再往下走是IP协议,这是已知的,发送方是我本机,接受方IP地址是DNS响应包的里的地址.</li>
</ul>
<p>&emsp; &emsp;IP数据包的标头(head)是20字节,加上嵌入的TCP数据包,总长度是5000字节.</p>
<p>&emsp; &emsp;最后IP数据包嵌入以太网数据包,以太网数据包需要设置双方的MAC地址,发送方是本机的网卡MAC地址,接受方是网关的MAC地址.他通过ARP协议可以得到.</p>
<p>&emsp; &emsp;以太网的数据部分最大长度是1500字节,现在IP数据包的长度是5000字节,所以这个IP数据包要被分割成4个包.<br>因为每一个包都有自己的IP标头(head).他们是20个字节.</p>
<table>
<thead>
<tr>
<th>以太网包头</th>
<th>ip包头</th>
<th>tcp 数据</th>
</tr>
</thead>
<tbody><tr>
<td>Ethernet head</td>
<td>IP head</td>
<td>TCP data_1(1500字节)</td>
</tr>
<tr>
<td>Ethernet head</td>
<td>IP head</td>
<td>TCP data_2(1500字节)</td>
</tr>
<tr>
<td>Ethernet head</td>
<td>IP head</td>
<td>TCP data_3(1500字节)</td>
</tr>
<tr>
<td>Ethernet head</td>
<td>IP head</td>
<td>TCP data_4(560字节)</td>
</tr>
</tbody></table>
<p>&emsp; &emsp;这就是http的请求德过程,请求结束之后.服务端会给本机响应.传回HTML网页.浏览器将他渲染出来.</p>
<p>&emsp; &emsp;这个过程进过多个网关的转发.Google的服务器收到了四个数据包之后,根据IP标题的序号.把四个数据包拼起来,取出一个完整的TCP数据包.<br>&emsp; &emsp;然后去读取Http请求,接着做一个http响应.最后再用TCP协议发回来.<br>&emsp; &emsp;本机收到这个响应之后,我们就能看到这个网页,也就完成一次网络通讯.</p>
]]></content>
<categories>
<category>网络通信协议</category>
</categories>
<tags>
<tag>网络通信协议</tag>
</tags>
</entry>
<entry>
<title>centos系统文件</title>
<url>/2018/11/21/%E7%B3%BB%E7%BB%9F%E6%96%87%E4%BB%B6/</url>
<content><![CDATA[<p>简单记录centos 系统根目录下的各种文件夹的作用</p>
<span id="more"></span>
<p>bin 文件夹 储存的是二进制目录 用户集工具<br>boot文件夹 启动目录<br>dev 文件夹 设备文件夹 创建设备节点<br>etc文件夹 是系统的配置的文件目录 壁纸 logo<br>home文件夹 用户文件夹<br>lib文件夹 库目录 是系统和应用层序的库文件<br>media文件夹 是媒体目录 存放可移动媒体设备的挂载点 光盘<br>mnt 文件夹 挂载目录 是可移动设备 u盘<br>opt 文件夹 可选目录 第三方的软件包 或者是下载的内容</p>
<p>proc文件夹 进程文件夹<br>root文件夹 根目录<br>run文件夹 运行目录 比如说是本地服务的运行文件<br>sbin文件夹 存放的是二进制文件<br>srv文件夹 服务目录 存放本地服务的相关文件<br>sys 文件夹 系统目录 存放硬件信息<br>tmp文件夹 临时文件夹<br>usr 文件夹 用户的二进制文件夹 用户的文件和数据都是存放在这里<br>var 文件夹 是可变化目录 一般用来存放日志文件</p>
]]></content>
</entry>
<entry>
<title>虚拟内存技术</title>
<url>/2019/02/26/%E8%99%9A%E6%8B%9F%E5%86%85%E5%AD%98%E6%8A%80%E6%9C%AF/</url>
<content><![CDATA[<p>虚拟内存技术</p>
<span id="more"></span>
<h3 id="虚拟内存技术"><a href="#虚拟内存技术" class="headerlink" title="虚拟内存技术"></a>虚拟内存技术</h3><p>操作系统的虚拟内存管理机制起来什么作用?</p>
<h5 id="一、-amp-emsp-可以控制物理内存的访问权限。"><a href="#一、-amp-emsp-可以控制物理内存的访问权限。" class="headerlink" title="一、&emsp;可以控制物理内存的访问权限。"></a>一、&emsp;可以控制物理内存的访问权限。</h5><p>&emsp;&emsp;物理内存本身是不限制访问的,任何地址理论上来说都是可以读写的,而操作系统要求不同的页面具有不同的访问权限,这是利用CPU模式和MMU内存保护机制实现的。<br>&emsp;&emsp;例如Test Segment被只读保护起来,防止执行了错误的指令意外改写了Test Segment,内核地址空间也被保护起来,防止在用户模式下访问内核数据或执行内核代码。<br>&emsp;这样错误的指令或者是恶意的代码的破坏能力受到了限制,顶多使当前进程因为段错误而终止,不会影响整个系统的稳定性。</p>
<h5 id="二、可以让每一个进程都有独立的地址空间。"><a href="#二、可以让每一个进程都有独立的地址空间。" class="headerlink" title="二、可以让每一个进程都有独立的地址空间。"></a>二、可以让每一个进程都有独立的地址空间。</h5><p>&emsp;&emsp;不同的进程中相同的VA(virtul address)被MMU映射到不同的PA(physical adress)。所以在每一个进程中访问任何虚拟地址都是不可能访问到属于另一个进程的物理内存的页面。并且每一个进程都认为自己独占了0x0000 0000 - 0xbfff ffff 的整个用户地址空间。</p>
<p>&emsp;&emsp;独占的好处就是,任何进程执行了错误指令或者是恶意的代码导致的非法内存访问都不会意外改写其他进程的数据,也不会影响其他进程的运行。<br><br></p>
<p>&emsp;&emsp;打开一个终端,查看终端进程的地址空间</p>
<pre><code>$ cat /proc/2668/maps
</code></pre>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line">08048000-08124000 r-xp 00000000 08:01 262149 /bin/bash</span><br><span class="line">08124000-08125000 r--p 000db000 08:01 262149 /bin/bash</span><br><span class="line">08125000-0812a000 rw-p 000dc000 08:01 262149 /bin/bash</span><br><span class="line">0812a000-0812f000 rw-p 00000000 00:00 0 </span><br><span class="line">09e01000-0a091000 rw-p 00000000 00:00 0 [heap]</span><br><span class="line">b715f000-b717e000 r--p 00000000 08:01 1192977 /usr/share/locale-langpack/zh_CN/LC_MESSAGES/bash.mo</span><br><span class="line">b717e000-b7189000 r-xp 00000000 08:01 1442771 /lib/i386-linux-gnu/libnss_files-2.15.so</span><br><span class="line">b7189000-b718a000 r--p 0000a000 08:01 1442771 /lib/i386-linux-gnu/libnss_files-2.15.so</span><br><span class="line">b718a000-b718b000 rw-p 0000b000 08:01 1442771 /lib/i386-linux-gnu/libnss_files-2.15.so</span><br><span class="line">b718b000-b71a1000 r-xp 00000000 08:01 1442765 /lib/i386-linux-gnu/libnsl-2.15.so</span><br><span class="line">b71a1000-b71a2000 r--p 00015000 08:01 1442765 /lib/i386-linux-gnu/libnsl-2.15.so</span><br><span class="line">b71a2000-b71a3000 rw-p 00016000 08:01 1442765 /lib/i386-linux-gnu/libnsl-2.15.so</span><br><span class="line">b71a3000-b71a5000 rw-p 00000000 00:00 0 </span><br><span class="line">b71a5000-b71ac000 r-xp 00000000 08:01 1442767 /lib/i386-linux-gnu/libnss_compat-2.15.so</span><br><span class="line">b71ac000-b71ad000 r--p 00006000 08:01 1442767 /lib/i386-linux-gnu/libnss_compat-2.15.so</span><br><span class="line">b71ad000-b71ae000 rw-p 00007000 08:01 1442767 /lib/i386-linux-gnu/libnss_compat-2.15.so</span><br><span class="line">b71c1000-b7365000 r--p 03f51000 08:01 534160 /usr/lib/locale/locale-archive</span><br><span class="line">b7365000-b7565000 r--p 00000000 08:01 534160 /usr/lib/locale/locale-archive</span><br><span class="line">b7565000-b7566000 rw-p 00000000 00:00 0 </span><br><span class="line">b7566000-b7705000 r-xp 00000000 08:01 1442720 /lib/i386-linux-gnu/libc-2.15.so</span><br><span class="line">b7705000-b7707000 r--p 0019f000 08:01 1442720 /lib/i386-linux-gnu/libc-2.15.so</span><br><span class="line">b7707000-b7708000 rw-p 001a1000 08:01 1442720 /lib/i386-linux-gnu/libc-2.15.so</span><br><span class="line">b7708000-b770c000 rw-p 00000000 00:00 0 </span><br><span class="line">b770c000-b770f000 r-xp 00000000 08:01 1442733 /lib/i386-linux-gnu/libdl-2.15.so</span><br><span class="line">b770f000-b7710000 r--p 00002000 08:01 1442733 /lib/i386-linux-gnu/libdl-2.15.so</span><br><span class="line">b7710000-b7711000 rw-p 00003000 08:01 1442733 /lib/i386-linux-gnu/libdl-2.15.so</span><br><span class="line">b7711000-b772d000 r-xp 00000000 08:01 1442817 /lib/i386-linux-gnu/libtinfo.so.5.9</span><br><span class="line">b772d000-b772f000 r--p 0001b000 08:01 1442817 /lib/i386-linux-gnu/libtinfo.so.5.9</span><br><span class="line">b772f000-b7730000 rw-p 0001d000 08:01 1442817 /lib/i386-linux-gnu/libtinfo.so.5.9</span><br><span class="line">b7730000-b7737000 r--s 00000000 08:01 531129 /usr/lib/i386-linux-gnu/gconv/gconv-modules.cache</span><br><span class="line">b7737000-b7741000 r-xp 00000000 08:01 1442775 /lib/i386-linux-gnu/libnss_nis-2.15.so</span><br><span class="line">b7741000-b7742000 r--p 00009000 08:01 1442775 /lib/i386-linux-gnu/libnss_nis-2.15.so</span><br><span class="line">b7742000-b7743000 rw-p 0000a000 08:01 1442775 /lib/i386-linux-gnu/libnss_nis-2.15.so</span><br><span class="line">b7743000-b7745000 rw-p 00000000 00:00 0 </span><br><span class="line">b7745000-b7746000 r-xp 00000000 00:00 0 [vdso]</span><br><span class="line">b7746000-b7766000 r-xp 00000000 08:01 1442700 /lib/i386-linux-gnu/ld-2.15.so</span><br><span class="line">b7766000-b7767000 r--p 0001f000 08:01 1442700 /lib/i386-linux-gnu/ld-2.15.so</span><br><span class="line">b7767000-b7768000 rw-p 00020000 08:01 1442700 /lib/i386-linux-gnu/ld-2.15.so</span><br><span class="line">bff9d000-bffbe000 rw-p 00000000 00:00 0 [stack]</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="三、VA到PA的映射会给分配和释放内存带来便利"><a href="#三、VA到PA的映射会给分配和释放内存带来便利" class="headerlink" title="三、VA到PA的映射会给分配和释放内存带来便利"></a>三、VA到PA的映射会给分配和释放内存带来便利</h5><p>&emsp;&emsp;物理地址不连续的几块内存空间也可以映射成虚拟地址连续的一块内存。比如malloc会分配一块很大的内存空间,虽然有足够多的空闲物理内存,但是却没有足够大的连续空闲内存,这个时候就可以分配多个不连续的物理页面而映射到连续的虚拟地址范围。</p>
<h5 id="四、"><a href="#四、" class="headerlink" title="四、"></a>四、</h5><p>&emsp;&emsp;一个系统如果同时运行很多进程,为进程分配的内存之和可能会大于实际可用的物理内存,虚拟内存管理机制使这种情况下各种进程仍然能够正常运行。进程访问的是虚拟内存页面,这些页面数据可以保存在物理页面中,也可以零时保存在磁盘上而不占用页面的数据。<br>&emsp;&emsp;可以在磁盘上开辟一个分区或者文件专门用于临时保存虚拟内存页面的数据,叫做交换设备(Swap Device)。启动了交换设备之后,系统可以分配内存总量是 物理内存和交换设备的大小之和。</p>
<p>&emsp;&emsp;当物理内存不够的时候,操作系统将不常用的物理页面中的数据临时保存到交换设备。解除VA到PA的映射,这个物理页面就可以认为是空闲的。也可以重新分配给进程使用,这个过程称为Page out.</p>
]]></content>
<tags>
<tag>linux virtual memory</tag>
</tags>
</entry>
<entry>
<title>Exynos-4412-PWM-platform_driver</title>
<url>/2019/03/05/Exynos-4412-PWM-platform-driver/</url>
<content><![CDATA[<p>Exynos-4412平台的PWM驱动</p>
<span id="more"></span>
<p>使用的硬件资源:</p>
<p> GPD0CON 0x114000a0 配置GPIO复用<br> TCFG0 0x139D_0000 配置预分频<br> TCFG1 0x139D_0004 配置分割器 二级分频<br> TCON 0x139D_0008 控制寄存器<br> TCNTB0 0x139D_000c 计数缓冲寄存器<br> TCMPB0 0x139D_0010 比较缓冲寄存器<br><br></p>
<p>Exynos4412_beep_device.c</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/module.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/kernel.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/init.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/fs.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/cdev.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/device.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><asm/io.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/platform_device.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">Exynos4412_beep_release</span><span class="params">(<span class="keyword">struct</span> device *dev)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412 beep release\n"</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">resource</span> <span class="title">beep_res</span>[] =</span></span><br><span class="line">{</span><br><span class="line"> [<span class="number">0</span>] = {</span><br><span class="line"> .start = <span class="number">0x114000a0</span>,</span><br><span class="line"> .end = <span class="number">0x11000c40</span> + <span class="number">0x3</span>,</span><br><span class="line"> .flags = IORESOURCE_MEM,</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> [<span class="number">1</span>] = {</span><br><span class="line"> .start = <span class="number">0x139d0000</span>,</span><br><span class="line"> .end = <span class="number">0x139d0000</span> + <span class="number">0x13</span>,</span><br><span class="line"> .flags = IORESOURCE_MEM,</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">platform_device</span> <span class="title">pdev</span> =</span></span><br><span class="line">{</span><br><span class="line"> .name = <span class="string">"Exynos4412-beep"</span>,</span><br><span class="line"> .id = <span class="number">-1</span>,</span><br><span class="line"> .dev.release = Exynos4412_beep_release,</span><br><span class="line"> .num_resources = ARRAY_SIZE(beep_res),</span><br><span class="line"> .resource =beep_res,</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> __init <span class="title function_">Exynos4412_beep_device_init</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_device_init\n"</span>);</span><br><span class="line"> platform_device_register(&pdev);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> __exit <span class="title function_">Exynos4412_beep_device_exit</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_device_exit\n"</span>);</span><br><span class="line"> platform_device_unregister(&pdev);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);</span><br><span class="line">module_init(Exynos4412_beep_device_init); </span><br><span class="line">module_exit(Exynos4412_beep_device_exit);</span><br></pre></td></tr></table></figure>
<br>
Exynos4412_beep_driver.c
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/module.h></span> <span class="comment">//linux 3.14/include/linux</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/kernel.h></span> <span class="comment">//printk </span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/init.h></span> <span class="comment">//module_init module_exit</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/fs.h></span> <span class="comment">//struct file_operations</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/cdev.h></span> <span class="comment">//struct cdev</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/device.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><asm/io.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/platform_device.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="type">dev_t</span> devno; <span class="comment">//�豸��</span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> major;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="keyword">class</span> *<span class="title">pcls</span>;</span> </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">device</span> *<span class="title">pdevice</span>;</span> <span class="comment">//这个结构体是用来生成设备节点的</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TCFG0 0x0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TCFG1 0x04</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TCON 0x8</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TCNTB0 0xc</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TCMPB0 0x10</span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> *pgpd0con;</span><br><span class="line"><span class="type">void</span> *ptimer0base;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_ioremap</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> pgpd0con = </span><br><span class="line"> ioremap(pdev->resource[<span class="number">0</span>].start,pdev->resource[<span class="number">0</span>].end-pdev->resource[<span class="number">0</span>].start+<span class="number">1</span>);</span><br><span class="line"> </span><br><span class="line"> ptimer0base = </span><br><span class="line"> ioremap(pdev->resource[<span class="number">1</span>].start,pdev->resource[<span class="number">1</span>].end-pdev->resource[<span class="number">1</span>].start+<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_on</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> writel((readl(ptimer0base+TCON)&(~(<span class="number">0xf</span><<<span class="number">0</span>)))|(<span class="number">0x9</span><<<span class="number">0</span>),ptimer0base+TCON);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_off</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> writel((readl(ptimer0base+TCON)&(~(<span class="number">0x1</span><<<span class="number">0</span>))),ptimer0base+TCON);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> HZ_BEEP 10000</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">Exynos4412_beep_setfre</span><span class="params">(<span class="type">int</span> fre)</span></span><br><span class="line">{</span><br><span class="line"> writel(HZ_BEEP/fre,ptimer0base+TCNTB0);</span><br><span class="line"> writel(HZ_BEEP/(fre*<span class="number">2</span>),ptimer0base+TCMPB0);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_init</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> writel((readl(pgpd0con)&(~(<span class="number">0xf</span><<<span class="number">0</span>)))|(<span class="number">0x2</span><<<span class="number">0</span>),pgpd0con);</span><br><span class="line"></span><br><span class="line"> writel((readl(ptimer0base+TCFG0)&(~(<span class="number">0xff</span><<<span class="number">0</span>)))|(<span class="number">0xff</span><<<span class="number">0</span>),ptimer0base+TCFG0);</span><br><span class="line"> writel((readl(ptimer0base+TCFG1)&(~(<span class="number">0xf</span><<<span class="number">0</span>)))|(<span class="number">0x1</span><<<span class="number">0</span>),ptimer0base+TCFG1); </span><br><span class="line"> writel(<span class="number">1000</span>,ptimer0base+TCNTB0);</span><br><span class="line"> writel(<span class="number">500</span>,ptimer0base+TCMPB0);</span><br><span class="line"> </span><br><span class="line"> writel((readl(ptimer0base+TCON)&(~(<span class="number">0xf</span><<<span class="number">0</span>)))|(<span class="number">0x2</span><<<span class="number">0</span>),ptimer0base+TCON); </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_open</span><span class="params">(<span class="keyword">struct</span> inode* inode,<span class="keyword">struct</span> file* file)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_open\n"</span>);</span><br><span class="line"> Exynos4412_beep_on();</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_release</span><span class="params">(<span class="keyword">struct</span> inode* inode,<span class="keyword">struct</span> file* file)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_beep_close\n"</span>);</span><br><span class="line"> Exynos4412_beep_off();</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MAGIC_NUM <span class="string">'k'</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BEEP_ON _IO(MAGIC_NUM,0)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BEEP_OFF _IO(MAGIC_NUM,1)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BEEP_FRE _IO(MAGIC_NUM,2)</span></span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">Exynos4412_beep_ioctl</span><span class="params">(<span class="keyword">struct</span> file* file,<span class="type">unsigned</span> <span class="type">int</span> cmd, <span class="type">unsigned</span> <span class="type">long</span> arg)</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">switch</span>(cmd)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> BEEP_ON:</span><br><span class="line"> Exynos4412_beep_on();</span><br><span class="line"> <span class="keyword">break</span>; </span><br><span class="line"> <span class="keyword">case</span> BEEP_OFF:</span><br><span class="line"> Exynos4412_beep_off();</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> BEEP_FRE:</span><br><span class="line"> Exynos4412_beep_setfre(arg);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">file_operations</span> <span class="title">fops</span> =</span> { <span class="comment">//ϵͳ���÷���</span></span><br><span class="line"> .open = Exynos4412_beep_open,</span><br><span class="line"> .release = Exynos4412_beep_release,</span><br><span class="line"> .unlocked_ioctl = Exynos4412_beep_ioctl,</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_probe</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_probe\n"</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span>(;i<pdev->num_resources;i++)</span><br><span class="line"> {</span><br><span class="line"> printk(<span class="string">"%p\n"</span>,pdev->resource[i].start);</span><br><span class="line"> printk(<span class="string">"%p\n"</span>,pdev->resource[i].end);</span><br><span class="line"></span><br><span class="line"> printk(<span class="string">"%x\n"</span>,pdev->resource[i].flags);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//1�����ַ��豸</span></span><br><span class="line"> major = register_chrdev(major,<span class="string">"Exynos4412-beep"</span>,&fops);</span><br><span class="line"> devno = MKDEV(major,<span class="number">0</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//2�Զ������豸�ڵ�</span></span><br><span class="line"> pcls = class_create(THIS_MODULE,<span class="string">"beep-auto"</span>);</span><br><span class="line"> pdevice = device_create(pcls,<span class="literal">NULL</span>,devno,<span class="literal">NULL</span>,<span class="string">"Exynos4412-beep"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//Ӳ����ʼ��</span></span><br><span class="line"> Exynos4412_beep_ioremap(pdev);</span><br><span class="line"> Exynos4412_beep_init();</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_remove</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_remove\n"</span>);</span><br><span class="line"></span><br><span class="line"> unregister_chrdev(major,<span class="string">"Exynos4412-beep"</span>);</span><br><span class="line"> </span><br><span class="line"> device_destroy(pcls,devno);</span><br><span class="line"> class_destroy(pcls);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_suspend</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev,<span class="type">pm_message_t</span> state)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_suspend\n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Exynos4412_beep_resume</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412_beep_resume\n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">platform_driver</span> <span class="title">pdrv</span> =</span></span><br><span class="line">{</span><br><span class="line"> .probe = Exynos4412_beep_probe,</span><br><span class="line"> .remove = Exynos4412_beep_remove,</span><br><span class="line"> .suspend = Exynos4412_beep_suspend,</span><br><span class="line"> .resume = Exynos4412_beep_resume,</span><br><span class="line"> .driver.name = <span class="string">"Exynos4412-beep"</span></span><br><span class="line"></span><br><span class="line">};</span><br><span class="line"><span class="comment">// �ں���ʱ�����insmodʱ������</span></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> __init <span class="title function_">hello_init</span><span class="params">(<span class="type">void</span>)</span> <span class="comment">//���ӱ�־����Ѻ�������init��</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"Exynos4412-beep driver init\n"</span>);</span><br><span class="line"> platform_driver_register(&pdrv);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// �ں˹ػ�����rmmodʱ�����</span></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> __exit <span class="title function_">hello_exit</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"exit Exynos4412 beep device\n"</span>);</span><br><span class="line"> platform_driver_unregister(&pdrv);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);<span class="comment">//�������</span></span><br><span class="line">module_init(hello_init); <span class="comment">//�������</span></span><br><span class="line">module_exit(hello_exit);</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>
]]></content>
</entry>
<entry>
<title>i2c_mpu6050</title>
<url>/2019/03/07/i2c-mpu6050/</url>
<content><![CDATA[<p>mpu6050芯片 linux 驱动</p>
<span id="more"></span>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">ifndef</span> MPU6050_HHHH</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MPU6050_HHHH</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MPU6050_MAGIC <span class="string">'K'</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> SMPLRT_DIV 0x19</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> CONFIG 0x1A</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_CONFIG 0x1B</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_CONFIG 0x1C</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_XOUT_H 0x3B</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_XOUT_L 0x3C</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_YOUT_H 0x3D</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_YOUT_L 0x3E</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_ZOUT_H 0x3F</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ACCEL_ZOUT_L 0x40</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TEMP_OUT_H 0x41</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TEMP_OUT_L 0x42</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_XOUT_H 0x43</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_XOUT_L 0x44</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_YOUT_H 0x45</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_YOUT_L 0x46</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_ZOUT_H 0x47</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GYRO_ZOUT_L 0x48</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PWR_MGMT_1 0x6B</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">union</span> <span class="title">mpu6050_data</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> x;</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> y;</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> z;</span><br><span class="line"> }accel;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> x;</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> y;</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> z;</span><br><span class="line"> }gyro;</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> temp;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GET_ACCEL _IOR(MPU6050_MAGIC, 0, union mpu6050_data)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GET_GYRO _IOR(MPU6050_MAGIC, 1, union mpu6050_data) </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> GET_TEMP _IOR(MPU6050_MAGIC, 2, union mpu6050_data)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>i2c_driver.c </p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/module.h></span> <span class="comment">//linux 3.14/include/linux</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/kernel.h></span> <span class="comment">//define of printk</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/init.h></span> <span class="comment">//module_init module_exit</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/fs.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/cdev.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/device.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><asm/io.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/platform_device.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/slab.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/uaccess.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"mpu6050.h"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/i2c.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="type">dev_t</span> devno;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> major;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="keyword">class</span> *<span class="title">pcls</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">device</span> *<span class="title">pdevice</span>;</span></span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">mpu6050_device</span>{</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_client</span> *<span class="title">client</span>;</span></span><br><span class="line">};</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">mpu6050_device</span> *<span class="title">mpu6050</span>;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这个函数为什么这样设计 函数的参数</span></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">mpu6050_read_byte</span><span class="params">(<span class="keyword">struct</span> i2c_client *client,<span class="type">unsigned</span> <span class="type">char</span> reg)</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">char</span> txbuf[<span class="number">1</span>] = {reg};</span><br><span class="line"> <span class="type">char</span> rxbuf[<span class="number">1</span>];</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_msg</span> <span class="title">msg</span>[2] =</span> {</span><br><span class="line"> {client->addr,<span class="number">0</span>,<span class="number">1</span>,txbuf},</span><br><span class="line"> {client->addr,<span class="number">1</span>,<span class="number">1</span>,rxbuf},</span><br><span class="line"> <span class="comment">//读出来的数据放在rxbuf</span></span><br><span class="line"> };</span><br><span class="line"> i2c_transfer(client->adapter,msg,ARRAY_SIZE(msg));</span><br><span class="line"> <span class="keyword">return</span> rxbuf[<span class="number">0</span>];</span><br><span class="line">}</span><br><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">mpu6050_write_byte</span><span class="params">(<span class="keyword">struct</span> i2c_client *client,<span class="type">unsigned</span> <span class="type">char</span> reg,<span class="type">unsigned</span> <span class="type">char</span> val )</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">char</span> txbuf[<span class="number">2</span>] = {reg,val};</span><br><span class="line"> </span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_msg</span> <span class="title">msg</span>[1] =</span> {</span><br><span class="line"> {client->addr,<span class="number">0</span>,<span class="number">2</span>,txbuf},</span><br><span class="line"> <span class="comment">//mpu6050地址 写标志位 字节数 写的内容 </span></span><br><span class="line"> };</span><br><span class="line"> i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));</span><br><span class="line"> <span class="comment">//adapter</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">mpu6050_init</span><span class="params">(<span class="keyword">struct</span> i2c_client *client)</span></span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> mpu6050_write_byte(client,PWR_MGMT_1,<span class="number">0x0</span>);</span><br><span class="line"> mpu6050_write_byte(client,SMPLRT_DIV,<span class="number">0x07</span>);</span><br><span class="line"> mpu6050_write_byte(client,CONFIG,<span class="number">0x06</span>);</span><br><span class="line"> mpu6050_write_byte(client,GYRO_CONFIG,<span class="number">0xf8</span>);</span><br><span class="line"> mpu6050_write_byte(client,ACCEL_CONFIG,<span class="number">0x19</span>);</span><br><span class="line"> printk(<span class="string">"mpu6050 init success \n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">mpu6050_open</span><span class="params">(<span class="keyword">struct</span> inode *inode, <span class="keyword">struct</span> file *file)</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mpu6050_release</span><span class="params">(<span class="keyword">struct</span> inode *inode, <span class="keyword">struct</span> file *file)</span></span><br><span class="line">{</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">mpu6050_ioctl</span><span class="params">(<span class="keyword">struct</span> file *file, <span class="type">unsigned</span> <span class="type">int</span> cmd, <span class="type">unsigned</span> <span class="type">long</span> arg)</span></span><br><span class="line">{</span><br><span class="line"> <span class="class"><span class="keyword">union</span> <span class="title">mpu6050_data</span> <span class="title">data</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_client</span> *<span class="title">client</span> =</span> mpu6050->client;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">switch</span>(cmd)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> GET_ACCEL:</span><br><span class="line"> data.accel.x = </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_XOUT_L);</span><br><span class="line"> data.accel.x |= </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_XOUT_H) << <span class="number">8</span>;</span><br><span class="line"></span><br><span class="line"> data.accel.y = </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_YOUT_L);</span><br><span class="line"> data.accel.y |= </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_YOUT_H) << <span class="number">8</span>;</span><br><span class="line"></span><br><span class="line"> data.accel.z = </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_ZOUT_L);</span><br><span class="line"> data.accel.z |= </span><br><span class="line"> mpu6050_read_byte(client,ACCEL_ZOUT_H)<< <span class="number">8</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> GET_GYRO:</span><br><span class="line"> data.gyro.x = </span><br><span class="line"> mpu6050_read_byte(client,GYRO_XOUT_L);</span><br><span class="line"> data.gyro.x |= </span><br><span class="line"> mpu6050_read_byte(client,GYRO_XOUT_H)<<<span class="number">8</span>;</span><br><span class="line"></span><br><span class="line"> data.gyro.y = </span><br><span class="line"> mpu6050_read_byte(client,GYRO_ZOUT_L);</span><br><span class="line"> data.gyro.y |= </span><br><span class="line"> mpu6050_read_byte(client,GYRO_ZOUT_H) << <span class="number">8</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> printk(<span class="string">"invaild argument\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> copy_to_user((<span class="type">void</span>*)arg,&data,<span class="keyword">sizeof</span>(data));</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">sizeof</span>(data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">file_operations</span> <span class="title">fops</span> =</span> {</span><br><span class="line"> .owner = THIS_MODULE,</span><br><span class="line"> .open = mpu6050_open,</span><br><span class="line"> .release = mpu6050_release,</span><br><span class="line"> .unlocked_ioctl = mpu6050_ioctl,</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">mpu6050_probe</span><span class="params">(<span class="keyword">struct</span> i2c_client * client, <span class="type">const</span> <span class="keyword">struct</span> device * id)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"mpu6050_probe\n"</span>);</span><br><span class="line"> </span><br><span class="line"> mpu6050 = kzalloc(<span class="keyword">sizeof</span>(*mpu6050),GFP_KERNEL);</span><br><span class="line"> mpu6050->client = client;</span><br><span class="line"> major = register_chrdev(major,<span class="string">"mpu6050"</span>,&fops);</span><br><span class="line"> devno = MKDEV(major,<span class="number">0</span>);</span><br><span class="line"> printk(<span class="string">"create the devno success\n"</span>);</span><br><span class="line"></span><br><span class="line"> pcls = class_create(THIS_MODULE,<span class="string">"mpu6050-auto"</span>);</span><br><span class="line"> pdevice = device_create(pcls,<span class="literal">NULL</span>,devno,<span class="literal">NULL</span>,<span class="string">"mpu6050"</span>);</span><br><span class="line"> printk(<span class="string">"create the device node\n"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//hardware init </span></span><br><span class="line"> mpu6050_init(client);</span><br><span class="line"> printk(<span class="string">"mpu6050_probe\n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">mpu6050_remove</span><span class="params">(<span class="keyword">struct</span> i2c_client * client)</span></span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> printk(<span class="string">"mpu6050 remove \n"</span>);</span><br><span class="line"> </span><br><span class="line"> unregister_chrdev(major,<span class="string">"mpu6050"</span>);</span><br><span class="line"> device_destroy(pcls,devno);</span><br><span class="line"></span><br><span class="line"> class_destroy(pcls);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">mpu6050_suspend</span><span class="params">(<span class="keyword">struct</span> i2c_client *client,<span class="type">pm_message_t</span> state)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_i2c_suspened\n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">mpu6050_resume</span><span class="params">(<span class="keyword">struct</span> i2c_client *client)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_i2c_resume\n"</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//一个是id_table 一个是.driver.of_match_table 都有什么用</span></span><br><span class="line"><span class="type">static</span> <span class="type">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_device_id</span> <span class="title">mpu6050_id</span>[] =</span> </span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> {<span class="string">"mpu6050"</span>,<span class="number">0</span>},</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">of_device_id</span> <span class="title">mpu6050_dt_match</span>[] =</span> </span><br><span class="line">{</span><br><span class="line"> {.compatible = <span class="string">"invense,mpu6050"</span>},</span><br><span class="line"></span><br><span class="line">}; <span class="comment">//这里为什么需要结构体数组 只有一个设备啊</span></span><br><span class="line"> <span class="comment">//结构体数组可以填多组</span></span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">i2c_driver</span> <span class="title">mpu6050_driver</span> =</span> {</span><br><span class="line"> .probe = mpu6050_probe,</span><br><span class="line"> .remove = mpu6050_remove,</span><br><span class="line"> .suspend = mpu6050_suspend,</span><br><span class="line"> .resume = mpu6050_resume,</span><br><span class="line"> .id_table = mpu6050_id,</span><br><span class="line"> .driver = {</span><br><span class="line"> .name = <span class="string">"mpu6050"</span>,</span><br><span class="line"> .owner = THIS_MODULE,</span><br><span class="line"> .of_match_table = mpu6050_dt_match,</span><br><span class="line"> },</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> __init <span class="title function_">fs4412_i2c_driver_init</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_i2c_driver_init\n"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//register </span></span><br><span class="line"> i2c_add_driver(&mpu6050_driver);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="type">static</span> <span class="type">void</span> __exit <span class="title function_">fs4412_i2c_driver_exit</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_i2c_driver_exit\n"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//unregister</span></span><br><span class="line"> i2c_del_driver(&mpu6050_driver);</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);<span class="comment">//许可声明 开源许可</span></span><br><span class="line">module_init(fs4412_i2c_driver_init);<span class="comment">//声明入口</span></span><br><span class="line">module_exit(fs4412_i2c_driver_exit);<span class="comment">//声明出口</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>test_mpu6050</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"stdio.h"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><fcntl.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/ioctl.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"mpu6050.h"</span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">int</span> fd;</span><br><span class="line"> <span class="class"><span class="keyword">union</span> <span class="title">mpu6050_data</span> <span class="title">data</span>;</span></span><br><span class="line"></span><br><span class="line"> fd = open(<span class="string">"/dev/mpu6050"</span>,O_RDWR);</span><br><span class="line"> <span class="keyword">if</span>(fd<<span class="number">0</span>)</span><br><span class="line"> { </span><br><span class="line"> perror(<span class="string">"open"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> ioctl(fd,GET_ACCEL,&data);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"acceleration data : x = %04x,y =%04x,z =%04x\n"</span>,data.accel.x,data.accel.y,data.accel.z);</span><br><span class="line"></span><br><span class="line"> ioctl(fd,GET_GYRO,&data);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"gyroscope data: x = %04x,y =%04x,z =%04x\n"</span>,data.gyro.x,data.gyro.y,data.gyro.z);</span><br><span class="line"> sleep(<span class="number">2</span>); </span><br><span class="line"> }</span><br><span class="line"> close(fd);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title>key_interrupt</title>
<url>/2019/03/08/key-interrupt/</url>
<content><![CDATA[<p>4412 按键 linux内核驱动</p>
<span id="more"></span>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/module.h></span> <span class="comment">//linux 3.14/include/linux</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/kernel.h></span> <span class="comment">//define of printk</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/init.h></span> <span class="comment">//module_init module_exit</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/fs.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/cdev.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/device.h></span> </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><asm/io.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/platform_device.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><linux/interrupt.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">timer_list</span> <span class="title">key2_timer</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">timer_list</span> <span class="title">key3_timer</span>;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="type">int</span> <span class="title function_">fs4412_led_on</span><span class="params">(<span class="type">int</span> ledno)</span>;</span><br><span class="line"><span class="keyword">extern</span> <span class="type">int</span> <span class="title function_">fs4412_led_off</span><span class="params">(<span class="type">int</span> ledno)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">k2_timer_fn</span><span class="params">(<span class="type">unsigned</span> <span class="type">long</span> data)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"k2_time_fn\n"</span>);</span><br><span class="line"> fs4412_led_on(<span class="number">2</span>);</span><br><span class="line"> fs4412_led_on(<span class="number">3</span>);</span><br><span class="line"> fs4412_led_off(<span class="number">4</span>);</span><br><span class="line"> fs4412_led_off(<span class="number">5</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">irqreturn_t</span> <span class="title function_">key2_fn</span><span class="params">(<span class="type">int</span> irqno,<span class="type">void</span> *data)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"key2 is pressed %d \n"</span>,irqno);</span><br><span class="line"> printk(<span class="string">"hello i am key2\n"</span>);</span><br><span class="line"> mod_timer(&key2_timer, jiffies+<span class="number">500</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> IRQ_HANDLED;</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">k3_timer_fn</span><span class="params">(<span class="type">unsigned</span> <span class="type">long</span> data)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"k3_time_fn\n"</span>);</span><br><span class="line"> printk(<span class="string">"\n\n\n\n"</span>);</span><br><span class="line"> fs4412_led_on(<span class="number">4</span>);</span><br><span class="line"> fs4412_led_on(<span class="number">5</span>);</span><br><span class="line"> fs4412_led_off(<span class="number">2</span>);</span><br><span class="line"> fs4412_led_off(<span class="number">3</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">irqreturn_t</span> <span class="title function_">key3_fn</span><span class="params">(<span class="type">int</span> irqno,<span class="type">void</span> *data)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"key3 is pressed %d \n"</span>,irqno);</span><br><span class="line"> printk(<span class="string">"hello i am key3\n"</span>);</span><br><span class="line"> mod_timer(&key3_timer, jiffies+<span class="number">500</span>);</span><br><span class="line"> <span class="keyword">return</span> IRQ_HANDLED;</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fs4412_key_probe</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span> <span class="comment">//在device定义的pdev</span></span><br><span class="line">{ </span><br><span class="line"> <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(;i < pdev->num_resources; i++)</span><br><span class="line"> {</span><br><span class="line"></span><br><span class="line"> printk(<span class="string">"%p\n"</span>,pdev->resource[i].start);</span><br><span class="line"> printk(<span class="string">"%p\n"</span>,pdev->resource[i].end);</span><br><span class="line"> printk(<span class="string">"%p\n"</span>,pdev->resource[i].flags);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//key2 register interrupt </span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">//IRQnumber //处理函数 //proc/interrupt里面</span></span><br><span class="line"> request_irq(pdev->resource[<span class="number">0</span>].start,key2_fn,pdev->resource[<span class="number">0</span>].flags,<span class="string">"key2"</span>,<span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//key3 register interrupt</span></span><br><span class="line"> request_irq(pdev->resource[<span class="number">1</span>].start,key3_fn,pdev->resource[<span class="number">1</span>].flags,<span class="string">"key3"</span>,<span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line"> key2_timer.function = k2_timer_fn;</span><br><span class="line"> init_timer(&key2_timer);</span><br><span class="line"> </span><br><span class="line"> key3_timer.function = k3_timer_fn;</span><br><span class="line"> init_timer(&key3_timer);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fs4412_key_remove</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_key_remove\n"</span>);</span><br><span class="line"> </span><br><span class="line"> free_irq(pdev->resource[<span class="number">0</span>].start,<span class="literal">NULL</span>);</span><br><span class="line"> free_irq(pdev->resource[<span class="number">1</span>].start,<span class="literal">NULL</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fs4412_key_suspend</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev,<span class="type">pm_message_t</span> state)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_key_suspened\n"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">fs4412_key_resume</span><span class="params">(<span class="keyword">struct</span> platform_device *pdev)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_key_resume\n"</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">of_device_id</span> <span class="title">key_tbl</span>[] =</span> </span><br><span class="line">{ </span><br><span class="line"> { .compatible = <span class="string">"fs4412,key"</span>,},</span><br><span class="line"> </span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">platform_driver</span> <span class="title">pdrv</span> =</span> </span><br><span class="line">{</span><br><span class="line"> .probe = fs4412_key_probe,</span><br><span class="line"> .remove = fs4412_key_remove,</span><br><span class="line"> .suspend = fs4412_key_suspend,</span><br><span class="line"> .resume = fs4412_key_resume,</span><br><span class="line"> .driver.name = <span class="string">"fs4412-key"</span>,</span><br><span class="line"> .driver.of_match_table = key_tbl,</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">int</span> __init <span class="title function_">fs4412_key_driver_init</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_key_driver_init\n"</span>);</span><br><span class="line"> platform_driver_register(&pdrv);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> __exit <span class="title function_">fs4412_key_driver_exit</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> printk(<span class="string">"fs4412_key_driver_exit\n"</span>);</span><br><span class="line"> platform_driver_unregister(&pdrv);</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);<span class="comment">//许可声明 开源许可</span></span><br><span class="line">module_init(fs4412_key_driver_init);<span class="comment">//声明入口</span></span><br><span class="line">module_exit(fs4412_key_driver_exit);<span class="comment">//声明出口</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
]]></content>
</entry>
<entry>
<title>Assert 如何工作</title>
<url>/2023/06/04/assert/</url>
<content><![CDATA[<p>Assert 为什么能够让程序退出?</p>
<span id="more"></span>
<h1 id="Assert"><a href="#Assert" class="headerlink" title="Assert"></a>Assert</h1><p>主要讨论下assert的实现方式,以glibc-2.2版本为例</p>
<h2 id="一、实验代码"><a href="#一、实验代码" class="headerlink" title="一、实验代码"></a>一、实验代码</h2><pre><code><figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><assert.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span> <span class="params">(<span class="type">int</span> argc, <span class="type">char</span> **argv)</span> {</span><br><span class="line"> assert(<span class="number">1</span> < <span class="number">0</span>);</span><br><span class="line"> <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line"> i = i;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</code></pre>
<h2 id="二、实验步骤"><a href="#二、实验步骤" class="headerlink" title="二、实验步骤"></a>二、实验步骤</h2><ol>
<li><p>使用<code>gcc -E main.c</code> 查看 预处理文件</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"># <span class="number">1</span> <span class="string">"main.c"</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"<built-in>"</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"<command-line>"</span></span><br><span class="line"># <span class="number">31</span> <span class="string">"<command-line>"</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/stdc-predef.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">32</span> <span class="string">"<command-line>"</span> <span class="number">2</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"main.c"</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/assert.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">35</span> <span class="string">"/usr/include/assert.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/features.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">424</span> <span class="string">"/usr/include/features.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/x86_64-linux-gnu/sys/cdefs.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">442</span> <span class="string">"/usr/include/x86_64-linux-gnu/sys/cdefs.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/x86_64-linux-gnu/bits/wordsize.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">443</span> <span class="string">"/usr/include/x86_64-linux-gnu/sys/cdefs.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/x86_64-linux-gnu/bits/long-double.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">444</span> <span class="string">"/usr/include/x86_64-linux-gnu/sys/cdefs.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">425</span> <span class="string">"/usr/include/features.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">448</span> <span class="string">"/usr/include/features.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/x86_64-linux-gnu/gnu/stubs.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">10</span> <span class="string">"/usr/include/x86_64-linux-gnu/gnu/stubs.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">1</span> <span class="string">"/usr/include/x86_64-linux-gnu/gnu/stubs-64.h"</span> <span class="number">1</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">11</span> <span class="string">"/usr/include/x86_64-linux-gnu/gnu/stubs.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">449</span> <span class="string">"/usr/include/features.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">36</span> <span class="string">"/usr/include/assert.h"</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"># <span class="number">66</span> <span class="string">"/usr/include/assert.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># <span class="number">69</span> <span class="string">"/usr/include/assert.h"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line"><span class="keyword">extern</span> <span class="type">void</span> __assert_fail (<span class="type">const</span> <span class="type">char</span> *__assertion, <span class="type">const</span> <span class="type">char</span> *__file,</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">int</span> __line, <span class="type">const</span> <span class="type">char</span> *__function)</span><br><span class="line"> __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="type">void</span> __assert_perror_fail (<span class="type">int</span> __errnum, <span class="type">const</span> <span class="type">char</span> *__file,</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">int</span> __line, <span class="type">const</span> <span class="type">char</span> *__function)</span><br><span class="line"> __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="type">void</span> __assert (<span class="type">const</span> <span class="type">char</span> *__assertion, <span class="type">const</span> <span class="type">char</span> *__file, <span class="type">int</span> __line)</span><br><span class="line"> __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># <span class="number">2</span> <span class="string">"main.c"</span> <span class="number">2</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># <span class="number">3</span> <span class="string">"main.c"</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span> <span class="params">(<span class="type">int</span> argc, <span class="type">char</span> **argv)</span> {</span><br><span class="line"></span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line">((<span class="type">void</span>) <span class="keyword">sizeof</span> ((</span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span></span><br><span class="line"><span class="number">1</span> < <span class="number">0</span></span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line">) ? <span class="number">1</span> : <span class="number">0</span>), __extension__ ({ <span class="keyword">if</span> (</span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span></span><br><span class="line"><span class="number">1</span> < <span class="number">0</span></span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line">) ; <span class="keyword">else</span> __assert_fail (</span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span></span><br><span class="line"><span class="string">"1 < 0"</span></span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span> <span class="number">3</span> <span class="number">4</span></span><br><span class="line">, <span class="string">"main.c"</span>, <span class="number">4</span>, __extension__ __PRETTY_FUNCTION__); }))</span><br><span class="line"># <span class="number">4</span> <span class="string">"main.c"</span></span><br><span class="line"> ;</span><br><span class="line"><span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">i = i;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p> 其中 assert(0)被展开成</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">((<span class="type">void</span>) <span class="keyword">sizeof</span> ((<span class="number">1</span> < <span class="number">0</span>) ? <span class="number">1</span> : <span class="number">0</span>), __extension__ ({ </span><br><span class="line"> <span class="keyword">if</span> (<span class="number">1</span> < <span class="number">0</span>) ; </span><br><span class="line"> <span class="keyword">else</span> __assert_fail(<span class="string">"0"</span>, <span class="string">"main.c"</span>, <span class="number">4</span>, __extension__ __PRETTY_FUNCTION__); </span><br><span class="line"> }))</span><br></pre></td></tr></table></figure>
<p> 其中<code>((void) sizeof ((1 < 0) ? 1 : 0), __extension__ ({ ... }))</code> 是一个逗号表达式 </p>
<p> 其中包含一个sizeof 运算符和一个匿名模块</p>
<p> 其中核心的是__assert_fail函数</p>
</li>
<li><p><code>__assert_fail</code>的实现</p>
<p> 不同版本的glibc中的__assert_fail实现不同</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">void</span><br><span class="line">__assert_fail (const char *assertion, const char *file, unsigned int line,</span><br><span class="line"> const char *function)</span><br><span class="line">{</span><br><span class="line">#ifdef FATAL_PREPARE</span><br><span class="line">FATAL_PREPARE;</span><br><span class="line">#endif</span><br><span class="line"></span><br><span class="line">/* Print the message. */</span><br><span class="line">(void) fprintf (stderr, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),</span><br><span class="line"> __assert_program_name ? __assert_program_name : "",</span><br><span class="line"> __assert_program_name ? ": " : "",</span><br><span class="line"> file, line,</span><br><span class="line"> function ? function : "", function ? ": " : "",</span><br><span class="line"> assertion);</span><br><span class="line">(void) fflush (stderr);</span><br><span class="line"></span><br><span class="line">abort ();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 最终 调用了abort() 让程序退出</p>
</li>
</ol>
<h2 id="四、如何关闭ASSERT"><a href="#四、如何关闭ASSERT" class="headerlink" title="四、如何关闭ASSERT"></a>四、如何关闭ASSERT</h2><p> assert.h中有如下代码<br> <figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">ifdef</span> NDEBUG</span></span><br><span class="line"></span><br><span class="line"><span class="meta"># <span class="keyword">define</span> assert(expr) (__ASSERT_VOID_CAST (0))</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* void assert_perror (int errnum);</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">If NDEBUG is defined, do nothing. If not, and ERRNUM is not zero, print an</span></span><br><span class="line"><span class="comment">error message with the error text for ERRNUM and abort.</span></span><br><span class="line"><span class="comment">(This is a GNU extension.) */</span></span><br><span class="line"></span><br><span class="line"><span class="meta"># <span class="keyword">ifdef</span> __USE_GNU</span></span><br><span class="line"><span class="meta"># <span class="keyword">define</span> assert_perror(errnum) (__ASSERT_VOID_CAST (0))</span></span><br><span class="line"><span class="meta"># <span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">else</span> <span class="comment">/* Not NDEBUG. */</span></span></span><br><span class="line"> ....</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure><br>对于gcc编译器而言,在编译时加上-DNDEBUG即可</p>
<h2 id="五、-void-sizeof-expr-1-0"><a href="#五、-void-sizeof-expr-1-0" class="headerlink" title="五、(void) sizeof ((expr) ? 1 : 0)"></a>五、(void) sizeof ((expr) ? 1 : 0)</h2><p> 这里使用的__extension__是一个GNU Libc的宏,用于指示编译器在处理代码时启用拓展特性。</p>
<p> <code>__extension__</code>包裹一段代码或者表达式,以指示编译器在处理该代码时启用拓展特性。</p>
<p> 当使用<code>__extension__</code>包裹代码的时候,编译器不会报错,</p>
<p> 这是因为<code>__extension__</code>提示编译器在处理代码时启用拓展特性,使得编译器能够接受非标准的语法或者特性,并且不产生警告或者错误(除非编译器开启严格模式)</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">__extension__ int x = 10; // 声明一个使用扩展特性的变量</span><br><span class="line"></span><br><span class="line">__extension__ ({</span><br><span class="line"> // 使用扩展特性的代码块</span><br><span class="line"> // ...</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>由于实际的断言逻辑包裹在__extension__中,用户的入参也就是一个表达式,将被放在__extension__中</p>
<p>如果入参有任何错误,都将不会有编译时的报警和错误提示</p>
<p>所以需要设计一种方案,既能让编译器有机会提示报警,又不能实际执行表达式,</p>
<p>因为在<code>__extension</code>中有一次执行,不能执行两次</p>
<p>所以这里使用了sizeof运算符,他能接受一个表达式,查看其类型,并找出其展位符,并且无需执行该表达式</p>
<p>举例来说:</p>
<p>如果我们有一个函数<code>int blow_up_to_world();</code> </p>
<p>那么表达式<code>sizeof(blow_up_to_world)</code>会找到表达式结果的大小(本例中时int),当然这个函数并不会被执行</p>
<p>但是,如果编译器启用了 <code>-pedantic</code> 和 <code>-ansi</code>,那么<code>__extension</code>中该报错的代码还是会报错</p>
<p>接下来,用户的入参没有直接给 sizeof 计算,而是使用了三元。</p>
<p>这是因为如果入参是 可变长度的数组或者是函数名时,可能会产生不良影响</p>
<p>至于为什么使用逗号,因为开发者希望assert是一个表达式,而不是类似do while() 块或者其他东西,使用使用逗号,并且丢弃了 sizeof的结果</p>
<p>如果函数<code>void testfunc();</code> 执行<code>assert(testfunc())</code> 会有编译报错。</p>
<h2 id="六、参考链接"><a href="#六、参考链接" class="headerlink" title="六、参考链接"></a>六、参考链接</h2><p><a href="https://stackoverflow.com/questions/56314110/libc6-comma-operator-in-assert-macro-definition">https://stackoverflow.com/questions/56314110/libc6-comma-operator-in-assert-macro-definition</a></p>
]]></content>
</entry>
<entry>
<title>git使用笔记</title>
<url>/2019/07/13/git/</url>
<content><![CDATA[<p>记录git使用常见命令</p>
<span id="more"></span>
<h1 id="一-git-clone"><a href="#一-git-clone" class="headerlink" title="一. git clone"></a>一. git clone</h1><p>git clone </p>
<p>如果只想克隆某一个分支的时候<br>比方说只想克隆dev分支<br>git clone -b dev <a href="https://github.com/repoweb">https://github.com/repoweb</a></p>
<h1 id="二-git-tag"><a href="#二-git-tag" class="headerlink" title="二. git tag"></a>二. git tag</h1><p>项目开发了一个版本比方说V0.1<br>git tag -a v0.1 -m ‘v0.1’</p>
<p>git tag 过滤<br>选择自己想看的tag<br>git tag -l ‘v0.0.*’</p>
<p>想要把这次的tag推送到远程时<br>git push –tag</p>
<p>git tag 默认是打在最近的一次提交上<br>如果想在某一次commit处加tag<br>git tag -a v0.02 f573hb89a -m ‘v0.02’</p>
<!-- more -->
<h1 id="三-git-status"><a href="#三-git-status" class="headerlink" title="三. git status"></a>三. git status</h1><p>git 中 文件的状态类型有四种<br>unstracked unmodified modified staged </p>
<p>git status可以显示三种状态</p>
<ol>
<li>已经添加到暂存区,待提交的 (git add 后)</li>
<li>已经修改 但是没有暂存的</li>
<li>未追踪的文件</li>
</ol>
<h1 id="四-git-diff-差异比较"><a href="#四-git-diff-差异比较" class="headerlink" title="四. git diff 差异比较"></a>四. git diff 差异比较</h1><p>git diff<br>比较所有文件差异</p>
<p>git diff [filename]<br>默认比较workspace 和暂存(add)后的差别 也就是storged区</p>
<p>git diff –staged<br>比较暂存区和上一次commit的差别</p>
<p>git diff HEAD [filename]<br>比较指定版本 和 workspace </p>
<h1 id="五-git-commit"><a href="#五-git-commit" class="headerlink" title="五. git commit"></a>五. git commit</h1><p>git commit -m ‘commit message’<br>提交信息最好遵从一定的规则<br>我看到的一般是<br><strong>type(scope):subject</strong></p>
<p>type有以下几种常见的类型:</p>
<ol>
<li>feat:新功能</li>
<li>fix: 修复bug</li>
<li>style: 格式 代码格式上的调整,不会影响到代码结构</li>
<li>refactor: 代码重构 比如if的嵌套太多,使用swith case 重写</li>
<li>chore: 项目上线,项目进行打包的时候,修改版本号的时候,最后一次提交记录</li>
</ol>
<p><strong>scope</strong><br>一般是自己负责的模块</p>
<p><strong>subject</strong><br>具体的描述</p>
<p>e.g.<br><strong>git commit -m ‘fix(spi):修复读写的bug’</strong></p>
<h1 id="六-git-commond"><a href="#六-git-commond" class="headerlink" title="六. git commond:"></a>六. git commond:</h1><p>git status<br>git add<br>git commit </p>
<p>查看历史记录<br>git log –pretty=oneline<br>git log –oneline<br>git relog</p>
<p>注意:git log –oneline 只能显示当前版本的之前版本 </p>
<h1 id="七-git-撤销"><a href="#七-git-撤销" class="headerlink" title="七. git 撤销"></a>七. git 撤销</h1><ol>
<li>未添加到暂存区的撤销<br> git checkout – filename<br> git checkout – .</li>
<li>添加到暂存区的撤销<br> git reset HEAD filename</li>
<li>已经提交,想要撤销某次提交<br> git revert commit_md5</li>
</ol>
<h1 id="八-git版本回滚"><a href="#八-git版本回滚" class="headerlink" title="八. git版本回滚"></a>八. git版本回滚</h1><h2 id="git-reset"><a href="#git-reset" class="headerlink" title="git reset"></a>git reset</h2><p>1.使用索引值(推荐)<br>2.使用^符号(只能后退)<br>3.使用~符号(只能后退)</p>
<p>git reset –hard [索引值]<br>e.g. git reset –hard cbeabd1</p>
<p>git reset –hard HEAD^<br>e.g. git reset –hard HEAD^^</p>
<p>回退比较多时<br>git reset –hard HEAD~3 </p>
<h3 id="git-reset-三个参数"><a href="#git-reset-三个参数" class="headerlink" title="git reset 三个参数"></a>git reset 三个参数</h3><p>回头看看git reset 命令本身</p>
<ul>
<li><p>–soft<br>仅仅在本地库中移动HEAD指针</p>
</li>
<li><p>–mixed<br>在本地库中重置HEAD指针<br>重置暂存区</p>
</li>
<li><p>–hard<br>在本地库中移动HEAD指针<br>重置暂存区<br>重置工作区</p>
</li>
</ul>
<p>–soft 只是移动了本地库<br> 往前推一个版本,等于说撤销git commit<br>(还有其他的理解,这种理解需要继续研究)<br>–mixed 移动<br>往前推一个版本,等于说撤销git add</p>
<h1 id="untrack文件"><a href="#untrack文件" class="headerlink" title="untrack文件"></a>untrack文件</h1><h2 id="某一个文件被add-commit之后怎么删除"><a href="#某一个文件被add-commit之后怎么删除" class="headerlink" title="某一个文件被add,commit之后怎么删除"></a>某一个文件被add,commit之后怎么删除</h2><p>工作区rm aaa.txt之后</p>
<ol>
<li><p>git status</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">git rm aaa.txt</span><br><span class="line">git rm aaa.txt --cached</span><br></pre></td></tr></table></figure>
</li>
<li><p>git add aaa.txt </p>
<ul>
<li>将删除的变化加入index</li>
</ul>
</li>
<li><p>git commit -m “deleted aaa.txt”</p>
</li>
<li><p>git reflog 查看上一次commit </p>
</li>
<li><p>git reset –hard</p>
</li>
</ol>
<p>还有一种情况 我们在工作区删除某个文件之后 只是git add</p>
<p>还有没有将删除操作commit到版本库中</p>
<p>git reset –hard HEAD </p>
<h2 id="删除的文件并找回"><a href="#删除的文件并找回" class="headerlink" title="删除的文件并找回"></a>删除的文件并找回</h2><p>前提:删除前,文件存在时的状态有没有提交到本地库</p>
<h1 id="branch"><a href="#branch" class="headerlink" title="branch"></a>branch</h1><p>分支的本质是指向提交对象的一个可变指针</p>
<p>查看分支:git branch -v<br>创建分支:git branch [分支名]<br>切换分支:git checkout [分支名]<br>创建分支并且跳转到分支中 git checkout -b [BranchName]<br>分支删除:git branch -d [BranchName]</p>
<h2 id="合并分支"><a href="#合并分支" class="headerlink" title="合并分支"></a>合并分支</h2><ol>
<li>切换到接收修改的分支上<br> git checkout [需要被添加的内容]</li>
<li>执行merge<br> git merge [有新内容的分支]</li>
</ol>
<h2 id="冲突"><a href="#冲突" class="headerlink" title="冲突"></a>冲突</h2><p>在同一文件的同一位置,两个分支都做了修改<br>需要合并时,到底要听谁的 这就是冲突</p>
<ol>
<li>编辑文件,删除特殊符号</li>
<li>把文件修改到满意的程度,保存退出</li>
<li>git add 文件名</li>
<li>git commit -m “日志“<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"><<<<<<< HEAD</span><br><span class="line">ggggggggggggg edit by hot-fix </span><br><span class="line">=======</span><br><span class="line">ggggggggggggg edit at master branch</span><br><span class="line">>>>>>>> master</span><br></pre></td></tr></table></figure></li>
</ol>
<h1 id="git-远程仓库"><a href="#git-远程仓库" class="headerlink" title="git 远程仓库"></a>git 远程仓库</h1><p>远程分支类似于本地分支,是指向远程仓库文件的指针<br>在实际开发中,每一个本地分支都应该存在一个与远程分支的对应关系。</p>
<p>git fetch fetch 不会对本地仓库内容进行更新<br>git merge 真正的更新本地仓库的内容<br>git pull = git fetch + git merge</p>
<p>A 把本地库 push 远程库中<br>B clone 远程库 到本地 使用 push 提交<br>A 需要pull 把远程的代码变化下载到本地</p>
<h1 id="git-remote"><a href="#git-remote" class="headerlink" title="git remote"></a>git remote</h1><p>添加新的仓库<br>git remote add origin2 <a href="https://github.com/xxx.git">https://github.com/xxx.git</a></p>
]]></content>
</entry>
</search>