• 【2018-2019-1】20165223-20165218 实验二 固件程序设计



    小组成员:20165223 ,20165218

    实验名称:固件程序设计


    目录


    一、实验内容

    二、实验总结


    一、实验内容


    任务一:固件程序设计-1-MDK

    (一)实验要求

    0.注意不经老师允许不准烧写自己修改的代码
    1.三人一组
    2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.1-1.5安装MDK,ULink驱动

    注意:要用系统管理员身分运行uVision4,破解MDK(破解程序中target一定选ARM)

    3.提交破解程序中产生LIC的截图
    4.提交破解成功的截图

    (二)实验步骤

    • 1.安装MDK4.74

    • 2.安装ULink驱动

    • 3.运行UV4

    • 4.按实验指导步骤用注册机产生LIC

    • 5.按实验指导步骤破解MDK

    返回目录


    任务二:固件程序设计-2-LED

    (一)实验要求

    0.注意不经老师允许不准烧写自己修改的代码
    1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
    2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.9”完成LED实验,提交运行结果截图

    注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

    3.实验报告中分析代码

    (二)实验步骤

    (1)向KEIL-MDK 中添加 Z32 SC-000 芯片库

    • 1.安装SC-000 库

    • 2.建立新工程时使用SC-000

    • 3.确定cpu型号时选SC-000

    • 4.成功搭建Z32工程基础环境截图

    • 打开Part2-Z32-安全/实验1-LED闪烁/Z32HUA.uvproj,编译LED工程,产生bin文件

    (2)将程序下载到Z32实验箱上,观察结果

    • 1.用USB下载线连接电脑与实验箱,按住reboot键连开Z32两次开关,连接设备

    • 2.下载代码

    • 3.关掉Z32电源再打开,程序自动运行,观察结果

    (3)实验结果

    关闭Z32电源开关,再打开,程序自动运行,Z32核心板上L2灯(上方的红灯)持续闪烁,实验成功。

    (三)代码分析

    (1)实验代码及注释

    • 完整代码:LED.cpp

    • 主要代码:

    int main(void)
    {
    	SystemInit ();
    	if(0 == GPIO_GetVal(0))
    	{
    		BtApiBack(0x55555555, 0xAAAAAAAA);
    	}
    	GPIO_PuPdSel(0,0);            //设置 GPIO0 为上拉
    	GPIO_InOutSet(0,0);            //设置 GPIO0 为输出
    	while(1)
    	{
    		delay(100);
    		GPIO_SetVal(0,0);        //输出低电平,点亮 LED
    		delay(100);
    		GPIO_SetVal(0,1);	      //输出高电平,熄灭 LED
    	}
    }
    
    

    (2)细节分析

    1.SystemInit ():系统初始化,设置中断向量,使能所有中断;
    2.if(0 == GPIO_GetVal(0)):判断按键,返回 boot 条件,进行程序下载;
    3.GPIO0:设置其状态为上拉输出;
    4.while循环:进入循环程序,delay(100)设置LED 灯间隔 100ms 持续闪烁;
    5.delay延时函数:当系统时钟为内部 OSC 时钟时,延时 1ms。

    返回目录


    任务三:固件程序设计-3-UART

    (一)实验要求

    0.注意不经老师允许不准烧写自己修改的代码
    1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
    2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.0”完成UART发送与中断接收实验,提交运行结果截图

    注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

    3.实验报告中分析代码

    (二)实验步骤

    (1)下载程序到Z32并运行

    • 1.同任务二一样先用USB下载线连接设备并下载程序

    • 2.用9针串口线将Z32模块的串口与电脑USB接口连接

    • 3.打开串口调试助手(sscom),设置各个参数,观察串口通信收发的数据

      • 选择Z32对应串口(COM6)
      • 选择波特率为115200
      • 选择校验位为Even
      • 勾选“发送新行”
      • 点击“打开串口”
    • 4.串口调试助手中看到收发信息

    (2)实验结果

    关闭Z32电源开关,再打开,程序自动运行,可以在串口调试助手看到如下实验现象:显示“A Welcome to Z32HUA! 1234567890 0xAA”,证明PC机串口已经接收到Z32串口发送来的信息。在串口调试助手的字符串输入框输入字符串“abcdefg”,点击发送按钮,可以看到串口调试助手接收到我们发送输入的字符串“abcdefg”,并显示在串口助手上。实验成功。

    (三)代码分析

    (1)实验代码及注释

    • 完整代码:UART.cpp

    • 主要代码:

    int main(void)
    {
    	SystemInit ();
    	if(0 == GPIO_GetVal(0))
    	{
    		BtApiBack(0x55555555, 0xAAAAAAAA);
    	}
    	UART_Init();    //初始化Uart
    	UART_SendByte('A');                                           //Uart发送一个字符A
    	UART_SendByte('
    ');UART_SendByte('
    ');        //换行
    	UART_SendString("Welcome to Z32HUA!");       //Uart发送字符串
    	UART_SendByte('
    ');UART_SendByte('
    ');        //换行
    	UART_SendNum(1234567890);                          //Uart发送一个十进制数
    	UART_SendByte('
    ');UART_SendByte('
    ');        //换行
    	UART_SendHex(0xAA);                                       //Uart发送一个十六进制数
    	UART_SendByte('
    ');UART_SendByte('
    ');        //换行
    	while(1)
    	{
    		if(uart_rx_end)
    		{
    			uart_rx_end=0;
    			uart_SendString(shuju,shuju_lens);
    		}
    	}        //等待接收中断。
    }
    
    

    (2)细节分析

    1.SystemInit ():系统初始化,中断设置,使能所有中断;
    2.if(0 == GPIO_GetVal(0)):判断按键,返回boot条件,确认是否进行程序下载;
    3.UART_Init():初始化Uart,使能Uart接口,配置Uart中断并使能;
    4.PC机串口向Z32串口逐行发送:单个字符“A”,字符串“Welcome to Z32HUA!”,十进制数字串“1234567890”,16进制数“0xAA”;
    5.while循环:进入循环程序,等待串口中断到来并判断数据是否接收完毕,若中断到来,转入执行串口中断服务程序,待接收数据完毕,Z32将数据发回串口助手。
    6.delay延时函数:当系统时钟为内部 OSC 时钟时,延时 1ms。

    返回目录


    任务四:固件程序设计-4-国密算法

    (一)实验要求

    0.网上搜集国密算法标准SM1,SM2,SM3,SM4
    1.网上找一下相应的代码和标准测试代码,在Ubuntu中分别用gcc和gcc-arm编译
    2.四个算法的用途?
    3.《密码学》课程中分别有哪些对应的算法?
    4.提交2,3两个问题的答案
    5.提交在Ubuntu中运行国密算法测试程序的截图

    (二)实验步骤

    • 1.网上搜集国密算法标准SM1、SM2、SM3、SM4,回答实验要求中T2和T3提问
    // T2:四个算法的用途?
    答:
           SM1为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
           SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。
           SM3为消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
           SM4为无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
    
    // T3:《密码学》课程中分别有哪些对应的算法?
    答:
           SM1对应AES算法;
           SM2对应ECC算法;
           SM3对应MD5算法;
           SM4对应3DES算法。
    
    
    • 2.网上找一下相应的代码和标准测试代码,在Ubuntu中分别用gcc和gcc-arm编译
    • 3.提交在Ubuntu中运行国密算法测试程序的截图

    (三)代码分析

    实验代码及注释分析(点击链接查看)

    (1)SM1未公开,无代码

    (2)SM2.cSM2test.c

    (3)SM3.cSM3test.c

    (4)SM4.cSM4test.c

    返回目录


    任务五:固件程序设计-5-SM1

    (一)实验要求

    0.注意不经老师允许不准烧写自己修改的代码
    1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
    2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.16”完成SM1加密实验,提交运行结果截图

    注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

    3.实验报告中分析代码

    (二)实验步骤

    (1)将程序下载到Z32并运行

    • 1.先用USB下载线连接设备并下载程序

    • 2.用9针串口线将Z32模块的串口与电脑USB接口连接

    • 3.打开串口助手,设置参数

      • 选择Z32对应串口(COM6)
      • 选择波特率为115200
      • 选择校验位为Even
      • 点击“打开串口”
    • 4.关闭电源,再打开,程序自动运行。

    (2)实验箱上的操作

    • 1.此时,显示屏显示:“SLE4428实验!请插入IC卡...”

    • 2.插入SLE4428 IC卡,显示屏显示:“已插入SLE4428 用户代码为:D27600000400”

    • 3.按下矩阵键盘的A键,显示屏显示:“按-A键校验密码 校验0xFF,0xFF”

    • 4.按照显示屏提示,按下矩阵键盘的A键,显示屏接着显示:“校验成功 剩余机会:8次”

    • 5.再次按下矩阵键盘的A键,进入加解密实验,显示屏显示:“加密解密实验 1.加密 2.解密”

    • 6.按下矩阵键盘的1键,进行加密,此时显示屏上显示:“看串口调试助手 A键确认加密”,观察串口助手看到加密结果

    • 7.按下矩阵键盘的A键确认加密,显示屏显示:“加密完成 A键存入IC卡”,观察串口助手也显示“已将数据写入IC卡”

    • 8.再按A键屏幕回到步骤5中加解密实验界面

    • 9.额外将解密部分也运行了一下,串口助手的截图如下

    (三)代码分析

    (1)实验代码及注释

    //主函数
    int main(void)
    {
    	SystemInit ();
    	if(0 == GPIO_GetVal(0))
    	{
    		BtApiBack(0x55555555, 0xAAAAAAAA);
    	}
    	/*初始化IC卡插入检测IO口GPIO6*/
    	GPIO_Config(6);		
    	GPIO_PuPdSel(6,0);	//上拉
    	GPIO_InOutSet(6,1);	//输入	   
    	UART_Init();
    	lcd_init();
    	KEY_Init();
    	lcd_pos(0,0);//定位第一行
    	lcd_string("SLE4428 实验!");
    //A段程序
    A:	while(1)
    	{
    		lcd_pos(1,0);//定位第二行
    		lcd_string("请插入IC卡.  ");
    		delay(1000);
    		if(GPIO_GetVal(6)==0) break;
    		
    		lcd_pos(1,0);//定位第二行
    		lcd_string("请插入IC卡.. ");
    		delay(1000);
    		if(GPIO_GetVal(6)==0) break;
    		
    		lcd_pos(1,0);//定位第二行
    		lcd_string("请插入IC卡...");
    		delay(1000);
    		if(GPIO_GetVal(6)==0) break;
    		
    	}
    	if(SLE4428_InitAndRST(2)!=0xFFFFFFFF)  //收到ATR
    	{
    		lcd_pos(1,0);//定位第二行
    		lcd_string("已插入SLE4428");
    	}
    	else
    	{
    		lcd_pos(1,0);//定位第二行
    		lcd_string("卡不正确     ");
    		SLE4428_Deactivation();	//下电,去激活
    		delay(1000);
    		goto A;	
    	}
    	lcd_pos(2,0);//定位第三行
    	lcd_string("用户代码为:");
    	SLE4428_ReadData(0x15,UserCode,6); //读取用户代码
    	lcd_pos(3,0);//定位第四行
    	for(UINT8 i=0;i<6;i++)
    		lcd_Hex(UserCode[i]) ;
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	lcd_wcmd(0x01);//清屏
    	lcd_pos(0,0);//定位第一行
    	lcd_string("按-A键校验密码");
    	lcd_pos(1,0);//定位第二行
    	lcd_string("校验0xFF,0xFF");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	lcd_pos(2,0);//定位第三行
    	if(SLE4428_PassWord(0xFF,0xFF)==1)	  
    		lcd_string("校验成功");
    	else
    		{lcd_string("校验失败"); return 0;}
    
    	lcd_pos(3,0);//定位第四行
    	switch(SLE4428_ReadByte(0x03fd))   //查看剩余密码验证机会
    	{
    		case 0xff: lcd_string("剩余机会: 8次");break;
    		case 0x7f: lcd_string("剩余机会: 7次");break;
    		case 0x3f: lcd_string("剩余机会: 6次");break;
    		case 0x1f: lcd_string("剩余机会: 5次");break;
    		case 0x0f: lcd_string("剩余机会: 4次");break;
    		case 0x07: lcd_string("剩余机会: 3次");break;
    		case 0x03: lcd_string("剩余机会: 2次");break;
    		case 0x01: lcd_string("剩余机会: 1次");break;
    		case 0x00: lcd_string("剩余机会: 0次");break;
    		default: break;
    	}
    	while(KEY_ReadValue()!='A'); //等待A键按下
    //B段程序
    B:	lcd_wcmd(0x01);//清屏
    	lcd_pos(0,0);//定位第一行
    	lcd_string("加密解密实验");
    	lcd_pos(1,0);//定位第二行
    	lcd_string("1.加密");
    	lcd_pos(2,0);//定位第三行
    	lcd_string("2.解密");
    	do
    	{
    		C=KEY_ReadValue();
    	}
    	while(C!='1'&&C!='2'); //等待1或2键按下
    	lcd_wcmd(0x01);//清屏
    	if(C=='1')	goto jiami;
    	else if(C=='2')	goto jiemi;
    	else ;
    //加密程序
    jiami:
    	lcd_pos(0,0);//定位第一行
    	lcd_string("观看串口调试助手");
    	lcd_pos(1,0);//定位第二行
    	lcd_string("A 键确认加密");
    	UART_SendString("将加密以下数据:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiamiqian[i]);
    	}
    	UART_SendString("
    ");
    	UART_SendString("加密密钥:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiamimiyue[i]);
    	}
    	UART_SendString("
    ");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    
    	SM1_Init(jiamimiyue);		 //SM1初始化
    	SM1_Crypto(jiamiqian, 16, 0, 0, 0,jiamihou); //进行加密
    	SM1_Close(); //关闭安全模块
    	UART_SendString("加密后的数据:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiamihou[i]);
    	}
    	UART_SendString("
    ");
    	lcd_pos(2,0);//定位第三行
    	lcd_string("加密完成");
    	lcd_pos(3,0);//定位第四行
    	lcd_string("A 键存入IC卡");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	for(UINT8 i=0;i<16;i++)
    	{
    		SLE4428_Write_Byte(0x20+i,jiamihou[i]);	//设置IC卡 0x20地址为存储加密数据的地址
    	}
    	UART_SendString("已将数据写入IC卡。
    ");
    	UART_SendString("
    ");
    	goto B;
    //解密程序
    jiemi:
    	lcd_pos(0,0);//定位第一行
    	lcd_string("观看串口调试助手");
    	lcd_pos(1,0);//定位第二行
    	lcd_string(" A键读取IC卡数据");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	SLE4428_ReadData(0x20,jiemiqian,16);
    	UART_SendString("读取的数据为:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiemiqian[i]);
    	}
    	UART_SendString("
    ");
    	lcd_wcmd(0x01);//清屏
    	lcd_pos(0,0);//定位第一行
    	lcd_string("读取成功");
    	lcd_pos(1,0);//定位第二行
    	lcd_string("选择密钥解密:");
    	lcd_pos(2,0);//定位第三行
    	lcd_string("1.正确密钥");
    	lcd_pos(3,0);//定位第四行
    	lcd_string("2.错误密钥");
    	do
    	{
    		C=KEY_ReadValue();
    	}
    	while(C!='1'&&C!='2'); //等待1或2键按下
    	lcd_wcmd(0x01);//清屏
    	if(C=='1')	
    	{
    	for(UINT8 i=0;i<16;i++)
    		jiemimiyue[i] = jiamimiyue[i];	
    	}
    	else if(C=='2')
    	{
    	for(UINT8 i=0;i<16;i++)
    		jiemimiyue[i] = cuowumiyue[i];
    	}
    	else ;
    	UART_SendString("将使用以下密钥进行解密:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiemimiyue[i]);
    	}
    	UART_SendString("
    ");
    	lcd_pos(0,0);//定位第一行
    	lcd_string("A 键确认解密");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	SM1_Init(jiemimiyue);		 //SM1初始化
    	SM1_Crypto(jiemiqian, 16, 1, 0, 0,jiemihou); //进行解密
    	SM1_Close(); //关闭安全模块
    	lcd_pos(1,0);//定位第二行
    	lcd_string("解密完成");
    	lcd_pos(2,0);//定位第三行
    	lcd_string("A 键返回");
    	UART_SendString("解密后的数据为:
    ");
    	for(UINT8 i=0;i<16;i++)
    	{
    		UART_SendHex(jiemihou[i]);
    	}
    	UART_SendString("
    ");
    	UART_SendString("
    ");
    	while(KEY_ReadValue()!='A'); //等待A键按下
    	goto B;
    	SLE4428_Deactivation();	//下电,去激活,实验结束
    	while(1)
    	{
    
    	}
    }
    
    

    (2)细节分析

    • 主函数:
    1.SystemInit ():系统初始化,中断设置,使能所有中断;
    2.if(0 == GPIO_GetVal(0)):判断按键,返回boot条件,确认是否进行程序下载;
    3.GPIO_Config(6):初始化IC卡插入检测端口GPIO6;
    4.GPIO:将GPIO设为上拉输入;
    5.UART_Init()、cd_init()、KEY_Init():串口初始化;LCD12864初始化;矩阵键盘初始化;
    6.lcd_pos(x,0):用于定位显示屏上第x+1行(例 lcd_pos(1,0),定位第二行);
    7.lcd_string("xxxxxxx"):显示屏上显示的内容。
    
    
    • A段程序(A):
    //if-else 结构:判断是否收到ATR(矩阵键盘按下A键),是则继续,否则执行else部分
    
    1.第二行显示“请插入IC卡”,等待卡片插入;
    2.SLE4428 IC卡正确插入,第二行显示“已插入SLE4428”,卡片插入错误则第二行显示“卡不正确     ”;
    3.IC卡正确插入,则显示“用户代码为:XXXXXXXXXX”(XXXXXXXXXX代表用户的代码),等待按下键盘的“A”键;
    4.按下“A”键,显示屏第一行显示“按-A键校验密码”,第二行显示“校验0xFF,0xFF”,等待“A”键按下。
    5.按下“A”键,若校验密码正确,显示屏第三行显示“校验成功”,否则显示“校验失败”,第四行显示剩余密码验证机会次数“剩余机会: X次”(X初始最大为8,最小0,当校验密码错误验证一次后,X减1),等待“A”键按下。
    
    
    • B段程序(B):
    1.按下“A”键,显示屏第一行显示“加密解密试验”,第二、三行分别显示“1.加密”、“2.解密”两个选项。
    2.等待按键按下:如果“1”按下,跳转至加密程序段,如果“2”按下,跳转至解密程序段;
    
    
    • 加密程序段(jiami):
    1.第一行显示“观看串口调试助手”,第二行显示“A键确认加密”,通过串口发送字符串“将加密以下数据:”并将加密前的数据发送至PC机,发送换行,串口继续发送“加密密钥:”并将加密密钥数组发送至PC机,发送完毕等待“A”键按下;
    2.按下“A”键后,SM1初始化;
    3.进行SM1加密;
    4.关闭SM1加密安全模块;
    5.通过串口发送字符串“加密后的数据:”并将加密后的数据发送至PC机,换行,在液晶屏第三行显示“加密完成”,第四行显示“A键存入IC卡”,等待“A”键按下。当“A”键按下后,向SLE4428 IC卡加密后的数据,通过串口向PC发送“已将数据写入IC卡。”跳转至B段程序。
    
    
    • 解密程序段(jiemi):
    1.屏幕第一行显示“观看串口调试助手”,第二行显示“A键读取IC卡数据”,当“A”键按下,读取SLE4428 IC卡解密前数据,通过串口发送“读取的数据为:”至PC机并发送解密前的数据至PC机。在显示屏的四行分别显示“读取成功”,“选择密钥解密”,“1.正确密钥”,“错误密钥”,等待按键“1”或“2”按下。如果“1”按下,解密密钥为正确的密钥,“2”按下,解密密钥为错误的密钥,然后通过串口发送“将使用以下密钥进行解密:”并将相应的解密密钥数据发送至PC机。发送完毕,第一行显示“A键确认解密”,等待“A”键按下。
    2.按下“A”键后,SM1初始化;
    3.进行SM1解密;
    4.关闭SM1解密安全模块;
    5.显示屏第二行显示“解密完成”,第三行显示“A键返回”,通过串口将“解密后的数据为:”和解密后的数据发送至PC机,发送完毕等待“A”键按下,若“A”键按下,跳转至B段程序。
    6.断电,去除IC卡激活,实验结束。
    
    

    返回目录


    二、实验总结


    (一)遇到的问题

    (1)任务一,在破解MDK时遇到如下问题:

    • 直接打开uVision4后,点File>>License Management,报错如下

    • 点击确定后却仍能进入到License Management中,于是按照实验指导步骤复制CID,再运行keil-MDK注册机,粘贴CID并选择ARM,点击generate生成LIC

    • 将生成的LIC复制回License Management下方的LIC空格中,点击Add LIC,报错如下

    解决方法:

    • 上网搜索后发现原因是没有以管理员的身份打开uVision4,重新用管理员身份打开UV4后一路无报错,最终成功完成破解

    (2)任务四,在编译运行SM2test.c测试代码时遇到如下报错:

    解决方法:

    • 再次编译运行即可

    (二)分析与总结

    • 经过上一次实验,我和队友已经对Z32实验箱有了基本的认识,因此本次实验在环境设置方面没有遇到什么障碍。
    • 在将代码从本机下载到实验箱的过程中有遇到难题,即用USB连接好后,无论如何都无法连接上设备,后来发现在按住reboot键后打开关闭开关一次的时候已经连接上了,可能是实验箱的原因(?)
    • 实验时在任务四中耗时最长,除了在网上搜索代码花了很长时间以外,测试代码的运行也让人头痛了很久,最终还是成功编译运行了这几个算法。
    • 实验时间虽短,但前期的准备工作是必不可少的,实验之前我和队友就已经将各个任务都捋了一遍,以便真正在实验室中能顺利完成实验,最终也还完成的较成功,这与两个人的努力是分不开的。希望下次实验也能顺利完成。

    (三)参考资料

    1. STM32使用MDK5时遇到TOOLS.INI: TOOLCHAIN NOT INSTALLED 及破解方法
    2. 关于国密算法 SM1,SM2,SM3,SM4 的笔记
    3. 信息安全实验箱指导书

    返回目录

  • 相关阅读:
    安装Oracle时出现环境变量Path的值大于1023的解决办法
    JavaScript通过元素id和name直接获取元素的方法
    [转载]T-SQL(Oracle)语句查询执行顺序
    [转载]T-SQL(MSSQL)语句查询执行顺序
    HTML5权威指南 17.其他API
    HTML5权威指南 16.拖放API与通知API
    HTML5权威指南 15.获取地理位置信息
    HTML5权威指南 14.使用Web Workers处理线程
    HTML5权威指南 13.扩展的XMLHttpRequest API
    HTML5权威指南 12.WebRTC通信
  • 原文地址:https://www.cnblogs.com/moddy13162201/p/9881983.html
Copyright © 2020-2023  润新知