Jump to content

    

Recommended Posts

Добрый день.

Попал недавно в ситуацию аналогичную той, которая случилась когда я работал давным-давно автослесарем, ремонтируя крайслеры. Приехал клиент на Чероки, старом еще, похожим на кирпичь. Я спросил, что у него болит и был оочень удивлён его абсолютно нестандартным ответом. Мужик достал лист А4 весь исписанный убористым почерком и начал "констатировать симптомы". "При повороте налево при скорости от 10 до 20 км/ч дребезг в районе раздатки, при торможении на скорости 40-60 км/ч постукивание заднего моста, на неровной дороге громыхание по всему кузову и т.д. и т.п........". Через минуту, когда моё удивление прошло, и мужик уже добрался до второй трети своих недугов, я его решительно остановил, забрался под машину даже не утруждаясь поднять её на подъёмнике и двумя пластиковыми хомутами закрепил троссики стояночного тормоза. Не обращая внимание на возражения владельца машины что "Он ещё не все неисправности мне описал", отправил его на обкатку. Через пять минут вернулся клиент, ещё более удивлённый, чем до этого был я. Конечно его первый вопрос "А что было то???".

А быто просто то, что пластиковые клипсы крепления двух троссов стояночного тормоза к балкам кузова развалились и троссы стучали по кузову, по рычагам.

Что касается настоящего времени. Делаю я контактную сварку с управлением по току с помощью n-го кол-ва симисторов, коммутирующих первичку транса. Выбрал для этого китайскую платку с stm32f030f4 rev.A. Ног всего 20, катастрофически нехватает, но 2 я оставил для USART - в дальнейшем хочу прикрутить к сварке еще другие узлы. Программа заливается по stlink через плату stm32vldiscovery. На ней кроме stlink есть stm32f100RB rev.Z. На плате кнопка есть, светодиодиков два, и решил я с неё по USART управлять stm32f030f4 для включения транса просто отправляя байтик. Приборов особых нет, что бы визуализировать передачу на ногу TX USART1 stm32f100RB повесил светодиод, в baud rate register забил 0xFFFF, тактирование APB2 уменьшил на 8 (USART1 сидит на APB2, всё тактируется от HSI 8MHz) и ...... ничего не получил. Даже idle line. Светодиод не засветился. Налетел я на первый косяк с выбором baud rate. Дело в том, что в RM0360 про stm32f030f4, в параграфе про auto baud rate указано минимальное значение для скорости передачи - fCK/65535. Вот я и забил 0xFFFF. После недели плясок с бубном нашёл предельное значение - 0xFFF7. Оно оказалось одинаково для всех чипов которые у меня есть - stm030, stm051, stm100, stm303, stm334. Правда в отличии от stm100 у всех остальных idle line активировалось, но передачи при 0xFFFF не было. Решив этот косяк я напоролся вооще на непонятное мне поведение stm32f100RB в данном коде:

				movs	r10,#0
				movs	r11,#1
;Handler mode
EXTI0_IRQ_		PROC
				cpsid	i
				ldr		r0,=USART1_DR
				movs	r1,#2_11010111
				strh	r1,[r0]
				ldr		r0,=GPIOC_BSRR
				movw	r1,#0x200
				str		r1,[r0]
				mov32	r2,#0x7A1200
LEDloop
				subs	r2,#1
				BNE		LEDloop
				lsl		r1,#16
				str		r1,[r0]
 				ldr		r0,=a_EXTI_PR0
				str		r11,[r0]	;clear interrupt flag in EXTI_PR0
				cpsie	i

				BX		LR
  				ALIGN
  				ENDP

- кнопка на ноге A0 и запускает обработчик внешнего прерывания EXTI0. В нем загорается светодиод, USART1 выталкивает байт, потом цикл считает до 8000000, делая задержку в 3 сек, гаснет светодиод и наконец снимается флаг отложенного прерывания в модуле внешних прерываний и выход из EXTI0. Всё вроде просто, но ! Байт выталкивался дважды! и задержка была 6 сек. Очередные пляски с бубном и, оказывается, что это происходит, когда делитель APB2 больше чем 4. В остальных случаях всё нормально. Тут я встал на путь владелца Черокки, испытал это на разных контроллерах, с прерываниями от разных источников, с разными baud rate, на разных шинах, получил совершенно непохожие результаты и запутался окончательно.

Решение было как с пластиковыми хомутами. Подказали мне его на stm community forum, но в какой странной форме "Всем хорошо известно, что необходимо сразу же после входа в обработчик прерывания, стнят флаг этого прерывания в модуле, который его вызвал". Это где же "хорошо известно"??? Я весь референс мануал прчитал и не нашёл "хорошо известных" рекрмендаций!!

Ну и напоследок нашёл еще одну ж..у с внешним прерыванием. Необходимо при входе в обработчик не только сразу же снять флаг, но и маскировать это прерывание, иначе, если нет приборной компенсации дребезга контактов, произойдет ложный вызов обработчика, и включить его перед выходом. Вот так:

				movs	r10,#0
                movs	r11,#1
;Handler mode
EXTI0_IRQ_		PROC
				cpsid	i
				movs	r10,#0
				movs	r11,#1
				ldr		r3,=a_EXTI_IMR0
				str		r10,[r3]
				ldr		r0,=a_EXTI_PR0
				str		r11,[r0]	;clear interrupt flag in EXTI_PR0
				ldr		r0,=USART3_DR
				movs	r1,#2_11010111
				strh	r1,[r0]
				ldr		r0,=GPIOC_BSRR
				movw	r1,#0x200
				str		r1,[r0]
				mov32	r2,#0x7A1200
LEDloop
				subs	r2,#1
				BNE		LEDloop
				lsl		r1,#16
				str		r1,[r0]
				str		r11,[r3]
				cpsie	i

				BX		LR
				ALIGN
				ENDP

 

Share this post


Link to post
Share on other sites

А вопрос-то в чем?

Процедура сброса pending-битов прерываний следует из логики работы контроллера прерываний NVIC.

Его работу Вы можете найти, например, тут, но лучше читать первоисточник (глава B3.4 Nested Vectored Interrupt Controller, NVIC).

Референс-мануалы на конкретные МК не должны в принципе описывать поведение составных частей ядра, если только ядро не реализует ту или иную функцию как IMPLEMENTATION DEFINED.

 

P.S. Вообще говоря, вешать дребезжащие кнопки на внешнее аппаратное прерывание - не самая лучшая идея. На грани с бредовой.

P.S. Зачем в таком ПО ассемблер? Почему не написать на Си?

Share this post


Link to post
Share on other sites
5 hours ago, ЯЛёша said:

После недели плясок с бубном нашёл предельное значение - 0xFFF7

Похоже на настоящий баг.

 

5 hours ago, ЯЛёша said:

Всё вроде просто, но ! Байт выталкивался дважды! и задержка была 6 сек. Очередные пляски с бубном и, оказывается, что это происходит, когда делитель APB2 больше чем 4.

Из-за слишком низкой частоты APB флаг оставался активным после выхода из процедуры прерывания - все правильно.

 

5 hours ago, ЯЛёша said:

Ну и напоследок нашёл еще одну ж..у с внешним прерыванием.

А это не ж, а норма жизни.

Share this post


Link to post
Share on other sites
12 часов назад, ЯЛёша сказал:

Ну и напоследок нашёл еще одну ж..у с внешним прерыванием. Необходимо при входе в обработчик не только сразу же снять флаг, но и маскировать это прерывание, иначе, если нет приборной компенсации дребезга контактов, произойдет ложный вызов обработчика, и включить его перед выходом. Вот так:


				movs	r10,#0
                movs	r11,#1
;Handler mode
EXTI0_IRQ_		PROC
				cpsid	i
				movs	r10,#0
				movs	r11,#1
				ldr		r3,=a_EXTI_IMR0
				str		r10,[r3]
				ldr		r0,=a_EXTI_PR0
				str		r11,[r0]	;clear interrupt flag in EXTI_PR0
				ldr		r0,=USART3_DR
				movs	r1,#2_11010111
				strh	r1,[r0]
				ldr		r0,=GPIOC_BSRR
				movw	r1,#0x200
				str		r1,[r0]
				mov32	r2,#0x7A1200
LEDloop
				subs	r2,#1
				BNE		LEDloop
				lsl		r1,#16
				str		r1,[r0]
				str		r11,[r3]
				cpsie	i

				BX		LR
				ALIGN
				ENDP

 

Автору следовало больше потратить слов на описание того, что он привёл, вместо словесного поноса, не относящегося к делу. Это что - код ISR или что вообще такое??? :wacko2:

Если это ISR, то на кой в ней делать глобальный запрет прерываний CPSID/CPSIE? Автору стоит почитать что такое NVIC, и что такое уровни приоритета прерываний.

Если это ISR, то порча регистров R10, R11 - это тоже нормальное поведение программы? Или автор в фоне/других ISR эти регистры сейчас не пользует и поэтому выстрел в ногу даёт промах? :biggrin:

Да и цикл на 0x7A1200 проходов внутри ISR - это нечто...  :unknw:

 

PS: Что такое "movs r1,#2_11010111" - такого синтаксиса вообще не понимаю. Из какого это ассемблера?

 

12 часов назад, ЯЛёша сказал:

Ну и напоследок нашёл еще одну ж..у с внешним прерыванием. Необходимо при входе в обработчик не только сразу же снять флаг, но и маскировать это прерывание, иначе, если нет приборной компенсации дребезга контактов, произойдет ложный вызов обработчика, и включить его перед выходом. Вот так:

Утверждать не буду, но подозреваю, что лучше не маскировать/квитировать, а просто перед выходом из ISR очистить ожидающее прерывание в EXTI_PR и в NVIC.CLRPEND для соответствующего вектора.

Потому как в коде автора нет гарантии, что событие (фронт/спад) генерации прерывания не произойдёт до маскирования EXTI_IMR и не запомнится в NVIC, а потом не стрельнёт после BX LR. Опять-же - автору читать мануал про ядро (и NVIC).

 

PS: Да и про DMB/DSB/ISB автору следовало бы почитать....

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

Автору следовало

 

1 hour ago, jcxz said:

Автору стоит

 

1 hour ago, jcxz said:

автору читать

 

1 hour ago, jcxz said:

автору следовало бы

Кто же еще наставит неразумных на путь истинный?

 

1 hour ago, jcxz said:

Из какого это ассемблера?

Стыдно не знать классику!

Share this post


Link to post
Share on other sites
On 5/8/2020 at 1:52 PM, Arlleex said:

но лучше читать первоисточник

Как транслировать псевдокод на родной язык? гугл нимуя не может.

On 5/8/2020 at 1:52 PM, Arlleex said:

вешать дребезжащие кнопки на внешнее аппаратное прерывание - не самая лучшая идея. На грани с бредовой.

Это не ко мне а к STMicroelectronics. Вот кнопка на stm32vldiscovery:

конденсатор С22 вооще не впаян, R21 не 10К а 220К, кнопка такого качества, что один клик получается через раз.

usBttn.jpeg

On 5/8/2020 at 1:52 PM, Arlleex said:

Зачем в таком ПО ассемблер? Почему не написать на Си?

Не программист. Учу С++. Математические способности малы, поэтому путь тернист

On 5/8/2020 at 4:35 PM, AVI-crak said:

Тут странность более высокого масштаба - экономия энергии мк на фоне сварочного аппарата.

Впаянный контрллер используется для разработки. Планируется изготовить в окончательном варианте одну плату. Изготовление платы технологией ЛУТ, поэтому выбрал, как мне казалось, микруху с жирными ножками. Но оказалось не так - самые жирные ножки в корпусе LQFP32. Ошибочка.

On 5/8/2020 at 5:55 PM, aaarrr said:

Из-за слишком низкой частоты APB флаг оставался активным после выхода из процедуры прерывания - все правильно.

Не из-за этого. Вот код,в файле, где проц тактируется кварцем 8Мгц, без всяких делителей, таймет 2 считает до 4 сек, на 1 сек сравнение канала 1 генерирует прерывание в котором USART3 толкает байт - поочерёдно 'А' либо 'Б' - на скорости 9600. Если снять отложенное прерывание сравнения почти сразу же - после инструкции отправки байта - всё ОК:

Downloads.tar.gz

Yes.jpeg

Если вставить перед этим пару тройку инструкций - трабл:

No.jpeg

On 5/9/2020 at 12:30 AM, jcxz said:

Это что - код ISR или что вообще такое??? 

Есть же коммент ;Handler mode и процесс с именем, не допускающем двойного толкования - EXTI0_IRQ_

On 5/9/2020 at 12:30 AM, jcxz said:

лучше не маскировать/квитировать, а просто перед выходом из ISR очистить ожидающее прерывание в EXTI_PR и в NVIC.CLRPEND для соответствующего вектора.

Согласен. Ещё лучше и до и после.

А совсем хорошо как в анекдоте про гнузинского гинеколога - "Вместо" :)

On 5/9/2020 at 12:30 AM, jcxz said:

Да и про DMB/DSB/ISB автору следовало бы почитать....

Никакого отношения к проблеме не имеет. Советую 82 страницу переведённой Евстифеевым книги Джозефа Ю. "Ядро CORTEX-M3 компании ARM. Полное руководство". Вот ответ с форума STM Community который работае в данной ситуации:

The interrupt handler might run twice.

 

After clearing the pending register of EXTI, it takes a few cycles internally to clear the interrupt request in NVIC. If the information does not reach the NVIC in time, the interupt handler runs again. Because EXTI runs on the APB2 clock, this depends on the APB2 prescaler.

 

Recommended practice is to check the peripheral status register at the beginning of the interrupt handler, and return when there is no apparent reason for the interrupt.

 

Перефразируя доктора из "Формула любви" - "NVIC дело тёмное, осмыслению не подлежит".

 

Важная новость. Британские учёные ПРЕДСКАЗЫВАЮТ появление нового штамма вируса. Нулевой пациент зараженный новым штаммом будет обнаружен в настоящее время в восточной европе в городе Рига. Органом которому данный штамм наносит наибольшее, невосстановимое поражение является мозг. К счастью у него ничтожно малая вирулентность, практически нулевой икубационный период и, что особенно важно, полностью отсутствует безсимптомная фаза.

Share this post


Link to post
Share on other sites
1 час назад, ЯЛёша сказал:

Как транслировать псевдокод на родной язык? гугл нимуя не может...

Очевидно, навыками чтения английского - там к каждой строке комментарий есть.

 

1 час назад, ЯЛёша сказал:

Это не ко мне а к STMicroelectronics. Вот кнопка на stm32vldiscovery...

То, что производитель платы завел кнопку на понравившийся ему вывод не отменяет факта думать рационально.

Нафига козе баян вешать ее на прерывание? Просто мониторьте ее периодически, с программным антидребезгом.

Сварочник - не батарейное устройство, от лишних потребляемых мкА ему не будет ни тепло, ни холодно.

 

1 час назад, ЯЛёша сказал:

Не из-за этого...

Никакого отношения к проблеме не имеет...

Еще как из-за этого и еще как имеет.

Вы как раз в первом случае в прерывании после очистки флага, имея после этой очистки еще несколько инструкций, обеспечили его очистку на NVIC до выхода из прерывания.

Во втором случае, передвинув очистку ближе к концу обработчика, Вы ловите ситуацию, когда реально флаг на NVIC еще не очистился (пока он там через клоковые домены дойдет), а CPU запустил процедуру выхода из обработчика. Из логики работы NVIC следует, что он введет CPU в повторную обработку прерывания.

 

С DSB/DMB/ISB советы правильные. Только интерфейс памяти может (но не обязан) содержать буфер записи, и тогда эти инструкции ни на что не повлияют.

Повлияет только повторное чтение того адреса, куда было записано.

 

Как-то так =)

Share this post


Link to post
Share on other sites
1 hour ago, ЯЛёша said:

Не из-за этого. Вот код,в файле, где проц тактируется кварцем 8Мгц, без всяких делителей

APB, причем тут "проц"? Даже в приведенной ниже цитате с форума STM описан как раз такой случай.

Share this post


Link to post
Share on other sites
2 hours ago, ЯЛёша said:

Советую 82 страницу

Вы ещё посоветуйте прочитать, что написано на заборе. Вот список документации, который нужно поизучать. И одной книгой он не ограничивается.

2 hours ago, ЯЛёша said:

А совсем хорошо как в анекдоте про гнузинского гинеколога - "Вместо" :)

 

2 hours ago, ЯЛёша said:

Перефразируя доктора из "Формула любви" - "NVIC дело тёмное, осмыслению не подлежит".

 

2 hours ago, ЯЛёша said:

Важная новость. Британские учёные ПРЕДСКАЗЫВАЮТ

И по-меньше болтологии. Здесь это флуд называется.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.