/**************************************************************************** * Copyright: (C)2018 Î人ÁèÔÆÎïÍøÖÇ¿ÆÊµÑéÊÒ www.iot-yun.com * Author: GuoWenxue QQ: 281143292 * Description: STM32L151C8T6 CubeMX ¿ª·¢°å FreeRTOS ÒÆÖ²ÒÀÀµº¯Êý * * ChangeLog: * °æ±¾ºÅ ÈÕÆÚ ×÷Õß ËµÃ÷ * V1.0.0 2018.11.05 GuoWenxue ·¢²¼¸Ã°æ±¾ ****************************************************************************/ #include "stm32l1xx.h" #include "stm32_vport.h" unsigned long ulTIM6_OverflowCount = 0UL; void prvSetupHardware( void ) { init_led_gpio(); //init_keys_interrupt(); stm32_init_printf(USART_PORT1, 115200); } void vConfigureTimerForRunTimeStats( void ) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; /* The time base for the run time stats is generated by the 16 bit timer 6. Each time the timer overflows ulTIM6_OverflowCount is incremented. Therefore, when converting the total run time to a 32 bit number, the most significant two bytes are given by ulTIM6_OverflowCount and the least significant two bytes are given by the current TIM6 counter value. Care must be taken with data consistency when combining the two in case a timer overflow occurs as the value is being read. The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is defined to call this function, so the kernel will call this function automatically at the appropriate time. */ /* TIM6 clock enable */ RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6, ENABLE ); /* The 32MHz clock divided by 5000 should tick (very) approximately every 150uS and overflow a 16bit timer (very) approximately every 10 seconds. */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 5000; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit( TIM6, &TIM_TimeBaseStructure ); /* Only interrupt on overflow events. */ TIM6->CR1 |= TIM_CR1_URS; /* Enable the interrupt. */ TIM_ITConfig( TIM6, TIM_IT_Update, ENABLE ); /* Enable the TIM6 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; /* Not used as 4 bits are used for the pre-emption priority. */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ClearITPendingBit( TIM6, TIM_IT_Update ); TIM_Cmd( TIM6, ENABLE ); } /*-----------------------------------------------------------*/ void TIM6_IRQHandler( void ) { /* Interrupt handler for TIM 6 The time base for the run time stats is generated by the 16 bit timer 6. Each time the timer overflows ulTIM6_OverflowCount is incremented. Therefore, when converting the total run time to a 32 bit number, the most significant two bytes are given by ulTIM6_OverflowCount and the least significant two bytes are given by the current TIM6 counter value. Care must be taken with data consistency when combining the two in case a timer overflow occurs as the value is being read. */ if( TIM_GetITStatus( TIM6, TIM_IT_Update) != RESET) { ulTIM6_OverflowCount++; TIM_ClearITPendingBit( TIM6, TIM_IT_Update ); } } /*-----------------------------------------------------------*/ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; /* Run time stack overflow checking is performed if configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is called if a stack overflow is detected. */ for( ;; ); } /*-----------------------------------------------------------*/ void vApplicationMallocFailedHook( void ) { /* Called if a call to pvPortMalloc() fails because there is insufficient free memory available in the FreeRTOS heap. pvPortMalloc() is called internally by FreeRTOS API functions that create tasks, queues or semaphores. */ for( ;; ); } /*-----------------------------------------------------------*/ void vApplicationIdleHook( void ) { /* Called on each iteration of the idle task. In this case the idle task just enters a low(ish) power mode. */ PWR_EnterSleepMode( PWR_Regulator_ON, PWR_SLEEPEntry_WFI ); } #if 0 void vApplicationTickHook( void ) { static unsigned long ulCounter = 0; static const unsigned long ulCheckFrequency = 5000UL / portTICK_PERIOD_MS; /* This is called from within the tick interrupt and performs the 'check' functionality as described in the comments at the top of this file. Is it time to perform the 'check' functionality again? */ ulCounter++; if( ulCounter >= ulCheckFrequency ) { ulCounter = 0; } } #endif /*-----------------------------------------------------------*/