|
|
 |
Ответов
|
Oct 20 2015, 12:34
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 23-12-10
Пользователь №: 61 816

|
Цитата(aaarrr @ Oct 20 2015, 14:52)  У ARM7TDMI нет ни кэша ни буфера записи. Ну я это подозревал. Тогда придется изложить, что же я наблюдаю. Код такой В *.h-файле: Код __no_init volatile unsigned long ForceReprogrammingSignature @ 0x40008000; В *.cpp-файле функция: Код void ForceReprogramming(bool Monopoly) { ForceReprogrammingSignature = 0x085D0B75; // asm("nop"); // маленькая задержка в пять ассемблерных команд - если раскомментировать, не помогает (возвращается старое значение) // asm("nop"); // asm("nop"); // asm("nop"); // asm("nop"); // volatile unsigned long x = ForceReprogrammingSignature; // чтение (в ассемблере две команды) - если раскомментировать, помогает (сохраняется записанное значение)
// vTaskDelay(10/portTICK_RATE_MS); // большая задержка в 10 мс - если раскомментировать, помогает (сохраняется записанное значение)
if (Monopoly) __disable_interrupt(); // при Monopoly == true запрещаем прерывания
PCLKSEL0_bit.PCLK_WDT = 1; // далее взводим WDT WDTC = CCLK / 4 * 5; // на 5 секунд WDMOD_bit.WDEN = 1; WDMOD_bit.WDRESET = 1; WDCLKSEL_bit.WDSEL = 1; WDFEED = 0xAA; WDFEED = 0x55;
if (Monopoly) // при Monopoly == true из функции не возвращаемся while (1); } Так вот, изначально в ForceReprogrammingSignature некое значение, назовем его "старым значением". Далее разные варианты: 1. Вызываем ForceReprogramming(false), она записывает в ForceReprogrammingSignature сигнатуру 0x085D0B75, назовем это "записанное значение", запускает WDT, возвращается, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "записанное значение", все ок, вопросов нет. 2. Вызываем ForceReprogramming( true), она записывает в ForceReprogrammingSignature сигнатуру, без задержки запрещает прерывания (тем самым в частности останавливает планировщик FreeRTOS), запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "старое значение", офигеваем. 3. Вызываем ForceReprogramming(true) с раскомментированной задержкой на 10 мс, она записывает в ForceReprogrammingSignature сигнатуру, через 10 мс запрещает прерывания, запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "сохраненное значение". 4. Вызываем ForceReprogramming(true) с закомментированной задержкой на 10 мс, но с раскомментированным чтением, она записывает в ForceReprogrammingSignature сигнатуру, тут же считывает ее (две ассемблерные команды), запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "сохраненное значение". 5. Вызываем ForceReprogramming(true) с закомментированными задержкой на 10 мс и чтением, но с раскомментированной задержкой из пяти nop'ов, она записывает в ForceReprogrammingSignature сигнатуру, выполняет 5 пустых команд, запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "старое значение". Вот и создается такое впечатление, как будто оператор Код ForceReprogrammingSignature = 0x085D0B75; пишет физически в кэш, и если после этого сразу отключить прерывания, то значение из кэша не успевает сброситься в "настоящий" RAM, поэтому после перезагрузки по WDT снова читаем оттуда старое значение. Звучит бредово, поэтому ищу другую версию )
Сообщение отредактировал murug - Oct 20 2015, 12:56
|
|
|
|
|
Oct 21 2015, 04:36
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(murug @ Oct 20 2015, 18:34)  2. Вызываем ForceReprogramming(true), она записывает в ForceReprogrammingSignature сигнатуру, без задержки запрещает прерывания (тем самым в частности останавливает планировщик FreeRTOS), запускает WDT, виснет в бесконечном цикле, через 5 секунд программа перезапускается, видим в ForceReprogrammingSignature "старое значение", офигеваем. И что? Очевидно, что startup инитит эту Вашу ForceReprogramming неким значением, либо эта область используется ROM-загрузчиком, либо используется самим startup на какие-то его нужды, ... Эксперимент проведён некорректно. Читайте юзермануал на предмет: какие области используются ROM-загрузчиком. И ставьте бряк не в функции main(), а сразу после вектора сброса. Чудес не бывает.
|
|
|
|
|
Oct 21 2015, 05:55
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 23-12-10
Пользователь №: 61 816

|
Цитата(jcxz @ Oct 21 2015, 07:36)  И что? Очевидно, что startup инитит эту Вашу ForceReprogramming неким значением, либо эта область используется ROM-загрузчиком, либо используется самим startup на какие-то его нужды, ... Эксперимент проведён некорректно. Читайте юзермануал на предмет: какие области используются ROM-загрузчиком. И ставьте бряк не в функции main(), а сразу после вектора сброса. Чудес не бывает. По-моему Вы невнимательно читали. В переменной ForceReprogrammingSignature восстанавливается значение, которое там было до вызова функции ForceReprogramming. Каким бы это значение не было. Ну и помимо того: 1. переменная помечена __no_init; 2. секция, в которую она помещена, указана для линкера do not initialize; 3. бряк ставил на первые выполняемые ассемблерные команды, уже там видел в отладчике "старое" значение в ForceReprogrammingSignature; 4. пробовал размещать переменную по двум разным адресам, результат один и тот же; 5. ну и в конце концов в случае описанных заплаток-то значение сохраняется. Цитата(aaarrr @ Oct 20 2015, 23:34)  Такое не работать просто не может, а в чудеса не очень верится. Что будет, если записать несколько чисел подряд? Попробую. Кстати, вспомнил - под отладчиком видел что внутри функции сигнатура 0x085D0B75 в переменную кладется. А вот после перезагрузки в самом начале cstartup.s - уже снова старое значение.
|
|
|
|
|
Oct 21 2015, 06:09
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 23-12-10
Пользователь №: 61 816

|
Цитата(zltigo @ Oct 21 2015, 09:00)  То есть весь этот вынос мозга Вы устраиваете по причине того, что сие оказывается "видит" отладчик?! Не совсем. То, что в ячейке "старое" значение, я вижу и без отладчика, но смотрю уже не на этапе выполнения cstartup.s, а после, когда все инициализации прошли и работает графический интерфейс у программы.
|
|
|
|
|
Oct 21 2015, 07:10
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (murug @ Oct 21 2015, 09:09)  Не совсем. То, что в ячейке "старое" значение, я вижу и без отладчика, но смотрю уже не на этапе выполнения cstartup.s, а после, когда все инициализации прошли и работает графический интерфейс у программы. Тем неменее 1) Никаких отладчиков для разборок с эффектом НЕ применять. 2) Никаких отображений далеко после старта через графический интерефейс - тоже. Тупо и просто в startup НИЧЕГО сложнее, чем изменить состояние какого-нибудь пина не предпринимать. Причем изменеие состояния пина обязательно контролировать по времени от снятия сброса с контроллера.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 07:35
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 23-12-10
Пользователь №: 61 816

|
Цитата(zltigo @ Oct 21 2015, 10:10)  Тем неменее 1) Никаких отладчиков для разборок с эффектом НЕ применять. 2) Никаких отображений далеко после старта через графический интерефейс - тоже. Тупо и просто в startup НИЧЕГО сложнее, чем изменить состояние какого-нибудь пина не предпринимать. Причем изменеие состояния пина обязательно контролировать по времени от снятия сброса с контроллера. Такие рекомендации исходя из предположения, что значение в ячейке все-таки какой-то программной инициализацией меняется, правильно я Вас понимаю? Цитата(aaarrr @ Oct 20 2015, 23:34)  Такое не работать просто не может, а в чудеса не очень верится. Что будет, если записать несколько чисел подряд? Попробовал писать подряд несколько разных значений. Получается, что после рестарта имеем в ячейке значение, которое записывалось предпоследней записью. Это если без последующего чтения, а если с ним - то сохраняется с последней записи. В ассемблерном листинге последняя запись безукоризненно присутствует наряду со всеми.
|
|
|
|
|
Oct 21 2015, 08:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (murug @ Oct 21 2015, 10:35)  Такие рекомендации исходя из предположения, что значение в ячейке все-таки какой-то программной инициализацией меняется, правильно я Вас понимаю? Да. Такие изменения делает какой-то конкретный кусок кода. Противное было-бы чисто чудом. Чудес в 21 веке не бывает. Я лично использую подобный подход - занесение массива данных и считывания его после перезапуска, достаточно широко. Например, в любом моем загрузчике используется область памяти для сохранения картины exception. Тоже пишется массив, записывается сигнатура наличия данных. При запуске основной программы распечатывается. Нималейших проблем, в том числе и на LPC2468. А чем вызвано фиксированное и причем в очень странном месте - середине памяти месторасположение этой сигнатуры? Нет, это как бы не криминал, но странно. Официально нельзя располагать подобное только в прследних 32 байтах памяти, которые используются заводским загрузчиком. QUOTE (murug @ Oct 21 2015, 11:03)  Встает вопрос, однако, где можно найти так сказать официальную инфу о наличии такой штуки в ARM7TDMI? Нет такой штуки у несчастного ARM7. Не говоря уже о том, что после этой записи контроллер по любому у Вас производит неоднократные записи при манипуляции с WD.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 08:48
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 23-12-10
Пользователь №: 61 816

|
Цитата(zltigo @ Oct 21 2015, 11:11)  Да. Такие изменения делает какой-то конкретный кусок кода. Противное было-бы чисто чудом. Я бы понял, если бы этот кусок какое-то фиксированное значение в ячейку заносил. Но он угадывает, что там было до последней записи... Что по-моему является еще бОльшим чудом ) Цитата(zltigo @ Oct 21 2015, 11:11)  Я лично использую подобный подход - занесение массива данных и считывания его после перезапуска, достаточно широко. А такая ситуация, что после последней записи и перед перезагрузкой нет обращений к on-chip static RAM, у Вас возникает? Цитата(zltigo @ Oct 21 2015, 11:11)  А чем вызвано фиксированное и причем в очень странном месте - середине памяти месторасположение этой сигнатуры? Нет, это как бы не криминал, но странно. Официально нельзя располагать подобное только в прследних 32 байтах памяти, которые используются заводским загрузчиком. Это уже в процессе экспериментов туда переместил, изначально как раз перед упомянутыми 32 байтами было. Цитата(zltigo @ Oct 21 2015, 11:11)  Нет такой штуки у несчастного ARM7. Не говоря уже о том, что после этой записи контроллер по любому у Вас производит неоднократные записи при манипуляции с WD. Эти записи в область AHB или APB peripherals, а не on-chip static RAM, видимо дело в этом. Вообще вроде удалось найти инфу (несколько зыбкую), что даже и кэш имеется: Вот здесь:Цитата Naming Conventions ... ARMx2z (e.g. ARM720T) indicates cache, MMU & Process ID support А что 2478 - это ARM720T - например вот здесь
|
|
|
|
|
Oct 21 2015, 09:13
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (murug @ Oct 21 2015, 11:48)  А такая ситуация, что после последней записи и перед перезагрузкой нет обращений к on-chip static RAM, у Вас возникает? Вообще-то сама "перезагрузка" это ВХОД В ЗАВОДСКОЙ загрузчик, где этих обращений явно хватает. Это раз. А то, что Ваши чудотворно действующие нопы это никак не обращение к памяти - это два. QUOTE А что 2478 - это ARM720T - например вот здесьА это ничего, что ПРОИЗВОДИТЕЛЬ конроллера пишет о своем изделии в Product data sheet - ARM7TDMI-S processor, running at up to 72 MHz
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 09:52
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (aaarrr @ Oct 21 2015, 12:24)  Ну, "перезагрузка" - это еще и сброс, который мог бы очистить буфер записи при его наличии. При наличии - да. Но его нет, а есть напротив куча команд - ну тот-же вечный цикл продолжающийся 5 секунд и команды в нем выпоняющиеся как-бы ничем не хуже несеольких нопов, которые типа "помогают". Вообще-то таинственные явления в NXP есть  - я не далее месяца тому назад в старом модернизируемом изделии на LPC2103 локализовал эффект, кода при работе SPI находящемся в режиме slave и тактирующимся софтовым мастером контроллер прерываний формировал нулевой вектор раз в несколько суток. Ничего из описанного в errata под этот эффект подогнать не удалось. Пришлось предпринимать близкие к шаманским действия  QUOTE (murug @ Oct 20 2015, 15:34)  PCLKSEL0_bit.PCLK_WDT = 1; // далее взводим WDT WDTC = CCLK / 4 * 5; // на 5 секунд WDMOD_bit.WDEN = 1; WDMOD_bit.WDRESET = 1; WDCLKSEL_bit.WDSEL = 1; WDFEED = 0xAA; WDFEED = 0x55; А если к этому добавить: CODE WDFEED = 0xAA; WDFEED = 0x5A; то есть перезепуск без 5 секунд? И еще, инициализация WD и в случае Monopoly=FALSE должна производиться при запрещенном прерывании, ибо любое вкоинивание прерывания это мгновенный перезапуск.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 09:55
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(zltigo @ Oct 21 2015, 15:45)  Вообще-то таинственные явления в NXP есть  - я не далее месяца тому назад в старом модернизируемом изделии на LPC2103 локализовал эффект, кода при работе SPI находящемся в режиме slave и тактирующимся софтовым мастером контроллер прерываний формировал нулевой вектор раз в несколько суток. Ничего из описанного в errata под этот эффект подогнать не удалось. Пришлось предпринимать боизкие к шаманским действия  Давно уже работал с LPC2378, но вроде смутно помнится, что был подобный баг в контроллере прерываний. И он был описан в еррата. И даже в соотв. порту uCOS было указано. Если это конечно он. Заключался он в том, что при чтении адреса вектора прерывания из VIC, мог считаться ноль - это ложное прерывание. Фрагмент моего ISR для IRQ где это проверяется: Код ISRirq: SUB LR, LR, #4 STMFD SP!, {R0-R3, R12, LR} MVN R1, #255 ;VICAddress LDR R0, [R1] CMP R0, #0 ;проверка на ложное IRQ STRNE R1, [R1] ;acknowlege IRQ MOVNE LR, PC BXNE R0 CMP R0, #0 LDMFDEQ SP!, {R0-R3, R12, PC}^;выйти если нет сис. вызовов ...
|
|
|
|
|
Nov 16 2015, 12:13
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (jcxz @ Oct 21 2015, 11:55)  Давно уже работал с LPC2378, но вроде смутно помнится, что был подобный баг в контроллере прерываний. И он был описан в еррата. Посмотрел еще раз в свежайшие errata - увы, ничего подобного не описано. QUOTE И даже в соотв. порту uCOS было указано. Очень бы хотелось взглянуть на то, что в uCOS написано. Это было просто в исходниках откомментировано, или какой то документ? QUOTE Если это конечно он. Описанной ситуации соответствует. Явную заплатку не делал - стучал в бубен в месте опроса-сброса SPI прерывания. Но хотелось-бы явного понимания что надо делать. QUOTE (GetSmart @ Nov 16 2015, 04:53)  Часто в векторе IRQ стоит что-то вроде LDR PC,[PC, #-xxx]. Оптимальнее будет ложный нулевой адрес "ловить" в ResetVector-е по значению младших пяти бит CPSR, равных режиму IRQ. Делал подобное для локализации проблемы вылета, но просто возвратиться не подумал. Пожалуй это вариант.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
Сообщений в этой теме
murug Кэширование записи в RAM в LPC2478? Oct 20 2015, 11:26  aaarrr Цитата(murug @ Oct 20 2015, 15:34) Вот и ... Oct 20 2015, 12:58   murug Цитата(aaarrr @ Oct 20 2015, 15:58) А Вы ... Oct 20 2015, 13:12        aaarrr Цитата(murug @ Oct 21 2015, 10:35) Попроб... Oct 21 2015, 07:44          aaarrr Цитата(murug @ Oct 21 2015, 11:48) А что ... Oct 21 2015, 09:04               jcxz Цитата(zltigo @ Nov 16 2015, 18:13) Очень... Nov 16 2015, 13:30                zltigo QUOTE (jcxz @ Nov 16 2015, 15:30) Ну или ... Nov 16 2015, 14:13                zltigo QUOTE (jcxz @ Nov 16 2015, 15:30) Так что... Nov 16 2015, 17:08                 jcxz Цитата(zltigo @ Nov 16 2015, 23:08) Зашел... Nov 17 2015, 04:56                  zltigo QUOTE (jcxz @ Nov 17 2015, 06:56) Ну что ... Nov 17 2015, 07:55           murug Цитата(zltigo @ Oct 21 2015, 12:13) Вообщ... Oct 21 2015, 10:10 GetSmart Цитата(aaarrr @ Oct 20 2015, 15:52) У ARM... Nov 16 2015, 02:53 aaarrr Можно все же увидеть листинг? Как-то уж очень чуде... Oct 20 2015, 13:25 murug Цитата(aaarrr @ Oct 20 2015, 16:25) Можно... Oct 20 2015, 14:30 aaarrr Такое не работать просто не может, а в чудеса не о... Oct 20 2015, 20:34 gerber Классический механизм "posted write" (... Oct 21 2015, 07:45 murug Цитата(gerber @ Oct 21 2015, 10:45) Класс... Oct 21 2015, 08:03  aaarrr Цитата(murug @ Oct 21 2015, 11:03) Встает... Oct 21 2015, 08:15 gerber Помимо ядра процессора с памятью может работать и ... Oct 21 2015, 10:26 aaarrr Цитата(gerber @ Oct 21 2015, 13:26) А не ... Oct 21 2015, 10:35 zltigo http://electronix.ru/forum/index.php?showt...=1312... Oct 24 2015, 16:26 murug Цитата(zltigo @ Oct 24 2015, 19:26) http:... Oct 27 2015, 12:22 zltigo Дошли руки. Заплатку на NULL вектор вставил по вар... Jan 6 2016, 09:51 ar__systems EMCStaticConfig0 bit 19 Feb 2 2016, 23:12 zltigo QUOTE (ar__systems @ Feb 3 2016, 01:12) E... Feb 2 2016, 23:19  ar__systems Цитата(zltigo @ Feb 2 2016, 18:19) К чему... Feb 2 2016, 23:39
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|