Pavel Chromy: memory leak in at91sam7 flash driver, possible incorrect pointer conversion in gpnvm command handling,
uninitialized buffer issue in handle_flash_info_command in flash.c, some formatting. git-svn-id: svn://svn.berlios.de/openocd/trunk@446 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
6d95014674
commit
f14f84ca1e
|
@ -77,7 +77,7 @@ flash_driver_t at91sam7_flash =
|
||||||
.protect = at91sam7_protect,
|
.protect = at91sam7_protect,
|
||||||
.write = at91sam7_write,
|
.write = at91sam7_write,
|
||||||
.probe = at91sam7_probe,
|
.probe = at91sam7_probe,
|
||||||
.auto_probe = at91sam7_auto_probe,
|
.auto_probe = at91sam7_probe,
|
||||||
.erase_check = at91sam7_erase_check,
|
.erase_check = at91sam7_erase_check,
|
||||||
.protect_check = at91sam7_protect_check,
|
.protect_check = at91sam7_protect_check,
|
||||||
.info = at91sam7_info
|
.info = at91sam7_info
|
||||||
|
@ -145,7 +145,7 @@ u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane)
|
||||||
return fsr;
|
return fsr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read clock configuration and set at91sam7_info->usec_clocks*/
|
/* Read clock configuration and set at91sam7_info->usec_clocks*/
|
||||||
void at91sam7_read_clock_info(flash_bank_t *bank)
|
void at91sam7_read_clock_info(flash_bank_t *bank)
|
||||||
{
|
{
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
|
@ -314,6 +314,9 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
|
||||||
u32 cidr, status;
|
u32 cidr, status;
|
||||||
int sectornum;
|
int sectornum;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr != 0)
|
||||||
|
return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
|
||||||
|
|
||||||
/* Read and parse chip identification register */
|
/* Read and parse chip identification register */
|
||||||
target_read_u32(target, DBGU_CIDR, &cidr);
|
target_read_u32(target, DBGU_CIDR, &cidr);
|
||||||
|
|
||||||
|
@ -554,7 +557,6 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
|
||||||
}
|
}
|
||||||
|
|
||||||
WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
|
WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,22 +581,16 @@ int at91sam7_protect_check(struct flash_bank_s *bank)
|
||||||
|
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr == 0)
|
||||||
|
{
|
||||||
|
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||||
|
}
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
if (bank->target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
|
for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
|
||||||
{
|
{
|
||||||
status = at91sam7_get_flash_status(bank, flashplane);
|
status = at91sam7_get_flash_status(bank, flashplane);
|
||||||
|
@ -619,7 +615,6 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch
|
||||||
|
|
||||||
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
|
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
|
||||||
bank->driver_priv = at91sam7_info;
|
bank->driver_priv = at91sam7_info;
|
||||||
at91sam7_info->probed = 0;
|
|
||||||
|
|
||||||
/* part wasn't probed for info yet */
|
/* part wasn't probed for info yet */
|
||||||
at91sam7_info->cidr = 0;
|
at91sam7_info->cidr = 0;
|
||||||
|
@ -634,22 +629,16 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
u8 flashplane;
|
u8 flashplane;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr == 0)
|
||||||
|
{
|
||||||
|
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||||
|
}
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
if (bank->target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((first < 0) || (last < first) || (last >= bank->num_sectors))
|
if ((first < 0) || (last < first) || (last >= bank->num_sectors))
|
||||||
{
|
{
|
||||||
if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
|
if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
|
||||||
|
@ -683,6 +672,11 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
|
||||||
|
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr == 0)
|
||||||
|
{
|
||||||
|
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||||
|
}
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
if (bank->target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
|
@ -693,17 +687,6 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
|
||||||
return ERROR_FLASH_SECTOR_INVALID;
|
return ERROR_FLASH_SECTOR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
at91sam7_read_clock_info(bank);
|
at91sam7_read_clock_info(bank);
|
||||||
|
|
||||||
for (lockregion=first;lockregion<=last;lockregion++)
|
for (lockregion=first;lockregion<=last;lockregion++)
|
||||||
|
@ -738,22 +721,16 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
|
||||||
u32 first_page, last_page, pagen, buffer_pos;
|
u32 first_page, last_page, pagen, buffer_pos;
|
||||||
u8 flashplane;
|
u8 flashplane;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr == 0)
|
||||||
|
{
|
||||||
|
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||||
|
}
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
if (bank->target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset + count > bank->size)
|
if (offset + count > bank->size)
|
||||||
return ERROR_FLASH_DST_OUT_OF_BANK;
|
return ERROR_FLASH_DST_OUT_OF_BANK;
|
||||||
|
|
||||||
|
@ -809,56 +786,34 @@ int at91sam7_probe(struct flash_bank_s *bank)
|
||||||
* if this is an at91sam7, it has the configured flash
|
* if this is an at91sam7, it has the configured flash
|
||||||
*/
|
*/
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
at91sam7_info->probed = 0;
|
int retval;
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr != 0)
|
||||||
|
{
|
||||||
|
return ERROR_OK; /* already probed */
|
||||||
|
}
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
if (bank->target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
retval = at91sam7_read_part_info(bank);
|
||||||
{
|
if (retval != ERROR_OK)
|
||||||
at91sam7_read_part_info(bank);
|
return retval;
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
at91sam7_info->probed = 1;
|
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int at91sam7_auto_probe(struct flash_bank_s *bank)
|
|
||||||
{
|
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
|
||||||
if (at91sam7_info->probed)
|
|
||||||
return ERROR_OK;
|
|
||||||
return at91sam7_probe(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||||
{
|
{
|
||||||
int printed, flashplane;
|
int printed, flashplane;
|
||||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
|
||||||
{
|
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
if (at91sam7_info->cidr == 0)
|
||||||
{
|
{
|
||||||
printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
|
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||||
buf += printed;
|
|
||||||
buf_size -= printed;
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
|
printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
|
||||||
|
@ -894,7 +849,7 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||||
buf_size -= printed;
|
buf_size -= printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
|
printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits);
|
||||||
buf += printed;
|
buf += printed;
|
||||||
buf_size -= printed;
|
buf_size -= printed;
|
||||||
|
|
||||||
|
@ -919,6 +874,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||||
u32 status;
|
u32 status;
|
||||||
char *value;
|
char *value;
|
||||||
at91sam7_flash_bank_t *at91sam7_info;
|
at91sam7_flash_bank_t *at91sam7_info;
|
||||||
|
int retval;
|
||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
|
@ -926,38 +882,19 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
|
bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
|
||||||
bit = atoi(args[1]);
|
bit = atoi(args[1]);
|
||||||
value = args[2];
|
value = args[2];
|
||||||
|
|
||||||
if (!bank)
|
if (bank == NULL)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
|
return ERROR_FLASH_BANK_INVALID;
|
||||||
return ERROR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
at91sam7_info = bank->driver_priv;
|
if (bank->driver != &at91sam7_flash)
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED)
|
|
||||||
{
|
{
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
|
||||||
}
|
return ERROR_FLASH_BANK_INVALID;
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
at91sam7_read_part_info(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at91sam7_info->cidr == 0)
|
|
||||||
{
|
|
||||||
WARNING("Cannot identify target as an AT91SAM");
|
|
||||||
return ERROR_FLASH_OPERATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
|
|
||||||
{
|
|
||||||
command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(value, "set") == 0)
|
if (strcmp(value, "set") == 0)
|
||||||
|
@ -973,6 +910,28 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
at91sam7_info = bank->driver_priv;
|
||||||
|
|
||||||
|
if (bank->target->state != TARGET_HALTED)
|
||||||
|
{
|
||||||
|
ERROR("target has to be halted to perform flash operation");
|
||||||
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at91sam7_info->cidr == 0)
|
||||||
|
{
|
||||||
|
retval = at91sam7_read_part_info(bank);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
|
||||||
|
{
|
||||||
|
command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure the flash controller timing */
|
/* Configure the flash controller timing */
|
||||||
at91sam7_read_clock_info(bank);
|
at91sam7_read_clock_info(bank);
|
||||||
at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
|
at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
|
||||||
|
|
|
@ -60,8 +60,6 @@ typedef struct at91sam7_flash_bank_s
|
||||||
u8 mck_valid;
|
u8 mck_valid;
|
||||||
u32 mck_freq;
|
u32 mck_freq;
|
||||||
|
|
||||||
int probed;
|
|
||||||
|
|
||||||
} at91sam7_flash_bank_t;
|
} at91sam7_flash_bank_t;
|
||||||
|
|
||||||
/* AT91SAM7 control registers */
|
/* AT91SAM7 control registers */
|
||||||
|
|
|
@ -93,7 +93,7 @@ static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset,
|
||||||
retval=bank->driver->write(bank, buffer, offset, count);
|
retval=bank->driver->write(bank, buffer, offset, count);
|
||||||
if (retval!=ERROR_OK)
|
if (retval!=ERROR_OK)
|
||||||
{
|
{
|
||||||
ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x", bank->base, offset);
|
ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -106,7 +106,7 @@ static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)
|
||||||
retval=bank->driver->erase(bank, first, last);
|
retval=bank->driver->erase(bank, first, last);
|
||||||
if (retval!=ERROR_OK)
|
if (retval!=ERROR_OK)
|
||||||
{
|
{
|
||||||
ERROR("failed erasing sectors %d to %d", first, last);
|
ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -119,7 +119,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last
|
||||||
retval=bank->driver->protect(bank, set, first, last);
|
retval=bank->driver->protect(bank, set, first, last);
|
||||||
if (retval!=ERROR_OK)
|
if (retval!=ERROR_OK)
|
||||||
{
|
{
|
||||||
ERROR("failed setting protection for areas %d to %d", first, last);
|
ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -311,6 +311,7 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
flash_bank_t *p;
|
flash_bank_t *p;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
int retval;
|
||||||
|
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
{
|
{
|
||||||
|
@ -351,8 +352,11 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
erase_state, protect_state);
|
erase_state, protect_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->driver->info(p, buf, 1024);
|
*buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
|
||||||
|
retval = p->driver->info(p, buf, sizeof(buf));
|
||||||
command_print(cmd_ctx, "%s", buf);
|
command_print(cmd_ctx, "%s", buf);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
ERROR("error retrieving flash info (%d)", retval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,7 +922,6 @@ int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
{
|
{
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(args[0], "on") == 0)
|
if (strcmp(args[0], "on") == 0)
|
||||||
|
|
|
@ -80,6 +80,7 @@ extern void flash_set_dirty(void);
|
||||||
extern int flash_get_bank_count();
|
extern int flash_get_bank_count();
|
||||||
|
|
||||||
extern flash_bank_t *get_flash_bank_by_num(int num);
|
extern flash_bank_t *get_flash_bank_by_num(int num);
|
||||||
|
extern flash_bank_t *get_flash_bank_by_num_noprobe(int num);
|
||||||
extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
|
extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
|
||||||
|
|
||||||
#define ERROR_FLASH_BANK_INVALID (-900)
|
#define ERROR_FLASH_BANK_INVALID (-900)
|
||||||
|
|
Loading…
Reference in New Issue