Разумеется, самый очевидный способ не дать злостным пиратам просто взять и спиратить вашу Интеллектуальную Собственность - вырубить единственную аппаратную связь контроллера с миром в лице JTAG-интерфейса.
Поскольку мне недавно удалось без проблем сделать запись и чтение в NVR область флешки, решил рискнуть и попробовать временно выключить JTAG. Делал я это из программы таким способом:
Во-первых, подготовил файл NVR.c, сделано частично на основе исходников от Дыхно.
Код: Выделить всё
/*
* NVR.c
* Чтобы было удобнее работать с FLASH-разделом "NVR"
* контроллера КР1921ВГ015
* E.J.SanYo 2o25
*/
#include <plib015.h>
#include <system_k1921vg015.h>
#include "NVR.h"
//небольшая задержка "на пересинхронизацию", согласно даташиту
void flash_delay(void)
{
uint8_t i;
for (i = 0; i < 5; i++)
__NOP();
}
//стирает страницу в области NVR
void nvr_page_erase(uint32_t addr)
{
FLASH->ADDR = addr;
FLASH->CMD = (FLASH_CMD_KEY_Access << FLASH_CMD_KEY_Pos) | FLASH_CMD_ERSEC_Msk | FLASH_CMD_NVRON_Msk;
flash_delay();
while (FLASH->STAT & FLASH_STAT_BUSY_Msk)
__NOP();
}
//пишет данные в NVR по 4 32-битных слова
void nvr_write_128b(uint32_t addr, uint32_t *data)
{
FLASH->ADDR = addr;
FLASH->DATA[0].DATA = (uint32_t)data[0];
FLASH->DATA[1].DATA = (uint32_t)data[1];
FLASH->DATA[2].DATA = (uint32_t)data[2];
FLASH->DATA[3].DATA = (uint32_t)data[3];
FLASH->CMD = (FLASH_CMD_KEY_Access << FLASH_CMD_KEY_Pos) | FLASH_CMD_WR_Msk | FLASH_CMD_NVRON_Msk;
flash_delay();
while (FLASH->STAT & FLASH_STAT_BUSY_Msk)
__NOP();
}
//читает данные из NVR по 4 32-битных слова
void nvr_read_128b(uint32_t addr, uint32_t *data)
{
FLASH->ADDR = addr;
FLASH->CMD = (FLASH_CMD_KEY_Access << FLASH_CMD_KEY_Pos) | FLASH_CMD_RD_Msk | FLASH_CMD_NVRON_Msk;
flash_delay();
while (FLASH->STAT & FLASH_STAT_BUSY_Msk)
__NOP();
data[0] = FLASH->DATA[0].DATA;
data[1] = FLASH->DATA[1].DATA;
data[2] = FLASH->DATA[2].DATA;
data[3] = FLASH->DATA[3].DATA;
}
Код: Выделить всё
#define __NOP() __asm volatile ("ADDI x0, x0, 0")Код: Выделить всё
#ifndef USER_NVR_H_
#define USER_NVR_H_
void nvr_page_erase(uint32_t);
void nvr_write_128b(uint32_t, uint32_t *);
void nvr_read_128b(uint32_t, uint32_t *);
#endif /* USER_NVR_H_ */
Код: Выделить всё
uint32_t cfg_buffer[4];
.
.
.
//чтобы выключить JTAG
nvr_read_128b(CFGWORD_BASE, cfg_buffer);
cfg_buffer[0] = 0xFFFFFFFB;
InterruptDisable();
nvr_page_erase(CFGWORD_BASE);
nvr_write_128b(CFGWORD_BASE, cfg_buffer);
InterruptEnable();
.
.
.
//чтобы снова включить JTAG
nvr_read_128b(CFGWORD_BASE, cfg_buffer);
cfg_buffer[0] = 0xFFFFFFFF;
InterruptDisable();
nvr_page_erase(CFGWORD_BASE);
nvr_write_128b(CFGWORD_BASE, cfg_buffer);
InterruptEnable();
Может, кто-то придумает, как провернуть всё это через OpenOCD, не засоряя код программы?
