|
|
  |
Самопрограммирование накристальной флеш виснет, Стирание всей флеши и запись первого байта дают зависание |
|
|
|
Nov 6 2007, 13:29
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554

|
И так, задача: МК перезаписывает свою флеш. Здесь все функции RAM. Стирание всей флеши и запись первого байта (ПРОВЕРЕНО, МК ВИСНЕТ ИМЕННО ПОСЛЕ ЗАПИСИ 1го байта) дают зависание, вот код, помогите пожалуйста...
void Ram_Func_Program_Flash (void) { _DINT(); IE1 &= ~BIT0;//asm ("clr.b &0") ; // 0 = IE1 блокировка NMI, ACCV и OF прерываний UINT8 Buffer_1_Byte; // Стереть сразу всю флеш WDTCTL = WDTPW + WDTHOLD; // Выключим WDT //FCTL2 = ( FWKEY | FSSEL_1 | 16 ); // частота тактового генератора flash FCTL2 = ( FWKEY | FSSEL_1 | 16 ); // частота тактового генератора flash FCTL3 = FWKEY; // очистим LOCK разрешим программирование-стирание FCTL1 = FWKEY | MERAS; // Стереть сразу всю флеш *(UINT16*)(0x4000 ) = 0; // фиктивная запись для запуска процедуры стирания сегмента while ( (FCTL3 & BIT0)==1 ) _NOP(); //wait while busy flag is 1 FCTL3 = FWKEY | LOCK; // выполнено, установим LOCK обратно for (UINT8 Block_Num=0; Block_Num<6; Block_Num++) { //Пришла команда, // Пишем блоки со 2-го по шестой // использльзовать в RAM доступ к плис, ram-версия драйвера плис // Вычитываем из плис 8КБ данных и побайтно пишем их в // блоки, предварительно их стирая // использльзовать в RAM доступ к плис, ram-версия методов записи и чтения драйвера плис for (UINT16 i = 0; i <= 8192 - 1; i++) // Читаем из BAR1 очередную порцию(8К) от прошивки {
Buffer_1_Byte = Read_From_FPGA_Byte_RAM_Ptr_Global(DPM_MEMORY_WINDOW_OFFSET +offsetof( DPM_DATA_PACKET, ExtData) +offsetof (DPM_TM_WRITE_MEM_IN,Data) + i ); FCTL2 = ( FWKEY | FSSEL_1 | 16 ); // частота тактового генератора flash FCTL3 = FWKEY; // очистим LOCK разрешим программирование-стирание FCTL1 = FWKEY | WRT; // разрешение записи *(BYTE*)(0x4000 + Block_Num*8192 + i) = Buffer_1_Byte; // пишем байт //<------------------------------(ПРОВЕРЕНО, МК ВИСНЕТ ИМЕННО ПОСЛЕ ЗАПИСИ 1го байта) while ( (FCTL3 & BIT0)==1 ) _NOP(); //wait while busy flag is 1 FCTL1 = FWKEY; // выполнено, очистка WRT FCTL3 = FWKEY | LOCK; // выполнено, установим LOCK обратно } Write_To_FPGA_Byte_RAM_Ptr_Global(DPM_MEMORY_WINDOW_OFFSET + offsetof(DPM_DATA_PACKET, byExtDataStructType) ,EST_NONE); Write_To_FPGA_Byte_RAM_Ptr_Global(DPM_MEMORY_WINDOW_OFFSET ,DPM_STATUS_OK); // Выдать IRQ через ПЛИС к PCI-E Write_To_FPGA_Byte_RAM_Ptr_Global(DPM_CPU_INTERRUPT_ADDR, COMMAND_PROGRAMM_MCU_FLASH + Block_Num + 1); // Ожидание инкремнированной команды UINT8 Com = Read_From_FPGA_Byte_RAM_Ptr_Global(DPM_MCU_INTERRUPT_ADDR); while (Com != COMMAND_PROGRAMM_MCU_FLASH + Block_Num ) Com = Read_From_FPGA_Byte_RAM_Ptr_Global(DPM_MCU_INTERRUPT_ADDR); } [size=1] Спасибо Вам!
Сообщение отредактировал Bom_Shankar - Nov 6 2007, 13:58
|
|
|
|
|
Nov 6 2007, 17:22
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
А вы контролировали в асм-овом исходнике как эта команда Код *(BYTE*)(0x4000 + Block_Num*8192 + i) = Buffer_1_Byte; компилируется? И нельзя ли ее записать "по-человечески", с использованием указателя? Что-то типа Код BYTE *ptr_block=(BYTE *)0x4000; ptr_block+=(BYTE *)(Block_Num*8192); ptr_block[i]=Buffer_1_Byte;
|
|
|
|
|
Nov 7 2007, 08:27
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554

|
Цитата(rezident @ Nov 6 2007, 20:22)  А вы контролировали в асм-овом исходнике как эта команда Код *(BYTE*)(0x4000 + Block_Num*8192 + i) = Buffer_1_Byte; компилируется? И нельзя ли ее записать "по-человечески", с использованием указателя? Что-то типа Код BYTE *ptr_block=(BYTE *)0x4000; ptr_block+=(BYTE *)(Block_Num*8192); ptr_block[i]=Buffer_1_Byte; Компилируется *(BYTE*)(0x4000 + Block_Num*8192 + i) = Buffer_1_Byte; // пишем байт в MOV.B R10, R12 AND.W #0xff, R12 MOV.W #0x2000, R14 CALL #?Mul16 ADD.W #0x4000, R12 ADD.W R9, R12 MOV.B R8, 0(R12) А на счёт формы записи - так у меня просто компактно в одну строчку, по сути тоже самое. Ваш примерчик попробовал - не помогло, тоже самое . Видно здесь какой-то скрытый ньюанс именно с флеш. В предыдущем варианте реализации этой же задачи у меня тоже не получилось полностью, но что интересно, там я делал поблочное стирание флешки, а не как здесь целиком, и вот где-то условно в середине флешки тоже всё зависало, но при этом часть флешки удавалось записать, во всяком случае запись не подвешивала МК(до какого-то места в середине флеш).
|
|
|
|
|
Nov 7 2007, 09:15
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554

|
Цитата(Сергей Борщ @ Nov 7 2007, 11:54)  Что значит "зависание"? Контроллер парит над столом или все же исполняет код в цикле и не возникает условие выхода или пытается исполнить команду по какому-то адресу из флеш, а поскольку флеш стерта - считывает оттуда код команды безусловного перехода на себя? В последнем случае у вас или разрешены прерывания (а вектора стерты), либо срабатывает собака. Да в том то и проблема, что ничего из перечисленного как-то не вероятно. После первой попытки записи код останавливается, если же закоментить именно эту строчку, то весь цикл отрабатывает хорошо до конца (и это уже при стёртой полностью флеш). Прерывания запрещены и Собака отключена, что не мешает циклу без записи завершаться. Все функции в RAM, поэтому даже со стёртой флешкой цикл завершается нормально без записи(опять-таки не прерывания, ни собака не возникают никоим образом). Стоит только сделать запись (в той злосчастной строчке ), как МК виснет. Как именно виснет, сложно сказать, код в РАМ, смотрю без отладчика, ну во всяком случае это не IRQ, не WDT и не обращение за кодом из флеш.
|
|
|
|
|
Nov 7 2007, 10:09
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
Цитата CALL #?Mul16 А этот мул находится во флэше, которую стёр. Подготовь указатель до начала стирания/записи и проконтролируй по листингу, чтоб было только ++ и никаких вызовов функций. Для справки, call - это вызов подпрограммы....
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Nov 7 2007, 10:49
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554

|
Да, скорее всего в этом дело, мне же уже подсказали посмотреть АСМ, а я не заметил вызова MUL, сейчас исправлю.
Да, скорее всего в этом дело, мне же уже подсказали посмотреть АСМ, а я не заметил вызова MUL, сейчас исправляю.
|
|
|
|
|
Nov 8 2007, 11:13
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554

|
Ура, всё получилось! В сухом остатке: нужно сверяться по map файлу на предмет вызовов из флеш, когда уже всё стёрто, как в моём случае - функция программирования работала из Ram. Скрытым подводным камнем была операция умножения, неочивидно приводящая к зависанию, так как вызывала MUL, котрой уже не было. Всем спасибо!
|
|
|
|
|
Nov 14 2007, 04:43
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
Цитата Просто хочу не наступать на такого рода грабли Включите генерацию ассемблерного листинга и смотрите, что компилер делает. Это 100%-ный способ. При максимальной оптимизации ИАР 3.30а заменяет, например, умножение на 512 или сдвиг на 9 влево вызовом библиотечной функции Код 435 // cur *= Fixed_Point_m; 436 cur <<= 9; \ 000010 B012.... CALL #?ShiftLeft32_4 \ 000014 B012.... CALL #?ShiftLeft32_5 Код 435 cur *= Fixed_Point_m; \ 000010 B012.... CALL #?ShiftLeft32_4 \ 000014 B012.... CALL #?ShiftLeft32_5
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|