- /*
- FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.
- FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
- http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
- ***************************************************************************
- * *
- * FreeRTOS tutorial books are available in pdf and paperback. *
- * Complete, revised, and edited pdf reference manuals are also *
- * available. *
- * *
- * Purchasing FreeRTOS documentation will not only help you, by *
- * ensuring you get running as quickly as possible and with an *
- * in-depth knowledge of how to use FreeRTOS, it will also help *
- * the FreeRTOS project to continue with its mission of providing *
- * professional grade, cross platform, de facto standard solutions *
- * for microcontrollers - completely free of charge! *
- * *
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
- * *
- * Thank you for using FreeRTOS, and thank you for your support! *
- * *
- ***************************************************************************
- This file is part of the FreeRTOS distribution.
- FreeRTOS is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License (version 2) as published by the
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
- >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
- distribute a combined work that includes FreeRTOS without being obliged to
- provide the source code for proprietary components outside of the FreeRTOS
- kernel.
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details. You should have received a copy of the GNU General Public License
- and the FreeRTOS license exception along with FreeRTOS; if not itcan be
- viewed here: http://www.freertos.org/a00114.html and also obtained by
- writing to Real Time Engineers Ltd., contact details for whom are available
- on the FreeRTOS WEB site.
- 1 tab == 4 spaces!
- ***************************************************************************
- * *
- * Having a problem? Start by reading the FAQ "My application does *
- * not run, what could be wrong?" *
- * *
- * http://www.FreeRTOS.org/FAQHelp.html *
- * *
- ***************************************************************************
- http://www.FreeRTOS.org - Documentation, books, training, latest versions,
- license and Real Time Engineers Ltd. contact details.
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
- including FreeRTOS+Trace - an indispensable productivity tool, and our new
- fully thread aware and reentrant UDP/IP stack.
- http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
- Integrity Systems, who sell the code with commercial support,
- indemnification and middleware, under the OpenRTOS brand.
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety
- engineered and independently SIL3 certified version for use in safety and
- mission critical applications that require provable dependability.
- */
- /******************************************************************************
- * >>>>>> NOTE 1: <<<<<<
- *
- * main() can be configured to create either a very simple LED flasher demo, or
- * a more comprehensive test/demo application.
- *
- * To create a very simple LED flasher example, set the
- * mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY constant (defined below) to 1. When
- * this is done, only the standard demo flash tasks are created. The standard
- * demo flash example creates three tasks, each of which toggle an LED at a
- * fixed but different frequency.
- *
- * To create a more comprehensive test and demo application, set
- * mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 0.
- *
- * >>>>>> NOTE 2: <<<<<<
- *
- * In addition to the normal set of standard demo tasks, the comprehensive test
- * makes heavy use of the floating point unit, and forces floating point
- * instructions to be used from interrupts that nest three deep. The nesting
- * starts from the tick hook function, resulting is an abnormally long context
- * switch time. This is done purely to stress test the FPU context switching
- * implementation, and that part of the test can be removed by setting
- * configUSE_TICK_HOOK to 0 in FreeRTOSConfig.h.
- ******************************************************************************
- *
- * main() creates all the demo application tasks and software timers, then starts
- * the scheduler. The web documentation provides more details of the standard
- * demo application tasks, which provide no particular functionality, but do
- * provide a good example of how to use the FreeRTOS API.
- *
- */
- /* A TCP echo server which is implemented with LwIP under FreeRTOS.
- The server listen to port 80, IP address could configure statically
- to 192.168.1.2 or assign by DHCP server. This server replies
- "Hello World!!" if the received string is "nuvoton", otherwise
- reply "Wrong Password!!" to its client. */
- #include <stdio.h>
- /* Kernel includes. */
- #include "FreeRTOS.h"
- #include "task.h"
- #include "timers.h"
- #include "semphr.h"
- /* Demo application includes. */
- #include "partest.h"
- #include "flash.h"
- #include "flop.h"
- #include "integer.h"
- #include "PollQ.h"
- #include "semtest.h"
- #include "dynamic.h"
- #include "BlockQ.h"
- #include "blocktim.h"
- #include "countsem.h"
- #include "GenQTest.h"
- #include "QueueSet.h"
- #include "recmutex.h"
- #include "death.h"
- /* Hardware and starter kit includes. */
- #include "NUC472_442.h"
- #include "lwip/api.h"
- #include "lwip/netif.h"
- #include "lwip/tcpip.h"
- #include "ethernetif.h"
- #include "tcp_client.h"
- /* Priorities for the demo application tasks. */
- #if 0
- #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL )
- #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
- #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
- #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
- #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
- #else
- #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL )
- #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1UL )
- #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
- #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
- #endif
- #define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE )
- /* The time between cycles of the 'check' task. */
- #define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )
- /* The LED used by the check timer. */
- #define mainCHECK_LED ( 3UL )
- /* A block time of zero simply means "don't block". */
- #define mainDONT_BLOCK ( 0UL )
- /* The period after which the check timer will expire, in ms, provided no errors
- have been reported by any of the standard demo tasks. ms are converted to the
- equivalent in ticks using the portTICK_RATE_MS constant. */
- #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
- /* The period at which the check timer will expire, in ms, if an error has been
- reported in one of the standard demo tasks. ms are converted to the equivalent
- in ticks using the portTICK_RATE_MS constant. */
- #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
- /* Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 1 to create a simple demo.
- Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 0 to create a much more
- comprehensive test application. See the comments at the top of this file, and
- the documentation page on the http://www.FreeRTOS.org web site for more
- information. */
- #define mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY 0
- #define CHECK_TEST
- //#define USE_DHCP
- #ifdef USE_DHCP
- #include "lwip/dhcp.h"
- #endif
- /*-----------------------------------------------------------*/
- /*
- * Set up the hardware ready to run this demo.
- */
- static void prvSetupHardware( void );
- /*-----------------------------------------------------------*/
- #ifdef CHECK_TEST
- static void vCheckTask( void *pvParameters );
- #endif
- unsigned char my_mac_addr[6] = {0x00, 0x00, 0x00, 0x55, 0x66, 0x77};
- struct netif netif;
- static void vWebTask( void *pvParameters );
- int main(void)
- {
- /* Configure the hardware ready to run the test. */
- prvSetupHardware();
- xTaskCreate( vWebTask, ( signed portCHAR * ) "Web", TCPIP_THREAD_STACKSIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
- #ifdef CHECK_TEST
- xTaskCreate( vCheckTask, ( signed portCHAR * ) "Check", mainCHECK_TASK_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
- #endif
- //vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
- vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
- vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
- vStartGenericQueueTasks( tskIDLE_PRIORITY );
- vStartQueueSetTasks();
- printf("FreeRTOS is starting ...\n");
- /* Start the scheduler. */
- vTaskStartScheduler();
- /* If all is well, the scheduler will now be running, and the following line
- will never be reached. If the following line does execute, then there was
- insufficient FreeRTOS heap memory available for the idle and/or timer tasks
- to be created. See the memory management section on the FreeRTOS web site
- for more details. */
- for( ;; );
- }
- /*-----------------------------------------------------------*/
- static void prvSetupHardware( void )
- {
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Enable External XTAL (4~24 MHz) */
- CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
- /* Waiting for 12MHz clock ready */
- CLK_WaitClockReady( CLK_STATUS_HXTSTB_Msk);
- /* Switch HCLK clock source to HXT */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT,CLK_CLKDIV0_HCLK(1));
- /* Set PLL to power down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
- CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
- /* Set PLL frequency */
- CLK->PLLCTL = CLK_PLLCTL_84MHz_HXT;
- /* Waiting for clock ready */
- CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
- /* Switch HCLK clock source to PLL */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL,CLK_CLKDIV0_HCLK(1));
- /* Enable IP clock */
- CLK_EnableModuleClock(UART0_MODULE);
- CLK_EnableModuleClock(EMAC_MODULE);
- /* Select IP clock source */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));
- // Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
- CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
- /* Update System Core Clock */
- /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
- SystemCoreClockUpdate();
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Set GPG multi-function pins for UART0 RXD and TXD */
- SYS->GPG_MFPL = SYS_GPG_MFPL_PG1MFP_UART0_RXD | SYS_GPG_MFPL_PG2MFP_UART0_TXD ;
- // Configure RMII pins
- SYS->GPC_MFPL = SYS_GPC_MFPL_PC0MFP_EMAC_REFCLK |
- SYS_GPC_MFPL_PC1MFP_EMAC_MII_RXERR |
- SYS_GPC_MFPL_PC2MFP_EMAC_MII_RXDV |
- SYS_GPC_MFPL_PC3MFP_EMAC_MII_RXD1 |
- SYS_GPC_MFPL_PC4MFP_EMAC_MII_RXD0 |
- SYS_GPC_MFPL_PC6MFP_EMAC_MII_TXD0 |
- SYS_GPC_MFPL_PC7MFP_EMAC_MII_TXD1;
- SYS->GPC_MFPH = SYS_GPC_MFPH_PC8MFP_EMAC_MII_TXEN;
- // Enable high slew rate on all RMII pins
- PC->SLEWCTL |= 0x1DF;
- // Configure MDC, MDIO at PB14 & PB15
- SYS->GPB_MFPH = SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
- /* Lock protected registers */
- SYS_LockReg();
- /* Init UART to 115200-8n1 for print message */
- UART_Open(UART0, 115200);
- }
- /*-----------------------------------------------------------*/
- void vApplicationMallocFailedHook( void )
- {
- /* vApplicationMallocFailedHook() will only be called if
- configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
- function that will get called if a call to pvPortMalloc() fails.
- pvPortMalloc() is called internally by the kernel whenever a task, queue,
- timer or semaphore is created. It is also called by various parts of the
- demo application. If heap_1.c or heap_2.c are used, then the size of the
- heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
- FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
- to query the size of free heap space that remains (although it does not
- provide information on how the remaining heap might be fragmented). */
- taskDISABLE_INTERRUPTS();
- for( ;; );
- }
- /*-----------------------------------------------------------*/
- void vApplicationIdleHook( void )
- {
- /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
- to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
- task. It is essential that code added to this hook function never attempts
- to block in any way (for example, call xQueueReceive() with a block time
- specified, or call vTaskDelay()). If the application makes use of the
- vTaskDelete() API function (as this demo application does) then it is also
- important that vApplicationIdleHook() is permitted to return to its calling
- function, because it is the responsibility of the idle task to clean up
- memory allocated by the kernel to any task that has since been deleted. */
- }
- /*-----------------------------------------------------------*/
- void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
- {
- ( void ) pcTaskName;
- ( void ) pxTask;
- /* Run time stack overflow checking is performed if
- configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
- function is called if a stack overflow is detected. */
- taskDISABLE_INTERRUPTS();
- for( ;; );
- }
- /*-----------------------------------------------------------*/
- void vApplicationTickHook( void )
- {
- /* This function will be called by each tick interrupt if
- configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
- added here, but the tick hook is called from an interrupt context, so
- code must not attempt to block, and only the interrupt safe FreeRTOS API
- functions can be used (those that end in FromISR()). */
- #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
- {
- /* In this case the tick hook is used as part of the queue set test. */
- vQueueSetAccessQueueSetFromISR();
- }
- #endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
- }
- static void vWebTask( void *pvParameters )
- {
- struct ip_addr ipaddr;
- struct ip_addr netmask;
- struct ip_addr gw;
- IP4_ADDR(&gw, 192,168,1,1);
- IP4_ADDR(&ipaddr, 192,168,1,2);
- IP4_ADDR(&netmask, 255,255,255,0);
- printf("Local IP:192.168.1.2\n");
- tcpip_init(NULL, NULL);
- netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, tcpip_input);
- netif_set_default(&netif);
- #ifdef USE_DHCP
- dhcp_start(&netif);
- #else
- netif_set_up(&netif);
- #endif
- //NVIC_SetPriority(EMAC_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ(EMAC_TX_IRQn);
- //NVIC_SetPriority(EMAC_RX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ(EMAC_RX_IRQn);
- tcp_client_init();
- vTaskSuspend( NULL );
- }
- /*-----------------------------------------------------------*/
- #ifdef CHECK_TEST
- static void vCheckTask( void *pvParameters )
- {
- portTickType xLastExecutionTime;
- xLastExecutionTime = xTaskGetTickCount();
- printf("Check Task is running ...\n");
- for( ;; ) {
- /* Perform this check every mainCHECK_DELAY milliseconds. */
- vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
- if( xArePollingQueuesStillRunning() != pdTRUE ) {
- printf( "ERROR IN POLL Q\n" );
- }
- }
- }
- #endif