Browse Source

优化前上传一次

codex/plsr-2026-minimal
ywh 3 weeks ago
parent
commit
a6c667d485
7 changed files with 530 additions and 9 deletions
  1. +1
    -1
      Core/Src/main.c
  2. +274
    -3
      EWARM/Modbus.ewp
  3. +4
    -0
      PLSR/Inc/plsr.h
  4. +5
    -2
      PLSR/Src/plsr.c
  5. +176
    -2
      PLSR/Src/plsr_planner.c
  6. +32
    -0
      PLSR/Src/plsr_planner.h
  7. +38
    -1
      PLSR/Src/plsr_platform_f407.c

+ 1
- 1
Core/Src/main.c View File

@@ -81,7 +81,7 @@ static void AppTaskStart(void *pArg)
{ {
PlsrServicePersistence(); PlsrServicePersistence();
} }
OSTimeDly(1U);
// OSTimeDly(1U);
} }
} }




+ 274
- 3
EWARM/Modbus.ewp View File

@@ -226,7 +226,7 @@
<name>CCDefines</name> <name>CCDefines</name>
<state>USE_HAL_DRIVER</state> <state>USE_HAL_DRIVER</state>
<state>STM32F407xx</state> <state>STM32F407xx</state>
<state>PLSR_DEBUG_TIMING=1</state>
<state>PLSR_DEBUG_TIMING=0</state>
</option> </option>
<option> <option>
<name>CCPreprocFile</name> <name>CCPreprocFile</name>
@@ -1291,7 +1291,7 @@
<name>CCDefines</name> <name>CCDefines</name>
<state>USE_HAL_DRIVER</state> <state>USE_HAL_DRIVER</state>
<state>STM32F407xx</state> <state>STM32F407xx</state>
<state>PLSR_DEBUG_TIMING=1</state>
<state>PLSR_DEBUG_TIMING=0</state>
</option> </option>
<option> <option>
<name>CCPreprocFile</name> <name>CCPreprocFile</name>
@@ -1580,7 +1580,7 @@
<name>CCDefines</name> <name>CCDefines</name>
<state>USE_HAL_DRIVER</state> <state>USE_HAL_DRIVER</state>
<state>STM32F407xx</state> <state>STM32F407xx</state>
<state>PLSR_DEBUG_TIMING=1</state>
<state>PLSR_DEBUG_TIMING=0</state>
</option> </option>
<option> <option>
<name>CCPreprocFile</name> <name>CCPreprocFile</name>
@@ -1836,5 +1836,276 @@
</settings> </settings>
</configuration> </configuration>
</file> </file>
<configuration>
<name>Modbus</name>
<settings>
<name>ICCARM</name>
<data>
<version>35</version>
<wantNonLocal>0</wantNonLocal>
<debug>1</debug>
<option>
<name>CCOptimizationNoSizeConstraints</name>
<state>0</state>
</option>
<option>
<name>CCDefines</name>
<state>USE_HAL_DRIVER</state>
<state>STM32F407xx</state>
<state>PLSR_DEBUG_TIMING=0</state>
</option>
<option>
<name>CCPreprocFile</name>
<state>0</state>
</option>
<option>
<name>CCPreprocComments</name>
<state>0</state>
</option>
<option>
<name>CCPreprocLine</name>
<state>0</state>
</option>
<option>
<name>CCListCFile</name>
<state>0</state>
</option>
<option>
<name>CCListCMnemonics</name>
<state>0</state>
</option>
<option>
<name>CCListCMessages</name>
<state>0</state>
</option>
<option>
<name>CCListAssFile</name>
<state>0</state>
</option>
<option>
<name>CCListAssSource</name>
<state>0</state>
</option>
<option>
<name>CCEnableRemarks</name>
<state>0</state>
</option>
<option>
<name>CCDiagSuppress</name>
<state></state>
</option>
<option>
<name>CCDiagRemark</name>
<state></state>
</option>
<option>
<name>CCDiagWarning</name>
<state></state>
</option>
<option>
<name>CCDiagError</name>
<state></state>
</option>
<option>
<name>CCObjPrefix</name>
<state>1</state>
</option>
<option>
<name>CCAllowList</name>
<version>1</version>
<state>11111110</state>
</option>
<option>
<name>CCDebugInfo</name>
<state>1</state>
</option>
<option>
<name>IEndianMode</name>
<state>1</state>
</option>
<option>
<name>IProcessor</name>
<state>1</state>
</option>
<option>
<name>IExtraOptionsCheck</name>
<state>0</state>
</option>
<option>
<name>IExtraOptions</name>
<state></state>
</option>
<option>
<name>CCLangConformance</name>
<state>0</state>
</option>
<option>
<name>CCSignedPlainChar</name>
<state>1</state>
</option>
<option>
<name>CCRequirePrototypes</name>
<state>0</state>
</option>
<option>
<name>CCDiagWarnAreErr</name>
<state>0</state>
</option>
<option>
<name>CCCompilerRuntimeInfo</name>
<state>0</state>
</option>
<option>
<name>IFpuProcessor</name>
<state>1</state>
</option>
<option>
<name>OutputFile</name>
<state>$FILE_BNAME$.o</state>
</option>
<option>
<name>CCLibConfigHeader</name>
<state>1</state>
</option>
<option>
<name>PreInclude</name>
<state></state>
</option>
<option>
<name>CompilerMisraOverride</name>
<state>0</state>
</option>
<option>
<name>CCIncludePath2</name>
<state>$PROJ_DIR$/../USB_DEVICE/App</state>
<state>$PROJ_DIR$/../USB_DEVICE/Target</state>
<state>$PROJ_DIR$/../Core/Inc</state>
<state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc</state>
<state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy</state>
<state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state>
<state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc</state>
<state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32F4xx/Include</state>
<state>$PROJ_DIR$/../Drivers/CMSIS/Include</state>
<state>$PROJ_DIR$\..\Modbus\Inc</state>
<state>$PROJ_DIR$\..\PLSR\Inc</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\Config</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Source</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Ports\ARM-Cortex-M4\IAR</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU\ARM-Cortex-M4\IAR</state>
<state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-LIB</state>
<state>$PROJ_DIR$\..\Modbus\Inc</state>
</option>
<option>
<name>CCStdIncCheck</name>
<state>0</state>
</option>
<option>
<name>CCCodeSection</name>
<state>.text</state>
</option>
<option>
<name>IProcessorMode2</name>
<state>1</state>
</option>
<option>
<name>CCOptLevel</name>
<state>3</state>
</option>
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>2</state>
</option>
<option>
<name>CCOptLevelSlave</name>
<state>3</state>
</option>
<option>
<name>CompilerMisraRules98</name>
<version>0</version>
<state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
</option>
<option>
<name>CompilerMisraRules04</name>
<version>0</version>
<state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
</option>
<option>
<name>CCPosIndRopi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndRwpi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndNoDynInit</name>
<state>0</state>
</option>
<option>
<name>IccLang</name>
<state>0</state>
</option>
<option>
<name>IccCDialect</name>
<state>1</state>
</option>
<option>
<name>IccAllowVLA</name>
<state>0</state>
</option>
<option>
<name>IccStaticDestr</name>
<state>1</state>
</option>
<option>
<name>IccCppInlineSemantics</name>
<state>0</state>
</option>
<option>
<name>IccCmsis</name>
<state>1</state>
</option>
<option>
<name>IccFloatSemantics</name>
<state>0</state>
</option>
<option>
<name>CCNoLiteralPool</name>
<state>0</state>
</option>
<option>
<name>CCOptStrategySlave</name>
<version>0</version>
<state>2</state>
</option>
<option>
<name>CCEncSource</name>
<state>0</state>
</option>
<option>
<name>CCEncOutput</name>
<state>0</state>
</option>
<option>
<name>CCEncOutputBom</name>
<state>1</state>
</option>
<option>
<name>CCEncInput</name>
<state>0</state>
</option>
<option>
<name>IccExceptions2</name>
<state>0</state>
</option>
<option>
<name>IccRTTI2</name>
<state>0</state>
</option>
</data>
</settings>
</configuration>
</group> </group>
</project> </project>

+ 4
- 0
PLSR/Inc/plsr.h View File

@@ -128,8 +128,12 @@ extern volatile uint32_t PlsrProfileProducerItemCount;
extern volatile uint32_t PlsrProfileProducerTotalCycles; extern volatile uint32_t PlsrProfileProducerTotalCycles;
extern volatile uint32_t PlsrProfileProducerMaxItemCycles; extern volatile uint32_t PlsrProfileProducerMaxItemCycles;
extern volatile uint32_t PlsrFiniteBlockIrqCount[4]; extern volatile uint32_t PlsrFiniteBlockIrqCount[4];
extern volatile uint32_t PlsrFiniteBlockIrqLastCycles[4];
extern volatile uint32_t PlsrFiniteBlockIrqTotalCycles[4];
extern volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4]; extern volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4];
extern volatile uint32_t PlsrFiniteFinalIrqCount[4];
extern volatile uint32_t PlsrFiniteFinalIrqLastCycles[4]; extern volatile uint32_t PlsrFiniteFinalIrqLastCycles[4];
extern volatile uint32_t PlsrFiniteFinalIrqTotalCycles[4];
extern volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4]; extern volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4];
#endif #endif




+ 5
- 2
PLSR/Src/plsr.c View File

@@ -59,8 +59,8 @@
/* A profile item can represent only one pulse. At the 100 kHz limit these /* A profile item can represent only one pulse. At the 100 kHz limit these
thresholds provide 4 ms of startup data, refill toward 8 ms, and cap each thresholds provide 4 ms of startup data, refill toward 8 ms, and cap each
1 ms producer pass at 2 ms worth of newly planned items. */ 1 ms producer pass at 2 ms worth of newly planned items. */
#define PLSR_PROFILE_STARTUP_TARGET (400U)
#define PLSR_PROFILE_STARTUP_BUDGET (400U)
#define PLSR_PROFILE_STARTUP_TARGET (800U)
#define PLSR_PROFILE_STARTUP_BUDGET (800U)
#define PLSR_PROFILE_REFILL_TARGET (800U) #define PLSR_PROFILE_REFILL_TARGET (800U)
#define PLSR_PROFILE_REFILL_BUDGET (200U) #define PLSR_PROFILE_REFILL_BUDGET (200U)
#define PLSR_TIMED_START_BUILD_BUDGET (32U) #define PLSR_TIMED_START_BUILD_BUDGET (32U)
@@ -5725,6 +5725,9 @@ uint8_t PlsrInit(void)
PlsrProfileProducerItemCount = 0UL; PlsrProfileProducerItemCount = 0UL;
PlsrProfileProducerTotalCycles = 0UL; PlsrProfileProducerTotalCycles = 0UL;
PlsrProfileProducerMaxItemCycles = 0UL; PlsrProfileProducerMaxItemCycles = 0UL;
#if !defined(PLSR_HOST_TEST)
PlsrPlannerTimingReset();
#endif
#endif #endif
PlsrError = PLSR_ERROR_NONE; PlsrError = PLSR_ERROR_NONE;
PlsrRunStatus = PLSR_STATUS_IDLE; PlsrRunStatus = PLSR_STATUS_IDLE;


+ 176
- 2
PLSR/Src/plsr_planner.c View File

@@ -5,6 +5,47 @@


#define PLSR_PLANNER_Q32_ONE (4294967296ULL) #define PLSR_PLANNER_Q32_ONE (4294967296ULL)


#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
#define PLSR_PLANNER_CYCCNT_ADDRESS (0xE0001004UL)

volatile PLSR_PLANNER_TIMING PlsrPlannerTiming;

static uint32_t PlsrPlannerTimingNow(void)
{
return *((volatile uint32_t *)PLSR_PLANNER_CYCCNT_ADDRESS);
}

static void PlsrPlannerTimingRecord(
volatile PLSR_PLANNER_TIMING_SAMPLE *sample,
uint32_t startedAt)
{
uint32_t elapsed = PlsrPlannerTimingNow() - startedAt;
uint32_t total = sample->totalCycles;

sample->lastCycles = elapsed;
if ((sample->callCount == 0UL) || (elapsed < sample->minCycles))
{
sample->minCycles = elapsed;
}
if (sample->callCount != 0xFFFFFFFFUL)
{
sample->callCount++;
}
sample->totalCycles = (elapsed > (0xFFFFFFFFUL - total))
? 0xFFFFFFFFUL : total + elapsed;
if (elapsed > sample->maxCycles)
{
sample->maxCycles = elapsed;
}
}

void PlsrPlannerTimingReset(void)
{
(void)memset((void *)&PlsrPlannerTiming, 0, sizeof(PlsrPlannerTiming));
}
#endif

static const uint32_t PlsrPlannerSmoothIntegralQ24[65] = static const uint32_t PlsrPlannerSmoothIntegralQ24[65] =
{ {
0UL, 64UL, 504UL, 1688UL, 3968UL, 7688UL, 13176UL, 20752UL, 0UL, 64UL, 504UL, 1688UL, 3968UL, 7688UL, 13176UL, 20752UL,
@@ -402,38 +443,86 @@ static void PlsrPlannerStartRamp(PLSR_PLANNER_CONTEXT *context,
uint32_t toHz, uint32_t toHz,
uint32_t pulseCount) uint32_t pulseCount)
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
uint32_t totalStartedAt = PlsrPlannerTimingNow();
uint32_t phaseStartedAt;
#endif

context->rampKind = rampKind; context->rampKind = rampKind;
context->rampRelativePulse = 0UL; context->rampRelativePulse = 0UL;
context->rampPulseCount = pulseCount; context->rampPulseCount = pulseCount;
context->rampFromHz = fromHz; context->rampFromHz = fromHz;
context->rampToHz = toHz; context->rampToHz = toHz;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
context->rampDurationMs = PlsrPlannerRampTime(&context->block, fromHz, toHz); context->rampDurationMs = PlsrPlannerRampTime(&context->block, fromHz, toHz);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampTime, phaseStartedAt);
phaseStartedAt = PlsrPlannerTimingNow();
#endif
context->rampTotalAreaQ32 = PlsrPlannerRampAreaQ32( context->rampTotalAreaQ32 = PlsrPlannerRampAreaQ32(
context, fromHz, toHz, PLSR_PLANNER_Q32_ONE); context, fromHz, toHz, PLSR_PLANNER_Q32_ONE);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampTotalArea,
phaseStartedAt);
phaseStartedAt = PlsrPlannerTimingNow();
#endif
context->rampAreaStepQ32 = context->rampTotalAreaQ32 / pulseCount; context->rampAreaStepQ32 = context->rampTotalAreaQ32 / pulseCount;
context->rampAreaRemainder = context->rampAreaRemainder =
(uint32_t)(context->rampTotalAreaQ32 % pulseCount); (uint32_t)(context->rampTotalAreaQ32 % pulseCount);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampAreaSplit,
phaseStartedAt);
#endif
context->rampRemainderAccumulator = 0UL; context->rampRemainderAccumulator = 0UL;
context->rampTargetAreaQ32 = 0ULL; context->rampTargetAreaQ32 = 0ULL;
context->rampBoundaryQ32 = 0ULL; context->rampBoundaryQ32 = 0ULL;
context->rampActualTimeQ32 = 0ULL; context->rampActualTimeQ32 = 0ULL;
context->rampLastPhaseStepQ32 = 0ULL; context->rampLastPhaseStepQ32 = 0ULL;
context->lastRampHz = 0UL; context->lastRampHz = 0UL;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
context->rampFirstBoundaryQ32 = PlsrPlannerExactBoundaryQ32( context->rampFirstBoundaryQ32 = PlsrPlannerExactBoundaryQ32(
context, 0ULL, context->rampAreaStepQ32); context, 0ULL, context->rampAreaStepQ32);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampFirstBoundary,
phaseStartedAt);
#endif
if (pulseCount > 1UL) if (pulseCount > 1UL)
{ {
uint64_t secondTargetAreaQ32 = context->rampAreaStepQ32 * 2ULL
uint64_t secondTargetAreaQ32;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
secondTargetAreaQ32 = context->rampAreaStepQ32 * 2ULL
+ ((uint64_t)context->rampAreaRemainder * 2ULL) / pulseCount; + ((uint64_t)context->rampAreaRemainder * 2ULL) / pulseCount;
context->rampSecondBoundaryQ32 = PlsrPlannerExactBoundaryQ32( context->rampSecondBoundaryQ32 = PlsrPlannerExactBoundaryQ32(
context, context->rampFirstBoundaryQ32, context, context->rampFirstBoundaryQ32,
secondTargetAreaQ32); secondTargetAreaQ32);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampSecondBoundary,
phaseStartedAt);
#endif
} }
else else
{ {
context->rampSecondBoundaryQ32 = PLSR_PLANNER_Q32_ONE; context->rampSecondBoundaryQ32 = PLSR_PLANNER_Q32_ONE;
} }
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.startRamp, totalStartedAt);
#endif
} }


static uint8_t PlsrPlannerSameSetting( static uint8_t PlsrPlannerSameSetting(
@@ -452,6 +541,12 @@ static uint8_t PlsrPlannerBuildStep(PLSR_PLANNER_CONTEXT *context,
PLSR_PLATFORM_TIMER_SETTING *setting, PLSR_PLATFORM_TIMER_SETTING *setting,
uint32_t *normalizedRequestedHz) uint32_t *normalizedRequestedHz)
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
uint32_t startedAt;
uint8_t result;
#endif

if (requestedHz == 0UL) if (requestedHz == 0UL)
{ {
requestedHz = 1UL; requestedHz = 1UL;
@@ -461,9 +556,19 @@ static uint8_t PlsrPlannerBuildStep(PLSR_PLANNER_CONTEXT *context,
requestedHz = PLSR_FREQUENCY_MAX_HZ; requestedHz = PLSR_FREQUENCY_MAX_HZ;
} }
*normalizedRequestedHz = requestedHz; *normalizedRequestedHz = requestedHz;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
startedAt = PlsrPlannerTimingNow();
result = PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
PLSR_OUTPUT_PULSE_DIR,
requestedHz, setting);
PlsrPlannerTimingRecord(&PlsrPlannerTiming.timerSetting, startedAt);
return result;
#else
return PlsrPlatformBuildTimerSetting(context->block.pulseOutput, return PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
PLSR_OUTPUT_PULSE_DIR, PLSR_OUTPUT_PULSE_DIR,
requestedHz, setting); requestedHz, setting);
#endif
} }


static uint8_t PlsrPlannerTakeRampStep( static uint8_t PlsrPlannerTakeRampStep(
@@ -476,6 +581,11 @@ static uint8_t PlsrPlannerTakeRampStep(
uint64_t denominator; uint64_t denominator;
uint64_t requestedHz; uint64_t requestedHz;
uint64_t actualDeltaQ32; uint64_t actualDeltaQ32;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
uint32_t totalStartedAt = PlsrPlannerTimingNow();
uint32_t phaseStartedAt;
#endif


context->rampTargetAreaQ32 += context->rampAreaStepQ32; context->rampTargetAreaQ32 += context->rampAreaStepQ32;
context->rampRemainderAccumulator += context->rampAreaRemainder; context->rampRemainderAccumulator += context->rampAreaRemainder;
@@ -499,8 +609,17 @@ static uint8_t PlsrPlannerTakeRampStep(
} }
else else
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
nextBoundaryQ32 = PlsrPlannerPredictedBoundaryQ32( nextBoundaryQ32 = PlsrPlannerPredictedBoundaryQ32(
context, context->rampTargetAreaQ32); context, context->rampTargetAreaQ32);
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampPredictedBoundary,
phaseStartedAt);
#endif
} }


desiredDeltaQ32 = (nextBoundaryQ32 > context->rampActualTimeQ32) desiredDeltaQ32 = (nextBoundaryQ32 > context->rampActualTimeQ32)
@@ -509,11 +628,20 @@ static uint8_t PlsrPlannerTakeRampStep(
/* The allocated pulse count closes the ramp area exactly. Derive the /* The allocated pulse count closes the ramp area exactly. Derive the
physical duration from N/averageHz instead of rounding it to whole physical duration from N/averageHz instead of rounding it to whole
milliseconds; short clipped ramps can be well below 1 ms. */ milliseconds; short clipped ramps can be well below 1 ms. */
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
denominator = (uint64_t)context->rampPulseCount * desiredDeltaQ32; denominator = (uint64_t)context->rampPulseCount * desiredDeltaQ32;
requestedHz = (denominator == 0ULL) requestedHz = (denominator == 0ULL)
? context->rampToHz ? context->rampToHz
: (context->rampTotalAreaQ32 : (context->rampTotalAreaQ32
+ denominator / 2ULL) / denominator; + denominator / 2ULL) / denominator;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampRequestedDivide,
phaseStartedAt);
#endif
if (requestedHz == 0ULL) if (requestedHz == 0ULL)
{ {
requestedHz = 1ULL; requestedHz = 1ULL;
@@ -533,21 +661,39 @@ static uint8_t PlsrPlannerTakeRampStep(
if (PlsrPlannerBuildStep(context, (uint32_t)requestedHz, setting, if (PlsrPlannerBuildStep(context, (uint32_t)requestedHz, setting,
requestedFrequencyHz) == 0U) requestedFrequencyHz) == 0U)
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampStep,
totalStartedAt);
#endif
return 0U; return 0U;
} }


#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
phaseStartedAt = PlsrPlannerTimingNow();
#endif
denominator = (uint64_t)context->rampPulseCount denominator = (uint64_t)context->rampPulseCount
* setting->actualFrequencyHz; * setting->actualFrequencyHz;
actualDeltaQ32 = (denominator == 0ULL) actualDeltaQ32 = (denominator == 0ULL)
? desiredDeltaQ32 ? desiredDeltaQ32
: (context->rampTotalAreaQ32 : (context->rampTotalAreaQ32
+ denominator / 2ULL) / denominator; + denominator / 2ULL) / denominator;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampActualDivide,
phaseStartedAt);
#endif
context->rampActualTimeQ32 += actualDeltaQ32; context->rampActualTimeQ32 += actualDeltaQ32;
context->rampLastPhaseStepQ32 = context->rampLastPhaseStepQ32 =
nextBoundaryQ32 - context->rampBoundaryQ32; nextBoundaryQ32 - context->rampBoundaryQ32;
context->rampBoundaryQ32 = nextBoundaryQ32; context->rampBoundaryQ32 = nextBoundaryQ32;
context->lastRampHz = setting->actualFrequencyHz; context->lastRampHz = setting->actualFrequencyHz;
context->rampRelativePulse++; context->rampRelativePulse++;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampStep, totalStartedAt);
#endif
return 1U; return 1U;
} }


@@ -602,6 +748,10 @@ PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
uint64_t exitWeight; uint64_t exitWeight;
uint64_t totalWeight; uint64_t totalWeight;
uint64_t scaledEntry; uint64_t scaledEntry;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
uint32_t startedAt = PlsrPlannerTimingNow();
#endif


if ((context == NULL) || (block == NULL) if ((context == NULL) || (block == NULL)
|| (block->pulseBudget == 0UL) || (block->pulseBudget == 0UL)
@@ -614,6 +764,10 @@ PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
|| (appliedHz > PLSR_FREQUENCY_MAX_HZ) || (appliedHz > PLSR_FREQUENCY_MAX_HZ)
|| (block->curveMode > 2U) || (block->pulseOutput > 3U)) || (block->curveMode > 2U) || (block->pulseOutput > 3U))
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
#endif
return PLSR_PLANNER_INVALID; return PLSR_PLANNER_INVALID;
} }


@@ -640,6 +794,10 @@ PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
context->entryPulses = block->pulseBudget; context->entryPulses = block->pulseBudget;
context->clipped = 1U; context->clipped = 1U;
context->active = 1U; context->active = 1U;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
#endif
return PLSR_PLANNER_CLIPPED; return PLSR_PLANNER_CLIPPED;
} }


@@ -695,6 +853,10 @@ PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
context->clipped = 1U; context->clipped = 1U;
} }
context->active = 1U; context->active = 1U;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
#endif
return (context->clipped != 0U) ? PLSR_PLANNER_CLIPPED return (context->clipped != 0U) ? PLSR_PLANNER_CLIPPED
: PLSR_PLANNER_OK; : PLSR_PLANNER_OK;
} }
@@ -707,10 +869,18 @@ uint16_t PlsrPlannerGenerate(PLSR_PLANNER_CONTEXT *context,//规划账本:三
uint32_t requestedFrequencyHz; uint32_t requestedFrequencyHz;
uint32_t repeatCount; uint32_t repeatCount;
uint16_t produced = 0U; uint16_t produced = 0U;
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
uint32_t startedAt = PlsrPlannerTimingNow();
#endif


if ((context == NULL) || (output == NULL) || (capacity == 0U) if ((context == NULL) || (output == NULL) || (capacity == 0U)
|| (context->active == 0U)) || (context->active == 0U))
{ {
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.generate, startedAt);
#endif
return 0U; return 0U;
} }
while ((produced < capacity)&& (context->generatedPulses < context->block.pulseBudget)) while ((produced < capacity)&& (context->generatedPulses < context->block.pulseBudget))
@@ -746,6 +916,10 @@ uint16_t PlsrPlannerGenerate(PLSR_PLANNER_CONTEXT *context,//规划账本:三
{ {
context->active = 0U; context->active = 0U;
} }
#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
PlsrPlannerTimingRecord(&PlsrPlannerTiming.generate, startedAt);
#endif
return produced; return produced;
} }




+ 32
- 0
PLSR/Src/plsr_planner.h View File

@@ -95,6 +95,38 @@ typedef struct
uint8_t active; // 是否还可 Generate,吐完或失败清 0 uint8_t active; // 是否还可 Generate,吐完或失败清 0
} PLSR_PLANNER_CONTEXT; } PLSR_PLANNER_CONTEXT;


#if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
&& !defined(PLSR_HOST_TEST)
typedef struct
{
volatile uint32_t callCount;
volatile uint32_t lastCycles;
volatile uint32_t totalCycles;
volatile uint32_t minCycles;
volatile uint32_t maxCycles;
} PLSR_PLANNER_TIMING_SAMPLE;

typedef struct
{
PLSR_PLANNER_TIMING_SAMPLE begin;
PLSR_PLANNER_TIMING_SAMPLE generate;
PLSR_PLANNER_TIMING_SAMPLE startRamp;
PLSR_PLANNER_TIMING_SAMPLE rampTime;
PLSR_PLANNER_TIMING_SAMPLE rampTotalArea;
PLSR_PLANNER_TIMING_SAMPLE rampAreaSplit;
PLSR_PLANNER_TIMING_SAMPLE rampFirstBoundary;
PLSR_PLANNER_TIMING_SAMPLE rampSecondBoundary;
PLSR_PLANNER_TIMING_SAMPLE rampPredictedBoundary;
PLSR_PLANNER_TIMING_SAMPLE rampRequestedDivide;
PLSR_PLANNER_TIMING_SAMPLE timerSetting;
PLSR_PLANNER_TIMING_SAMPLE rampActualDivide;
PLSR_PLANNER_TIMING_SAMPLE rampStep;
} PLSR_PLANNER_TIMING;

extern volatile PLSR_PLANNER_TIMING PlsrPlannerTiming;
void PlsrPlannerTimingReset(void);
#endif

PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context, PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
const PLSR_MOTION_BLOCK *block, const PLSR_MOTION_BLOCK *block,
uint32_t appliedHz, uint32_t appliedHz,


+ 38
- 1
PLSR/Src/plsr_platform_f407.c View File

@@ -1611,8 +1611,12 @@ volatile uint32_t PlsrFinalArmJobMaxCycles[4];
volatile uint32_t PlsrFinalArmQueueToStopLastCycles[4]; volatile uint32_t PlsrFinalArmQueueToStopLastCycles[4];
volatile uint32_t PlsrFinalArmQueueToStopMaxCycles[4]; volatile uint32_t PlsrFinalArmQueueToStopMaxCycles[4];
volatile uint32_t PlsrFiniteBlockIrqCount[4]; volatile uint32_t PlsrFiniteBlockIrqCount[4];
volatile uint32_t PlsrFiniteBlockIrqLastCycles[4];
volatile uint32_t PlsrFiniteBlockIrqTotalCycles[4];
volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4]; volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4];
volatile uint32_t PlsrFiniteFinalIrqCount[4];
volatile uint32_t PlsrFiniteFinalIrqLastCycles[4]; volatile uint32_t PlsrFiniteFinalIrqLastCycles[4];
volatile uint32_t PlsrFiniteFinalIrqTotalCycles[4];
volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4]; volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4];
volatile uint32_t PlsrAbReloadCounterBefore[4]; volatile uint32_t PlsrAbReloadCounterBefore[4];
volatile uint32_t PlsrAbReloadCounterArmed[4]; volatile uint32_t PlsrAbReloadCounterArmed[4];
@@ -2910,6 +2914,22 @@ uint8_t PlsrPlatformInit(void)
sizeof(PlsrFinalArmQueuedAt)); sizeof(PlsrFinalArmQueuedAt));
(void)memset((void *)PlsrFinalArmQueueTimingPending, 0, (void)memset((void *)PlsrFinalArmQueueTimingPending, 0,
sizeof(PlsrFinalArmQueueTimingPending)); sizeof(PlsrFinalArmQueueTimingPending));
(void)memset((void *)PlsrFiniteBlockIrqCount, 0,
sizeof(PlsrFiniteBlockIrqCount));
(void)memset((void *)PlsrFiniteBlockIrqLastCycles, 0,
sizeof(PlsrFiniteBlockIrqLastCycles));
(void)memset((void *)PlsrFiniteBlockIrqTotalCycles, 0,
sizeof(PlsrFiniteBlockIrqTotalCycles));
(void)memset((void *)PlsrFiniteBlockIrqMaxCycles, 0,
sizeof(PlsrFiniteBlockIrqMaxCycles));
(void)memset((void *)PlsrFiniteFinalIrqCount, 0,
sizeof(PlsrFiniteFinalIrqCount));
(void)memset((void *)PlsrFiniteFinalIrqLastCycles, 0,
sizeof(PlsrFiniteFinalIrqLastCycles));
(void)memset((void *)PlsrFiniteFinalIrqTotalCycles, 0,
sizeof(PlsrFiniteFinalIrqTotalCycles));
(void)memset((void *)PlsrFiniteFinalIrqMaxCycles, 0,
sizeof(PlsrFiniteFinalIrqMaxCycles));
#endif #endif


HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8
@@ -5110,10 +5130,19 @@ static void PlsrHandleCounterIrq(uint8_t counterIndex)
#if PLSR_DEBUG_TIMING #if PLSR_DEBUG_TIMING
{ {
uint32_t elapsedCycles = DWT->CYCCNT - startedAt; uint32_t elapsedCycles = DWT->CYCCNT - startedAt;
uint32_t totalCycles;


if (PlsrFiniteCompletionPending[owner] != 0U) if (PlsrFiniteCompletionPending[owner] != 0U)
{ {
totalCycles = PlsrFiniteFinalIrqTotalCycles[owner];
if (PlsrFiniteFinalIrqCount[owner] != 0xFFFFFFFFUL)
{
PlsrFiniteFinalIrqCount[owner]++;
}
PlsrFiniteFinalIrqLastCycles[owner] = elapsedCycles; PlsrFiniteFinalIrqLastCycles[owner] = elapsedCycles;
PlsrFiniteFinalIrqTotalCycles[owner] =
(elapsedCycles > (0xFFFFFFFFUL - totalCycles))
? 0xFFFFFFFFUL : totalCycles + elapsedCycles;
if (elapsedCycles > PlsrFiniteFinalIrqMaxCycles[owner]) if (elapsedCycles > PlsrFiniteFinalIrqMaxCycles[owner])
{ {
PlsrFiniteFinalIrqMaxCycles[owner] = elapsedCycles; PlsrFiniteFinalIrqMaxCycles[owner] = elapsedCycles;
@@ -5121,7 +5150,15 @@ static void PlsrHandleCounterIrq(uint8_t counterIndex)
} }
else else
{ {
PlsrFiniteBlockIrqCount[owner]++;
totalCycles = PlsrFiniteBlockIrqTotalCycles[owner];
if (PlsrFiniteBlockIrqCount[owner] != 0xFFFFFFFFUL)
{
PlsrFiniteBlockIrqCount[owner]++;
}
PlsrFiniteBlockIrqLastCycles[owner] = elapsedCycles;
PlsrFiniteBlockIrqTotalCycles[owner] =
(elapsedCycles > (0xFFFFFFFFUL - totalCycles))
? 0xFFFFFFFFUL : totalCycles + elapsedCycles;
if (elapsedCycles > PlsrFiniteBlockIrqMaxCycles[owner]) if (elapsedCycles > PlsrFiniteBlockIrqMaxCycles[owner])
{ {
PlsrFiniteBlockIrqMaxCycles[owner] = elapsedCycles; PlsrFiniteBlockIrqMaxCycles[owner] = elapsedCycles;


Loading…
Cancel
Save