我没有看到一个示例、如何为要在电源循环之间保留的设置留出存储空间?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我没有看到一个示例、如何为要在电源循环之间保留的设置留出存储空间?
嘿、Keith、
要做到这一点、没有一个简单的方法(与 FRAM 不同)。 您很可能需要将其作为存储器中的指针执行此操作、然后当您准备好"保存"该变量的状态时、在指针地址写入闪存。 (闪存写入示例。) 如果您确实需要经常执行此操作、则应考虑使用 EEPROM 示例和较低的32kB 存储器来实现更高的写入周期。
现在有一个 TI clang #persistent 声明 可能会有所帮助、因为在重置此属性时不会重新初始化变量。 您仍需要单独处理向非易失性存储器的复制。
嘿、Keith、
闪存写入示例不能保证该区域在代码方面是安全的。 选择地址是因为编译的代码永远不会到达闪存的该区域。 知道程序的性质就能保证安全性。 如果需要确定性更强的方法、我建议自定义链接器文件、以分配一个闪存区域供编写。
因此、在链接器文件的"Memory"部分中挖出一个特殊段、并确保编译器不会将任何内容放入其中、方法是将该段保留在链接器的"SECTIONS"部分之外。
我对这件事不熟悉、我曾尝试这么做、但遇到了链接器错误-这是一件好事。 是否有相关的教程?
另外、Theia 是否有方法了解使用了多少闪存?
更多详细信息:
我曾尝试分割出一个8 KB 的部分、这远远超过了我需要的值(96字节)、所以我更改了这个:
为此、请执行以下操作:
链接器卡住。 我只能改变什么?
Keith、
对于链接器调整、您还需要将段添加到存储器中。 但请记住、随着中断表加载到存储器的开头、您可能还需要向前移动中断表。
如下所示:(请注意、我不考虑这里的 ISR 表。)
MEMORY
{
App_Write (RW) : origin = 0x00000000, length = 0x00002000
FLASH (RX) : origin = 0x00002000, length = 0x0001E000
SRAM (RWX) : origin = 0x20200000, length = 0x00008000
BCR_CONFIG (R) : origin = 0x41C00000, length = 0x00000080
BSL_CONFIG (R) : origin = 0x41C00100, length = 0x00000080
}
对于 EEPROM 示例、我将介绍 Brandon Fisher94 、因为他对该示例比较熟悉。 您需要参考类型 A 或 B 的用户指南、以了解它们是如何设置该结构的。
好吧、更荒谬的是、当我采用 flashctl 多大小写入示例并在循环中添加32位写入时、它绝不会降落、
返回的代码*3*不是枚举项之一。
#include "ti_msp_dl_config.h"
#include <stdio.h>
#include <string.h>
/* Address in main memory to write to */
#define MAIN_BASE_ADDRESS (0x00001000)
/* 8-bit data to write to flash */
uint8_t gData8 = 0x11;
/* 16-bit data to write to flash */
uint16_t gData16 = 0x2222;
/* 32-bit data to write to flash */
uint32_t gData32 = 0x33333333;
/* Array to write 64-bits to flash */
uint32_t gDataArray64[] = {0xABCDEF00, 0x12345678};
volatile DL_FLASHCTL_COMMAND_STATUS gCmdStatus;
/* Codes to understand where error occured */
#define NO_ERROR 0
#define ERROR_ERASE 1
#define ERROR_8BIT_W 2
#define ERROR_16BIT_W 3
#define ERROR_32BIT_W 4
#define ERROR_64BIT_W 5
volatile uint8_t gErrorType = NO_ERROR;
// place to store the variables
uint8_t Recall8;
uint16_t Recall16;
uint32_t Recall32;
int main(void) {
SYSCFG_DL_init();
// Check the Memory
Recall8 = *(uint8_t *)(MAIN_BASE_ADDRESS);
Recall16 = *(uint16_t *)(MAIN_BASE_ADDRESS + 8);
Recall32 = *(uint32_t *)(MAIN_BASE_ADDRESS + 16);
/* Unprotect sector in main memory with ECC generated by hardware */
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
/* Erase sector in main memory */
gCmdStatus = DL_FlashCTL_eraseMemoryFromRAM(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_COMMAND_SIZE_SECTOR);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_ERASE;
}
if (gErrorType == NO_ERROR) {
/* 8-bit write to flash in main memory */
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdStatus = DL_FlashCTL_programMemoryFromRAM8WithECCGenerated(
FLASHCTL, MAIN_BASE_ADDRESS, &gData8);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_8BIT_W;
}
}
if (gErrorType == NO_ERROR) {
/*
* 16-bit write to flash in main memory with ECC generated by hardware.
* The target program address must be a flash word address
* (8-byte aligned), so we increase the address in increments of 8.
*/
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdStatus = DL_FlashCTL_programMemoryFromRAM16WithECCGenerated(
FLASHCTL, (MAIN_BASE_ADDRESS + 8), &gData16);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_16BIT_W;
}
}
if (gErrorType == NO_ERROR) {
/* 32-bit write to flash in main memory with ECC generated by hardware */
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdStatus = DL_FlashCTL_programMemoryFromRAM32WithECCGenerated(
FLASHCTL, (MAIN_BASE_ADDRESS + 16), &gData32);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_32BIT_W;
}
}
if (gErrorType == NO_ERROR) {
/*
* 64-bit write to flash in main memory with ECC generated by hardware.
* Data must be loaded 32-bits at a time, but a single word program
* is executed
*/
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdStatus = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated(
FLASHCTL, (MAIN_BASE_ADDRESS + 24), &gDataArray64[0]);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_64BIT_W;
}
}
/* After successful completion, toggle LED and USER_TEST pin */
if (gErrorType == NO_ERROR) {
/*
* Check the contents of MAIN_BASE_ADDRESS at breakpoint:
* FF FF FF 11
* FF FF FF FF
* FF FF 22 22
* FF FF FF FF
* 33 33 33 33
* FF FF FF FF
* AB CD EF 00
* 12 34 56 78
*/
while (1) {
DL_GPIO_togglePins(GPIO_LEDS_PORT,
GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
// Check the Memory
Recall8 = *(uint8_t *)(MAIN_BASE_ADDRESS);
Recall16 = *(uint16_t *)(MAIN_BASE_ADDRESS + 8);
Recall32 = *(uint32_t *)(MAIN_BASE_ADDRESS + 16);
delay_cycles(16000000);
gData32 = 31;
/* 32-bit write to flash in main memory with ECC generated by hardware */
DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdStatus = DL_FlashCTL_programMemoryFromRAM32WithECCGenerated(
FLASHCTL, (MAIN_BASE_ADDRESS + 16), &gData32);
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
/* If command was not successful, set error flag */
gErrorType = ERROR_32BIT_W;
}
}
}
/* Unsuccessful example run */
else {
/* Check gErrorType value */
__BKPT(0);
}
}