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

maxntf

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

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

  • Посещение

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


  1. У меня при таких действиях происходит следующее: Первый брекпоинт на 'B .' PC = текущему адресу, LR = 0xFFFFFFF1 Переставляю указатель на BX LR, делаю шаг в отладчике и получаю PC = 0х000010BC, LR = 0x00000F03. Это вообще похоже на системную память. Что я делаю не так?
  2. Вот полный пример кода исследования HatdFault. HardFaultHandler.s AREA OSKERNEL, CODE, READONLY, ALIGN=2 PRESERVE8 EXPORT HardFault_Handler IMPORT HardFaultHandler_c THUMB HardFault_Handler movs R0, #4 mov R1, LR tst R0, R1 ;// Check EXC_RETURN in Link register bit 2. bne Uses_PSP mrs R0, MSP ;// Stacking was using MSP. b Pass_StackPtr Uses_PSP mrs R0, PSP ;// Stacking was using PSP. Pass_StackPtr ALIGN ldr R2,=HardFaultHandler_c bx R2 ;// Stack pointer passed through R0. END HardFaultHandler_c.c // System Handler Control and State Register #define SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) // Memory Management Fault Status Register #define NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) // Bus Fault Status Register #define NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) // Usage Fault Status Register #define NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) // Hard Fault Status Register #define NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) // Debug Fault Status Register #define NVIC_DFSR (*(volatile unsigned int*) (0xE000ED30u)) // Bus Fault Manage Address Register #define NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) // Auxiliary Fault Status Register #define NVIC_AFSR (*(volatile unsigned int*) (0xE000ED3Cu)) static volatile unsigned int _Continue; // Set this variable to 1 to run further static struct { struct { volatile unsigned int r0; // Register R0 volatile unsigned int r1; // Register R1 volatile unsigned int r2; // Register R2 volatile unsigned int r3; // Register R3 volatile unsigned int r12; // Register R12 volatile unsigned int lr; // Link register volatile unsigned int pc; // Program counter union { volatile unsigned int byte; struct { unsigned int IPSR : 8; // Interrupt Program Status register (IPSR) unsigned int EPSR : 19; // Execution Program Status register (EPSR) unsigned int APSR : 5; // Application Program Status register (APSR) } bits; } psr; // Program status register. } SavedRegs; union { volatile unsigned int byte; struct { unsigned int MEMFAULTACT : 1; // Read as 1 if memory management fault // is active unsigned int BUSFAULTACT : 1; // Read as 1 if bus fault exception is active unsigned int UnusedBits1 : 1; unsigned int USGFAULTACT : 1; // Read as 1 if usage fault exception // is active unsigned int UnusedBits2 : 3; unsigned int SVCALLACT : 1; // Read as 1 if SVC exception is active unsigned int MONITORACT : 1; // Read as 1 if debug monitor exception // is active unsigned int UnusedBits3 : 1; unsigned int PENDSVACT : 1; // Read as 1 if PendSV exception is active unsigned int SYSTICKACT : 1; // Read as 1 if SYSTICK exception is active unsigned int USGFAULTPENDED : 1; // Usage fault pended; usage fault started // but was replaced by a higher-priority // exception unsigned int MEMFAULTPENDED : 1; // Memory management fault pended; memory // management fault started but was // replaced by a higher-priority exception unsigned int BUSFAULTPENDED : 1; // Bus fault pended; bus fault handler was // started but was replaced by a // higher-priority exception unsigned int SVCALLPENDED : 1; // SVC pended; SVC was started but was // replaced by a higher-priority exception unsigned int MEMFAULTENA : 1; // Memory management fault handler enable unsigned int BUSFAULTENA : 1; // Bus fault handler enable unsigned int USGFAULTENA : 1; // Usage fault handler enable } bits; } syshndctrl; // System Handler Control and State // Register (0xE000ED24) union { volatile unsigned char byte; struct { unsigned char IACCVIOL : 1; // Instruction access violation unsigned char DACCVIOL : 1; // Data access violation unsigned char UnusedBits : 1; unsigned char MUNSTKERR : 1; // Unstacking error unsigned char MSTKERR : 1; // Stacking error unsigned char UnusedBits2 : 2; unsigned char MMARVALID : 1; // Indicates the MMAR is valid } bits; } mfsr; // Memory Management Fault Status // Register (0xE000ED28) union { volatile unsigned int byte; struct { unsigned int IBUSERR : 1; // Instruction access violation unsigned int PRECISERR : 1; // Precise data access violation unsigned int IMPREISERR : 1; // Imprecise data access violation unsigned int UNSTKERR : 1; // Unstacking error unsigned int STKERR : 1; // Stacking error unsigned int UnusedBits : 2; unsigned int BFARVALID : 1; // Indicates BFAR is valid } bits; } bfsr; // Bus Fault Status Register (0xE000ED29) volatile unsigned int bfar; // Bus Fault Manage Address Register // (0xE000ED38) union { volatile unsigned short byte; struct { unsigned short UNDEFINSTR : 1; // Attempts to execute an undefined // instruction unsigned short INVSTATE : 1; // Attempts to switch to an invalid state // (e.g., ARM) unsigned short INVPC : 1; // Attempts to do an exception with a bad // value in the EXC_RETURN number unsigned short NOCP : 1; // Attempts to execute a coprocessor // instruction unsigned short UnusedBits : 4; unsigned short UNALIGNED : 1; // Indicates that an unaligned access fault // has taken place unsigned short DIVBYZERO : 1; // Indicates a divide by zero has taken // place (can be set only if DIV_0_TRP // is set) } bits; } ufsr; // Usage Fault Status Register (0xE000ED2A) union { volatile unsigned int byte; struct { unsigned int UnusedBits : 1; unsigned int VECTBL : 1; // Indicates hard fault is caused by failed // vector fetch unsigned int UnusedBits2 : 28; unsigned int FORCED : 1; // Indicates hard fault is taken because of // bus fault/memory management fault/usage // fault unsigned int DEBUGEVT : 1; // Indicates hard fault is triggered by // debug event } bits; } hfsr; // Hard Fault Status Register (0xE000ED2C) union { volatile unsigned int byte; struct { unsigned int HALTED : 1; // Halt requested in NVIC unsigned int BKPT : 1; // BKPT instruction executed unsigned int DWTTRAP : 1; // DWT match occurred unsigned int VCATCH : 1; // Vector fetch occurred unsigned int EXTERNAL : 1; // EDBGRQ signal asserted } bits; } dfsr; // Debug Fault Status Register (0xE000ED30) volatile unsigned int afsr; // Auxiliary Fault Status Register // (0xE000ED3C) Vendor controlled (optional) } HardFaultRegs; void HardFaultHandler_c(unsigned int* pStack); void HardFaultHandler_c(unsigned int* pStack) { if (NVIC_HFSR & (1uL << 31)) { NVIC_HFSR |= (1uL << 31); // Reset Hard Fault status *(pStack + 6u) += 2u; // PC is located on stack at SP + 24 bytes; // increment PC by 2 to skip break instruction. return; // Return to interrupted application } // // Read NVIC registers // HardFaultRegs.syshndctrl.byte = SYSHND_CTRL; // System Handler Control and // State Register HardFaultRegs.mfsr.byte = NVIC_MFSR; // Memory Fault Status Register HardFaultRegs.bfsr.byte = NVIC_BFSR; // Bus Fault Status Register HardFaultRegs.bfar = NVIC_BFAR; // Bus Fault Manage Address Register HardFaultRegs.ufsr.byte = NVIC_UFSR; // Usage Fault Status Register HardFaultRegs.hfsr.byte = NVIC_HFSR; // Hard Fault Status Register HardFaultRegs.dfsr.byte = NVIC_DFSR; // Debug Fault Status Register HardFaultRegs.afsr = NVIC_AFSR; // Auxiliary Fault Status Register // // Halt execution // If NVIC registers indicate readable memory, change the variable value // to != 0 to continue execution. // _Continue = 0u; while (_Continue == 0u); // // Read saved registers from the stack // HardFaultRegs.SavedRegs.r0 = pStack[0]; // Register R0 HardFaultRegs.SavedRegs.r1 = pStack[1]; // Register R1 HardFaultRegs.SavedRegs.r2 = pStack[2]; // Register R2 HardFaultRegs.SavedRegs.r3 = pStack[3]; // Register R3 HardFaultRegs.SavedRegs.r12 = pStack[4]; // Register R12 HardFaultRegs.SavedRegs.lr = pStack[5]; // Link register LR HardFaultRegs.SavedRegs.pc = pStack[6]; // Program counter PC HardFaultRegs.SavedRegs.psr.byte = pStack[7]; // Program status word PSR // // Halt execution // To step out of the HardFaultHandler, change the variable value to != 0. // _Continue = 0u; while (_Continue == 0u) { } } В общем после вылета в HardFault в режиме отладки проверяю структуру HardFaultRegs и там все значения 0. Где то ошибка в функции, как узнать причину?
  3. Прошу прощения, только создал сообщение и нашел ошибку. IMPORT HardFault_Handler Брал из готового примера. Неудобно когда похожие названия. В общем исправил, вроде все собралось, буду проверять. EXPORT HardFault_Handler IMPORT HardFaultHandler_с ... ldr R2,=HardFaultHandler_с И в main.c extern void HardFaultHandler_с(unsigned int* pStack); void HardFaultHandler_с(unsigned int* pStack){ }
  4. Хочу включить в проект на Keil исследование причины вылета в HardFault. Но в ассемблере никак не могу разобраться. Смысл я в общем понял в ассемблерном куске кода копируются данные регистров которые нужно проверить, а в Си функции уже их разбираемым. Есть startupxxx.s файл, в нем есть описание этой функции по умолчанию и там стоит атрибут WEAK. Посмотрел он указывает на то, что эта функция может быть переопределена в другом месте и будет иметь приоритет. В общем создаю новый asm файл, и компилятор начинает ругаться на то, что функция дублируется. Подскажите как правильно прикрутить asm файл с функцией HardFault, чтоб в main.c описать функцию void HardFaultHandler(unsigned int* pStack){...} ;---------------------------------------------------------------------- ;File : HardFaultHandler.S ;Purpose : HardFault exception handler for Keil assembler. ;-------- END-OF-HEADER --------------------------------------------- ;*/ AREA OSKERNEL, CODE, READONLY, ALIGN=2 PRESERVE8 EXPORT HardFault_Handler IMPORT HardFault_Handler THUMB HardFault_Handler ;// This version is for Cortex M0 movs R0, #4 mov R1, LR tst R0, R1 ;// Check EXC_RETURN in Link register bit 2. bne Uses_PSP mrs R0, MSP ;// Stacking was using MSP. b Pass_StackPtr Uses_PSP mrs R0, PSP ;// Stacking was using PSP. Pass_StackPtr ALIGN ldr R2,=HardFaultHandler bx R2 ;// Stack pointer passed through R0. END ;/****** End Of File *************************************************/ Или второй вариант. Пробую написать этот код в startup файле ; Dummy Exception Handlers (infinite loops which can be modified) NMI_Handler PROC EXPORT NMI_Handler [WEAK] B . ENDP HardFault_Handler\ PROC EXPORT HardFault_Handler [WEAK] ;// This version is for Cortex M0 movs R0, #4 mov R1, LR tst R0, R1 ;// Check EXC_RETURN in Link register bit 2. bne Uses_PSP mrs R0, MSP ;// Stacking was using MSP. b Pass_StackPtr Uses_PSP mrs R0, PSP ;// Stacking was using PSP. Pass_StackPtr ALIGN ldr R2,=HardFaultHandler bx R2 ;// Stack pointer passed through R0. B . ENDP SVC_Handler PROC ... А в main.c прописываю extern void HardFaultHandler(unsigned int* pStack); void HardFaultHandler(unsigned int* pStack){ ... } Тогда компилятор ругается что в startup файле символ HardFaultHandler не определен. Может его нужно как то определить в startup.s а не в main.c
  5. Спасибо! То, что нужно. FUNC void Setup (void) { SP = _RDWORD(0x08005000); // Setup Stack Pointer PC = _RDWORD(0x08005004); // Setup Program Counter XPSR = 0x01000000; // Set Thumb bit } Setup(); LOAD %L INCREMENTAL nocode // load debug info without performing reset FUNC void OnResetExec(void) { Setup(); }
  6. Это куда? Вот файлик debug.ini FUNC void Setup (void) { SP = _RDWORD(0x08005000); // Setup Stack Pointer PC = _RDWORD(0x08005004); // Setup Program Counter XPSR = 0x01000000; // Set Thumb bit } Setup(); LOAD %L INCREMENTAL nocode // load debug info without performing reset Там бы дописать что-то типа: IF(RESET) Setup(); Только возможно ли такое? У меня сейчас получается что при загрузке отладчика срабатывает функция Setup(), а когда я нажимаю в нем Reset то SP и PC сбрасываются. И получается что нужно перезагружать отладчик.
  7. Отлаживаю в Keil - ST-Link Debugger. Попробовал по совету x893 создал файл debug.ini. Похоже это то, что мне нужно. Только там получается что при запуске отладчика, он стартует с 0x08005004, а после reset(в отладчике) уже с 0x08000004. Помогите пожалуйста допилить этот ini.
  8. Подскажите как отладчику указать, чтоб он стартовал с определенного адреса? Читал, что вроде как нужно в скаттер файле определить точку входа через команду ENTRY. Только как это сделать я не знаю, что указывать в ее параметрах? Или это не то? Сам файл у меня тот, что предлагается стандартно (с измененной адресацией под бут) ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08005000 0x0000B000 { ; load region size_region ER_IROM1 0x08005000 0x0000B000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x200000C0 0x00001F40 { ; RW data .ANY (+RW +ZI) } }
  9. Спасибо, понял в чем тут дело. Просто раньше работал только с 8 битными МК, там таких проблем нет. А у меня получилось, что буфер char - выравнивание у него по одному байту (без атрибута, начинаться может с любого адреса), а в качестве аргумента функции я передаю указатель на этот буфер с приведением типа до uint32.
  10. Всем привет, наткнулся на такой баг - объявил буфер в глобальных переменных. Передаю его адрес в аргументе функции. И когда обращаюсь в функции к этой переменной через указатель сразу вылетаю в HardFault_Handler. Пол дня парился, и в конце концов выяснил, что линковщик расположил ее по адресу не кратному 4. Проверил, действительно если передать в функцию указатель не кратный 4, то при чтении по этому адресу вылетаем в HardFault_Handler. И теперь не могу добиться, чтоб этот буфер разместился по корректному адресу. Добавляю перед ним или после него новые переменные, адреса смещаются, и у него все равно адрес не корректный. Что делать? P.S Keil V5.23.0.0
  11. Да как только отключил, все работает нормально.
  12. Понял. То есть даже если не включены прерывания по ошибкам, флаги все равно нужно сбрасывать при их установке?
  13. Отладка с приемом по UART

    Народ подскажите, натолкнулся на такую штуку: Включен USART1 на прием и разрешен только один тип прерывания по приему байта. void USART1_IRQHandler(void){ char bt; if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET){ bt = (char)USART_ReceiveData(USART1); USART_ClearITPendingBit(USART1, USART_IT_RXNE); if(bt != 0){ bUartRx[cUartRx] = bt; if(cUartRx >= (BRXSIZE-2)) bUartRx[(BRXSIZE-1)] = 0, cUartRx = 0, fUartRxOver = 1; else cUartRx++, bUartRx[cUartRx] = 0; xSemaphoreGiveFromISR(xSemRxInBuf, NULL); } } } void UART_Init(void){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); USART_InitStruct.USART_BaudRate = 19200; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1, &USART_InitStruct); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPriority = 0; NVIC_Init(&NVIC_InitStruct); Так вот, во время отладки при нажатии Stop или остановки по брекпоинту, если в этот момент что то принималось в UART, то после запуска отладчика все время висим в обработчике прерывания. Причем все флаги сброшены и больше не устанавливаются, даже если приходят данные. P.S. STM32F051R8T6 Keil v.5.23.0.0
  14. Меня интересует, нужна ли повторная инициализация startup в основной программе, или от нее нужно избавиться?
  15. Всем привет. Для написания собственного бутлоадера, интересует что находится между окончанием таблицы прерываний и адресом входа в основную программу (в частности начало файла startup)? Начинается с такого: 0x080000C0 F000F802 BL.W __scatterload (0x080000C8) 0x080000C4 F000F83E BL.W __rt_entry (0x08000144) 0x080000C8 A00C ADR r0,{pc}+0x34; @0x080000FC ... Это в Keil по крайне мере. В отладчике проверил, в этот кусок кода попадаем в конце выполнения startup файла. Мысль одна, что это какая то подготовка регистров ядра. Кто может подсказать, там есть что-то важное или на этот кусок не нужно обращать внимания (не трогать его вообще) и там все всегда стандартно (одинаково)? Если этот код будет дублироваться как в самом загрузчике, так и в основной программе - это нормально? Или может в проекте с основной программой нужно как то написать scatter файл, чтоб проект вообще компилировался без этой инициализации и startup файла?
  16. Так в этих походу тоже. Я ведь не 433МГц принимаю, а то что выдает компаратор данного приемника. И задача практически аналогична, там преамбула и блок данных. Только тот компаратор что в приемнике не всегда выдает нормальный сигнал (когда помехи). Когда помех нет, сигнал как на первой картинки, а когда помехи как на второй. Но в том сигнале есть вся полезная часть, вот я и хочу ее выбирать (взять максимум с этого приемника). А по поводу NRF24L01. Нужно принимать сигнал с готовых устройств, работающих на частоте 433 и передающих данные в формате KeeLoq. P.S. Собственно задача попробовать сделать выборку по напряжению от 2,8В до 3,3В, а остальное откинуть.
  17. Это радиоприемник H5V4D на частоте 433МГц. Собственно я не писал что за источник сигнала, потому как хотел решить задачу именно по получению полезного сигнала из того что есть, а не ковырянием самих модулей. Если дальности действия будет мало, буду искать другой. Но пока задача стоит использовать именно этот. Просто сейчас на определенном удалении с промежуточными стенами, изменением расположения объектов (людей) и т.д., на выходе приемника то нормальный сигнал, то такая хрень. Но сигнал есть всегда, вот я и хочу получить данные по такому корявому сигналу. Сейчас принимаю сигнал с внешнего GPIO через EXTI прерывания. Сам не так давно работаю с STM. Сейчас посмотрел что там EXTI прерывание вроде как на выход компаратора можно настроить. Если так, то по идеи можно отследить нарастание и спад сигнала где-то в пределах от 2,8V до VDD там где полезная часть. Что скажете, или затея глупая?
  18. На выходе приемника при слабом уровне сигнала от передатчика получаем очень искаженный сигнал. Но по верхнему уровню сигнала вроде как видна полезная часть сигнала амплитудой примерно 0,5В. Приемник подключен к STM32F072. Какими аппаратными средствами можно отфильтровать такой сигнал? У меня пока напрашивается только вариант с АЦП. Длительность самого короткого импульса 280 мкс. Максимальная частота дескритизации АЦП на 12бит = 1Мгц. более чем достаточно. Опыта обработки сигналов мало, у кого есть дельные советы? Может еще нужно какой то фильтр поставить на входе МК.
  19. Не имею ни капли сомнения, что оно и правильно, и даже уже понимаю зачем. Со всей уверенностью считаю, что ребята которые все это разрабатывали по умнее всех нас вместе взятых. Хотел написать, что о такой фиче, нужно упоминать через каждую страницу мануала. А потом призадумался, может это такой тактический ход, для тех кто не особо любитель почитать? (пишу о себе:)). Пока это все разгребал, докапался до таких вещей, что неизвестно когда бы ещё специально лез в эти дебри. Но... Было бы чудесно, если бы отладчик спросил, делать переход по вектору прерывания или нет. Это очень удобно для освоения, когда начинающий ещё не знает куда должна пойти программа, и хочет по шагать.
  20. Я даже уже перед выполнением: xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); Отключаю прерывания TIM10 Вот весь проект, убрал все лишнее и переименовал задачи, номер задачи соответствует приоритету, а то я и сам уже начал путаться. xSemaphoreHandle xSem1ms; void Task1(void *pParams); void Task2(void *pParams); void TIM10_IRQHandler(void) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { NVIC->ICER[TIM10_IRQn >> 0x05] = (uint32_t)0x01 << (TIM10_IRQn & (uint8_t)0x1F); xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } int main(void) { NVIC_InitTypeDef NVIC_InitStruct; RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); RCC_HSEConfig(RCC_HSE_OFF); while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET); SystemCoreClockUpdate(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitStruct.NVIC_IRQChannel = TIM10_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 14; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); } void Task1(void *pParams) { xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); while(1); } void Task2(void *pParams) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; vSemaphoreCreateBinary(xSem1ms); xSemaphoreTake(xSem1ms, 0); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 16000 - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInit(TIM10, &TIM_TimeBaseInitStruct); TIM_ClearFlag(TIM10, TIM_FLAG_Update); TIM_ITConfig(TIM10, TIM_IT_Update, ENABLE); TIM_Cmd(TIM10, ENABLE); xSemaphoreTake(xSem1ms, 100); vTaskDelete(NULL); } И на всякий случай заново опишу ситуацию. Со строчки portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) если шагами, попадаем в Task1 - цикл while(1); А если через Run, то попадаем в Task2 на строку vTaskDelete(NULL); P.S. И напоследок. Проверил свое убеждение, что командами Step отладчик не попадает в прерывание, а Run попадает. Проверил на том же TIM10. Включил его, сразу установил флаг прерывания - если пройти его шагами, программа дальше пойдет не попадая в прерывания. А если через Run, то в прерывания попадает. Возможно 9 листов "ереси" того стоило? :) Уверен что не каждый, тем более начинающий об этом знает. И шагая по программе нужно учитывать что в это время могло произойти прерывание и жизнь пошла бы по другому.
  21. И наконец поставил четвертый брекпоинт в xPortPendSVHandler. Нахожусь на строчке portEND_SWITCHING_ISR(xHigherPriorityTaskWoken). 2 раза нажимаю Step, попадаю в Task1. А нажимаю Run, попадаю вначале в xPortPendSVHandler, снова Run и на Task2 на строку после xSemaphoreTake
  22. Нет. Поставил 3 брекпоинта. Task1, Task2 и в xPortSysTickHandler. Сразу попадаем в Task1. P.S. Возможно я ошибаюсь, но что то мне подсказывает, что по функции Step и Step Over отладчик не может попасть в прерывание, а собственно это и должно произойти после выход из обработчика прерывания TIM10, программа должна попасть в PendSV Handler.
  23. Оптимизация стоит Level 0, и сделал я это сразу после установки кейла. Никогда оптимизацию не использую. Да хоть по Cи, хоть по disasm. Был бы disbasic :) думаю так же работал. Эта реплика к чему? Где про это сказано?
  24. Тот что в Keil. Причем только в пошаговом режиме кнопками Step или Step Over при выходе из обработчика прерываний. А если поставить брекпоинты в задачах, и выйти из прерывания Step Out или Run тогда попадаем куда нужно, то есть в Task2.
×
×
  • Создать...