Skip to content
Permalink
4fc29938c1
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
506 lines (452 sloc) 16.6 KB
/******************************************************************************
* File Name: main.c
*
* Description: This is the source code for the XMC MCU: Flash Protection Example
* for ModusToolbox. This example demonstrates how flash protection
* can be configured.
*
* Related Document: See README.md
*
******************************************************************************
*
* Copyright (c) 2015-2021, Infineon Technologies AG
* All rights reserved.
*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
/*******************************************************************************
* Include header files
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "cybsp.h"
#include "cy_utils.h"
#include "retarget_io.h"
#include "shell.h"
#include <xmc_common.h>
#include <xmc_flash.h>
/*******************************************************************************
* Macros
*******************************************************************************/
/* User Configuration Block 0 (UCB0) id */
#define UCB0 0
/* Maximum number of times the UCBs can be programmed */
#define UCB_PROGRAM_MAX_LIMIT 4
/* UCBs can be programmed upto 4 times maximum, use 3 for safe use */
#define UCB_PROGRAM_SAFE_LIMIT 3
/* Set to 1 to enable safety check when programming UCBs
* Set to 0 to disable safety check
*/
#define UCB_PROGRAM_SAFETY_ENABLED 1
/*******************************************************************************
* Function Prototypes
********************************************************************************/
void initialize_shell();
void help_cmd(int32_t argc, char **argv);
void flash_protection_install_cmd(int32_t argc, char **argv);
void flash_protection_uninstall_cmd(int32_t argc, char **argv);
void flash_protection_disable_cmd(int32_t argc, char **argv);
void flash_protection_resume_cmd(int32_t argc, char **argv);
void flash_protection_status_cmd(int32_t argc, char **argv);
void flash_ucb_program_count();
void flash_ucb_program_count(uint32_t count);
/*******************************************************************************
* Global Variables
*******************************************************************************/
const shell_cmd_t shell_cmd_table[] =
{
{"help", 0u, 0u, help_cmd, "Display help message", ""},
{"install", 2u, 2u, flash_protection_install_cmd, "Install protection", "<passwd0> <passwd1>"},
{"uninstall", 2u, 2u, flash_protection_uninstall_cmd, "Remove protection", "<passwd0> <passwd1>"},
{"disable", 2u, 2u, flash_protection_disable_cmd, "Disables protection temporarily", "<passwd0> <passwd1>"},
{"resume", 0u, 0u, flash_protection_resume_cmd, "Re-enables global read protection", ""},
{"status", 0u, 0u, flash_protection_status_cmd, "Report flash protection status", ""},
{0, 0u, 0u, 0, 0, 0}
};
uint8_t ucb_program_count = 0;
/*******************************************************************************
* Function Name: initialize_shell
********************************************************************************
* Summary:
* This function prompts useful information about the shell and supported
* commands.
*
* Parameters:
* none
*
* Return:
* void
*
*******************************************************************************/
void initialize_shell()
{
const char DELIMITER_STR[] = "*****************************************";
shell_print("\r\n%s", DELIMITER_STR);
shell_print(" %s", "Shell Application");
shell_print(DELIMITER_STR);
shell_print(" Version %s", "1.0.0");
shell_print(" Built %s", __DATE__ " at " __TIME__);
shell_print("\n Enter 'help' for command list.");
shell_print("\nNote: UCBs can be programmed only 4 times.\r\nCurrent UCB "
"Program Count: %d\n", ucb_program_count);
shell_print("%s\n", DELIMITER_STR);
}
/*******************************************************************************
* Function Name: help_cmd
********************************************************************************
* Summary:
* This function displays all the commands supported by the shell
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
*
* Return:
* void
*
*******************************************************************************/
void help_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argc);
/* Display help options */
shell_help();
}
/*******************************************************************************
* Function Name: flash_protection_install_cmd
********************************************************************************
* Summary:
* This function installs global read protection on the flash. Refer
* XMC_FLASH_PROTECTION_t for other protection options.
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
void flash_protection_install_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
#if UCB_PROGRAM_SAFETY_ENABLED
if(ucb_program_count == UCB_PROGRAM_SAFE_LIMIT)
{
shell_print("UCB program safe limit reached. Protection can"
" be changed only one last time. Device might become unusable"
" if there is any failure!"
"\r\nSet UCB_PROGRAM_SAFETY_ENABLED to 0 in code to enable"
" programming the last time!");
return;
}
#endif
if(ucb_program_count == UCB_PROGRAM_MAX_LIMIT)
{
shell_print("ERROR: UCBs can be programmed only four times. Cannot install"
" protection!");
return;
}
/* Check if protection is installed */
if ((XMC_FLASH_GetStatus() & XMC_FLASH_STATUS_PROTECTION_INSTALLED) == 0)
{
/* Increment UCB program counter */
ucb_program_count++;
/* Flash UCB program count into flash */
flash_ucb_program_count(ucb_program_count);
/* Erase User Configuration Block if no protection installed */
XMC_FLASH_EraseUCB(XMC_FLASH_UCB0);
/* Install global read flash protection using user0 pwd0 and pwd1
* credentials
*/
XMC_FLASH_InstallProtection(UCB0, XMC_FLASH_PROTECTION_READ_GLOBAL,
strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 16));
/* Confirm if protection installation was successful */
XMC_FLASH_ConfirmProtection(UCB0);
/* Reset device for the changes to take effect */
XMC_SCU_RESET_ClearDeviceResetReason();
NVIC_SystemReset();
}
else
{
shell_print("ERROR: Protection already installed!!");
}
}
/*******************************************************************************
* Function Name: flash_protection_uninstall_cmd
********************************************************************************
* Summary:
* This function uninstalls flash read protection. Note: For uninstalling flash
* write protection on the sectors, use XMC_FLASH_VerifyWriteProtection with
* appropriate sector protection mask.
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
void flash_protection_uninstall_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
#if UCB_PROGRAM_SAFETY_ENABLED
if(ucb_program_count == UCB_PROGRAM_SAFE_LIMIT)
{
shell_print("UCB program safe limit reached. Protection can"
" be changed only one last time. Device might become unusable"
" if there is any failure!"
"\n\rSet UCB_PROGRAM_SAFETY_CHECK to DISABLE in code to enable"
" programming the last time!");
return;
}
#endif
if(ucb_program_count == UCB_PROGRAM_MAX_LIMIT)
{
shell_print("ERROR: UCBs can be programmed only four times. Cannot uninstall"
" protection!");
return;
}
/* Check if protection is installed */
if ((XMC_FLASH_GetStatus() & XMC_FLASH_STATUS_PROTECTION_INSTALLED) != 0)
{
/* Verify if read protection is installed using user0 pwd0 and pwd1 credentials.
* Calling this function temporarily disables flash protection as well
*/
if (XMC_FLASH_VerifyReadProtection(strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 16)))
{
shell_print("Protection disabled");
/* Increment UCB program counter */
ucb_program_count++;
/* Flash UCB program count into flash */
flash_ucb_program_count(ucb_program_count);
/* Erase User Configuration block to remove protection */
shell_print("Erase UCB");
XMC_FLASH_EraseUCB(XMC_FLASH_UCB0);
/* Reset device for the changes to take effect */
XMC_SCU_RESET_ClearDeviceResetReason();
NVIC_SystemReset();
}
else
{
shell_print("ERROR: Unable to uninstall protection, check credentials!");
}
}
else
{
shell_print("No Protection installed!");
}
}
/*******************************************************************************
* Function Name: flash_protection_disable_cmd
********************************************************************************
* Summary:
* This function disables flash protection temporarily
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
void flash_protection_disable_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
/* Check if protection is installed */
if ((XMC_FLASH_GetStatus() & XMC_FLASH_STATUS_PROTECTION_INSTALLED) != 0)
{
/* Verify if read protection is installed using user0 pwd0 and pwd1 credentials.
* Calling this function temporarily disables flash protection as well
*/
if(XMC_FLASH_VerifyReadProtection(strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 16)))
{
shell_print("Protection disabled temporarily");
}
else
{
shell_print("ERROR: A problem occurred while disabling the read protection!!");
}
}
else
{
shell_print("ERROR: Protection not yet installed!!");
}
}
/*******************************************************************************
* Function Name: flash_protection_resume_cmd
********************************************************************************
* Summary:
* This function resumes flash protection as it was configured before
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
void flash_protection_resume_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argv);
/* Re-enable flash protection */
XMC_FLASH_ResumeProtection();
shell_print("Flash Protection re-enabled!");
}
/*******************************************************************************
* Function Name: flash_ucb_program_count
********************************************************************************
* Summary:
* This function programs the UCB program count into the flash sector 8
*
* Parameters:
* uint32_t count - UCB programming count
*
* Return:
* void
*
*******************************************************************************/
void flash_ucb_program_count(uint32_t count)
{
/* Data array */
uint32_t data[XMC_FLASH_WORDS_PER_PAGE] = {count, 0};
/* Erase Flash Sector 8 */
XMC_FLASH_EraseSector(XMC_FLASH_SECTOR_8);
/* Program Flash Sector 8 */
XMC_FLASH_ProgramPage(XMC_FLASH_SECTOR_8, data);
}
/*******************************************************************************
* Function Name: flash_get_ucb_program_count
********************************************************************************
* Summary:
* This function retrieves the UCB program count into the flash sector 8
*
* Parameters:
* none
*
* Return:
* uint32_t
*
*******************************************************************************/
uint32_t flash_get_ucb_program_count()
{
/* Point to XMC_FLASH_SECTOR_8 flash address */
const uint32_t *address = XMC_FLASH_SECTOR_8;
return *address;
}
/*******************************************************************************
* Function Name: flash_protection_status_cmd
********************************************************************************
* Summary:
* This function displays the flash protection status
*
* Parameters:
* int32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
void flash_protection_status_cmd(int32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argv);
/* Check Flash Protection Status */
uint32_t status = XMC_FLASH_GetStatus();
shell_print("UCB Program Count: %d", flash_get_ucb_program_count());
/* Check if protection is installed */
if ((status & (XMC_FLASH_STATUS_PROTECTION_INSTALLED)) != 0)
{
shell_print("Protection installed");
/* Display message if protection is in disabled state temporarily */
if ((status & XMC_FLASH_STATUS_READ_PROTECTION_DISABLED_STATE) != 0)
{
shell_print("Read protection temporarily disabled");
}
}
else
{
shell_print("Protection not installed");
}
}
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function. It initializes the shell and processes the user
* input for demonstrating flash protection options like:
* 1. Installing Flash Protection
* 2. Uninstalling Flash Protection
* 3. Disabling Flash Protection
* 4. Resuming Flash Protection
* 5. Checking Flash Protection Status
*
* Parameters:
* none
*
* Return:
* int
*
*******************************************************************************/
int main(void)
{
cy_rslt_t result;
/* Initialize the device and board peripherals */
result = cybsp_init();
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Initialize retarget-io to use the debug UART port */
retarget_io_init();
/* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
printf("\x1b[2J\x1b[;H");
printf("**************** XMC MCU: Flash Protection *****************\r\n");
/* Initialize the UCB Program counter */
ucb_program_count = flash_get_ucb_program_count();
/* Reset the counter and erase flash sector if invalid count
* value found in flash for counter
*/
if(ucb_program_count > UCB_PROGRAM_MAX_LIMIT)
{
flash_ucb_program_count(0);
ucb_program_count = 0;
}
/* Initialize shell */
shell_init(shell_cmd_table, initialize_shell);
while(1)
{
/* Process user input */
shell_process_input();
}
}
/* [] END OF FILE */