|
STM32 – вопросы – проблемы - решения. |
|
|
|
 |
Ответов
(195 - 209)
|
Jun 29 2011, 18:24
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Вот работающие куски. По крайней мере я несколько раз всё стёр, и зашил и считал тестовые данные  CODE template<typename props> void stm32_flash_t<props>::wait() { while (FLASH->SR & FLASH_SR_BSY) ; }
template<typename props> void stm32_flash_t<props>::delay() { for (volatile int i = 0; i < 0xFF; i++) ; }
template<typename props> bool stm32_flash_t<props>::wait(uint32_t timeout) { while (FLASH->SR & FLASH_SR_BSY) { if (!--timeout) return false; delay(); } return true; }
template<typename props> bool stm32_flash_t<props>::write_halfword(uint32_t addr, uint32_t data) { TCritSect cs; volatile uint16_t* addr_16 = reinterpret_cast<volatile uint16_t*>(addr);
uint32_t cr = FLASH->CR; FLASH->CR = FLASH_CR_PG; wait(); addr_16[0] = data; wait(); FLASH->CR = cr & ~FLASH_CR_PG; return (*(uint16_t*)addr == data); }
template<typename props> bool stm32_flash_t<props>::write(uint32_t addr, void* buf, uint32_t count) { uint8_t* src = static_cast<uint8_t*>(buf); uint32_t end = addr + count;
while (addr < end) { uint32_t w = 0xFFFFFFFF; if ((uint32_t)addr & 1) // odd flash address - step back --addr; else w = 0xFFFFFF00 | (*src++); if (addr < end) w = (w & 0xFFFF00FF) | (*src++ << 8);
if (!write_halfword(addr, w)) return false; addr += 2; } return true; }
template<typename props> bool stm32_flash_t<props>::erase_page(uint32_t addr) { TCritSect cs; wait(); FLASH->CR |= FLASH_CR_PER; FLASH->AR = addr; FLASH->CR |= FLASH_CR_STRT; return wait(PAGE_ERASE_TIMEOUT); }
template<typename props> bool stm32_flash_t<props>::mass_erase() { TCritSect cs; wait(); FLASH->CR |= FLASH_CR_MER; FLASH->CR |= FLASH_CR_STRT; return wait(MASS_ERASE_TIMEOUT); } Что касается тактирования - я ничего специально не включал и не отключал, работал от HSE. (Инициализацию можно посмотреть вот здесь)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 30 2011, 05:04
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(AHTOXA @ Jun 29 2011, 22:24)  Что касается тактирования - я ничего специально не включал и не отключал, работал от HSE. Не помню точно в какой ветке, но я где-то на форуме читал обсуждения, якобы STM32 можно просто «убить» при едино разовом не корректном обращении с flash, камень потом перестает программироваться, читаться и т.п. В чем там прикол? Или просто слухи?
--------------------
Magic Friend
|
|
|
|
|
Jun 30 2011, 06:55
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
УРААА!!!! Заработала хреновина! Я слопушил - адрес страницы для стирания это адрес её первого байта а не порядковый номер страницы как я подумал. Получалось что моя программа сама себя затирала. Вот такой вот заскок мозга случился. Всем большущее спасибо за участие!  Извлёк урок: Чтобы такого геморроя с отладкой не было нужно сразу ставить защиту от стирания на область прошивки и быть внимательнее. Вот выстраданное: Код int flash_page_erase(uint32_t page_address) // page_address not page_number { static const uint32_t FPEC_KEY1 = 0x45670123; static const uint32_t FPEC_KEY2 = 0xCDEF89AB;
int res;
ENTER_CRITICAL_SECTION(); { FPEC->KEYR = FPEC_KEY1; // Authorize the FPEC Access FPEC->KEYR = FPEC_KEY2;
while (FPEC->SR & FPEC_SR_BSY) {;}
FPEC->SR = FPEC_SR_EOP | FPEC_SR_WRPRTERR | FPEC_SR_PGERR; // clr bits by writing 1 FPEC->CR = FPEC_CR_PER; // page erase operation w/o fpec interrupts FPEC->AR = page_address; // page address FPEC->CR = FPEC_CR_STRT | FPEC_CR_PER; // start operation FPEC->SR; // according to errata: must be dummy cycle before polling BSY after START operation
while (FPEC->SR & FPEC_SR_BSY) {;}
res = ((FPEC->SR & FPEC_SR_EOP) != 0);// EOP is asserted at the end of each successful program or erase operation
FPEC->CR = FPEC_CR_LOCK; // Set the Lock Bit to lock the FPEC and the FCR } LEAVE_CRITICAL_SECTION();
return (res); }
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 1 2011, 10:26
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(AHTOXA @ Jun 30 2011, 09:40)  Я тоже это читал. К сожалению, точные причины/алгоритм "убиения" там не были описаны, так что пока считаю на уровне слухов. Кстати, в примере от ST (AN2557 - "in-application programming using the USART") тактирование также производится от HSE. Поработал с Flash, вроде бы все нормально и адекватно. Смотрел примеры из периферийной библиотеки, официальный Programming manual и код пользователя AHTOXA. Кстати в Programming manual клик все таки оговаривается о HSI на стр.10: ”For write and erase operations on the Flash memory (write/erase), the internal RC oscillator (HSI) must be ON.” Но я просто тактировал от HSE, и все нормально было, надобы разобраться что за там прикол. Скорее «убиени проца» у людей происходило из за многократного стирания/записи flash в цикле, просто выработали ресурс поди. Цитата(demiurg_spb @ Jun 30 2011, 10:55)  Код ........................................... ENTER_CRITICAL_SECTION(); ........................................... LEAVE_CRITICAL_SECTION(); } Что там определено, можете привести эти функции?
--------------------
Magic Friend
|
|
|
|
|
Jul 1 2011, 11:27
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Danis @ Jul 1 2011, 14:26)  Что там определено, можете привести эти функции? Пожалуйста. Код #ifndef _ATOMIC_H_ #define _ATOMIC_H_
#ifdef __cplusplus extern "C" { #endif
//============================================================================= static __asm __inline uint32_t get_interrupt_state(void) { mrs r0, primask bx lr }
//============================================================================= static __asm __inline void set_interrupt_state(uint32_t status) { msr primask, r0 bx lr }
#define ENTER_CRITICAL_SECTION() do {uint32_t sreg_temp = get_interrupt_state(); __disable_irq() #define LEAVE_CRITICAL_SECTION() set_interrupt_state(sreg_temp);} while (0)
#ifdef __cplusplus } #endif
#endif Цитата(Danis @ Jul 1 2011, 14:26)  Кстати в Programming manual клик все таки оговаривается о HSI на стр.10 Да я об этом писал несколькими постами ранее.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 1 2011, 20:11
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Цитата(Danis @ Jun 30 2011, 07:04)  Не помню точно в какой ветке, но я где-то на форуме читал обсуждения, якобы STM32 можно просто «убить» при едино разовом не корректном обращении с flash, камень потом перестает программироваться, читаться и т.п. В чем там прикол? Или просто слухи? Сделал собственный бутлоадер. При простой записи ничего с флешью не происходит, при оладке кода некоректности было много, но все решалось простой перепрошивкой в отладчике. Когда начал прорабатывать варианты зашиты кода, вот тут впервые немного поволновался. После установки битов зашиты записи отладчик контроллер не увидел, думал все приплыли надо перепаивть. Но потом SEGGER J-Flash ARM меня спас, закладка Target->Unsecure chip. Так что не получилось пока убить флеш. Пытался использовать USER option byte, но крайне неудобно сделано, особенно если использовать совместно с write protect и закрытым загрузчиком. Думаю пока хватит одной защиты от чтения.
|
|
|
|
|
Jul 9 2011, 23:07
|

Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535

|
Цитата(Flexz @ Jul 9 2011, 23:49)  Спасибо большое, ща тоже нашел её в Design support у 103 их Но что-то странно к 217 стмцы не выкладывают, а в файле что идет в архиве написано что тока недавно появилась поодержка Connectivity Line, хотя они вроде как древние кто-нить испытывал прогу на F2 ?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|