2019-2020-1 20175208 20175218 20175230 实验二 固件程序设计

不想你离开。 提交于 2019-12-04 15:55:24

2019-2020-1 20175208 20175218 20175230 实验二 固件程序设计

一、实验内容

1、固件程序设计-1-MDK

  1. 注意不经老师允许不准烧写自己修改的代码
  2. 三人一组
  3. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.1-1.5安装MDK,JLink驱动,注意,要用系统管理员身分运行uVision4,破解MDK(破解程序中target一定选ARM)
  4. 提交破解程序中产生LIC的截图
  5. 提交破解成功的截图

2、固件程序设计-2-LED

  1. 注意不经老师允许不准烧写自己修改的代码
  2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
  3. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.9”完成LED实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
  4. 实验报告中分析代码

3、固件程序设计-3-UART

  1. 注意不经老师允许不准烧写自己修改的代码
  2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
  3. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.0”完成UART发送与中断接收实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
  4. 实验报告中分析代码

4、固件程序设计-4-国密算法

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

5、固件程序设计-5-SM1

  1. 注意不经老师允许不准烧写自己修改的代码
  2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
  3. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.16”完成SM1加密实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
  4. 实验报告中分析代码

6、固件程序设计-6-清理

  1. 实验结束后,把实验室原来的网线插回,否则以后做实验的同学无法开机
  2. 只有用实验室机器的小组做
  3. 提交你们小组使用的计算机的编号照片
  4. 提交插好网线的照片
  5. 提交盖好后盖的照片

二、实验小组成员及分工

  1. 成员列表
学号 姓名
20175208 张家华
20175218 陈敬勇
20175230 滕星
  1. 实验分工

实验内容:三人共同完成实验

撰写博客:陈敬勇

三、实验步骤

1、固件程序设计-1-MDK

  1. 参考信息安全系统实验箱指导书的第一章,1.1-1.5安装好MDK,JLink驱动

  1. 运行keil-MDK注册机破解MDK
  2. 破解程序中产生LIC的截图

  1. 破解成功的截图

2、开发化境的熟悉-目标机宿主机联通

  1. 安装sc000库,打开Z32文件夹下的软件资料,找到Support.exe文件,双击进行安装

  2. 安装完成后,运行keil uVision4,进行工程基础编程环境搭建。其中,芯片库选择 Generic SC000 Device Database。ARM 结构目录,选择 SC000。

  1. 打开“ Z32 开发指南 实验1-LED闪烁”目录的工程文件。双击打开Z32HUA.uvproj文件。点击编译,进行编译。

  1. 将实验箱接入电源,把笔记本电脑与实验箱连接好,在软件资料文件夹下的Z32下载调试工具中打开Z32下载调试工具 NZDownloadTool.exe 。打开实验箱的电源开关前,按住 Reboot 键不放,两次打开电源开关, Z32 即可被电脑识别,进行下载调试。

  2. 出现设备已连接,设备选择中显示芯片型号后,点击浏览,选择LED闪烁文件夹下bin文件夹中的Z32HUA.bin,最后点击下载。

  3. 关闭实验箱 Z32 的电源开关,再打开,程序自动运行,此时可以看到实验箱 Z32 核心板上 L2 灯开始闪烁。

  1. 代码分析

main 函数代码如下:

int main(void)
{
    /*********************此段代码勿动*********************/
    //系统中断向量设置,使能所有中断
    SystemInit();
        //返回 boot 条件
    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
    }
}
//延时函数,当系统时钟为内部延时函数,当系统时钟为内部OSC时钟时,延时1ms
void delay(int ms)
{
    int i;
    while(ms----)
    {
        for(i=0;i<950;i++) ;for(i=0;i<950;i++) ;
    }
}

主函数代码的执行过程为:

  • 系统初始化,中断设置,使能所有中断;
  • 判断按键,返回 boot 条件,确认是否进行程序下载;
  • 设置 GPIO0 状态为上拉输出;
  • 进入循环程序, LED 灯间隔 100ms 闪烁;

3、固件程序设计-3-UART

  1. Z32 SC-000 芯片库,安装截图

  1. 打开“ Z32 开发指南 实验 2 UART 发送与中断接收 ”,双击打开Z32HUA.uvproj文件。点击编译,进行编译。

  1. 保持上面实验电脑与实验箱的连接状态,在软件资料文件夹下的Z32下载调试工具中打开Z32下载调试工具 NZDownloadTool.exe 。打开实验箱的电源开关前,按住 Reboot 键不放,两次打开电源开关, Z32 即可被电脑识别,进行下载调试。
  2. 出现设备已连接,设备选择中显示芯片型号后,点击浏览,选择 UART 发送与中断接收文件夹下bin文件夹中的 Z32HUA.bin,最后点击下载。

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

  2. 首先在电脑上打开串口助手,选择对应的串口号,设置波特率为 115200 ,偶校验( Even ),选中“发送新行”,然后打开串口。其中串口号可通过设备管理器查看。

  3. 关闭实验箱 Z32 电源开关,再打开,程序自动运行,可以在串口调试助手看到显示“ 0 0xAA ”。

  4. 代码分析

Uart.c

extern UINT8 shuju[64];
extern UINT8 shuju_lens;
extern UINT8 uart_rx_num;
extern UINT8 uart_rx_end;

void UART_IrqService(void)
{
//*****your code*****/
    UARTCR &= ~TRS_EN;
    {
        do
        {
            shuju[uart_rx_num] = UARTDR;
            if(shuju[uart_rx_num]=='\r'||shuju[uart_rx_num]=='\n')
            {
                shuju_lens = uart_rx_num;
                uart_rx_num=0;
                uart_rx_end=1;
            }
            else
                uart_rx_num++;
        }
        while(FIFO_NE & UARTISR);
    }
    UARTCR |= TRS_EN;
}

/**
* @函数:波特率设置
* @set:0-默认波特率115200,其他:需根据时钟源和分频计算出set = 时钟(hz)/波特率
* @返回: none
*/
void UART_BrpSet(UINT16 set)
{
    UINT16 brp=0;
    UINT8 fd=0;
    if(0 == set)
    {
    //uartband@115200bps
        fd = SCU->UARTCLKCR & 0x80;
        switch(fd)
        {
        case 0x80:/*外部时钟12M晶振*/
            brp = 0x0068;
            break;
        case 0x00:/*内部时钟*/
            brp = 0x00AD;
            break;
        default:
            brp = 0x00AD;
            break;
        }
        fd = SCU->UARTCLKCR & 0x7f ;
        brp =brp/(fd+1);
    }
    else
    {
        brp = set;
    }
    UARTBRPH = (UINT8)((brp >> 8) & 0xFF);
    UARTBRPL = (UINT8)((brp) & 0xFF);
}

/**
* @函数:初始化
* @返回:none
*/
void UART_Init(void)
{
    IOM->CRA |= (1<<0);//使能Uart接口
    SCU->MCGR2 |= (1<<3); //使能Uart总线时钟
    
    /******配置Uart时钟(建议使用外部晶振)******/
    SCU->SCFGOR |= (1<<6);// 使能外部晶振
    SCU->UARTCLKCR |= (1<<7);//使用外部时钟
    //SCU->UARTCLKCR &= ~(1<<7);//使用内部OSC时钟
    
    UART_BrpSet(0);//设置波特率为默认115200
    UARTISR = 0xFF;//状态寄存器全部清除
    UARTCR |= FLUSH; //清除接收fifo
    UARTCR = 0;//偶校验
    
    /******配置中断使能******/
    UARTIER |= FIFO_NE;
    //UARTIER |= FIFO_HF;
    //UARTIER |= FIFO_FU;
    //UARTIER |= FIFO_OV;
    //UARTIER |= TXEND;
    //UARTIER |= TRE;
    ModuleIrqRegister(Uart_Exception, UART_IrqService);//挂载中断号
}

/**
* @函数:Uart发送一个字节
* @dat:  要发送的数据字节
* @返回:None
*/
void UART_SendByte(UINT8 dat)
{
    UARTCR |= TRS_EN;
    UARTDR = dat;
    do
    {
        if(UARTISR & TXEND)
        {
            UARTISR |= TXEND;//清除发送完成标志,写1清除
            break;
        }
    }
    while (1);
    UARTCR &= (~TRS_EN);
}

/**
* @函数:Uart发送一个字符串
* @str:  要发送的字符串
* @返回:None
*/
void UART_SendString(UINT8 * str)
{
    UINT8 *p ;
    p=str;
    while(*p!=0)
    {
        UART_SendByte(*p++);
    }
}

/**
* @函数:Uart发送某一长度的字符串
* @buf:  要发送的字符串
* @length:  要发送的长度
* @返回:None
*/

void uart_SendString(UINT8 buf[],UINT8 length)
{
    UINT8 i=0;
    while(length>i)
    {
        UART_SendByte(buf[i]);
        i=i+1;
    }
}

/**
* @函数:Uart发送一个十进制整数
* @num:  要发送的整数
* @返回:None
*/
void UART_SendNum(INT32 num)
{
    INT32 cnt = num,k;
    UINT8 i,j;
    if(num<0)
    {
        UART_SendByte('-');
        num=-num;
    }
    //计算出i为所发数据的位数
    for(i=1;; i++)
    {
        cnt = cnt/10;
        if(cnt == 0)
            break;
    }
    //算出最大被除数从高位分离
    k = 1;
    for(j=0; j<i-1; j++)
    {
        k = k*10;
    }
    //分离并发送各个位
    cnt = num;
    for(j=0; j<i; j++)
    {
        cnt = num/k;
        num = num%k;
        UART_SendByte(0x30+cnt);
        k /= 10;
    }
}

/**
* @函数:Uart发送一个16进制整数
* @dat:  要发送的16进制数
* @返回:None
*/
void UART_SendHex(UINT8 dat)
{
    UINT8 ge,shi;
    UART_SendByte('0');
    UART_SendByte('x');
    ge = dat%16;
    shi = dat/16;
    if(ge>9)
        ge+=7;//转换成大写字母
    if(shi>9)
        shi+=7;
    UART_SendByte(0x30+shi);
    UART_SendByte(0x30+ge);
    UART_SendByte(' ');
}

/**
* @函数:Uart接收一个字节
* @param receive addsress
* @返回:flag
*/
UINT8 UART_GetByte(UINT8 *data)
{
    UINT8 ret= 0;
    if(0 != (UARTISR & FIFO_NE))
    {
        *data = UARTDR;
        ret = 1;
    }
    return ret;
}
/**
* @函数:Uart 接收多个字节
* @param receive addsress
* @len:长度
* @返回:none
*/
void UART_Receive(UINT8 *receive, UINT8 len)
{
    while(len != 0)
    {
        if(len >= 4)
        {
            while (!(UARTISR & FIFO_FU));
            *receive++ = UARTDR;
            *receive++ = UARTDR;
            *receive++ = UARTDR;
            *receive++ = UARTDR;
            len -= 4;
        }
        else if(len >= 2)
        {
            while (!(UARTISR & FIFO_HF));
            *receive++ = UARTDR;
            *receive++ = UARTDR;
            len -= 2;
        }
        else
        {
            while (!(UARTISR & FIFO_NE));
            *receive++ = UARTDR;
            len--;
        }
    }
}

主函数

UINT8 shuju_lens;
UINT8 shuju[64];
UINT8 uart_rx_num;
UINT8uart_rx_end;
int main(void)
{
    /*********************此段代码勿动***********************/
//系统中断向量设置,使能所有中断
    SystemInit ();
// 返回boot条件
    if(0 == GPIO_GetVal(0))
    {
        BtApiBack(0x55555555, 0xAAAAAAAA);
    }
    /*********************此段代码勿动***********************/
    UART_Init();    //初始化Uart
    UART_SendByte('A');//Uart发送一个字符A
    UART_SendByte('\r');
    UART_SendByte('\n');//换行
    UART_SendString("Welcome to Z32HUA!");  //Uart发送字符串
    UART_SendByte('\r');
    UART_SendByte('\n');//换行
    UART_SendNum(1234567890);//Uart发送一个十进制数
    UART_SendByte('\r');
    UART_SendByte('\n');//换行
    UART_SendHex(0xAA);//Uart发送一个十六进制数
    UART_SendByte('\r');
    UART_SendByte('\n');//换行
    while(1)
    {
        if(uart_rx_end)
        {
            uart_rx_end=0;
            uart_SendString(shuju,shuju_lens);
        }
    }  //等待接收中断。
}
//延时函数,当系统时钟为内部OSC时钟时,延时1ms
void delay(int ms)
{
    int i;
    while(ms--)
    {
        for(i=0; i<950; i++) ;
    }
}

代码的执行过程为:

  • 系统初始化,中断设置,使能所有中断;
  • 判断按键,返回 boot 条件,确认是否进行程序下载;
  • 初始化 Uart ,使能 Uart 接口,配置 Uart 中断并使能;
  • 先发送单个字符“ A ”,换行,再发送字符串 Welcome to Z32H UA!换行,发送数字串“ 1234567890 ”,换行,再发送 16 位数“ 0xAA ”,换行。
  • 进入 while 循环程序,等待串口中断到来并判断数据是否接收完毕,若中断到来,转入执行串口中断服务程序,待接收数据完毕, Z32 将数据发回串口助手。

四、实验中遇到的问题及解决方法

问题:

解决方法:

五、实验感想

通过本次实验,我们知道了交叉编译环境以及了解了开发环境的配置,我们知道了如何在Linux中编译程序并将生成的可执行文件在arm超级终端上运行。
在这次实验中,我们通过自己的笔记本电脑打开两个虚拟机主机,也就是提供了虚拟机运行的环境,然后把arm编译工具共享给win7虚拟机,在win7虚拟机下用arm编译工具编译helloword.c文件,将生成的可执行文件在arm超级终端上运行。由于电脑配置的原因,在做实验时,遇到ping不通的情况,而且根据网上大佬的方法进行调整,还是无法实现,就只能换一台电脑重新开始,耗费了我们很多时间,最终下课的时候,第三步只做了一半,没能完成最后步骤,在第二天,借用他们向实验室借的实验箱继续做,最终才把最后一步完成。

六、参考资料

1.实验指导

2.Arm实验箱实验环境

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!