Не получил я ответа на свой вопрос еще раз перечитав ДШ и апноут, и поскольку для спора нет официальных данных, я решил получить ответ на практике.
YS писал(а):молоток ударяет сразу по всем шестнадцати гвоздям
Именно в этом-то я и не был уверен. Прочитав про электрические процессы при программировании флеша, у меня создалось следующее впечатление. Во время программирования весь 64-байтный ряд флеша подвергается воздействию высокого напряжения программирования, и в этом смысле молоток действительно ударяет сразу по всем гвоздям. Однако, это лишь молоточек по сравнению с реальным ударом кувалдой, который получают биты, изменяющие свое состояние из 1 в 0. Короче, по данным апноута, я понял так, что каждый бит способен выдержать в зависимости от частоты тактирования флеша 40-80 ударов молоточком прежде чем забьется по шляпку (т.е. изменит свое состояние из 1 в 0 даже если пользователь все время записывает 1 в этот бит) и лишь 1 удар кувалдой.
Для проверки этой гипотезы код из примера ТИ для работы с флешью был адаптирован следуюшим образом:
Спойлер
Код: Выделить всё
#include <msp430g2231.h>
ORG 0x0F800 ; Program Reset
RESET: mov.w #0x0280, SP ; Initialize stackpointer
mov.w #WDTPW+WDTHOLD, &WDTCTL ; Stop WDT
mov.b &CALBC1_1MHZ, &BCSCTL1 ; Set DCO to 1MHz
mov.b &CALDCO_1MHZ, &DCOCTL
mov.w #0x1040, R10 ; 1st address in SegC
loop: call #Erase_SegC ; erase segment C in info memory
mov.b #0x7F, R5 ; R5 = value to write to flash
mov.b #8, R6 ; R6 = bit counter
wbyte: call #Write_SegC ; write value to segment C
mov.b @R10, R11 ; R11 = value from flash
nop ; set BREAK point here
setc
rrc.b R5 ; update value to write
dec.b R6 ; update bit counter
jnz wbyte
jmp loop ;
;-------------------------------------------------------------------------------
Erase_SegC:
mov.w #FWKEY+FSSEL0+FN1, &FCTL2 ; *Timing generator = MCLK/3
mov.w #FWKEY, &FCTL3 ; Lock = 0
mov.w #FWKEY+ERASE, &FCTL1 ; Erase bit = 1, allow interrupts
mov.w #0, 0(R10) ; Dummy write to SegC to erase
ret
;-------------------------------------------------------------------------------
Write_SegC:
mov.w #FWKEY+WRT, &FCTL1 ; Write bit = 1, block interrupts
mov.w #FWKEY, &FCTL3 ; Lock = 0
mov.b R5, 0(R10) ; write value to flash
mov.w #FWKEY+LOCK, &FCTL3 ; Lock = 1;
ret
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
ORG 0x0FFFE ; MSP430 RESET Vector
DW RESET
END
(извиняюсь за табуляцию, но в IAR будет выглядеть нормально) и произведена проверка его работы живьем на MSP430F2231. В цикле программы первоначальное значение байта 0хFF по адресу 0х1040 (это первый байт Сегмента С информационной памяти) изменялось до 0х00 путем обнуления одного из битов без стирания флеша между записями. Т.е. этот байт в промежутке между стираниями перезаписывался 8 раз. Чтобы исключить повторный удар кувалдой по байту в каждый его бит записывался 0 только 1 раз. Т.е. последовательность записываемых байтов по адресу 0х1040 была следующей:
0x7F - 0xBF - 0xDF - 0xEF - 0xF7 - 0xFB - 0xFD - 0xFE
Каждый байт этой последовательности содержить лишь один 0 и нули эти в разных местах. Записанный байт потом читался из флеша и в отладчике контролировалось его содержимое и состояние остальных байтов сегмента. Оказалось, что во всем сегменте изменялось лишь значение записываемого байта и принимаемые им значения менялись так:
0xFF - 0x7F - 0x3F - 0x1F - 0x0F - 0x07 - 0x03 - 0x01 - 0x00
т.е. каждый раз производилось стирание одной единицы в байте. Затем производилось стирание всего сегмента, в результате которого значение насилуемого байта восстанавливалось до 0хFF, и производилась новая серия его модификаций. Прокрутив всю программу несколько раз никаких побочных эффектов замечено не было. Кто хочет - проверьте сами.
Короче, экспериментально выяснилось, что при соблюдении указанной осторожности, значение байта флеша между стираниями можно изменять до 8 раз.