/* * FreeRTOS V202212.00 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /** * @file main.c * @brief Implements the main function. */ /* FreeRTOS include. */ #include #include "task.h" /* TCP/IP stack includes. */ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" /* Standard includes. */ #include #include #include /* Visual studio intrinsics used so the __debugbreak() function is available * should an assert get hit. */ #if defined( _WIN32 ) #include #endif /* Test Specific configs. */ #include "test_config.h" /* Unity framework includes. */ #include "unity_fixture.h" #include "unity_internals.h" /*-----------------------------------------------------------*/ /* Use by the pseudo random number generator. */ static UBaseType_t ulNextRand; /*-----------------------------------------------------------*/ void CellularTestTask( void * pvParameters ) { ( void ) pvParameters; /* Initialize unity. */ UnityFixture.Verbose = 1; UnityFixture.GroupFilter = 0; UnityFixture.NameFilter = 0; UnityFixture.RepeatCount = 1; /* Run Unity Tests. */ UNITY_BEGIN(); #if defined( testCELLULAR_API ) && testCELLULAR_API == 1 RUN_TEST_GROUP( Full_CELLULAR_API ); #endif UNITY_END(); /* This task has finished. FreeRTOS does not allow a task to run off the * end of its implementing function, so the task must be deleted. */ vTaskDelete( NULL ); } /*-----------------------------------------------------------*/ int main( void ) { /*** * See https://www.FreeRTOS.org/mqtt_lts/index.html for configuration and usage instructions. ***/ /* FreeRTOS Cellular Library init needs thread ready environment. * CellularDemoTask invoke setupCellular to init FreeRTOS Cellular Library and register network. * Then it runs the MQTT demo. */ xTaskCreate( CellularTestTask, /* Function that implements the task. */ "CellularTest", /* Text name for the task - only used for debugging. */ testconfigTEST_STACKSIZE, /* Size of stack (in words, not bytes) to allocate for the task. */ NULL, /* Task parameter - not used in this case. */ testconfigTEST_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */ NULL ); /* Used to pass out a handle to the created task - not used in this case. */ /* Start the RTOS scheduler. */ vTaskStartScheduler(); } /*-----------------------------------------------------------*/ /* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect * events are only received if implemented in the MAC driver. */ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ { ( void ) eNetworkEvent; } /*-----------------------------------------------------------*/ void vAssertCalled( const char * pcFile, uint32_t ulLine ) { volatile uint32_t ulBlockVariable = 0UL; volatile char * pcFileName = ( volatile char * ) pcFile; volatile uint32_t ulLineNumber = ulLine; ( void ) pcFileName; ( void ) ulLineNumber; configPRINTF( ( "vAssertCalled( %s, %u\n", pcFile, ulLine ) ); /* Setting ulBlockVariable to a non-zero value in the debugger will allow * this function to be exited. */ taskDISABLE_INTERRUPTS(); { while( ulBlockVariable == 0UL ) { #if defined( _WIN32 ) __debugbreak(); #endif } } taskENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ void vApplicationIdleHook( void ) { const uint32_t ulMSToSleep = 1; const TickType_t xKitHitCheckPeriod = pdMS_TO_TICKS( 1000UL ); static TickType_t xTimeNow, xLastTimeCheck = 0; /* 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 application tasks make use of the * vTaskDelete() API function to delete themselves 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 deleted itself. */ /* _kbhit() is a Windows system function, and system functions can cause * crashes if they somehow block the FreeRTOS thread. The call to _kbhit() * can be removed if it causes problems. Limiting the frequency of calls to * _kbhit() should minimize the potential for issues. */ xTimeNow = xTaskGetTickCount(); if( ( xTimeNow - xLastTimeCheck ) > xKitHitCheckPeriod ) { /* Uncomment the print line to get confirmation that tests are still * running if you suspect a previous run resulted in a crash. */ /* configPRINTF( ( "Running...\n" ) ); /**/ xLastTimeCheck = xTimeNow; } /* This is just a trivial example of an idle hook. It is called on each * cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in * FreeRTOSConfig.h. It must *NOT* attempt to block. In this case the * idle task just sleeps to lower the CPU usage. */ Sleep( ulMSToSleep ); } /*-----------------------------------------------------------*/ #if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 ) const char * pcApplicationHostnameHook( void ) { /* Assign the name "FreeRTOS" to this network node. This function will * be called during the DHCP: the machine will be registered with an IP * address plus this name. */ return mainHOST_NAME; } #endif /*-----------------------------------------------------------*/ #if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ { BaseType_t xReturn; /* Determine if a name lookup is for this node. Two names are given * to this node: that returned by pcApplicationHostnameHook() and that set * by mainDEVICE_NICK_NAME. */ if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 ) { xReturn = pdPASS; } else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 ) { xReturn = pdPASS; } else { xReturn = pdFAIL; } return xReturn; } #endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */ /*-----------------------------------------------------------*/ /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t * pulIdleTaskStackSize ) { /* If the buffers to be provided to the Idle task are declared inside this * function then they must be declared static - otherwise they will be allocated on * the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; /* Pass out a pointer to the StaticTask_t structure in which the Idle task's * state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. * Note that, as the array is necessarily of type StackType_t, * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ void getUserCmd( char * pucUserCmd ) { char cTmp; scanf( "%c%c", pucUserCmd, &cTmp ); } /*-----------------------------------------------------------*/ UBaseType_t uxRand( void ) { const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; /* Utility function to generate a pseudo random number. */ ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL ); } /*-----------------------------------------------------------*/ BaseType_t xApplicationGetRandomNumber() { return uxRand(); } /*-----------------------------------------------------------*/ /* * Callback that provides the inputs necessary to generate a randomized TCP * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION * SYSTEMS. */ extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, uint16_t usSourcePort, uint32_t ulDestinationAddress, uint16_t usDestinationPort ) { ( void ) ulSourceAddress; ( void ) usSourcePort; ( void ) ulDestinationAddress; ( void ) usDestinationPort; return uxRand(); } /*-----------------------------------------------------------*/ /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the * application must provide an implementation of vApplicationGetTimerTaskMemory() * to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t * pulTimerTaskStackSize ) { /* If the buffers to be provided to the Timer task are declared inside this * function then they must be declared static - otherwise they will be allocated on * the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; /* Pass out a pointer to the StaticTask_t structure in which the Timer * task's state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; /* Pass out the array that will be used as the Timer task's stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. * Note that, as the array is necessarily of type StackType_t, * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } /*-----------------------------------------------------------*/