Перейти к содержанию
    

LAS9891

Участник
  • Постов

    352
  • Зарегистрирован

  • Посещение

Весь контент LAS9891


  1. Что было сделано: 1) Естественно, сначала проверил, что я записываю в почтовый ящик для отправки. Оказалось что записываю я всё верно. 2) Проверил работу внешнего преобразователя TTL->CAN на плате и даже заменил его - не помогло. маилбокс всегда один. ящик в проекте настроен всегда на передачу не успевают. я отслеживаю состояние шины, на ней только 2 устройства, которыми я сам управляю накиньте ещё вариантов Проект один и тот же во всех контроллерах, контроллеры одинаковые, платы одинаковые! Для каждого экземпляра контроллера и платы делать свой проект?
  2. И один и тот же проект будет работать по разному на разных экземплярах микроконтроллера одной и той же модели ?
  3. Имеется контроллер от GigaDevice GD32F103R. В контроллере имеется аппаратный модуль CAN. Этот модуль настроил согласно UserManual и успешно использовал это ПО сначала в отладчике, а затем и в целевом устройстве. Всё было замечательно до тех пор, пока не пришлось прошить очередной образец устройства уже отлаженным ПО. В этом конкретном образце устройства обнаружился баг в работе CAN. Баг проявляется, когда устройству необходимо направить в шину помимо ID ещё и байты с данными. В моём проекте устройство отправляет в шину за раз до 8 байт данных. В случае если устройство отправляет от 0 до 6 байт включительно, багов не возникает. В случае если устройство отправляет 7 байт, то последний байт данных представляет случайное значение, хотя при формировании посылки байт имеет определённое значение. В случае если устройство отправляет 8 байт, то уже последние два байта представляют случайные значения. Что было сделано: 1) Естественно, сначала проверил, что я записываю в почтовый ящик для отправки. Оказалось что записываю я всё верно. 2) Проверил работу внешнего преобразователя TTL->CAN на плате и даже заменил его - не помогло. 3) Проверил посылку осциллографом прямо на ноге микроконтроллера: 7й и 8й байт - всегда случайные значения. 4) Проверил ещё раз ПО на отладчике и ещё раз на другом образце целевого устройства - всё работает правильно, никаких случайных значений в 7м и 8м байтах. 5) На косячном образце стёр всю FLASH и заново записал ПО - не помогло. 6) Заменил на косячном образце микроконтроллер на новый, записал ПО, и....... БАГ ПРОПАЛ! Всё стало работать правильно. Что это было? Кто сталкивался? Есть ли какие-то особенности в использовании/настройке CAN, которые могут влиять подобным образом?
  4. Спасибо огромное! А можно ссылку на pdf, откуда скрин сделали?
  5. В проекте использую GigaDevice GD32F103RBT6. Настраиваю GPIO. Возникла проблема при настройке порта B пины 1 и 2. Процесс настройки выглядит следующим образом: 1) Настраиваю несколько пинов, отличных от PB1 и PB2. Всё проходит нормально. 2) Настраиваю PB2 на выход в режиме pushpull и вывожу лог. 1. Всё проходит нормально, на выходе осциллографом вижу лог. 1 и в отладке в соответствующих регистрах - соответствующие биты имеются. 3) Опять настраиваю несколько пинов, отличных от PB1 и PB2. Всё проходит нормально. 4) Настраиваю PB1 на вход с внутренней подтяжкой к питанию. Сначала чищу соответствующие биты в регистре GPIO_CTL0 (регистр определяющий режим работы вывода). В отладке вижу, что сбрасывается только то, что нужно. Затем в этом же регистре устанавливаю нужные мне биты. В отладке снова вижу, что устанавливается только то, что нужно. При этом в этот момент на осциллографе наблюдаю, что на пине PB2 (именно на PB2, я не описАлся) устанавливается лог. 0 !? КАК ПОЧЕМУ?! Что было сделано: 1) Попробовал после настройки PB1, снова настроить PB2 - не помогло. В отладке вижу, что в регистрах всё правильно, но осциллограф кажет на PB2 лог. 0. 2) Попробовал читать регистр GPIO_CTL0 и проверять, что в нём творится до настройки PB1 и после. Настройки для PB2 не меняются! 3) На плате ноги PB1 и PB2 не замыкаются. Ногу PB2 поднял - она ни с чем не соединена, но это не помогло. 4) Проверил проект на другой плате - всё работает также. 5) Проверил настройку других пинов - замечаний нет. Кто сталкивался с подобным? Что ещё попробовать? В чём проблема?
  6. вот спасибо. Теперь выходит, для прерывания можно назначить только один источник. Товарищ был прав:
  7. У меня на самом деле GD32F103RB, и тут я не нашёл System configuration controller Вообще пост получился исключительный. Мне было лень внимательно читать даташит и решил быстренько спросить на форуме. Я как всегда ожидал ответа в стиле "читай даташит", ну и готовился, что закидают помидорами, а тут на две страницы ответов/споров, даже после того, как я уже выяснил то, что хотел изначально. Магия блин. Вопрос не глобального масштаба - а популярности... В серьёзных темах ответа не дождешься, только "читайдаташитами" закидают.
  8. Да ничего не мешает. Меня интересовало есть ли возможность проверить это по регистрам EXTIx, ну раз нет, значит определю по другому. проверим
  9. Согласен. Но изначально были условия: уже готовая схема, обязательный опрос кнопок по прерываниям.
  10. Я думал, что я что-то не дочитал про External interrupt. Надеялся, что есть какой-то регистр (который относится к External interrupt), в котором это отражается.
  11. Как же ответить на поставленный вопрос?
  12. Есть stm32. На пин PA0 и на пин PB0 установлены кнопки. На оба пина настроено и включено прерывание NVIC_EnableIRQ(EXTI0_IRQn). Согласно документации PA0 и PB0 приходятся на линию EXTI0. При нажатии одной из кнопок возникает прерывание EXTI0_IRQHandler. Как в обработчике прерывания определить с какого пина возникло прерывание? Вариант 1: в обработчике прерывания проверить уровень на пинах PA0 и PB. Есть ещё варианты?
  13. А как лучше? в main.c в while(1){} её ждать ?
  14. Сохранили пару дней жизни мне
  15. Почему именно должно? Если приоритет кнопки будет находиться в интервале между 10 и 15 (приоритеты 11, 12, 13, 14) это будет неправильно? Приоритет кнопки и configMAX_SYSCALL_INTERRUPT_PRIORITY обязательно должны быть равны? Или это рекомендация из соображений экономии памяти и т. д. ?
  16. Почему? Хотя и так тоже работает Всё заработало когда сделал так: #define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 175
  17. Наверно имелось в виду: ((250 & 0xF0) >> 4) = 10 Согласны ли Вы с ? Я сделал так: #define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 250 В контроллере прерывания настроил так: При запуске отладки, до нажатия кнопки (прерывания) всё вроде норм. После нажатия случается один раз прерывание и всё виснет тут: void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = vPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); // <-------------------------------------------------------ВОТ ТУТ } Что не верно?
  18. 3) Макрос configKERNEL_INTERRUPT_PRIORITY - это макрос, который определяет приоритет прерывания, используемого для тиков FreeRTOS. Т.е. это приоритет прерывания SysTick микроконтроллера равный 14. Так или не так? 4) Макрос configMAX_SYSCALL_INTERRUPT_PRIORITY - это макрос, который устанавливает наивысший приоритет ЧЕГО?, из которого могут быть вызваны защищенные для прерываний функции FreeRTOS API, т.е. функции в названии которых есть FromISR (например xSemaphoreGiveFromISR). Так или не так? Тока приоритет чего? прерываний или задач
  19. 1) Как вообще сосуществуют понятия приоритет прерываний и приоритет задач? Вот в STMке назначено 16 приоритетов вытеснения и 0 субприоритетов на прерывания. Эта цифра 16 относится только к приоритетам прерываний или ещё также и к приоритетам задач? 2) Вот в STMке чем меньше число (номер) приоритета, тем выше приоритет. Это утверждение относится только к приоритетам прерываний или и к приоритетам задач? 3) Макрос configKERNEL_INTERRUPT_PRIORITY - это макрос, который определяет приоритет прерывания, используемого для тиков FreeRTOS. Т.е. это приоритет прерывания SysTick микроконтроллера. Так или не так? 4) Макрос configMAX_SYSCALL_INTERRUPT_PRIORITY - это макрос, который устанавливает наивысший приоритет ЧЕГО?, из которого могут быть вызваны защищенные для прерываний функции FreeRTOS API, т.е. функции в названии которых есть FromISR (например xSemaphoreGiveFromISR). Так или не так? 5) Для макросов из пунктов 3 и 4 приоритеты должны быть выбраны из диапазона 0...15. Так или не так? Т.е. контроллер тут получается законодатель мод? 6) Везде пишут, что если SysTick используется для шедулера, то приоритет SysTickа нужно сделать самым низким, я сделал его 15 при настройке контроллера. Значит ли это, что и configKERNEL_INTERRUPT_PRIORITY должен быть равен 15 ?
  20. Как раз вопрос про приоритеты, но не задач, а прерываний. В файле FreeRTOSConfig.h у меня есть макрос: /* Define configASSERT() to disable interrupts and sit in a loop. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } Программа не работала согласно ожиданиям, пока не закомментировал этот макрос. Отладка вставала тут: #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = vPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); //-<----------------------------------------------------ВОТ ТУТА ВИСЕЛО. } Ну ок, косяки с приоритетами прерываний. Почитал как надо делать тут. Контроллер настроил так: - общее количество приоритетов вытеснения прерывании 16 (0...15); - общее количество субприоритетов 0. - используемые прерывания: SysTick (приоритет 15) и EXTI10_15 (приоритет 2). Далее настраиваем макросы: /* Interrupt nesting behaviour configuration. */ #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 3 //#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] Судя по статье (в самом низу зелёная картинка), при таких макросах, и если в обработчике прерывания (ISR) используются функции API FreeRTOS, то приоритет такого прерывания должен быть в диапазоне от 0 до 3. У меня прерывание SysTick использует только FreeRTOS. Прерывание EXTI10_15 использует функцию xSemaphoreGiveFromISR, приоритет прерывания 2. Следовательно, проблем не должно бы быть, НО при таких настройках проект при отладке опять висит где и висел. Где я опять накосячил?
  21. Проблему решил без макроса, в самой задаче.
  22. ОК. Удивляет, что нету упоминаний о том, что и соответственно задача сразу начнёт выполняться.
  23. Согласен. Никто не мешает создать и собственную RTOS. Мне тогда не понятно, почему в примерах это не упоминается: раз, два. Есть способ не изменяя RTOSных файлов учесть этот момент? Ну кроме переписывания xSemaphoreGive(). Подумал использовать сразу после vSemaphoreCreateBinary функцию xSemaphoreTake. Но тут пишут: Захват семафора осуществляется API - функцией xSemaphoreTake() и может вызываться только из задач.
  24. Согласен. Это состояние по умолчанию? В смысле это так и должно быть всегда, или это можно менять в настройках FreeRTOS?
×
×
  • Создать...