Bläddra i källkod

修复了WAIT信号和WAIT时间存在7ms延时的问题

codex/plsr-2026-minimal
ywh 1 månad sedan
förälder
incheckning
de8cbf8254
5 ändrade filer med 131 tillägg och 13 borttagningar
  1. +2
    -0
      Core/Inc/stm32f4xx_it.h
  2. Binär
      Document/信捷XD_XL系列PLC用户手册_硬件篇_PD01_20260410_V1.6.pdf
  3. +102
    -12
      PLSR/Src/plsr.c
  4. +2
    -0
      PLSR/Src/plsr_platform.h
  5. +25
    -1
      PLSR/Src/plsr_platform_f407.c

+ 2
- 0
Core/Inc/stm32f4xx_it.h Visa fil

@@ -66,6 +66,8 @@ void TIM1_TRG_COM_TIM11_IRQHandler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void TIM1_BRK_TIM9_IRQHandler(void);
void TIM8_BRK_TIM12_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
/* USER CODE END EFP */

#ifdef __cplusplus


Binär
Document/信捷XD_XL系列PLC用户手册_硬件篇_PD01_20260410_V1.6.pdf Visa fil


+ 102
- 12
PLSR/Src/plsr.c Visa fil

@@ -143,10 +143,10 @@ typedef struct
volatile uint8_t generatorComplete;
} PLSR_PROFILE_QUEUE;

/* A WAIT_TIME boundary is a cold start, but its planner work is predictable
while the source segment is still running. Build that next stream in the
inactive queue bank and publish it only after the startup horizon is ready.
The boundary path then contains no planner loop. */
/* WAIT_TIME and WAIT_SIGNAL boundaries are cold starts, but their planner
work is predictable while the source segment is still running or waiting.
Build that next stream in the inactive queue bank and publish it only after
the startup horizon is ready. The release path then has no planner loop. */
typedef struct
{
PLSR_PROFILE_ENTRY firstRun;
@@ -313,6 +313,8 @@ static volatile uint32_t PlsrSegmentElapsedMs;
static volatile uint32_t PlsrWaitElapsedMs;
static volatile uint8_t PlsrExtPreviousLevel;
static volatile uint8_t PlsrExtEdgePending;
static volatile uint8_t PlsrWaitSignalArmedMask;
static volatile uint8_t PlsrWaitSignalPendingMask;
static volatile uint8_t PlsrStopRequested;
static volatile uint8_t PlsrStopPulsesRemaining;
static volatile uint8_t PlsrAbStopArmed;
@@ -379,6 +381,9 @@ static void PlsrEnterErrorIfEpoch(PLSR_ERROR error,
static void PlsrMarkPersistenceDirty(uint16_t delayMs);
static void PlsrCheckpointPosition(uint8_t wasBusy);
static void PlsrPollPositionCheckpoint(void);
static void PlsrArmWaitSignal(uint8_t inputSelection);
static void PlsrDisarmWaitSignal(void);
static uint8_t PlsrWaitSignalDetected(uint8_t inputSelection);
static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void);
static uint8_t PlsrPrepareShortProfile(PLSR_SHORT_PROFILE *profile,
uint8_t segmentNumber,
@@ -2360,8 +2365,10 @@ static void PlsrServiceTimedStartPreparation(void)
sourceSegment = PlsrCurrentSegment;
if ((sourceSegment == 0U)
|| (sourceSegment > PlsrActiveConfig.segmentCount)
|| (PlsrActiveConfig.segments[sourceSegment - 1U].waitType
!= PLSR_WAIT_TIME))
|| ((PlsrActiveConfig.segments[sourceSegment - 1U].waitType
!= PLSR_WAIT_TIME)
&& (PlsrActiveConfig.segments[sourceSegment - 1U].waitType
!= PLSR_WAIT_SIGNAL)))
{
PlsrInvalidateTimedStartLocked();
PlsrPlatformExitCritical(criticalState);
@@ -3293,6 +3300,7 @@ static uint8_t PlsrStartSegment(uint8_t segmentNumber,
{
return 0U;
}
PlsrDisarmWaitSignal();

criticalState = PlsrPlatformEnterCritical();
position = PlsrPosition;
@@ -3445,6 +3453,7 @@ static void PlsrPollPositionCheckpoint(void)

static void PlsrFinishCompleted(void)
{
PlsrDisarmWaitSignal();
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput);
PlsrRemainingPulses = 0UL;
PlsrPulseActive = 0U;
@@ -3482,6 +3491,7 @@ static void PlsrFinishCompleted(void)

static void PlsrFinishStopped(void)
{
PlsrDisarmWaitSignal();
PlsrDiagnosticFinishSegment(0U);
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput);
PlsrRemainingPulses = 0UL;
@@ -3520,6 +3530,7 @@ static void PlsrFinishStopped(void)

static void PlsrEnterError(PLSR_ERROR error)
{
PlsrDisarmWaitSignal();
PlsrDiagnosticFinishSegment(0U);
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput);
PlsrRemainingPulses = 0UL;
@@ -4461,6 +4472,82 @@ static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void)
return PLSR_PLATFORM_QUEUE_APPLIED;
}

/* EXTI only records a WAIT edge. Motion state transitions and timer startup
remain in the task context. The armed mask prevents an edge from an idle
or unrelated input from releasing a later segment. */
void PlsrWaitInputExtiIrq(uint8_t inputSelection)
{
uint8_t bit;

if (inputSelection > 1U)
{
return;
}
bit = (uint8_t)(1U << inputSelection);
if ((PlsrWaitSignalArmedMask & bit) != 0U)
{
PlsrWaitSignalPendingMask |= bit;
}
}

static void PlsrArmWaitSignal(uint8_t inputSelection)
{
uint32_t criticalState;
uint8_t bit;

if (inputSelection > 1U)
{
return;
}
bit = (uint8_t)(1U << inputSelection);
criticalState = PlsrPlatformEnterCritical();
PlsrWaitSignalPendingMask = 0U;
PlsrWaitSignalArmedMask = bit;
PlsrPlatformExitCritical(criticalState);
}

static void PlsrDisarmWaitSignal(void)
{
uint32_t criticalState = PlsrPlatformEnterCritical();

PlsrWaitSignalArmedMask = 0U;
PlsrWaitSignalPendingMask = 0U;
PlsrPlatformExitCritical(criticalState);
}

static uint8_t PlsrWaitSignalDetected(uint8_t inputSelection)
{
uint32_t criticalState;
uint8_t bit;

if (inputSelection > 1U)
{
return 0U;
}
bit = (uint8_t)(1U << inputSelection);
criticalState = PlsrPlatformEnterCritical();
if ((PlsrWaitSignalPendingMask & bit) != 0U)
{
PlsrWaitSignalPendingMask &= (uint8_t)~bit;
PlsrWaitSignalArmedMask &= (uint8_t)~bit;
PlsrPlatformExitCritical(criticalState);
return 1U;
}
PlsrPlatformExitCritical(criticalState);

/* Preserve the original level semantics: a signal already high when the
segment enters WAIT must release it even though no new EXTI edge occurs. */
if (PlsrPlatformReadInput(inputSelection) != 0U)
{
criticalState = PlsrPlatformEnterCritical();
PlsrWaitSignalPendingMask &= (uint8_t)~bit;
PlsrWaitSignalArmedMask &= (uint8_t)~bit;
PlsrPlatformExitCritical(criticalState);
return 1U;
}
return 0U;
}

static void PlsrHandleBoundary(uint8_t extEdge)
{
const PLSR_SEGMENT_CONFIG *segment;
@@ -4550,14 +4637,13 @@ static void PlsrHandleBoundary(uint8_t extEdge)
break;

case PLSR_WAIT_SIGNAL:
if (PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.waitInput) != 0U)
PlsrRunStatus = PLSR_STATUS_WAITING;
PlsrArmWaitSignal((uint8_t)PlsrActiveConfig.waitInput);
if (PlsrWaitSignalDetected(
(uint8_t)PlsrActiveConfig.waitInput) != 0U)
{
PlsrTransitionToNext(0U);
}
else
{
PlsrRunStatus = PLSR_STATUS_WAITING;
}
break;

case PLSR_ACT_TIME:
@@ -4634,7 +4720,8 @@ static void PlsrPollWaiting(uint8_t extEdge)
}
break;
case PLSR_WAIT_SIGNAL:
if (PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.waitInput) != 0U)
if (PlsrWaitSignalDetected(
(uint8_t)PlsrActiveConfig.waitInput) != 0U)
{
PlsrTransitionToNext(0U);
}
@@ -4786,6 +4873,8 @@ uint8_t PlsrInit(void)
PlsrSegmentClockStarted = 0U;
PlsrExtPreviousLevel = 0U;
PlsrExtEdgePending = 0U;
PlsrWaitSignalArmedMask = 0U;
PlsrWaitSignalPendingMask = 0U;
PlsrStopRequested = 0U;
PlsrStopPulsesRemaining = 0U;
PlsrAbStopArmed = 0U;
@@ -4995,6 +5084,7 @@ static void PlsrExecuteClear(void)
{
uint32_t criticalState;

PlsrDisarmWaitSignal();
criticalState = PlsrPlatformEnterCritical();
PlsrPosition = 0L;
PlsrPositionValid = 1U;


+ 2
- 0
PLSR/Src/plsr_platform.h Visa fil

@@ -117,6 +117,8 @@ uint8_t PlsrExecTakeCountedRunIrq(
void PlsrExecCountedSegmentBoundaryIrq(uint8_t pulseOutput,
uint32_t completedPulses);
void PlsrExecCountedStreamFaultIrq(uint8_t pulseOutput);
/* EXTI callback: records only an armed WAIT input edge. */
void PlsrWaitInputExtiIrq(uint8_t inputSelection);
PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq(
uint8_t pulseOutput,
const PLSR_PLATFORM_TIMER_SETTING *setting,


+ 25
- 1
PLSR/Src/plsr_platform_f407.c Visa fil

@@ -2756,6 +2756,7 @@ uint8_t PlsrPlatformInit(void)
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_TIM10_CLK_ENABLE();
__HAL_RCC_TIM11_CLK_ENABLE();
__HAL_RCC_TIM13_CLK_ENABLE();
@@ -2802,7 +2803,7 @@ uint8_t PlsrPlatformInit(void)
gpio.Alternate = 0U;
HAL_GPIO_Init(GPIOH, &gpio);

gpio.Mode = GPIO_MODE_INPUT;
gpio.Mode = GPIO_MODE_IT_RISING;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
gpio.Alternate = 0U;
@@ -2810,6 +2811,11 @@ uint8_t PlsrPlatformInit(void)
HAL_GPIO_Init(GPIOB, &gpio);
gpio.Pin = GPIO_PIN_12;
HAL_GPIO_Init(GPIOG, &gpio);
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5 | GPIO_PIN_12);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2U, 0U);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2U, 0U);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

for (index = 0U; index < 4U; index++)
{
@@ -4818,6 +4824,24 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void)
PlsrDispatchTimerIrq(3U);
}

void EXTI9_5_IRQHandler(void)
{
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_5) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
PlsrWaitInputExtiIrq(0U);
}
}

void EXTI15_10_IRQHandler(void)
{
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_12) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);
PlsrWaitInputExtiIrq(1U);
}
}

static void PlsrHandleCounterIrq(uint8_t counterIndex)
{
TIM_TypeDef *counter;


Laddar…
Avbryt
Spara