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

maxntf

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

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

  • Посещение

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


  1. Этот пост я проглядел. то есть не совсем проглядел, а проглядывал его с телефона дома, и не особо придал значение коду с дефайнами. После продолжение ветки перешло на второй лист, и туда забыл посмотреть. Но зато комент, где было сказано что тачлиб юзает SysTick натолкнула на мысль, что нужно из нее удалить все упоминания SysTick чтоб она вообще забыла о его существовании. По этому автору esaulenka отдельное спасибо. Это все хорошо. Только мне не понятен один момент, откинув всю лирику о приоритетах задач, концепции FreeRTOS и т.д. Планировщик, очень сокращенно - это функция которая управляет регистром PC, то есть выбирает куда перекинуть ход выполнения программы. Он вызывается по прерыванию таймера на котором он работает - SysTick, или через API функции FreeRTOSа. У меня 3 задачи, не в одной нет никаких API функций, даже делай. 1-я вызывает функцию, которая отключает SysTick и по какой то причине он не включается. Каким образом моя программа оказывается во второй задачи и там висит, потому как SysTick отключен и планировщик больше не вызывается, а API функций в задачах нет, чтоб вызвать планировщик. P.S. Остается только один вариант - когда 1-я задача включает SysTick, срабатывает прерывание, мы попадаем в планировщик, он передает управление 2-й задаче, и тут по какой то причине SysTick отключается (уже в планировщике).
  2. Нужные макросы чего? Просто эта библиотека TouchSensorLib была заточена под SysTick. Ее нужно перебирать. Только хрена было ее делать под хардтимер не понятно. Там и так хренова куча настроек, ну добавили бы еще одну по выбору и настройке таймера. Тем более что там нужно только мсек и сек считать и все! Заделал такое: #define enableInterrupts() {NVIC->ISER[TIM3_IRQn >> 0x05] = (uint32_t)0x01 << (TIM3_IRQn & (uint8_t)0x1F);} #define disableInterrupts() {NVIC->ICER[TIM3_IRQn >> 0x05] = (uint32_t)0x01 << (TIM3_IRQn & (uint8_t)0x1F);} Все вроде работает. Осталось проверить чтоб теперь TIM3 не вис. Если будет виснуть, тогда косяк где то в TouchSensorLib.
  3. Нашел костыль. В функции обработка кнопок есть дефайн отключения а потом включения прерываний. Там осталось от оригинала управление SysTick: #define enableInterrupts() {SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;} #define disableInterrupts() {SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;} , а я кручу тайминг на TIM3. Только пока не могу понять как это приводит к полному отключению прерываний. Проверил все места где disableInterrupts применяется, всегда есть обратный на включение enableInterrupts, а пока SysTick отключен, планировщик ведь не может передать управление. Дело в том что функция в которой SysTick включается/отключается вызывается из задачи 1, а когда происходит баг, программа весит в задаче 2.
  4. С памятью все ок! Ловушки хоть и примитивные - бесконечный цикл (для отладки сгодится) везде стоят: vApplicationStackOverflowHook, HardFault_Handler и т.д. Я не проект готовый делаю, а только разбираюсь. С STM и FreeRTOS, ранее не работал. Нужно было сделать захват сигнала с частотой 10мкс. Думал попробовать на таймере ОС, вот и поднял частоту. То оказалась глупая затея, а вот баг вылез. Вот и хочу разобраться, чтоб потом таких грабель не было.
  5. Гуру Keil, подскажите возможно ли установить брекпоинт по записи в регистр конкретного значения? Отладка через SL_Link Debugger.
  6. Я функцию TSL_tim_ProcessIT перенес в TIM3. Возможно у них где то в инициализации есть управление SysTick, буду искать. Спасибо за наводку.
  7. Не понял что значит переносить под FreeRTOS? Какие могут быть коллизии, если FreeRTOS использует прерывания с самыми высокими приоритетами? Я же обработчик делаю на низкоприоритетных TIM3 приоритет 36, а SysTick приоритет 6; В общем из за малого опыта, тажело судить что происходит, но причина выявлена - 100% перестает работать SysTick, а соответственно и scheduler который крутится на этом таймере. Вот только что происходит с SysTick, понять не могу. Кто может, опишите регистры SysTick или ткните где посмотреть. PS: Судя по функции SysTick_Config там всего 3 бита, интуитивно по названиям дефайнов SysTick_CTRL_CLKSOURCE_Msk, SysTick_CTRL_TICKINT_Msk, SysTick_CTRL_ENABLE_Msk. один включает тактирование, второй инициализирует и третий запускает. Вот этот SysTick_CTRL_TICKINT_Msk и сбрасывается. Где не могу поймать. если бы в Кеил можно было установить брекпоинт на запись в бит. Кто знает можно такое?
  8. В Кеил брекпоинт можно поставить только на весь регистр, вот если бы на изменение бита.:) Глючит из за библиотеки, там в прерывании таймера, у меня TIM3, вызывается некая функция обработчика этих кнопок. Вот тут то и происходит баг.
  9. Да при тике 1кгц все работает. 2-я задача читает блоками аудио файл с флешь и DMA его пересылает в DAC. Она то и оставалась работать. Я ее отключил. 1-я задача обрабатывает сенсорные кнопки библиотекой touch-sensing library от ST. Собственно вызывает функцию, которая возвращает состояние кнопок. И если кнопка нажата, устанавливает глобальный флаг. 3-я задача проверяет этот флаг, когда он установился, запускает два таймера, один читает IR код с фотоприемника, а второй его передает. Сразу оговорюсь, с ARM только начал разбираться, так что некоторые мои рассуждения могут быть глупые, не судите строго :). Глючит именно пара задач 1 и 3. Причем если я блокирую одну из них, глюк пропадает. У меня пока один вариант: - библиотека touch-sensing library как то конфликтует с FreeRTOS. Сейчас просматриваю не использует ли она какие то аппаратные ресурсы что и ОС, например SysTickTimer. В планировщик больше вообще не попадаем после глюка. Надо проверить что там с прерываниями SysTickTimer, которые где то в FreeRTOS По ходу прерывания SysTick отключаются. Точнее я вижу что в структуре описания этого регистра меняется значение CTRL - при старте CTRL = 0х00000007 / 0х00010007, а после глюка 0х00010005, и больше в прерывание не попадаем. Сейчас поставил частоту 20000Нz и глюк начал проявляться практически сразу.
  10. Всем привет. На FreeRTOS вертятся 3 задачи, больше ничего из инструментария ОС не пользую. Так вот когда configTICK_RATE_HZ установлен 1000Hz, все работает без проблем. Меняю это значение на 10000Hz, после ресета все задачи какое то время работают, а потом работает только одна - 2-я задача (скорее работает просто функция). Шедуллер перестает работать вовсе - vApplicationTickHook перестает вызываться и задачи не переключаются. МК STM32L152rc работает на 16MHz. В чем может быть дело? Как отследить где планировщик заткнулся и почему?
  11. stm32L152RC SysTick

    Помогите разобраться, не правильно работает функция SystemCoreClockUpdate() Когда запускаю тактирование без PLL от встроенного генератора HSI - 16Mhz, работает правильно. А когда включаю PLL, функция SystemCoreClockUpdate() возвращает все равно значение 16MHz, хотя реальная частота 32MHz. Работает только если самому прописать SystemCoreClock = 32000000 перед вызовом SysTick_Config. RCC_Init(); SystemCoreClockUpdate(); SysTick_Config(SystemCoreClock/1000);//TO=1ms void RCC_Init(void) { RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); FLASH->ACR=FLASH_ACR_ACC64; FLASH->ACR|=FLASH_ACR_LATENCY; FLASH->ACR|=FLASH_ACR_PRFTEN; RCC_PLLConfig(RCC_PLLSource_HSI, RCC_PLLMul_4, RCC_PLLDiv_2); RCC_PLLCmd(ENABLE);//Включаем PLL RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); RCC_HSEConfig(RCC_HSE_OFF); while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET); }
  12. Используем эти БП уже долгое время, особых проблем нет. Нужно кое что свое добавить и по быстрому сделать, а я в силовой электронике не особо. Вот и решили быстро передрать то что было. По тепловым характеристикам, шум и т.д. все идентично. Намотали нам 2 варианта по 5 шт. Сказали что в первом варианте при высоком входном напряжении заметили перенасыщение (как это проверить самому я не знаю). И сделали вариант 2 на один виток меньше. Вот мои замеры индуктивности. Оригинал (под рукой только 2 шт.): а) первичка 1103uH вторичка 11uH б) первичка 1082uH вторичка 10,9uH Вариант 1: а) первичка 1225uH вторичка 12,3uH б) первичка 1219uH вторичка 12,2uH в) первичка 1219uH вторичка 12,2uH г) первичка 1215uH вторичка 12,2uH д) первичка 1226uH вторичка 12,3uH Вариант 2: а) первичка 1017uH вторичка 10,3uH б) первичка 1036uH вторичка 10,4uH в) первичка 1031uH вторичка 10,4uH г) первичка 1029uH вторичка 10,4uH д) первичка 1020uH вторичка 10,3uH
  13. Там был еще узел для резервного аккумулятора, я его убрал чтоб уменьшить размер схемы. Индуктивность обмоток я могу измерить есть RLC прибор. Меня интересует правильно ли там подобраны сердечник и провод. Такие моменты как перенасыщение сердечника и что там еще может быть? А все выше перечисленные параметры это само собой.
  14. Просьба по сути. Я сам вижу что там на входе не хватает термистора, дросселя, кондера. Я привел схему изделия которое уже есть, о его недостатках речь не идет. Вопрос про трансформатор.
  15. Сам не занимаюсь расчетами трансформаторов и всех тонкостей не знаю. Нужно собрать ИБП по образцу. У меня есть оригинальный БП, а так же трансформаторы которые я заказал намотать по образцу. Подскажите какие и как снять параметры чтоб определить что новые трансформаторы работают не хуже оригинала. Схему БП прилагаю, из подручных средств есть - осциллограф, мультиметр, ЛАТР.
  16. Да действительно коротит, а я уже думал может индуктивность меняется или еще какая хрень. Спасибо. Никогда не подумал бы, что эта эмаль такая...
  17. Собрана схема DC-DC на LM2576T-ADJ. И всплыл такой баг, как только дроссель касается обмоткой к предохранительной колодке входного питания, напряжение на выходе стабилизатора сразу начинает расти. Обмотка дросселя изолирована лаком и КЗ соответственно нет. Кто может объяснить что происходит в этот момент?
  18. Coocox настройка heap?

    Просто у меня в отладке, когда указатель стека попадает в секцию bss сразу происходит вылет в то самое прерывание. Поскольку с прерываниями я еще не успел толком разобраться, вот и предположил что есть такая заглушка. Ну раз это не так, значит на данном этапе моих познаний ARM все равно как расположить стек и кучу (главное понял как :rolleyes: ). А дальше посмотрим.
  19. Coocox настройка heap?

    То есть не факт что программа обязательно вылетает в это прерывание?
  20. Люди подскажите чем Вы готовите звук. Пробую сделать как в статье Воспроизведение звука на STM32-Discovery при помощи Speex. Звук что в примере у меня играет. Поставил кодек SpeexACM_1.0.1.1 пробую из разных конвертеров ауди сделать закодированный файл, никак не получается то что нужно. Если у кого есть, поделитесь кодеком и конвертером на котором у Вас получилось.
  21. Coocox настройка heap?

    Когда он туда наезжает у меня программа вылетает в прерывание HardFault_Handler. Можно там фиксировать что переполнение стека. И потом менять его размер. А если наедет на кучу, как узнать?
  22. Coocox настройка heap?

    Уважаемые AHTOXA и zltigo спасибо Вам за помощь! Мне почему то больше понравился вариант сначала стек потом куча. Тогда исключается вариант их пересечения. Чтоб размер этих секций не превысил ОЗУ, я размер стека буду задавать какой нужен, а размер кучи все что осталось. А для контроля минимального размера кучи и сделаю условие в линкере. _StackSize = 0x1000;/*устанавливаем*/ _StackTop = . + _StackSize; PROVIDE(_stack = _StackTop); _HeapSize = _eram - _StackTop; _HeapBegin = _eram - _HeapSize; _HeapLimit = _eram; _HeapMinimal = 0x2000;/*устанавливаем*/ ASSERT(_HeapSize > _HeapMinimal, "warning! small size of the heap")
  23. Coocox настройка heap?

    Вух!!!, вроде все понял. Много вопросов отпало, когда собралась общая картинка. Просто начал я не с того боку и все из за того базового линк. Нужно было начинать с его ковыряния, а не кода Си. Вот линк: _eram = 0x20000000 + 0x00020000; SECTIONS { .text : { KEEP(*(.isr_vector)) ля-ля-ля } > rom .data : { ля-ля-ля } > ram .bss : { ля-ля-ля } > ram //Начало моей части где я настраиваю stack & heap //Стек _stack_size = 0x200;/*Размер - нужно только мне и для вычисления след. параметров*/ _StackTop = . + _stack_size;/*Вершина стека начало лок. данных + его размер*/ _StackLimit = .;/*Для наглядности - начало лок. данных*/ .stack :/*Это собственно секция стека*/ { . = . + _stack_size;/*установка размера этой секции*/ } > ram PROVIDE(_stack = _StackTop);/*значение _stack устанавливаем в _StackTop*/ /*_stack потом помещаем в начало вектора*/ //Куча _heap_size = 0x100;/*размер кучи*/ _heap_begin = _eram - _heap_size;/*адрес начала кучи*/ _heap_limit = _heap_begin + _heap_size;/*лимит кучи для проверки*/ .heap (_heap_begin):/*секцию под кучу располагаем адреса _heap_begin*/ { . = . + _heap_size;/*установка размера этой секции*/ } > ram } В startup файле устанавливаем только координаты начала стека, больше в нем нет ничего про стек и кучу! extern unsigned long _stack;//значение задано в линк. файле __attribute__ ((used,section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { /*----------Core Exceptions------------------------------------------------ */ (void *)&_stack, /*!< The initial stack pointer */ Reset_Handler, /*!< Reset Handler */ NMI_Handler, /*!< NMI Handler */ Для проверки переполнения кучи в файле syscalls.c extern int _heap_begin; extern int _heap_limit; caddr_t _sbrk ( int incr ) { static unsigned char *heap = NULL; unsigned char *prev_heap; unsigned char *new_heap; if (heap == NULL) { heap = (unsigned char *)&_heap_begin; } prev_heap = heap; new_heap = heap + incr; if(new_heap > (unsigned char *)&_heap_limit) { return 0; } heap = new_heap; return (caddr_t) prev_heap; } По map файлу (просто для наглядности): В итоге мы получили стек размером 0x200 который идет с адреса 0x20000a88 к 0x20000888. Куча которая начинается с адреса 0x2001ff00 и идет до конца памяти с ограничением переполнения. COMMON 0x20000884 0x20000884 errno 0x20000888 . = ALIGN (0x4) 0x20000888 __bss_end__ = . 0x20000888 _ebss = __bss_end__ 0x00000200 _stack_size = 0x200 0x20000a88 _StackTop = (. + _stack_size) 0x20000888 _StackLimit = . .stack 0x20000888 0x200 load address 0x080014b4 0x20000a88 . = (. + _stack_size) *fill* 0x20000888 0x200 0x20000a88 PROVIDE (_stack, _StackTop) 0x00000100 _heap_size = 0x100 0x2001ff00 _heap_begin = (_eram - _heap_size) 0x20020000 _heap_limit = (_heap_begin + _heap_size) .heap 0x2001ff00 0x100 load address 0x08020b2c 0x2001ff00 _end = . 0x20020000 . = (. + _heap_size) *fill* 0x2001ff00 0x100 Остался один вопрос: Эти самые секции объявляются для того, чтоб в эти места памяти никто ничего левого не подсунул? Типа ка в линке MCC18 под ПИК когда нужна секция, в которую линкер ничего не суют? Или то-же только для наглядности? И здесь и так никто ничего не подсунет. Все глобальные переменные по порядочку по секциям data и bss (в PIC они были разбросаны по банкам памяти). Стек от А до В, куча от С до D. Все локальные переменные в стеке. Тогда может вообще лишнее объявлять эти секции? Сделать себе _stack_size = 0x200; _StackTop = . + _stack_size; PROVIDE(_stack = _StackTop); //Куча _heap_size = 0x100; _heap_begin = _eram - _heap_size; _heap_limit = _heap_begin + _heap_size; И Все?!
  24. Coocox настройка heap?

    С этим вроде понял. Все дело в файле starup который coocox включает при выборе в репозитории компонента CMSIS BOOT. Не понятно зачем так? /*----------Stack Configuration-----------------------------------------------*/ #define STACK_SIZE 0x00002000 /*!< The Stack size suggest using even number */ __attribute__ ((section(".co_stack"))) unsigned long pulStack[STACK_SIZE]; __attribute__ ((used,section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { /*----------Core Exceptions------------------------------------------------ */ (void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer */ Reset_Handler, /*!< Reset Handler */ ля-ля-ля } В общем я поменял кусок, и теперь и стек начинается с __StackTop что в линкере указан, и проверка сохраняется ASSERT(__StackLimit >= __HeapLimit, "region ram overflowed with stack") /*----------Stack Configuration-----------------------------------------------*/ #define STACK_SIZE 0x00002000 /*!< The Stack size suggest using even number */ __attribute__ ((section(".co_stack"))) unsigned long pulStack[STACK_SIZE]; extern unsigned long __stack; __attribute__ ((used,section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { /*----------Core Exceptions------------------------------------------------ */ (void *)&__stack, /*!< The initial stack pointer */ Reset_Handler, /*!< Reset Handler */ Вот теперь после изменения startup и понял. Вот что у меня в этой функции. extern int _end; /*This function is used for handle heap option*/ __attribute__ ((used)) caddr_t _sbrk ( int incr ) { static unsigned char *heap = NULL; unsigned char *prev_heap; if (heap == NULL) { heap = (unsigned char *)&_end; } prev_heap = heap; heap += incr; return (caddr_t) prev_heap; } На сколько я понял _end это та что в линкере .heap (COPY): { __end__ = .; _end = __end__; end = __end__; *(.heap*) __HeapLimit = .; } > ram Не пойму как устанавливается значение __HeapLimit? И что в _sbrk нужно добавить, чтоб запретить выделять память после этого HeapLimit? FreeRTOS. Глобальных переменных, области data и bss?
  25. Coocox настройка heap?

    Тогда мне не понятно, зачем делать, чтоб куча шла на встречу стеку? Почему не выделить вначале кусок памяти под стек, а все что осталось под кучу? Но с таким-же успехом можно и в конце фиксированный под стек, а весь остаток под кучу. Главное. что ВЕСЬ а не какой-то опять-же фиксированный размер. Размер хипа следует указывать только минимальный, дабы уже линкер ругался, что совсем уж памяти не хватает. Возможно я здесь чего то не понял. RTOS использует собственный стек и кучу, или те же что и компилятор (у меня GCC)? В настройках RTOS есть 2 параметра: Получается что этими параметрами я задаю имеющуюся память в МК, потому что RTOS не имеет представления о том что у него на борту?
×
×
  • Создать...