diff options
-rw-r--r-- | .cproject | 127 | ||||
-rw-r--r-- | .settings/language.settings.xml | 11 | ||||
-rw-r--r-- | src/DuetNG/Pins_DuetNG.h | 1 | ||||
-rw-r--r-- | src/Platform.cpp | 193 | ||||
-rw-r--r-- | src/Platform.h | 6 | ||||
-rw-r--r-- | src/RepRap.cpp | 2 | ||||
-rw-r--r-- | src/Tasks.cpp | 301 | ||||
-rw-r--r-- | src/Tasks.h | 27 | ||||
-rw-r--r-- | src/Version.h | 10 |
9 files changed, 515 insertions, 163 deletions
@@ -213,6 +213,8 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/DuetNG}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/DuetWiFiSocketServer/src/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/portable/GCC/ARM_CM4F}""/> </option> <option id="gnu.cpp.compiler.option.preprocessor.def.1610427238" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> <listOptionValue builtIn="false" value="__SAM4E8E__"/> @@ -562,8 +564,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/DuetM}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/W5500Ethernet}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/W5500Ethernet/Wiznet/Ethernet}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> </option> <option id="gnu.cpp.compiler.option.preprocessor.def.1565207565" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> <listOptionValue builtIn="false" value="__SAM4S8C__"/> @@ -691,6 +692,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/DuetWiFiSocketServer/src/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> </option> <option id="gnu.cpp.compiler.option.preprocessor.def.178336065" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> <listOptionValue builtIn="false" value="__SAME70Q21__"/> @@ -709,6 +711,127 @@ </storageModule> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> </cconfiguration> + <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" moduleId="org.eclipse.cdt.core.settings" name="Duet2_RTOS"> + <macros> + <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm"/> + <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/> + <stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/> + <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/> + </macros> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactExtension="elf" artifactName="Duet2CombinedFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" name="Duet2_RTOS" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/Duet2CombinedFirmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/Duet2CombinedFirmware.bin"> + <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.435431950" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release"> + <option id="cdt.managedbuild.option.gnu.cross.path.1881231799" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/> + <option id="cdt.managedbuild.option.gnu.cross.prefix.172065168" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/> + <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1838379384" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/> + <builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.591414239" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/> + <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1539163958" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1036697395" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + <tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cross.c.compiler.463703707" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler"> + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.456685708" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.c.optimization.level.more" valueType="enumerated"/> + <option id="gnu.c.compiler.option.debugging.level.1579494397" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/> + <option id="gnu.c.compiler.option.misc.verbose.328543251" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/> + <option id="gnu.c.compiler.option.misc.other.465279131" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -std=gnu99 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -nostdlib -Wdouble-promotion -fsingle-precision-constant "-Wa,-ahl=$*.s"" valueType="string"/> + <option id="gnu.c.compiler.option.include.paths.288982451" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/cores/arduino}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/libraries/Storage}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/common/utils}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/common/services/ioport}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/drivers}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4e/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/header_files}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/duetNG}""/> + </option> + <option id="gnu.c.compiler.option.preprocessor.def.symbols.1227675538" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> + <listOptionValue builtIn="false" value="__SAM4E8E__"/> + <listOptionValue builtIn="false" value="RTOS"/> + <listOptionValue builtIn="false" value="DUET_NG"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1065384487" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1102044150" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/> + <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1402882499" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/> + <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} "${workspace_loc}/${CoreName}/SAM4E8E/cores/arduino/syscalls.o" ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1768134875" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"> + <option id="gnu.cpp.link.option.nostdlibs.399544265" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/> + <option id="gnu.cpp.link.option.paths.605414111" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths"> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/SAM4E8E_RTOS/}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/SAM4E}""/> + </option> + <option id="gnu.cpp.link.option.libs.847860449" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs"> + <listOptionValue builtIn="false" value="${CoreName}"/> + <listOptionValue builtIn="false" value="FreeRtos"/> + </option> + <option id="gnu.cpp.link.option.flags.161856294" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -T${workspace_loc:/${CoreName}/variants/duetNG/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1270956612" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool command="g++" id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1697970502" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler"> + <option id="gnu.cpp.compiler.option.optimization.level.1835678360" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.debugging.level.737051102" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.other.verbose.1225557122" name="Verbose (-v)" superClass="gnu.cpp.compiler.option.other.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/> + <option id="gnu.cpp.compiler.option.other.other.1423466590" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -std=gnu++14 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -fno-threadsafe-statics -fno-rtti -fno-exceptions -nostdlib -Wdouble-promotion -fsingle-precision-constant "-Wa,-ahl=$*.s"" valueType="string"/> + <option id="gnu.cpp.compiler.option.include.paths.1505018967" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/cores/arduino}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/libraries/Flash}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/libraries/SharedSpi}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/libraries/Storage}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/libraries/Wire}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/common/utils}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/common/services/clock}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/common/services/ioport}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/drivers}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/services/flash_efc}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4e/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/header_files}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/duetNG}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/DuetNG}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/DuetWiFiSocketServer/src/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/portable/GCC/ARM_CM4F}""/> + </option> + <option id="gnu.cpp.compiler.option.preprocessor.def.1443248224" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> + <listOptionValue builtIn="false" value="__SAM4E8E__"/> + <listOptionValue builtIn="false" value="RTOS"/> + <listOptionValue builtIn="false" value="DUET_NG"/> + <listOptionValue builtIn="false" value="DUET_WIFI"/> + <listOptionValue builtIn="false" value="_XOPEN_SOURCE"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.65828751" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry excluding="src/Networking/LwipEthernet|src/Alligator|src/SAME70_TEST|src/Display|src/Duet|src/DuetM|src/RADDS" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> <project id="RepRapFirmware.cdt.managedbuild.target.gnu.cross.exe.1494358155" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/> diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index a8f44d89..c7d9cc75 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -66,4 +66,15 @@ </provider> </extension> </configuration> + <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" name="Duet2_RTOS"> + <extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> + <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> + <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> + <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> + <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1189573167678144698" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> + <language-scope id="org.eclipse.cdt.core.gcc"/> + <language-scope id="org.eclipse.cdt.core.g++"/> + </provider> + </extension> + </configuration> </project> diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h index 249a3c1e..22454a40 100644 --- a/src/DuetNG/Pins_DuetNG.h +++ b/src/DuetNG/Pins_DuetNG.h @@ -129,6 +129,7 @@ constexpr Pin VssaSensePin = 103; // Digital pin number to turn the IR LED on (high) or off (low), also controls the DIAG LED constexpr Pin Z_PROBE_MOD_PIN = 34; +constexpr Pin DiagPin = Z_PROBE_MOD_PIN; // Cooling fans constexpr size_t NUM_FANS = 9; diff --git a/src/Platform.cpp b/src/Platform.cpp index 43dcb2c2..ce6b9cd2 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -32,6 +32,7 @@ #include "Version.h" #include "SoftTimer.h" #include "Logger.h" +#include "Tasks.h" #include "Libraries/Math/Isqrt.h" #include "Wire.h" @@ -107,8 +108,6 @@ constexpr uint16_t driverNormalVoltageAdcReading = PowerVoltageToAdcReading(27.5 #endif -const uint8_t memPattern = 0xA5; - static uint32_t fanInterruptCount = 0; // accessed only in ISR, so no need to declare it volatile const uint32_t fanMaxInterruptCount = 32; // number of fan interrupts that we average over static volatile uint32_t fanLastResetTime = 0; // time (microseconds) at which we last reset the interrupt count, accessed inside and outside ISR @@ -148,7 +147,7 @@ uint32_t lastSoftTimerInterruptScheduledAt = 0; // Urgent initialisation function // This is called before general init has been done, and before constructors for C++ static data have been called. // Therefore, be very careful what you do here! -void UrgentInit() +extern "C" void UrgentInit() { #if defined(DUET_NG) // When the reset button is pressed on pre-production Duet WiFi boards, if the TMC2660 drivers were previously enabled then we get @@ -172,132 +171,6 @@ void UrgentInit() #endif } -// Arduino initialise and loop functions -// Put nothing in these other than calls to the RepRap equivalents -void setup() -{ - // Fill the free memory with a pattern so that we can check for stack usage and memory corruption - char* heapend = sbrk(0); - register const char * stack_ptr asm ("sp"); - while (heapend + 16 < stack_ptr) - { - *heapend++ = memPattern; - } - - // Trap integer divide-by-zero. - // We could also trap unaligned memory access, if we change the gcc options to not generate code that uses unaligned memory access. - SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; - - // When doing a software reset, we disable the NRST input (User reset) to prevent the negative-going pulse that gets generated on it - // being held in the capacitor and changing the reset reason from Software to User. So enable it again here. We hope that the reset signal - // will have gone away by now. -#ifndef RSTC_MR_KEY_PASSWD -// Definition of RSTC_MR_KEY_PASSWD is missing in the SAM3X ASF files -# define RSTC_MR_KEY_PASSWD (0xA5u << 24) -#endif - RSTC->RSTC_MR = RSTC_MR_KEY_PASSWD | RSTC_MR_URSTEN; // ignore any signal on the NRST pin for now so that the reset reason will show as Software - -#if USE_CACHE - // Enable the cache - struct cmcc_config g_cmcc_cfg; - cmcc_get_config_defaults(&g_cmcc_cfg); - cmcc_init(CMCC, &g_cmcc_cfg); - EnableCache(); -#endif - - // Go on and do the main initialisation - reprap.Init(); -} - -void loop() -{ - reprap.Spin(); -} - -extern "C" -{ - // This intercepts the 1ms system tick. It must return 'false', otherwise the Arduino core tick handler will be bypassed. - int sysTickHook() - { - reprap.Tick(); - return 0; - } - - // Exception handlers - // By default the Usage Fault, Bus Fault and Memory Management fault handlers are not enabled, - // so they escalate to a Hard Fault and we don't need to provide separate exception handlers for them. - void hardFaultDispatcher(const uint32_t *pulFaultStackAddress) - { - reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::hardFault, pulFaultStackAddress + 5); - } - - // The fault handler implementation calls a function called hardFaultDispatcher() - void HardFault_Handler() __attribute__((naked)); - void HardFault_Handler() - { - __asm volatile - ( - " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ - " ite eq \n" /* load the appropriate stack pointer into R0 */ - " mrseq r0, msp \n" - " mrsne r0, psp \n" - " ldr r2, handler_hf_address_const \n" - " bx r2 \n" - " handler_hf_address_const: .word hardFaultDispatcher \n" - ); - } - - void wdtFaultDispatcher(const uint32_t *pulFaultStackAddress) - { - reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::wdtFault, pulFaultStackAddress + 5); - } - - void WDT_Handler() __attribute__((naked)); - void WDT_Handler() - { - __asm volatile - ( - " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ - " ite eq \n" /* load the appropriate stack pointer into R0 */ - " mrseq r0, msp \n" - " mrsne r0, psp \n" - " ldr r2, handler_wdt_address_const \n" - " bx r2 \n" - " handler_wdt_address_const: .word wdtFaultDispatcher \n" - ); - } - - void otherFaultDispatcher(const uint32_t *pulFaultStackAddress) - { - reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::otherFault, pulFaultStackAddress + 5); - } - - // The fault handler implementation calls a function called otherFaultDispatcher() - void OtherFault_Handler() __attribute__((naked)); - void OtherFault_Handler() - { - __asm volatile - ( - " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ - " ite eq \n" /* load the appropriate stack pointer into R0 */ - " mrseq r0, msp \n" - " mrsne r0, psp \n" - " ldr r2, handler_oflt_address_const \n" - " bx r2 \n" - " handler_oflt_address_const: .word otherFaultDispatcher \n" - ); - } - - // We could set up the following fault handlers to retrieve the program counter in the same way as for a Hard Fault, - // however these exceptions are unlikely to occur, so for now we just report the exception type. - void NMI_Handler () { reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::NMI); } - - // 2017-05-25: A user is getting 'otherFault' reports, so now we do a stack dump for those too. - void SVC_Handler () __attribute__ ((alias("OtherFault_Handler"))); - void DebugMon_Handler () __attribute__ ((alias("OtherFault_Handler"))); - void PendSV_Handler () __attribute__ ((alias("OtherFault_Handler"))); -} - //************************************************************************************************* // Platform class @@ -327,6 +200,8 @@ Platform::Platform() : // Initialise the Platform. Note: this is the first module to be initialised, so don't call other modules from here! void Platform::Init() { + pinMode(DiagPin, OUTPUT_LOW); // set up diag LED for debugging and turn it off + // Deal with power first pinMode(ATX_POWER_PIN, OUTPUT_LOW); deferredPowerDown = false; @@ -369,6 +244,7 @@ void Platform::Init() #if SAM4E || SAM4S || SAME70 // Read the unique ID of the MCU memset(uniqueId, 0, sizeof(uniqueId)); + DisableCache(); cpu_irq_disable(); const uint32_t rc = flash_read_unique_id(uniqueId, 4); @@ -1878,7 +1754,12 @@ void Platform::SoftwareReset(uint16_t reason, const uint32_t *stk) srdBuf[slot].magic = SoftwareResetData::magicValue; srdBuf[slot].resetReason = reason; srdBuf[slot].when = (uint32_t)realTime; // some compilers/libraries use 64-bit time_t - GetStackUsage(nullptr, nullptr, &srdBuf[slot].neverUsedRam); +#ifdef RTOS + // Should we store the stack data for any other task(s) here? + Tasks::GetHandlerStackUsage(nullptr, &srdBuf[slot].neverUsedRam); +#else + Tasks::GetStackUsage(nullptr, nullptr, &srdBuf[slot].neverUsedRam); +#endif srdBuf[slot].hfsr = SCB->HFSR; srdBuf[slot].cfsr = SCB->CFSR; srdBuf[slot].icsr = SCB->ICSR; @@ -1936,8 +1817,10 @@ void Platform::InitialiseInterrupts() NVIC_SetPriority(WDT_IRQn, NvicPriorityWatchdog); // set priority for watchdog interrupts #endif +#ifndef RTOS // Set the tick interrupt to the highest priority. We need to to monitor the heaters and kick the watchdog. NVIC_SetPriority(SysTick_IRQn, NvicPrioritySystick); // set priority for tick interrupts +#endif #if SAM4E || SAME70 NVIC_SetPriority(UART0_IRQn, NvicPriorityPanelDueUart); // set priority for UART interrupt @@ -2138,7 +2021,8 @@ void Platform::Diagnostics(MessageType mtype) #endif // Print memory stats and error codes to USB and copy them to the current webserver reply - const char *ramstart = + { + const char * const ramstart = #if SAME70 (char *) 0x20400000; #elif SAM4E || SAM4S @@ -2148,14 +2032,23 @@ void Platform::Diagnostics(MessageType mtype) #else # error Unsupported processor #endif - const struct mallinfo mi = mallinfo(); - MessageF(mtype, "Static ram used: %d\n", &_end - ramstart); - MessageF(mtype, "Dynamic ram used: %d\n", mi.uordblks); - MessageF(mtype, "Recycled dynamic ram: %d\n", mi.fordblks); - uint32_t currentStack, maxStack, neverUsed; - GetStackUsage(¤tStack, &maxStack, &neverUsed); - MessageF(mtype, "Stack ram used: %" PRIu32 " current, %" PRIu32 " maximum\n", currentStack, maxStack); - MessageF(mtype, "Never used ram: %" PRIu32 "\n", neverUsed); + MessageF(mtype, "Static ram used: %d\n", &_end - ramstart); + + const struct mallinfo mi = mallinfo(); + MessageF(mtype, "Dynamic ram used: %d\n", mi.uordblks); + MessageF(mtype, "Recycled dynamic ram: %d\n", mi.fordblks); + + uint32_t maxStack, neverUsed; +#ifdef RTOS + Tasks::GetHandlerStackUsage(&maxStack, &neverUsed); + MessageF(mtype, "Handler stack ram used: %" PRIu32 "\n", maxStack); +#else + uint32_t currentStack; + Tasks::GetStackUsage(¤tStack, &maxStack, &neverUsed); + MessageF(mtype, "Stack ram used: %" PRIu32 " current, %" PRIu32 " maximum\n", currentStack, maxStack); +#endif + MessageF(mtype, "Never used ram: %" PRIu32 "\n", neverUsed); + } // Show the up time and reason for the last reset const uint32_t now = (uint32_t)(millis64()/1000u); // get up time in seconds @@ -2334,6 +2227,10 @@ void Platform::Diagnostics(MessageType mtype) MessageF(mtype, "Soft timer interrupts executed %u, next %u scheduled at %u, now %u\n", numSoftTimerInterruptsExecuted, STEP_TC->TC_CHANNEL[STEP_TC_CHAN].TC_RB, lastSoftTimerInterruptScheduledAt, GetInterruptClocks()); #endif + +#ifdef RTOS + Tasks::CurrentTaskDiagnostics(mtype); +#endif } bool Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, int d) @@ -2565,24 +2462,6 @@ bool Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, int d) return false; } -extern "C" uint32_t _estack; // this is defined in the linker script - -// Return the stack usage and amount of memory that has never been used, in bytes -void Platform::GetStackUsage(uint32_t* currentStack, uint32_t* maxStack, uint32_t* neverUsed) const -{ - const char * const ramend = (const char *)&_estack; - register const char * stack_ptr asm ("sp"); - const char * const heapend = sbrk(0); - const char * stack_lwm = heapend; - while (stack_lwm < stack_ptr && *stack_lwm == memPattern) - { - ++stack_lwm; - } - if (currentStack != nullptr) { *currentStack = ramend - stack_ptr; } - if (maxStack != nullptr) { *maxStack = ramend - stack_lwm; } - if (neverUsed != nullptr) { *neverUsed = stack_lwm - heapend; } -} - void Platform::ClassReport(uint32_t &lastTime) { const Module spinningModule = reprap.GetSpinningModule(); diff --git a/src/Platform.h b/src/Platform.h index 253b66ec..f1a16a35 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -181,7 +181,12 @@ enum class SoftwareResetReason : uint16_t hardFault = 0x30, // most exceptions get escalated to a hard fault stuckInSpin = 0x40, // we got stuck in a Spin() function for too long wdtFault = 0x50, // secondary watchdog + usageFault = 0x60, otherFault = 0x70, + stackOverflow = 0x80, + assertCalled = 0xA0, + + // Bits that are or'ed in inAuxOutput = 0x0800, // this bit is or'ed in if we were in aux output at the time inLwipSpin = 0x2000, // we got stuck in a call to LWIP for too long inUsbOutput = 0x4000, // this bit is or'ed in if we were in USB output at the time @@ -713,7 +718,6 @@ private: uint32_t errorCodeBits; void InitialiseInterrupts(); - void GetStackUsage(uint32_t* currentStack, uint32_t* maxStack, uint32_t* neverUsed) const; // DRIVES void SetDriverCurrent(size_t driver, float current, int code); diff --git a/src/RepRap.cpp b/src/RepRap.cpp index e9f76235..a51761d6 100644 --- a/src/RepRap.cpp +++ b/src/RepRap.cpp @@ -119,7 +119,7 @@ void RepRap::Init() #if SUPPORT_12864_LCD display->Init(); #endif - active = true; // must do this before we start the network, else the watchdog may time out + active = true; // must do this before we start the network or call Spin(), else the watchdog may time out platform->MessageF(UsbMessage, "%s Version %s dated %s\n", FIRMWARE_NAME, VERSION, DATE); diff --git a/src/Tasks.cpp b/src/Tasks.cpp new file mode 100644 index 00000000..9e9b69fb --- /dev/null +++ b/src/Tasks.cpp @@ -0,0 +1,301 @@ +/* + * Startup.cpp + * + * Created on: 26 Mar 2018 + * Author: David + */ + +#include "Tasks.h" +#include "RepRap.h" +#include "Platform.h" + +#ifdef RTOS +# include "FreeRTOS.h" +# include "task.h" +#endif + +const uint8_t memPattern = 0xA5; + +extern "C" char *sbrk(int i); + +#ifdef RTOS +const uint32_t MainTaskStackSize = 2048; // task stack size in dwords +const uint32_t MainTaskPriority = 1; + +static StackType_t mainTaskStack[MainTaskStackSize]; +static StaticTask_t mainTaskBuffer; +static TaskHandle_t mainTaskHandle; + +extern "C" void MainTask(void * pvParameters); +#endif + +// Application entry point +extern "C" void AppMain() +{ + // Fill the free memory with a pattern so that we can check for stack usage and memory corruption + char* heapend = sbrk(0); + register const char * stack_ptr asm ("sp"); + while (heapend + 16 < stack_ptr) + { + *heapend++ = memPattern; + } + + // Trap integer divide-by-zero. + // We could also trap unaligned memory access, if we change the gcc options to not generate code that uses unaligned memory access. + SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; + + // When doing a software reset, we disable the NRST input (User reset) to prevent the negative-going pulse that gets generated on it + // being held in the capacitor and changing the reset reason from Software to User. So enable it again here. We hope that the reset signal + // will have gone away by now. +#ifndef RSTC_MR_KEY_PASSWD +// Definition of RSTC_MR_KEY_PASSWD is missing in the SAM3X ASF files +# define RSTC_MR_KEY_PASSWD (0xA5u << 24) +#endif + RSTC->RSTC_MR = RSTC_MR_KEY_PASSWD | RSTC_MR_URSTEN; // ignore any signal on the NRST pin for now so that the reset reason will show as Software + +#if USE_CACHE + // Enable the cache + struct cmcc_config g_cmcc_cfg; + cmcc_get_config_defaults(&g_cmcc_cfg); + cmcc_init(CMCC, &g_cmcc_cfg); + EnableCache(); +#endif + +#ifdef RTOS + // Create the startup task + mainTaskHandle = xTaskCreateStatic(MainTask, "MAIN", ARRAY_SIZE(mainTaskStack), nullptr, MainTaskPriority, mainTaskStack, &mainTaskBuffer); + vTaskStartScheduler(); // doesn't return +} + +extern "C" void MainTask(void *pvParameters) +{ +#endif + reprap.Init(); + for (;;) + { + reprap.Spin(); + } +} + +extern "C" uint32_t _estack; // this is defined in the linker script + +namespace Tasks +{ + +#ifdef RTOS + + void GetHandlerStackUsage(uint32_t* maxStack, uint32_t* neverUsed) + { + const char * const ramend = (const char *)&_estack; + const char * const heapend = sbrk(0); + const char * stack_lwm = heapend; + while (stack_lwm < ramend && *stack_lwm == memPattern) + { + ++stack_lwm; + } + if (maxStack != nullptr) { *maxStack = ramend - stack_lwm; } + if (neverUsed != nullptr) { *neverUsed = stack_lwm - heapend; } + } + + static void TaskDiagnostics(MessageType mtype, TaskHandle_t ct) + { + TaskStatus_t taskDetails; + vTaskGetInfo(ct, &taskDetails, pdTRUE, eInvalid); + reprap.GetPlatform().MessageF(mtype, "Task %s: state %d stack rem %u\n", taskDetails.pcTaskName, (int)taskDetails.eCurrentState, (unsigned int)taskDetails.usStackHighWaterMark); + } + + // Write data about the current task + void CurrentTaskDiagnostics(MessageType mtype) + { + const TaskHandle_t ct = xTaskGetCurrentTaskHandle(); + TaskDiagnostics(mtype, ct); + } + +#else + + // Return the system stack usage and amount of memory that has never been used, in bytes + void GetStackUsage(uint32_t* currentStack, uint32_t* maxStack, uint32_t* neverUsed) + { + const char * const ramend = (const char *)&_estack; + const char * const heapend = sbrk(0); + const char * stack_lwm = heapend; + register const char * stack_ptr asm ("sp"); + while (stack_lwm < stack_ptr && *stack_lwm == memPattern) + { + ++stack_lwm; + } + if (currentStack != nullptr) { *currentStack = ramend - stack_ptr; } + if (maxStack != nullptr) { *maxStack = ramend - stack_lwm; } + if (neverUsed != nullptr) { *neverUsed = stack_lwm - heapend; } + } + +#endif +} + +#ifdef RTOS + +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + +extern "C" void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize ) +{ + /* 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. */ + *pulIdleTaskStackSize = ARRAY_SIZE(uxIdleTaskStack); +} + +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + +extern "C" void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize ) +{ + /* 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. */ + *pulTimerTaskStackSize = ARRAY_SIZE(uxTimerTaskStack); +} + +#endif + +// Exception handlers +extern "C" +{ + // This intercepts the 1ms system tick. It must return 'false', otherwise the Arduino core tick handler will be bypassed. + int sysTickHook() + { + reprap.Tick(); + return 0; + } + + // Exception handlers + // By default the Usage Fault, Bus Fault and Memory Management fault handlers are not enabled, + // so they escalate to a Hard Fault and we don't need to provide separate exception handlers for them. + void hardFaultDispatcher(const uint32_t *pulFaultStackAddress) + { + reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::hardFault, pulFaultStackAddress + 5); + } + + // The fault handler implementation calls a function called hardFaultDispatcher() + void HardFault_Handler() __attribute__((naked)); + void HardFault_Handler() + { + __asm volatile + ( + " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ + " ite eq \n" /* load the appropriate stack pointer into R0 */ + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, handler_hf_address_const \n" + " bx r2 \n" + " handler_hf_address_const: .word hardFaultDispatcher \n" + ); + } + + void wdtFaultDispatcher(const uint32_t *pulFaultStackAddress) + { + reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::wdtFault, pulFaultStackAddress + 5); + } + + void WDT_Handler() __attribute__((naked)); + void WDT_Handler() + { + __asm volatile + ( + " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ + " ite eq \n" /* load the appropriate stack pointer into R0 */ + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, handler_wdt_address_const \n" + " bx r2 \n" + " handler_wdt_address_const: .word wdtFaultDispatcher \n" + ); + } + + void otherFaultDispatcher(const uint32_t *pulFaultStackAddress) + { + reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::otherFault, pulFaultStackAddress + 5); + } + + // 2017-05-25: A user is getting 'otherFault' reports, so now we do a stack dump for those too. + // The fault handler implementation calls a function called otherFaultDispatcher() + void OtherFault_Handler() __attribute__((naked)); + void OtherFault_Handler() + { + __asm volatile + ( + " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ + " ite eq \n" /* load the appropriate stack pointer into R0 */ + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, handler_oflt_address_const \n" + " bx r2 \n" + " handler_oflt_address_const: .word otherFaultDispatcher \n" + ); + } + + // We could set up the following fault handlers to retrieve the program counter in the same way as for a Hard Fault, + // however these exceptions are unlikely to occur, so for now we just report the exception type. + void NMI_Handler () { reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::NMI); } + void UsageFault_Handler () { reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::usageFault); } + + void DebugMon_Handler () __attribute__ ((alias("OtherFault_Handler"))); + +#ifdef RTOS + // FreeRTOS hooks that we need to provide + void stackOverflowDispatcher(const uint32_t *pulFaultStackAddress) + { + reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::stackOverflow, pulFaultStackAddress + 5); + } + + void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) __attribute((naked)); + void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) + { + __asm volatile + ( + " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ + " ite eq \n" /* load the appropriate stack pointer into R0 */ + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, handler_sovf_address_const \n" + " bx r2 \n" + " handler_sovf_address_const: .word stackOverflowDispatcher \n" + ); + } + + void assertCalledDispatcher(const uint32_t *pulFaultStackAddress) + { + reprap.GetPlatform().SoftwareReset((uint16_t)SoftwareResetReason::assertCalled, pulFaultStackAddress + 5); + } + + void vAssertCalled(uint32_t line, const char *file) __attribute((naked)); + void vAssertCalled(uint32_t line, const char *file) + { + __asm volatile + ( + " tst lr, #4 \n" /* test bit 2 of the EXC_RETURN in LR to determine which stack was in use */ + " ite eq \n" /* load the appropriate stack pointer into R0 */ + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, handler_asrt_address_const \n" + " bx r2 \n" + " handler_asrt_address_const: .word assertCalledDispatcher \n" + ); + } +#endif + +} + +// End diff --git a/src/Tasks.h b/src/Tasks.h new file mode 100644 index 00000000..7822c201 --- /dev/null +++ b/src/Tasks.h @@ -0,0 +1,27 @@ +/* + * Startup.h + * + * Created on: 26 Mar 2018 + * Author: David + */ + +#ifndef SRC_TASKS_H_ +#define SRC_TASKS_H_ + +#include "RepRapFirmware.h" +#include "MessageType.h" + +void setup(); +void loop(); + +namespace Tasks +{ +#ifdef RTOS + void GetHandlerStackUsage(uint32_t* maxStack, uint32_t* neverUsed); + void CurrentTaskDiagnostics(MessageType mtype); +#else + void GetStackUsage(uint32_t* currentStack, uint32_t* maxStack, uint32_t* neverUsed); +#endif +} + +#endif /* SRC_TASKS_H_ */ diff --git a/src/Version.h b/src/Version.h index 09aa937a..55e79c07 100644 --- a/src/Version.h +++ b/src/Version.h @@ -8,12 +8,18 @@ #ifndef SRC_VERSION_H_ #define SRC_VERSION_H_ +#ifdef RTOS +# define RTOSVER "(RTOS)" +#else +# define RTOSVER +#endif + #ifndef VERSION -# define VERSION "1.21" +# define VERSION "2.0" RTOSVER "alpha1" #endif #ifndef DATE -# define DATE "2018-03-21" +# define DATE "2018-03-28" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman" |