#include "FreeRTOS.h" #include "task.h" #include "gd32f107c_eval.h" #include "gd32f10x_gpio.h" #include "stdio.h" #define BUTTON_USER GPIO_PIN_14 #define LED2_USER_PORT GPIOC #define LED5_TICK_PORT GPIOE #define LED2_USER GPIO_PIN_0 #define LED5_TICK GPIO_PIN_1 #define TASK_HELLO_WORLD_DELAY 500 #define TASK_TOGGLE_LED_DELAY 125 void vTaskHelloWorld( void *pvParameters); void vTaskToggleLed( void *pvParameters); int stdout_putchar (int ch); int stdin_getchar (void); void DelayMS(unsigned char ms); int stdout_putchar (int ch) { usart_data_transmit(EVAL_COM1, (uint16_t)ch); while (!usart_flag_get(EVAL_COM1, USART_FLAG_TBE)){} return ch; } int stdin_getchar (void) { return usart_data_receive(EVAL_COM1); } /**! \brief vInitMCU * Initial MCU configuration */ static void vInitMCU(void) { SystemInit(); //gd_eval_led_init(LED2); //gd_eval_led_on(LED2); rcu_periph_clock_enable(RCU_GPIOC); gpio_init(LED2_USER_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED2_USER); gpio_bit_set(LED2_USER_PORT, LED2_USER); rcu_periph_clock_enable(RCU_GPIOE); gpio_init(LED5_TICK_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED5_TICK); gpio_bit_set(LED5_TICK_PORT, LED5_TICK); gd_eval_com_init(EVAL_COM1); rcu_periph_clock_enable(RCU_GPIOB); gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_2MHZ, BUTTON_USER); } /**! \brief vTaskHelloWorld procedure * * \param Not Used. */ void vTaskHelloWorld( void *pvParameters) { char ButtonState = 0; for( ;; ) { ButtonState = !gpio_input_bit_get(GPIOB, BUTTON_USER); if (ButtonState) { printf("Hello world\n"); vTaskDelay(TASK_HELLO_WORLD_DELAY); } } } /**! \brief vTaskToggleLed procedure * * \param Not Used. */ void vTaskToggleLed( void *pvParameters) { char toggle = 1; for( ;; ) { if (toggle) { gpio_bit_reset(LED2_USER_PORT, LED2_USER); } else { gpio_bit_set(LED2_USER_PORT, LED2_USER); } toggle = !toggle; vTaskDelay(TASK_TOGGLE_LED_DELAY); } } int main(void) { vInitMCU(); xTaskCreate(vTaskToggleLed, "ToggleLed", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); xTaskCreate(vTaskHelloWorld, "HelloWorld", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); vTaskStartScheduler(); while(1); } /**! \func void vApplicationMallocFailedHook( void ) * \brief This hook function is called when allocation failed. */ void vApplicationMallocFailedHook( void ) { #if defined (DEBUG) printf("Malloc Failed Hook\n"); __ASM("BKPT #0\n"); #endif NVIC_SystemReset(); while(TRUE){} } /**! \func vApplicationTickHook( void ) * \brief Toggles LED5_TICK to indicate RTOS running well */ void vApplicationTickHook( void ) { static uint16_t tickCounter = 0; if(++tickCounter == configTICK_RATE_HZ) { gpio_bit_reset(LED5_TICK_PORT, LED5_TICK); tickCounter = 0; } else if(tickCounter == configTICK_RATE_HZ/2) { gpio_bit_set(LED5_TICK_PORT, LED5_TICK); } } /**! \func vApplicationIdleHook( void ) * \brief Idle task Hook */ void vApplicationIdleHook( void ) { #if defined (DEBUG) int32_t delta = (configTICK_RATE_HZ-(TASK_TOGGLE_LED_DELAY + TASK_HELLO_WORLD_DELAY)) % configTICK_RATE_HZ; if (delta < 0) delta = -delta; static uint32_t idleHookCounter = 0; uint32_t currentTick = xTaskGetTickCount(); if(currentTick > idleHookCounter + delta) { printf("Idle Hook %d\n", idleHookCounter);//__ASM("BKPT #0\n"); } idleHookCounter = currentTick; #endif } /**! \func vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) * \brief Stack overflow Hook */ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) { #if defined (DEBUG) printf("Stack Overflow Hook\n"); __ASM("BKPT #0\n"); #endif NVIC_SystemReset(); while(TRUE){} } __attribute__((used)) void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used. If the debugger won't show the values of the variables, make them global my moving their declaration outside of this function. */ static volatile uint32_t r0; static volatile uint32_t r1; static volatile uint32_t r2; static volatile uint32_t r3; static volatile uint32_t r12; static volatile uint32_t lr; /* Link register. */ static volatile uint32_t pc; /* Program counter. */ static volatile uint32_t psr;/* Program status register. */ r0 = pulFaultStackAddress[ 0 ]; r1 = pulFaultStackAddress[ 1 ]; r2 = pulFaultStackAddress[ 2 ]; r3 = pulFaultStackAddress[ 3 ]; r12 = pulFaultStackAddress[ 4 ]; lr = pulFaultStackAddress[ 5 ]; pc = pulFaultStackAddress[ 6 ]; psr = pulFaultStackAddress[ 7 ]; #ifdef DEBUG printf("Hard Fault Hook\n"); __asm volatile("BKPT #0\n") ; #endif NVIC_SystemReset(); /* When the following line is hit, the variables contain the register values. */ for( ;; ); } void DelayMS(unsigned char ms) { unsigned long us = 1000*ms; while (us--) { __NOP(); } }