Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers settings.c Source File

settings.c

Go to the documentation of this file.
00001 /**
00002  * @file    settings.c
00003  * @brief   Implementation of settings.h
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * Copyright 2019, Cypress Semiconductor Corporation 
00008  * or a subsidiary of Cypress Semiconductor Corporation.
00009  * SPDX-License-Identifier: Apache-2.0
00010  *
00011  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00012  * not use this file except in compliance with the License.
00013  * You may obtain a copy of the License at
00014  *
00015  * http://www.apache.org/licenses/LICENSE-2.0
00016  *
00017  * Unless required by applicable law or agreed to in writing, software
00018  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00019  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020  * See the License for the specific language governing permissions and
00021  * limitations under the License.
00022  */
00023 
00024 #include <string.h>
00025 
00026 #include "settings.h"
00027 #include "target_config.h"
00028 #include "compiler.h"
00029 #include "cortex_m.h"
00030 #include "daplink.h"
00031 
00032 // 'kvld' in hex - key valid
00033 #define CFG_KEY             0x6b766c64
00034 #define SECTOR_BUFFER_SIZE  16
00035 
00036 // For generating hexdumps on faults
00037 #define ALLOWED_HEXDUMP     16
00038 
00039 // WARNING - THIS STRUCTURE RESIDES IN RAM STORAGE!
00040 // Be careful with changes:
00041 // -Only add new members to end end of this structure
00042 // -Do not change the order of members in this structure
00043 // -Structure must remain packed so no padding bytes are added
00044 typedef struct __attribute__((__packed__)) cfg_ram {
00045     uint32_t key;               // Magic key to indicate a valid record
00046     uint16_t size;              // Offset of the last member from the start
00047 
00048     // Configurable values
00049     uint8_t hold_in_bl;
00050     char assert_file_name[64 + 1];
00051     uint16_t assert_line;
00052     uint8_t assert_source;
00053 
00054     // Additional debug information on faults
00055     uint8_t  valid_dumps;
00056     uint32_t hexdump[ALLOWED_HEXDUMP];  //Alignments checked
00057 
00058     // Disable msd support
00059     uint8_t disable_msd;
00060 
00061     //Add new entries from here
00062     uint8_t page_erase_enable;
00063 } cfg_ram_t;
00064 
00065 // Configuration RAM
00066 static cfg_ram_t config_ram __attribute__((section("cfgram"), zero_init));
00067 // Ram copy of RAM config
00068 static cfg_ram_t config_ram_copy;
00069 
00070 void config_init()
00071 {
00072     uint32_t new_size;
00073     // Initialize RAM copy
00074     memset(&config_ram_copy, 0, sizeof(config_ram_copy));
00075     // Read settings from RAM if the key is valid
00076     new_size = sizeof(config_ram);
00077 
00078     if (CFG_KEY == config_ram.key) {
00079         uint32_t size = MIN(config_ram.size, sizeof(config_ram));
00080         new_size = MAX(config_ram.size, sizeof(config_ram));
00081         memcpy(&config_ram_copy, (void *)&config_ram, size);
00082         config_ram_copy.assert_file_name[sizeof(config_ram_copy.assert_file_name) - 1] = 0;
00083     }
00084 
00085     // Initialize RAM
00086     memset((void *)&config_ram, 0, sizeof(config_ram));
00087     config_ram.key = CFG_KEY;
00088     config_ram.size = new_size;
00089     // Copy assert info back over (must be explicitly cleared)
00090     memcpy(config_ram.assert_file_name,
00091            config_ram_copy.assert_file_name,
00092            sizeof(config_ram_copy.assert_file_name));
00093     config_ram.assert_line =  config_ram_copy.assert_line;
00094     config_ram.assert_source =  config_ram_copy.assert_source;
00095     config_ram.valid_dumps = config_ram_copy.valid_dumps;
00096     memcpy(config_ram.hexdump, config_ram_copy.hexdump, sizeof(config_ram_copy.hexdump[0]) * config_ram_copy.valid_dumps);
00097     config_ram.disable_msd = config_ram_copy.disable_msd;
00098     config_ram.page_erase_enable = config_ram_copy.page_erase_enable;
00099     config_rom_init();
00100 }
00101 
00102 void config_ram_set_hold_in_bl(bool hold)
00103 {
00104     config_ram.hold_in_bl = hold;
00105 }
00106 
00107 void config_ram_set_assert(const char *file, uint16_t line)
00108 {
00109     // Initialize
00110     uint32_t file_name_size = strlen(file) + 1;
00111     const char *start;
00112     uint32_t assert_buf_size = sizeof(config_ram.assert_file_name);
00113     uint32_t copy_size;
00114     memset(config_ram.assert_file_name, 0, sizeof(config_ram.assert_file_name));
00115 
00116     // Determine size to copy
00117     if (file_name_size <= assert_buf_size) {
00118         start = file;
00119         copy_size = file_name_size;
00120     } else {
00121         start = &file[file_name_size - assert_buf_size];
00122         copy_size = assert_buf_size;
00123     }
00124 
00125     // Write to ram
00126     memcpy(config_ram.assert_file_name, start, copy_size);
00127     config_ram.assert_line = line;
00128 
00129     if (daplink_is_bootloader()) {
00130         config_ram.assert_source = ASSERT_SOURCE_BL;
00131     } else if (daplink_is_interface()) {
00132         config_ram.assert_source = ASSERT_SOURCE_APP;
00133     } else {
00134         config_ram.assert_source = ASSERT_SOURCE_NONE;
00135     }
00136 }
00137 
00138 void config_ram_clear_assert()
00139 {
00140     memset(config_ram.assert_file_name, 0, sizeof(config_ram.assert_file_name));
00141     config_ram.assert_line = 0;
00142     config_ram.valid_dumps = 0;
00143 }
00144 
00145 bool config_ram_get_hold_in_bl()
00146 {
00147     return config_ram.hold_in_bl;
00148 }
00149 
00150 bool config_ram_get_initial_hold_in_bl()
00151 {
00152     return config_ram_copy.hold_in_bl;
00153 }
00154 
00155 bool config_ram_get_assert(char *buf, uint16_t buf_size, uint16_t *line, assert_source_t *source)
00156 {
00157     // Initialize
00158     const char *start;
00159     uint32_t copy_size;
00160     uint32_t assert_size = strlen(config_ram.assert_file_name) + 1;
00161 
00162     if (0 != buf) {
00163         memset(buf, 0, buf_size);
00164     }
00165 
00166     if (0 != line) {
00167         *line = 0;
00168     }
00169 
00170     if (0 != source) {
00171         *source = ASSERT_SOURCE_NONE;
00172     }
00173 
00174     // If the string is empty then there is no assert
00175     if (0 == config_ram.assert_file_name[0]) {
00176         return false;
00177     }
00178 
00179     // Determine size to copy
00180     if (assert_size <= buf_size) {
00181         start = config_ram.assert_file_name;
00182         copy_size = assert_size;
00183     } else {
00184         start = &config_ram.assert_file_name[assert_size - buf_size];
00185         copy_size = buf_size;
00186     }
00187 
00188     // Copy data over
00189     if (0 != buf) {
00190         *line = config_ram.assert_line;
00191     }
00192 
00193     if (0 != line) {
00194         memcpy(buf, start, copy_size);
00195     }
00196 
00197     if (0 != source) {
00198         *source = (assert_source_t)config_ram.assert_source;
00199     }
00200 
00201     return true;
00202 }
00203 
00204 uint8_t config_ram_add_hexdump(uint32_t hexdump)
00205 {
00206     if (config_ram.valid_dumps >= ALLOWED_HEXDUMP) {
00207         return 0;
00208     }
00209 
00210     //alignment is maintained here
00211     config_ram.hexdump[config_ram.valid_dumps++] = hexdump;
00212     return config_ram.valid_dumps;
00213 }
00214 
00215 uint8_t config_ram_get_hexdumps(uint32_t **hexdumps)
00216 {
00217     if (config_ram.valid_dumps == 0) {
00218         return 0;
00219     }
00220 
00221     //prevent memcopy check alignment
00222     *hexdumps = config_ram.hexdump;
00223     return config_ram.valid_dumps;
00224 }
00225 
00226 void config_ram_set_disable_msd(bool disable_msd)
00227 {
00228     config_ram.disable_msd = disable_msd;
00229 }
00230 
00231 uint8_t config_ram_get_disable_msd(void)
00232 {
00233     return config_ram.disable_msd;
00234 }
00235 
00236 void config_ram_set_page_erase(bool page_erase_enable)
00237 {
00238     config_ram.page_erase_enable = page_erase_enable;
00239 }
00240 
00241 bool config_ram_get_page_erase(void)
00242 {
00243     return config_ram.page_erase_enable;
00244 }