EC_M051_IO_Toggle_With_UID_Protect_V1.00 (3).zip
(2.62 MB)
Nuvoton M051 系列微处理器提供UID (Unique Identifier),开发者在应用上可透过识别UID的正确性,决定应用是否继续执行,确保产品不被任意复制仿冒。单纯的UID识别安全性似乎不足,因此将提供一个可自行增加识别复杂度范例,开发者可以基于微处理器的UID,再进行自定义的运算,使用运算过的UID识别有更佳的安全性。
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* @brief
* Execution IO toggle example with UID protect.
* @note
* Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "M051Series.h"
#define PLL_CLOCK 50000000
#define UID_START_ADDR 0x00002000 // UID start address of APROM
#define UID_ADDR_OFFSET 0x100 // UID address offset of APROM
__attribute__((at(UID_START_ADDR + UID_ADDR_OFFSET))) static const uint32_t gau32UIDAddr[4]= {2,2,2};
/*---------------------------------------------------------------------------
Function: SYS_Init
Parameters: None.
Returns: None.
Description: System and periphial module clock setting.
---------------------------------------------------------------------------*/
void SYS_Init(void)
{
/* Enable Internal RC 22.1184MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
/* Waiting for Internal RC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
/* Enable external XTAL 12MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
/* Waiting for external XTAL clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(PLL_CLOCK);
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Select UART module clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
/* Set GPB multi-function pins for UART0 RXD(P0.3) and TXD(P0.2) */
SYS->P0_MFP &= ~(SYS_MFP_P03_Msk | SYS_MFP_P02_Msk);
SYS->P0_MFP |= (SYS_MFP_P03_RXD0 | SYS_MFP_P02_TXD0);
}
/*---------------------------------------------------------------------------
Function: UART0_Init
Parameters: None.
Returns: None.
Description: Initialize UART0 module, setting buadrate is 115200 bps
---------------------------------------------------------------------------*/
void UART0_Init()
{
/* Reset UART0 module */
SYS_ResetModule(UART0_RST);
/* Configure UART0 and set UART0 Baudrate */
UART_Open(UART0, 115200);
}
/*---------------------------------------------------------------------------
Function: Delay_count
Parameters: None.
Returns: None.
Description: Delay of IO toggle.
---------------------------------------------------------------------------*/
void Delay_count(int32_t u32count)
{
int32_t i32i,i32j;
for(i32i=0; i32i<=3000; i32i++)
for(i32j=0; i32j<u32count; i32j++);
}
/*---------------------------------------------------------------------------
Function: main
Parameters: None.
Returns: None.
Description: main routine of the example.
---------------------------------------------------------------------------*/
int main(void)
{
int32_t i32_cnt;
uint32_t au32mcuUID[4];
uint32_t au32modfiyUID[4];
/* Unlock protected registers */
SYS_UnlockReg();
/* Init System, peripheral clock and multi-function I/O */
SYS_Init();
/* Enable FMC ISP function */
FMC_Open();
/* Lock protected registers */
SYS_LockReg();
/* Init UART0 for printf */
UART0_Init();
printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
printf("Example : IO toggle with UID protect\n");
/* Configure PB.13 as Output mode*/
GPIO_SetMode(P3, BIT5, GPIO_PMD_OUTPUT);
SYS_UnlockReg();
for(i32_cnt = 0; i32_cnt < 3; i32_cnt++)
{
/* Read UID using FMC ISP form chip */
au32mcuUID[i32_cnt] = FMC_ReadUID(i32_cnt);
printf(" Unique ID %d ........................... [0x%08x]\n", i32_cnt, au32mcuUID[i32_cnt]);
}
for(i32_cnt = 0; i32_cnt < 3; i32_cnt++)
{
/* Read chnage UID form APROM */
au32modfiyUID[i32_cnt] = FMC_Read(UID_START_ADDR+UID_ADDR_OFFSET+(i32_cnt*4));
printf(" Modify ID %d ........................... [0x%08x]\n", i32_cnt, au32modfiyUID[i32_cnt]);
}
SYS_LockReg();
/************* User change UID compare implement ***************/
/* Compare original UID and change UID */
if((au32mcuUID[0] == au32modfiyUID[0]) && (au32mcuUID[1] == au32modfiyUID[1]) && (au32mcuUID[2] == au32modfiyUID[2]))
{
printf("=> Match UID, MCU toggle PB13...\n");
while(1)
{
Delay_count(500);
P35 = 0;
Delay_count(500);
P35 = 1;
}
}
else
{
printf("=> Conflict UID, MCU enter suspend...\n");
__WFI();
}
while(1);
}
|