如何 运行 一个包含多个差异的 .patch 文件

How to run a .patch file with several diffs inside

我从未使用过 .patch 文件,但我需要 运行 SEGGER 的 FreeRTOSV10_Core.patch 文件。

显示的文件可以在 SystemView Zip Archive.

中找到
diff -rupN org/Source/include/FreeRTOS.h new/Source/include/FreeRTOS.h
--- org/Source/include/FreeRTOS.h   2017-11-28 13:48:34.000000000 -0800
+++ new/Source/include/FreeRTOS.h   2017-12-11 00:54:49.522222000 -0800
@@ -157,6 +157,10 @@ extern "C" {
    #define INCLUDE_uxTaskGetStackHighWaterMark 0
 #endif

+#ifndef INCLUDE_pxTaskGetStackStart
+   #define INCLUDE_pxTaskGetStackStart 0
+#endif
+
 #ifndef INCLUDE_eTaskGetState
    #define INCLUDE_eTaskGetState 0
 #endif
@@ -393,6 +397,23 @@ extern "C" {
    #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
 #endif

+#ifndef traceREADDED_TASK_TO_READY_STATE
+   #define traceREADDED_TASK_TO_READY_STATE( pxTCB )   traceMOVED_TASK_TO_READY_STATE( pxTCB )
+#endif
+
+#ifndef traceMOVED_TASK_TO_DELAYED_LIST
+   #define traceMOVED_TASK_TO_DELAYED_LIST()
+#endif
+
+#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST
+   #define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()
+#endif
+
+#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST
+   #define traceMOVED_TASK_TO_SUSPENDED_LIST( pxTCB )
+#endif
+
+
 #ifndef traceQUEUE_CREATE
    #define traceQUEUE_CREATE( pxNewQueue )
 #endif
@@ -637,6 +658,18 @@ extern "C" {
    #define traceTASK_NOTIFY_GIVE_FROM_ISR()
 #endif

+#ifndef traceISR_EXIT_TO_SCHEDULER
+   #define traceISR_EXIT_TO_SCHEDULER()
+#endif
+
+#ifndef traceISR_EXIT
+   #define traceISR_EXIT()
+#endif
+
+#ifndef traceISR_ENTER
+   #define traceISR_ENTER()
+#endif
+
 #ifndef traceSTREAM_BUFFER_CREATE_FAILED
    #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
 #endif
diff -rupN org/Source/include/task.h new/Source/include/task.h
--- org/Source/include/task.h   2017-11-28 13:48:34.000000000 -0800
+++ new/Source/include/task.h   2017-12-11 00:56:29.783423000 -0800
@@ -1422,6 +1422,25 @@ TaskHandle_t xTaskGetHandle( const char
  */
 UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;

+/**
+ * task.h
+ * <PRE>uint8_t* pxTaskGetStackStart( TaskHandle_t xTask);</PRE>
+ *
+ * INCLUDE_pxTaskGetStackStart must be set to 1 in FreeRTOSConfig.h for
+ * this function to be available.
+ *
+ * Returns the start of the stack associated with xTask.  That is,
+ * the highest stack memory address on architectures where the stack grows down
+ * from high memory, and the lowest memory address on architectures where the
+ * stack grows up from low memory.
+ *
+ * @param xTask Handle of the task associated with the stack returned.
+ * Set xTask to NULL to return the stack of the calling task.
+ *
+ * @return A pointer to the start of the stack.
+ */
+uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
 /* When using trace macros it is sometimes necessary to include task.h before
 FreeRTOS.h.  When this is done TaskHookFunction_t will not yet have been defined,
 so the following two prototypes will cause a compilation error.  This can be
diff -rupN org/Source/portable/GCC/ARM_CM0/port.c new/Source/portable/GCC/ARM_CM0/port.c
--- org/Source/portable/GCC/ARM_CM0/port.c  2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM0/port.c  2017-12-11 01:11:45.061429000 -0800
@@ -333,13 +333,19 @@ void xPortSysTickHandler( void )
 uint32_t ulPreviousMask;

    ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
+   traceISR_ENTER();
    {
        /* Increment the RTOS tick. */
        if( xTaskIncrementTick() != pdFALSE )
        {
+      traceISR_EXIT_TO_SCHEDULER();
            /* Pend a context switch. */
            *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
        }
+       else
+       {
+           traceISR_EXIT();
+       }
    }
    portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
 }
diff -rupN org/Source/portable/GCC/ARM_CM0/portmacro.h new/Source/portable/GCC/ARM_CM0/portmacro.h
--- org/Source/portable/GCC/ARM_CM0/portmacro.h 2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM0/portmacro.h 2017-12-11 01:10:27.732228000 -0800
@@ -82,7 +82,7 @@ extern void vPortYield( void );
 #define portNVIC_INT_CTRL_REG      ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
 #define portNVIC_PENDSVSET_BIT     ( 1UL << 28UL )
 #define portYIELD()                    vPortYield()
-#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
+#define portEND_SWITCHING_ISR( xSwitchRequired ) { if( xSwitchRequired ) { traceISR_EXIT_TO_SCHEDULER(); portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } else { traceISR_EXIT(); } }
 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
 /*-----------------------------------------------------------*/

diff -rupN org/Source/portable/GCC/ARM_CM3/port.c new/Source/portable/GCC/ARM_CM3/port.c
--- org/Source/portable/GCC/ARM_CM3/port.c  2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM3/port.c  2017-12-11 01:14:50.515630000 -0800
@@ -431,14 +431,20 @@ void xPortSysTickHandler( void )
    save and then restore the interrupt mask value as its value is already
    known. */
    portDISABLE_INTERRUPTS();
+  traceISR_ENTER();
    {
        /* Increment the RTOS tick. */
        if( xTaskIncrementTick() != pdFALSE )
        {
+      traceISR_EXIT_TO_SCHEDULER();
            /* A context switch is required.  Context switching is performed in
            the PendSV interrupt.  Pend the PendSV interrupt. */
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
        }
+       else
+       {
+           traceISR_EXIT();
+       }
    }
    portENABLE_INTERRUPTS();
 }
diff -rupN org/Source/portable/GCC/ARM_CM3/portmacro.h new/Source/portable/GCC/ARM_CM3/portmacro.h
--- org/Source/portable/GCC/ARM_CM3/portmacro.h 2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM3/portmacro.h 2017-12-11 01:13:36.868029000 -0800
@@ -90,7 +90,7 @@ typedef unsigned long UBaseType_t;

 #define portNVIC_INT_CTRL_REG      ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
 #define portNVIC_PENDSVSET_BIT     ( 1UL << 28UL )
-#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
+#define portEND_SWITCHING_ISR( xSwitchRequired ) {} if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD() } else { traceISR_EXIT(); } }
 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
 /*-----------------------------------------------------------*/

diff -rupN org/Source/portable/GCC/ARM_CM4F/port.c new/Source/portable/GCC/ARM_CM4F/port.c
--- org/Source/portable/GCC/ARM_CM4F/port.c 2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM4F/port.c 2017-12-11 01:16:01.771230000 -0800
@@ -493,14 +493,20 @@ void xPortSysTickHandler( void )
    save and then restore the interrupt mask value as its value is already
    known. */
    portDISABLE_INTERRUPTS();
+  traceISR_ENTER();
    {
        /* Increment the RTOS tick. */
        if( xTaskIncrementTick() != pdFALSE )
        {
+           traceISR_EXIT_TO_SCHEDULER();
            /* A context switch is required.  Context switching is performed in
            the PendSV interrupt.  Pend the PendSV interrupt. */
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
        }
+       else
+       {
+           traceISR_EXIT();
+       }
    }
    portENABLE_INTERRUPTS();
 }
diff -rupN org/Source/portable/GCC/ARM_CM4F/portmacro.h new/Source/portable/GCC/ARM_CM4F/portmacro.h
--- org/Source/portable/GCC/ARM_CM4F/portmacro.h    2017-11-28 13:48:34.000000000 -0800
+++ new/Source/portable/GCC/ARM_CM4F/portmacro.h    2017-12-11 01:15:16.546830000 -0800
@@ -90,7 +90,7 @@ typedef unsigned long UBaseType_t;

 #define portNVIC_INT_CTRL_REG      ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
 #define portNVIC_PENDSVSET_BIT     ( 1UL << 28UL )
-#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
+#define portEND_SWITCHING_ISR( xSwitchRequired ) { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } }
 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
 /*-----------------------------------------------------------*/

diff -rupN org/Source/tasks.c new/Source/tasks.c
--- org/Source/tasks.c  2017-11-28 13:48:34.000000000 -0800
+++ new/Source/tasks.c  2017-12-11 01:08:48.591428000 -0800
@@ -237,6 +237,17 @@ count overflows. */
    taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                             \
    vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
    tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
+
+/*
+ * Place the task represented by pxTCB which has been in a ready list before
+ * into the appropriate ready list for the task.
+ * It is inserted at the end of the list.
+ */
+#define prvReaddTaskToReadyList( pxTCB )                                                           \
+   traceREADDED_TASK_TO_READY_STATE( pxTCB );                                                      \
+   taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                             \
+   vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
+   tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
 /*-----------------------------------------------------------*/

 /*
@@ -1598,7 +1609,7 @@ static void prvAddNewTaskToReadyList( TC
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }
-                   prvAddTaskToReadyList( pxTCB );
+                   prvReaddTaskToReadyList( pxTCB );
                }
                else
                {
@@ -1659,7 +1670,7 @@ static void prvAddNewTaskToReadyList( TC
            {
                mtCOVERAGE_TEST_MARKER();
            }
-
+      traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB);
            vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );

            #if( configUSE_TASK_NOTIFICATIONS == 1 )
@@ -3671,6 +3682,20 @@ static void prvCheckTasksWaitingTerminat
 #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
 /*-----------------------------------------------------------*/

+#if (INCLUDE_pxTaskGetStackStart == 1)
+   uint8_t* pxTaskGetStackStart( TaskHandle_t xTask)
+   {
+       TCB_t *pxTCB;
+       UBaseType_t uxReturn;
+        (void)uxReturn;
+
+       pxTCB = prvGetTCBFromHandle( xTask );
+       return ( uint8_t * ) pxTCB->pxStack;
+   }
+
+#endif /* INCLUDE_pxTaskGetStackStart */
+/*-----------------------------------------------------------*/
+
 #if ( INCLUDE_vTaskDelete == 1 )

    static void prvDeleteTCB( TCB_t *pxTCB )
@@ -3840,7 +3865,7 @@ TCB_t *pxTCB;

                    /* Inherit the priority before being moved into the new list. */
                    pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority;
-                   prvAddTaskToReadyList( pxMutexHolderTCB );
+                   prvReaddTaskToReadyList( pxMutexHolderTCB );
                }
                else
                {
@@ -3930,7 +3955,7 @@ TCB_t *pxTCB;
                    any other purpose if this task is running, and it must be
                    running to give back the mutex. */
                    listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
-                   prvAddTaskToReadyList( pxTCB );
+                   prvReaddTaskToReadyList( pxTCB );

                    /* Return true to indicate that a context switch is required.
                    This is only actually required in the corner case whereby
@@ -4940,6 +4965,7 @@ const TickType_t xConstTickCount = xTick
            /* Add the task to the suspended task list instead of a delayed task
            list to ensure it is not woken by a timing event.  It will block
            indefinitely. */
+      traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB);
            vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) );
        }
        else
@@ -4956,12 +4982,14 @@ const TickType_t xConstTickCount = xTick
            {
                /* Wake time has overflowed.  Place this item in the overflow
                list. */
+        traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
                vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
            }
            else
            {
                /* The wake time has not overflowed, so the current block list
                is used. */
+        traceMOVED_TASK_TO_DELAYED_LIST();
                vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );

                /* If the task entering the blocked state was placed at the
@@ -4991,11 +5019,13 @@ const TickType_t xConstTickCount = xTick
        if( xTimeToWake < xConstTickCount )
        {
            /* Wake time has overflowed.  Place this item in the overflow list. */
+      traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
            vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
        }
        else
        {
            /* The wake time has not overflowed, so the current block list is used. */
+      traceMOVED_TASK_TO_DELAYED_LIST();
            vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );

            /* If the task entering the blocked state was placed at the head of the

我试过 运行 我的 windows bash 中的这个 .patch 文件是这样的

$ patch /c/Users/ps/Documents/Git/STM32L432/Middlewares/Third_Party/FreeRTOS /c/Users/ps/Documents/Git/STM32L432/SEGGER/FreeRTOSV10/Patch/FreeRTOSV10_Core.patch

但是我收到以下错误消息

File /c/Users/ps/Documents/Git/STM32L432/Middlewares/Third_Party/FreeRTOS is not a regular file -- refusing to patch

当然,路径 /c/Users/ps/Documents/Git/STM32L432/Middlewares/Third_Party/FreeRTOS 不是文件路径,但它应该是所有 diff cmd 的根路径。那么如何确定一个根路径或连接多个路径以使用内部有多个差异的 .patch 文件?

顺便说一句:

$ patch --help
Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]

对我没有帮助...

编辑 1

现在我尝试从源目录 运行 我的 bash 并尝试像这样调用补丁

PS@PCENTW-PS MINGW64 ~/Documents/Git/STM32L432/Middlewares/Third_Party/FreeRTOS/Source (UseSystemView)
$ patch < /c/Users/ps/Documents/Git/STM32L432/SEGGER/FreeRTOSV10/Patch/FreeRTOSV10_Core.patch
can't find file to patch at input line 4
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|diff -rupN org/Source/include/FreeRTOS.h new/Source/include/FreeRTOS.h
|--- org/Source/include/FreeRTOS.h      2017-11-28 13:48:34.000000000 -0800
|+++ new/Source/include/FreeRTOS.h      2017-12-11 00:54:49.522222000 -0800
--------------------------
File to patch:

这似乎比我之前的电话好多了。但不管我得到错误 can't find file to patch at input line 4

  1. 打开cmd.exe
  2. 切换到所有文件所在的Source目录
    1. $ cd .../Source
  3. 运行 patch.exe
    1. $ patch < .../FreeRTOSV10_Core.patch
  4. 确定要修补的具体文件
    1. File to patch: .../FreeRTOS.h
  5. 完成