|
FreeRTOS + localtime() == Hard Fault |
|
|
|
Jul 7 2016, 21:36
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Здравствуйте. Все произошло во время того, когда я пытался поднять сервер mongoose на плате stm32-e407 с контроллером stm32f407zgt6. До этого хардфолты возникали довольно часто, но как-то удавалось от них уходить не разбираясь до конца, в чем же все-таки дело, но видимо время пришло: Делаю проект с помощью CubeMX на eclipse (генерирую для truestudio), в проекте включен FreeRTOS версии 8.2.1 с heap.4, включены кварцы, программа падает в функции localtime в StartDefaultTask, НО, если расскоментировать такие же три строчки перед osKernelStart, то и в таске оно не упадет. Хотелось бы разобраться в чем проблема или хотя бы куда копать, ниже код и содержимое регистров после ХФ: CODE #include "stm32f4xx_hal.h" #include "cmsis_os.h"
/* USER CODE BEGIN Includes */ /* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/ osThreadId defaultTaskHandle;
/* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); void StartDefaultTask(void const * argument);
/* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ extern void initialise_monitor_handles(void);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */ /* USER CODE END 0 */
int main(void) {
/* USER CODE BEGIN 1 */ #ifdef DEBUG initialise_monitor_handles(); printf("initializing\n"); #endif /* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();
/* Configure the system clock */ SystemClock_Config();
/* Initialize all configured peripherals */ MX_GPIO_Init();
/* USER CODE BEGIN 2 */ /* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */
/* Create the thread(s) */ /* definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 1024); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */
/* definition and creation of httpTask */ /* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */
/* Start scheduler */ // ЕСЛИ РАСКОММЕНТИРОВАТЬ 3 СТРОЧКИ НИЖЕ ВСЕ ОК // long a = 10241024; // time_t timet = a; // struct tm* mytime = localtime(&timet); osKernelStart(); /* We should never get here as control is now taken by the scheduler */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
} /* USER CODE END 3 */
}
/** System Clock Configuration */ void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 6; RCC_OscInitStruct.PLL.PLLN = 168; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0); }
/** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI PG11 ------> ETH_TX_EN PG13 ------> ETH_TXD0 PG14 ------> ETH_TXD1 */ void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE();
/*Configure GPIO pins : PG11 PG13 PG14 */ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/* StartDefaultTask function */ void StartDefaultTask(void const * argument) {
/* USER CODE BEGIN 5 */ long a = 10241024; time_t timet = a; struct tm* mytime = localtime(&timet); /* Infinite loop */ for(;;) { vTaskDelay(1000); } /* USER CODE END 5 */ } Код EXEC_RETURN (LR): lr 0xfffffffd -3 xPSR 0xffffffff ReturnAddress 0x8008fc9 LR (R14) 0x8008fc9 R12 0x8008ec2 R3 0x0 R2 0x0 R1 0x0 R0 0x1 Return instruction: 0x8008fc9: movs r0, r4 LR instruction: 0x8008fc9: movs r0, r4
CFSR 0x00008200 HFSR 0x40000000 BFAR 0x2800cb48 Добавлю, попробовал обновить FreeRTOS до V9.0.0rc2, ничего не поменялось
Сообщение отредактировал IgorKossak - Jul 8 2016, 09:45
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
|
|
|
|
|
Jul 8 2016, 07:02
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Обнаружил, что падает на исполнении вот этой инструкции Код ldr.w r3, [r5, r3, lsl #2] в фнкции localtime_r. В случае, если код вставлен до инициализации ядра, то до исполнения этой инструкции дело не доходит
|
|
|
|
|
Jul 8 2016, 08:45
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
В том то и дело, что проект пустой. Вот функция в которой падает
|
|
|
|
|
Jul 8 2016, 11:00
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Цитата(jcxz @ Jul 8 2016, 12:10)  Достаточно поставить бряк на этой инструкции (или чуть раньше) и посмотреть содержимое регистров. Далее - ознакомиться с картой памяти МК. И думать "как же я дошёл до адресов таких?"  Код r5 0x8008c14 r3 0x8000fc9 Вроде все нормально, и то и другое ссылается на флеш, меня смущает две вещи: 1. Тут вроде как сказано, что в thumb нельзя использовать Rm (ldr.w r3, [r5, r3, lsl #2]), т.е. r3, который в скобках 2. Я не понял, что есть lsl, гдб говорит, что регистра такого нет. Заранее говорю, что асм вижу в глаза вообще первый раз) В целом смущает, что функция вроде стандартная и падать, казалось бы, не должна. Еще больше смущает, что без FreeRTOS она и не падает.
|
|
|
|
|
Jul 8 2016, 11:01
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
localtime() возвращает указатель на глобальную структуру, что в многопоточной среде не очень хорошо. Поэтому не используйте localtime(), а используйте localtime_r(): Код time_t t = rtc_ReadTime(); struct tm stm; localtime_r(&t, &stm); Во-вторых, я заметил, что в свежих версиях arm-embedded что-то начудили с функциями времени, и они теперь подтягивают вызовы gettzinfo(), которые, в свою очередь, вызывают malloc(). Поэтому проверьте, как у вас настроена куча.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 8 2016, 11:14
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Кстати говоря, в мануале на cortex-m3 описано, как расшифровать регистры CFSR, HFSR, DFSR, AFSR, MMFAR и BFAR Оттуда можно почерпнуть, что именно вызвало падение А вот тут описано, как получить регистры, которые были в момент падения
|
|
|
|
|
Jul 8 2016, 11:31
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(lawless @ Jul 8 2016, 17:00)  Код r5 0x8008c14 r3 0x8000fc9 Вроде все нормально, и то и другое ссылается на флеш, меня смущает две вещи: Вы уверены, что на флешь??? Посмотрите внимательнее на свою команду: ldr.w r3, [r5, r3, lsl #2] исполнительный адрес вычисляется: R5 + R3 * 4 - возьмите калькулятор, подставьте свои значения и посчитайте. Цитата(lawless @ Jul 8 2016, 17:00)  1. Тут вроде как сказано, что в thumb нельзя использовать Rm (ldr.w r3, [r5, r3, lsl #2]), т.е. r3, который в скобках 2. Я не понял, что есть lsl, гдб говорит, что регистра такого нет. Там вообще про другое ядро разговор. У Вас - Cortex-M. Найдите на том же ресурсе мануал на Ваше ядро.
|
|
|
|
|
Jul 8 2016, 11:47
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Цитата(AHTOXA @ Jul 8 2016, 14:01)  localtime() возвращает указатель на глобальную структуру, что в многопоточной среде не очень хорошо. Поэтому не используйте localtime(), а используйте localtime_r(): Код time_t t = rtc_ReadTime(); struct tm stm; localtime_r(&t, &stm); Во-вторых, я заметил, что в свежих версиях arm-embedded что-то начудили с функциями времени, и они теперь подтягивают вызовы gettzinfo(), которые, в свою очередь, вызывают malloc(). Поэтому проверьте, как у вас настроена куча. Спасибо за подсказку, с localtime_r все сработало, помимо gettzinfo() сам localtime() вызывает malloc(), что, в принципе, понятно. Цитата Вы уверены, что на флешь??? Теперь не уверен, ссылается какраз таки куда-то на 0x2800cb38, где должен быть sram, но уже давно кончился, из-за этого, по-видимому и падает, тем более что в регистре BFAR какраз оно и содержится.
|
|
|
|
|
Jul 8 2016, 14:50
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Я так понял, основная проблема была с тем, что malloc() возвращал 0x0 при вызове из поток и решилась заменой функции _sbrk(), вот тут нашел ответ. Спасибо всем кто принимал участие)
|
|
|
|
|
Jul 8 2016, 19:46
|
Группа: Участник
Сообщений: 7
Регистрация: 7-07-16
Пользователь №: 92 473

|
Цитата(jcxz @ Jul 8 2016, 19:24)  А как тогда у Вас кривой адрес возникал? Хороший вопрос) Был бы рад, если бы мне кто-то на него ответил. Особенно учитывая, что программа теперь стала хардфолтится в функции svnprintf() и я подозреваю, что причина как-то связана с тем, что было в localtime()
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|