本章目标 
    了解S3C2410/S3C2440的时钟体系结构
    掌握通过设置MPLL改变系统时钟的方法
    掌握在不同的频率下设置存储控制器的方法

    掌握PWM定时器的用法
    了解WATCHDOG定时器的用法
10.1 时钟体系及各类时钟部件
10.1.1 S3C2410/S3C2440时钟系统
    S3C2410/S3C2440的时钟控制逻辑既可以外接晶振,然后通过内部电路产生时钟源;也
可以直接使用外部提供的时钟源,它们通过引脚的设置来选择。时钟控制逻辑给整个芯片提
供3种时钟:FCLK用于CPU核;HCLK用于AHB总线上的设备,比如CPU核、存储控制器、
中断控制器、LCD控制器、DMA和USB主机模块等;PCLK用于APB总线上的设备,比如
WATCHDOG、IIS、I2C、PWM定时器、MMC接口、ADC、UART、GPIO、RTC和SPI。
    为了降低电磁干扰、降低板间布线的要求,S3C2410/S3C2440外接的晶振频率通常很低,
本开发板上为12MHz,需要通过时钟控制逻辑的PLL提高系统时钟。
    S3C2410/S3C2440有两个PLL:MPLL和UPLL。UPLL专用于USB设备,MPLL用于设置
FCLK、HCLK、PCLK。它们的设置相似,本书以MPLL为例。
    上电时,PLL没被启动,FCLK即等于外部输入时钟,称为Fin。
    若要提高系统时钟,需要开启PLL。
    PLL设置过程如下所示,请参考图10.1,跟随FCLK的图像了解启动过程。
    (1)上电几毫秒后,晶振输出稳定,FCLK = Fin(晶振频率),nRESET信号恢复高电平后,
CPU开始执行命令。
    (2)可以在程序开头启动MPLL,设置MPLL的几个寄存器后,需要等待一段时间(Lock Time),
MPLL输出才稳定。在这段时间(Lock Time)内,FCLK停振,CPU停止工作。Lock Time的长短由
寄存器LOCKTIME设定。
    (3)Lock Time之后,MPLL输出正常,CPU工作在新的FCLK之下。
    FCLK、HCLK和PCLK的比例是可以改变的,设置它们三者的比例,启动MPLL只需要设置3个
寄存器(对于S3C2440的一些时钟比例,还需要额外设置一个寄存器)。
    【1】LOCKTIME寄存器(LOCK TIME COUNT):用于设置“Lock Time”的长度。
    前面说过,MPLL启动后需要等待一段时间,使得其输出稳定。S3C2410中,位[23:12]用于UPLL,
位[11:0]用于MPLL。S3C2440中,位[31:16]用于UPLL,位[15:0]用于MPLL。一般而言,使用它的
默认值即可,S3C2410中默认值为0x00FF FFFF,S3C2440中默认值为0xFFFF FFFF。
    【2】MPLLCON寄存器(Main PLL Control):用于设置FCLK与Fin的倍数。
    位[19:12]的值称为MDIV,位[9:4]的值称为PDIV,位[1:0]的值称为SDIV。FCLK与Fin的关系
有如下计算公式:
    ① 对于S3C2410: MPLL(FCLK) = (     m * Fin) / (p * 2^s)
    ② 对于S3C2440: MPLL(FCLK) = (2 * m * Fin) / (p * 2^s)
    其中:m = MDIV + 8,p = PDIV + 2,s = SDIV。
    当设置MPLLCON之后——相当于图10.1中的“首先使用软件设置PLL”,Lock Time就被自动插入。
Lock Time之后,MPLL输出稳定,CPU工作在新的FCLK下。
    【3】CLKDIVN寄存器(CLOCK DIVIDER CONTROL):用于设置FCLK、HCLK、PCLK三者的比例。
    对于S3C2410、S3C2440,这个寄存器表现稍有不同,请参考表10.1和图10.2.

     对于S3C2440的一些时钟比例,还需要额外的设置一个寄存器CAMDIVN。图10.2中,
HDIVN为CLKDIVN寄存器为位[2:1],PDIVN为位[0];HCLK4_HALF、HCLK3_HALF分
别为CAMDIVN寄存器的位[9]、[8]。各种时钟对比对应的寄存器设置如图10.2所示。

对于S3C2410,HDIVN是CLKDIVN寄存器的位[1];

     对于S3C2440,HDIVN是CLKDIVN寄存器的位[2:1],如果HDIVN非0,CPU的总线模式
应该从“fast bus mode”变为“asynchronous bus mode”,这可以通过如下指令来完成:
# MMU_SetAsyncBusMode
mrc p15, , r0, c1, c0,
orr r0, r0, #R1_nF:OR:RL_iA
mcr p15, , r0, c1, c0,
    其中的“R1_nF:OR:R1_iA”等于0xC000 0000。如果HDIVN非0时,而CPU的总线模式仍是
“fast bus mode”,则CPU的工作频率将自动变为HCLK,而不再是FCLK。
10.1.2 PWM定时器
    S3C2410/S3C2440的定时器部件完全一样,共有5个16位定时器。其中定时器0、1、2、3
有PWM功能;定时器4没有输出引脚。
    定时器部件的时钟源为PCLK,首先通过两个8位的预分频器降低频率:定时器0、1共用第
一个预分频器,定时器2、3、4共用第二个预分频器。预分频器的输出将进入第二部分分频器,
它们输出5种频率的时钟:2分频、4分频、8分频、16分频或者外部时钟TCLK0/TCLK1。每个
定时器的工作时钟可以从这5种频率中选择。
    这两个预分频都可以通过TCFG0寄存器来设置,每个定时器工作在哪种频率下也可以通过
TCFG1寄存器来选择。如图10.3所示,形象地说明定时器的结构。
 
                                            图10.3 定时器结构图
     上面只是确定了定时器的工作频率,至于定时器如何工作还得了解其内部结构,如图
10.4所示。
     
    定时器内部控制逻辑的工作流程如下:
    (1)程序初始,设定TCMPBn、TCNTBn这两个寄存器,它们表示定时器n的比较值、
初始计数值。

    (2)随之设置TCON寄存器启动定时器n,这时,TCMPBn、TCNTBn的值将被装入其
内部寄存器TCMPn、TCNTn中。在定时器n的工作频率下,TCNTn开始减1计数,其值可
以通过读取TCNTOn寄存器得知。 
    (3)当TCNTn的值等于TCMPn的值时,定时器n的输出管脚TOUTn反转;TCNTn继续
减1计数。
    (4)当TCNTn的值达到0时,其输出管脚TOUTn再次反转,并触发定时器n的中断(如果

 
中断使能了的话)。
    (5)当TCNTn的值达到0时,如果TCON寄存器中将定时器n设为“自动加载”,则TCMPB0
和TCNTB0寄存器的值将被自动装入TCMP0和TCNT0寄存器中,下一个计数流程开始。
    定时器n的输出管脚TOUTn初始状态为高电平,以后在TCNTn的值等于TCMPn的值、
TCNTn的值时反转。也可以通过TCON寄存器设置其初始电平,这样TOUTn的输出就完全
反相了。通过设置TCMPBn、TCNTBn的值可以设置管脚TOUTn输出信号的占空比,这就
是所谓的PWM,所以这些定时器又被称为PWM定时器。
    下面讲解定时器时寄存器的使用方法。
    (1)TCFG0寄存器(TIMER CONFIGURATION)
    位[7:0]、位[15:8]分别被用于控制预分频器0、1,它们的值为0~255。经过预分频器出来
的时钟频率为:PCLK/{prescaler value + 1}。
    (2)TCFG1寄存器
    经过预分频器得到的时钟将被2、4、8、16分频,除了这4种频率外,额外的,定时器0、1
还可以工作在外接的TCLK0时钟下,定时器2、3、4还可以工作在外接的TCLK1时钟下。
    通过TCFG1寄存器来设置这5个定时器,分别工作于这5个频率中哪一个下,如表10.2所示。
    
    这样,定时器n的工作频率或者外接的TCLK0或TCLK1可以通过这个公式计算:
        定时器工作频率 = PCLK / {prescaler value +1} / {divider value}
        {prescaler value} = 0~255
        {divider value}    = 2、4、8、16
    (3)TCNTBn/TCMPBn寄存器(COUNT BUFFER REGISTER & COMPARE BUFFER REGISTER)。
    n为0~4,这两个寄存器都只用到位[15:0],TCNTBn中保存定时器的初始值,TCMPBn
中保存比较值。它们的值在启动定时器时,被传到定时器内部寄存器TCNTn、TCMPn中。
    没有TCMPB4,因为定时器4没有输出管脚。
    (4)TCNTOn寄存器(COUNT OBSERVATION)
    n为0~4,定时器n被启动后,内部寄存器TCNTn在其工作时钟下不断减1计数,可以通过
读取TCNTOn寄存器得知其值。
    (5)TCON寄存器(TIMER CONTROL)
    它有以下4个作用:
    ① 第一次启动定时器时,手动将TCNTBn/TCMPBn寄存器中的数据装入内部寄存器
TCNTn、TCMPn中。
    ② 启动、停止定时器。
    ③决定在定时器计数到达0时,是否自动将TCNTBn/TCMPBn寄存器的值装入内部
寄存器TCNTn、TCMPn中。
    ④ 决定定时器的管脚TOUTn的输出电平是否反转、
    TCON寄存器位[3:0]、位[11:8]、位[15:12]、位[19:16]、位[22:20]分别用于定时器0~4。
除了定时器因为没有输出引脚在没有“输出反转”位外,其他位的功能相似。表10.3以定时器
0为例说明这些位的作用。
    

     在第一次使用定时器时,需要设置“手动更新”位为1,以使TCNTBn/TCMPBn寄存器的
值装入内部寄存器TCNTn、TCMPn中。下一次如果还要设置这一位,需要先将它清0。
    定时器还有其他功能,比如DMA、Dead zone等,需要了解的读者清参考数据手册。
寄存器中涉及它们的部分这里就省略了。

10.1.3 WATCHDOG定时器

    WATCHDOG定时器可以像一般16位定时器一样用于产生周期性中断,也可以用于发
出复位信号以重启失常的系统。它与PWM定时器的结构类似,如图10.5所示。

     同样,WATCHDOG定时器的8位分频器将PCLK分频后,被再次分频得到4种频率:
16、32、64、128分频,WATCHDOG定时器可以选择工作在哪种频率之下。WTCNT
寄存器按照其工作频率减1计数,当达到0时,可以产生中断信号,可以输出复位信号。
在第一次使用WATCHDOG定时器时,需要向WTCNT寄存器中写入初始计数值,以后
在计数值达到0时,自动从WATDAT寄存器中寄存器中装入,重新开始下一个计数周期。
    使用WATCHDOG定时器的“WATCHDOG功能”时,在正常的程序中,必须不断重新
设置WTCNT寄存器使得它不为0,这样可以保证系统不被重启,这称为喂狗。
    WATCHDOG定时器所涉及的寄存器如下:
    (1)WTCON寄存器(WATCHDOG TIMER CONTROL)
    用于设置预分频系数,选择工作频率,决定是否使用中断、是否启用WATDOG功能(即
是否输出复位信号),各位的作用如表10.4所示。
    

     与PWM定时器相似,WATDOG定时器的工作频率通过这个公式计算:
    WATDOG定时器工作频率 = PCLK / {prescaler value + 1} / {divider value}

{prescaler value} = 0~255;{divider value} = 16、32、64、128

    (2)WTDAT寄存器(WATCHDOG TIMER DATA)。
    用于决定WATCHDOG定时器的超时周期,在定时器启动后,当计数达到0时,WTDAT
寄存器的值会自动传入WTCNT寄存器。不过,第一次启动WATDOG定时器时,WTDAT
寄存器的值会自动传入WTCNT寄存器。
    (3)WTCNT寄存器(WATCHDOG TIMER COUNT)。
    在启动WATDOG定时器前,必须往这个寄存器写入初始值。启动定时器后,它减1计数,
当计数值到达0时:
    如果中断被使能的话发出中断;
    如果WATCHDOG功能被使能的话,发出复位信号,装载WTDAT寄存器的值并重新计数。
10.2 MPLL和定时器操作实例
10.2.1 程序设计
    本实例讲解MPLL、定时器的使用。首先启动MPLL提高系统时钟,初始化存储控制器使
SDRAM工作在新的HCLK下,然后将定时器0设为0.5s产生一次中断,在中断程序中改变
LED的状态。
10.2.2 代码详解
    源码在/work/hardware/timer目录下。
    本实验的重点在4点:
    ① 设置/启动 MPLL;
    ② 根据HCLK设置存储控制器;
    ③ 初始化定时器0;
    ④ 初始化定时器中断。
    相关函数在init.c中。
1.设置/启动 MPLL
    clock_init函数用于设置MPLL,本开发板的输入时钟频率Fin为12MHz,将FCLK、HCLK、
PCLK分别设为200MHz、100MHz和50MHz,代码如下:
 行号
23行 #define s3c2410_MPLL_200MHz ((0x5c << 12) | (0x04 << 4) | (0x00)) /*MDIV = 0x5c, PDIV = 0x04, SDIV = 0*/
24行 #define s3c2440_MPLL_200MHz ((0x5c << 12) | (0x01 << 4) | (0x02))
25行 /*
26行 *对于MPLLCON寄存器,[19:12]为MDIV、[1:0]为SDIV
27行 *有如下公式:
28行 * s3c2410:MPLL(FCLK) = (m * Fin)/(p * 2^s)
29行 * s3c2440:MPLL(FCLK) = (2*m*Fin)/(p * 2^s)
30行 * 其中:m = MDIV + 8,p = PDIV +2, s = SDIV
31行 *对于本开发板,Fin = 12MHz
32行 *设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK = 1:2:4
33行 *FCLK = 200MHz,HCLK = 100MHz,PCLK = 50MHz
34行 */
35行 void clock_init(void)
36行 {
37行 //LOCKTIME = 0x00ff ffff //使用默认值即可
38行 CLKDIVN = 0x03; //FCLK:HCLK:PCLK = 1:2:4,HDIVN = 1, PDIVN = 1
39行
40行 /*如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode”*/
41行 __asm__(
42行 "mrc p15, 0, r1, c1, c0, 0\n" //读出控制寄存器
43行 "orr r1, r1, #0xc0000000\n" //设置为“asynchronous bus mode”
44行 "mcr p15, 0, r1, c1, c0, 0\n" //写入控制寄存器
45行 )
46行
47行 /*判断是s3c2410还是s3c2440*/
48行 if((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
49行 {
50行 MPLLCON = S3C2410_MPLL_200MHz; /*现在,FCLK = 200MHz,HCLK = 100MHz,PCLK = 50MHz*/
51行 }
52行 else
53行 {
54行 MPLLCON = S3C2440_MPLL_200MHz;
55行 }
56行 }
57行

init.c->clock_init.c()

    如果处理器是S3C2410,使用第50行设置MPLL寄存器,令MDIV = 0x5c,PDIV = 0x04, 
SDIV = 0,所以:
    MPLL(FCLK) = (m * Fin)/(p * ^s) = (0x5c + ) * 12MHz/((0x04 + )*^) = 200MHz
HCLK = FCLK/ = 100MHz
PCLK = FCLK/ = 50MHz
    如果处理器是S3C2440,使用第54行设置MPLL寄存器,使用第29行的公式可以计算
出MPLL = 200MHz,所以FCLK、HCLK、PCLK分别为200MHz、100MHz和50MHz。 
2.设置存储控制器
memsetup函数被用来设置存储控制器,代码如下:
 行号
58行/*
59行*设置存储控制器以使用SDRAM
60行*/
61行void memsetup(void)
62行{
63行 volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
64行
65行 /*这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值
66行 *写在数组中,是因为要生成位置无关代码,使得这个函数可以被复制到
67行 *SDRAM之前就可以在Steppingstone中运行
68行 */
69行 /*存储控制器13个寄存器的值*/
70行 p[] = 0x22011110; //BWSCON
71行 P[] = 0x00000700; //BANKCON0
72行 p[] = 0x00000700; //BANKCON1
73行 p[] = 0x00000700; //BANKCON2
74行 p[] = 0x00000700; //BANKCON3
75行 p[] = 0x00000700; //BANKCON4
76行 p[] = 0x00000700; //BANKCON5
77行 p[] = 0x00018005; //BANKCON6
78行 p[] = 0x00018005; //BANKCON7
79行
80行 /*REFRESH,
81行 *HCLK = 12MHz :0x008c 07a3
82行 *HCLK = 100MHz:0x008c 04f4
83行 */
84行 p[] = 0x008c04f4;
85行 p[] = 0x000000b1; //BANKSIZE
86行 p[] = 0x00000030; //MRSRB6
87行 p[] = 0x00000030; //MRSRB7
88行}
89行

init.c->memsetup()

    除REFRESH寄存器外,其他寄存器的值与第6章的实验程序一样。现在HCLK等于
100MHz,REFRESH寄存器的值需要重新计算。参考第6章的公式可以计算:
    R_CNT = 2^11 + 1 - 100MHz * 7.8125uS = 0x04F4,
    所以,REFRESH = 0x008c0000 + R_CNT = 0x008c04f4。
    在连接脚本timer.lds中,全部代码的起始运行地址都被设为0x3000 0000,但是在执行
memsetup函数时,代码还在内部SRAM(steppingston)中,为了能在此处运行这个函数,
它应该是位置无关的。
3.初始化定时器0
    timer0_init函数用于初始化定时器0,根据相关寄存器的格式并参考代码中的注释就可
以理解这个函数,代码如下:
 行号
124行/*
125行*Timer input clock Frequency = PCLK / (prescaler value + 1) / (divider value)
126行*(prescaler value) = 0~255
127行*(divider value) = 2、4、8、16
128行*本实验的Timer0的时钟频率 = 100MHz/(99 + 1)/(16) = 62500Hz
129行*设置Timer0 0.5s触发一次中断
130行*/
131行void timer0_init(void)
132行{
133行 TCFG0 = ; //预分频器 0 = 99
134行 TCFG1 = 0x03; //选择16分频
135行 TCNTB0 = ; //0.5s触发一次中断
136行 TCON |= ( << ); //手动更新
137行 TCON = 0x09; //自动加载,清除“手动更新”位,启动定时器0
138行}
139行

init.c->timer0_init()

4.定时器中断
    head.S中调用timer0_init函数之后,定时器开始工作;调用init_irq函数使能定时器0
中断、设置CPSR寄存器开启IRQ中断后,每当定时器0计数达到0时,就会触发中断。
init_irq函数很简单,在init.c中,代码如下:
行号
140行/*
141行*定时器0中断使能
142行*/
143行void init_irq(void)
144行{
145行 //定时器0中断使能
146行 INTMSK &= (~( << ));
147行}

init.c->init_irq()

    发生定时器中断时,CPU将调用其中断服务程序Timer0_Handler,它在interrupt.c中:
 行号
03行void Timer0_Handler(void)
04行{
05行 /*
06行 *每次中断令3个LED改变状态
07行 */
08行 if(INTOFFSET == )
09行 {
10行 GPFDAT = ~(GPFDAT & (0x7 << ));
11行 }
12行 //清除中断
13行 SRCPND = << INTOFFSET;
14行 INTPND = INTPND;
15行}

interrupt.c

    定时器0的中断使用SRCPND、INTPND寄存器中的位10来表示。中断服务程序
Timer0_Handler先判断是否定时器0的中断,若是则反转3个LED的状态。
10.2.3 实例测试
    在timer目录下执行make命令生成timer.bin可执行程序,烧入NAND Flash中执行,
即可看到3个LED每1s闪烁一次。
    将head.S中对clock_init函数的调用去掉,不启动MPLL;并随之将init.c中的
memsetup函数的REFRESH寄存器改为12MHz对应的0x008c 07a3.重新编译、烧写,
可以看到差不多8sLED闪烁一次。
附:代码:
链接: https://pan.baidu.com/s/1kV24a9L 密码: tfab

JZ2440 裸机驱动 第10章 系统时钟和定时器的更多相关文章

  1. JZ2440 裸机驱动 第11章 通用异步收发器UART

    本章目标: 了解UART原理: 掌握S3C2410/S3C2440中UART的使用 11.1 UART原理及UART内部使用方法 11.1.1 UART原理说明     UART用于传输串行数据:   ...

  2. JZ2440 裸机驱动 第13章 LCD控制器(1)

    本章目标  了解LCD显示器的接口及时序: 掌握S3C2410/S3C2440 LCD控制器的使用方法: 了解帧缓冲区的概念,掌握如何设置帧缓冲区来显示图像: 13.1 LCD和LCD控制器 13.1 ...

  3. JZ2440 裸机驱动 第14章 ADC和触摸屏接口

    本章目标:     了解S3C2410/S3C2440和触摸屏的结构:     了解电阻触摸屏的工作原理和等效电路图:     了解S3C2410/S3C2440触摸屏控制器的多种工作模式:     ...

  4. JZ2440 裸机驱动 第6章 存储控制器

    本章目标:     了解S3C2410/S3C2440地址空间的布局     掌握如何通过总线形式访问扩展的外设,比如内存.NOR Flash.网卡等 ························ ...

  5. JZ2440 裸机驱动 第12章 I2C接口

    本章目标: 了解I2C总线协议: 掌握S3C2410/S3C2440中I2C接口的使用方法: 12.1 I2C总线协议及硬件介绍 12.1.1 I2C总线协议 1 I2C总线的概念 2 I2C总线的信 ...

  6. JZ2440 裸机驱动 第8章 NAND Flash控制器

    本章目标  了解NAND Flash 芯片的接口 掌握通过NAND Flash控制器访问NAND Flash的方法 8.1 NAND Flash介绍和NAND Flash控制器使用     NAND ...

  7. JZ2440 裸机驱动 第7章 内存管理单元MMU

    本章目标:     了解虚拟地址和物理地址的关系:     掌握如何通过设置MMU来控制虚拟地址到物理地址的转化:     了解MMU的内存访问权限机制:     了解TLB.Cache.Write ...

  8. JZ2440 裸机驱动 第5章 GPIO接口

    本章目标:     掌握嵌入式开发的步骤:编程.编译.烧写程序.运行     通过GPIO的操作了解软件如何控制硬件 5.1 GPIO硬件介绍     S3C2440A有130个多功能输入/输出口引脚 ...

  9. JZ2440 裸机驱动 第9章 中断体系结构

    本章目标:     了解ARM体系CPU的7种工作模式     了解S3C2410/S3C2440中断体系结构     掌握S3C2410/S3C2440的中断服务程序的编写方法 9.1 S3C241 ...

随机推荐

  1. Oracle12cr1新特性之容器数据库(CDB)和可插拔数据库(PDB) 的启动和关闭

    Oracle12c中引入的多宿主选项(multitenant option)允许一个容器数据库容纳多个独立的可插拔数据库(PDB).本文将说明如何启动和关闭容器数据库(CDB)和可插拔数据库(PDB) ...

  2. Nginx在windows上安装 及 Nginx的配置及优化

    https://www.cnblogs.com/Chiler/p/8027167.html http://www.runoob.com/linux/nginx-install-setup.html 前 ...

  3. POJ 2488 DFS

    DES:给一个n行m列的棋盘.马以L型走.问能否从某一位置开始走完棋盘上的每个位置.若能继续输出字典序最小的一条路径. 很典型的dfs.搜的时候就按照字典序从小到大的顺序.搜到第一条路径时停止搜索输出 ...

  4. git push时候总提示输入账号密码,如何免除设置?

    1. 打开.ssh所在目录 home,即C:\Users\Administrator2. 在home中,进入git bash命令终端,创建.git-credentials文件,编辑 touch .gi ...

  5. Ubuntu中使用WPS

    ubunu系统下用WPS办公软件比较好,比较兼容MS office, ubuntu下WPS相关命令有:et,wps,wpp. 使用Ctrl+Alt+T打开命令端, "et"命令可以 ...

  6. 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water) (详解)

    倒水(Water) Description 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水 ...

  7. DevExpress v18.1新版亮点——WPF篇(二)

    用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WPF v18.1 的新功能,快来下载试用新版本!点击下载& ...

  8. Windows折腾之路 兼谈纯净强迫情节

    早期新鲜感 想当年,终于有了第一台属于自己自由处置的电脑,1.2Ghz的CPU,256兆的内存.这在CPU刚刚上1G的年代,不说顶级,也算主流.操作系统呢,在别人的帮助下,装上新鲜的XP,各种的华丽, ...

  9. win10下用u盘装centos后如何修复win10引导

    相关参考: http://www.cnblogs.com/xiaoyao-lxy/p/5561728.html#wu

  10. Android Studio打开React Native创建的项目

    1.点击 Import project 2.找到项目下android文件夹,选择build.gradle文件,open