可以收发,开始写自动生成接口
This commit is contained in:
parent
ef1f6d6642
commit
9db1394184
File diff suppressed because one or more lines are too long
@ -207,7 +207,7 @@ ProjectManager.ProjectName=FDCAN
|
|||||||
ProjectManager.ProjectStructure=
|
ProjectManager.ProjectStructure=
|
||||||
ProjectManager.RegisterCallBack=
|
ProjectManager.RegisterCallBack=
|
||||||
ProjectManager.StackSize=0x2000
|
ProjectManager.StackSize=0x2000
|
||||||
ProjectManager.TargetToolchain=MDK-ARM V5.32
|
ProjectManager.TargetToolchain=CMake
|
||||||
ProjectManager.ToolChainLocation=
|
ProjectManager.ToolChainLocation=
|
||||||
ProjectManager.UAScriptAfterPath=
|
ProjectManager.UAScriptAfterPath=
|
||||||
ProjectManager.UAScriptBeforePath=
|
ProjectManager.UAScriptBeforePath=
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -157,9 +157,25 @@
|
|||||||
<Bp>
|
<Bp>
|
||||||
<Number>0</Number>
|
<Number>0</Number>
|
||||||
<Type>0</Type>
|
<Type>0</Type>
|
||||||
|
<LineNumber>249</LineNumber>
|
||||||
|
<EnabledFlag>1</EnabledFlag>
|
||||||
|
<Address>134224724</Address>
|
||||||
|
<ByteObject>0</ByteObject>
|
||||||
|
<HtxType>0</HtxType>
|
||||||
|
<ManyObjects>0</ManyObjects>
|
||||||
|
<SizeOfObject>0</SizeOfObject>
|
||||||
|
<BreakByAccess>0</BreakByAccess>
|
||||||
|
<BreakIfRCount>1</BreakIfRCount>
|
||||||
|
<Filename>..\User\bsp\fdcan.c</Filename>
|
||||||
|
<ExecCommand></ExecCommand>
|
||||||
|
<Expression>\\FDCAN\../User/bsp/fdcan.c\249</Expression>
|
||||||
|
</Bp>
|
||||||
|
<Bp>
|
||||||
|
<Number>1</Number>
|
||||||
|
<Type>0</Type>
|
||||||
<LineNumber>217</LineNumber>
|
<LineNumber>217</LineNumber>
|
||||||
<EnabledFlag>1</EnabledFlag>
|
<EnabledFlag>1</EnabledFlag>
|
||||||
<Address>134224716</Address>
|
<Address>134224896</Address>
|
||||||
<ByteObject>0</ByteObject>
|
<ByteObject>0</ByteObject>
|
||||||
<HtxType>0</HtxType>
|
<HtxType>0</HtxType>
|
||||||
<ManyObjects>0</ManyObjects>
|
<ManyObjects>0</ManyObjects>
|
||||||
|
|||||||
Binary file not shown.
@ -28,6 +28,10 @@ Project File Date: 12/27/2025
|
|||||||
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'D:\cangming\ARM\ARMCC\Bin'
|
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'D:\cangming\ARM\ARMCC\Bin'
|
||||||
Build target 'FDCAN'
|
Build target 'FDCAN'
|
||||||
Note: source file '..\User\bsp\fdcan.c' - object file renamed from 'FDCAN\fdcan.o' to 'FDCAN\fdcan_1.o'.
|
Note: source file '..\User\bsp\fdcan.c' - object file renamed from 'FDCAN\fdcan.o' to 'FDCAN\fdcan_1.o'.
|
||||||
|
compiling fdcan.c...
|
||||||
|
linking...
|
||||||
|
Program Size: Code=23940 RO-data=996 RW-data=176 ZI-data=41576
|
||||||
|
FromELF: creating hex file...
|
||||||
"FDCAN\FDCAN.axf" - 0 Error(s), 0 Warning(s).
|
"FDCAN\FDCAN.axf" - 0 Error(s), 0 Warning(s).
|
||||||
|
|
||||||
<h2>Software Packages used:</h2>
|
<h2>Software Packages used:</h2>
|
||||||
@ -51,7 +55,7 @@ Package Vendor: Keil
|
|||||||
|
|
||||||
* Component: ARM::CMSIS:CORE:5.4.0
|
* Component: ARM::CMSIS:CORE:5.4.0
|
||||||
Include file: CMSIS\Core\Include\tz_context.h
|
Include file: CMSIS\Core\Include\tz_context.h
|
||||||
Build Time Elapsed: 00:00:01
|
Build Time Elapsed: 00:00:05
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
<title>Static Call Graph - [FDCAN\FDCAN.axf]</title></head>
|
<title>Static Call Graph - [FDCAN\FDCAN.axf]</title></head>
|
||||||
<body><HR>
|
<body><HR>
|
||||||
<H1>Static Call Graph for image FDCAN\FDCAN.axf</H1><HR>
|
<H1>Static Call Graph for image FDCAN\FDCAN.axf</H1><HR>
|
||||||
<BR><P>#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Sat Dec 27 03:17:48 2025
|
<BR><P>#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Sat Dec 27 03:49:53 2025
|
||||||
<BR><P>
|
<BR><P>
|
||||||
<H3>Maximum Stack Usage = 352 bytes + Unknown(Functions without stacksize, Cycles, Untraceable Function Pointers)</H3><H3>
|
<H3>Maximum Stack Usage = 352 bytes + Unknown(Functions without stacksize, Cycles, Untraceable Function Pointers)</H3><H3>
|
||||||
Call chain for Maximum Stack Depth:</H3>
|
Call chain for Maximum Stack Depth:</H3>
|
||||||
@ -880,7 +880,7 @@ Global Symbols
|
|||||||
<BR>[Called By]<UL><LI><a href="#[9e]">>></a> Task_blink
|
<BR>[Called By]<UL><LI><a href="#[9e]">>></a> Task_blink
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
<P><STRONG><a name="[c7]"></a>BSP_FDCAN_Init</STRONG> (Thumb, 434 bytes, Stack size 56 bytes, fdcan_1.o(i.BSP_FDCAN_Init))
|
<P><STRONG><a name="[c7]"></a>BSP_FDCAN_Init</STRONG> (Thumb, 428 bytes, Stack size 56 bytes, fdcan_1.o(i.BSP_FDCAN_Init))
|
||||||
<BR><BR>[Stack]<UL><LI>Max Depth = 200<LI>Call Chain = BSP_FDCAN_Init ⇒ osMutexNew ⇒ xQueueCreateMutexStatic ⇒ prvInitialiseMutex ⇒ xQueueGenericSend ⇒ xTaskResumeAll ⇒ xTaskIncrementTick
|
<BR><BR>[Stack]<UL><LI>Max Depth = 200<LI>Call Chain = BSP_FDCAN_Init ⇒ osMutexNew ⇒ xQueueCreateMutexStatic ⇒ prvInitialiseMutex ⇒ xQueueGenericSend ⇒ xTaskResumeAll ⇒ xTaskIncrementTick
|
||||||
</UL>
|
</UL>
|
||||||
<BR>[Calls]<UL><LI><a href="#[cd]">>></a> HAL_FDCAN_Start
|
<BR>[Calls]<UL><LI><a href="#[cd]">>></a> HAL_FDCAN_Start
|
||||||
@ -911,7 +911,7 @@ Global Symbols
|
|||||||
<BR>[Called By]<UL><LI><a href="#[9e]">>></a> Task_blink
|
<BR>[Called By]<UL><LI><a href="#[9e]">>></a> Task_blink
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
<P><STRONG><a name="[d7]"></a>BSP_FDCAN_Transmit</STRONG> (Thumb, 318 bytes, Stack size 136 bytes, fdcan_1.o(i.BSP_FDCAN_Transmit))
|
<P><STRONG><a name="[d7]"></a>BSP_FDCAN_Transmit</STRONG> (Thumb, 320 bytes, Stack size 136 bytes, fdcan_1.o(i.BSP_FDCAN_Transmit))
|
||||||
<BR><BR>[Stack]<UL><LI>Max Depth = 172<LI>Call Chain = BSP_FDCAN_Transmit ⇒ HAL_FDCAN_AddMessageToTxFifoQ ⇒ FDCAN_CopyMessageToRAM
|
<BR><BR>[Stack]<UL><LI>Max Depth = 172<LI>Call Chain = BSP_FDCAN_Transmit ⇒ HAL_FDCAN_AddMessageToTxFifoQ ⇒ FDCAN_CopyMessageToRAM
|
||||||
</UL>
|
</UL>
|
||||||
<BR>[Calls]<UL><LI><a href="#[d8]">>></a> HAL_FDCAN_GetTxFifoFreeLevel
|
<BR>[Calls]<UL><LI><a href="#[d8]">>></a> HAL_FDCAN_GetTxFifoFreeLevel
|
||||||
@ -1563,7 +1563,7 @@ Global Symbols
|
|||||||
</UL>
|
</UL>
|
||||||
<BR>[Address Reference Count : 1]<UL><LI> freertos.o(i.MX_FREERTOS_Init)
|
<BR>[Address Reference Count : 1]<UL><LI> freertos.o(i.MX_FREERTOS_Init)
|
||||||
</UL>
|
</UL>
|
||||||
<P><STRONG><a name="[9e]"></a>Task_blink</STRONG> (Thumb, 308 bytes, Stack size 32 bytes, blink.o(i.Task_blink))
|
<P><STRONG><a name="[9e]"></a>Task_blink</STRONG> (Thumb, 298 bytes, Stack size 32 bytes, blink.o(i.Task_blink))
|
||||||
<BR><BR>[Stack]<UL><LI>Max Depth = 232<LI>Call Chain = Task_blink ⇒ BSP_FDCAN_Init ⇒ osMutexNew ⇒ xQueueCreateMutexStatic ⇒ prvInitialiseMutex ⇒ xQueueGenericSend ⇒ xTaskResumeAll ⇒ xTaskIncrementTick
|
<BR><BR>[Stack]<UL><LI>Max Depth = 232<LI>Call Chain = Task_blink ⇒ BSP_FDCAN_Init ⇒ osMutexNew ⇒ xQueueCreateMutexStatic ⇒ prvInitialiseMutex ⇒ xQueueGenericSend ⇒ xTaskResumeAll ⇒ xTaskIncrementTick
|
||||||
</UL>
|
</UL>
|
||||||
<BR>[Calls]<UL><LI><a href="#[11e]">>></a> osDelay
|
<BR>[Calls]<UL><LI><a href="#[11e]">>></a> osDelay
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
Dependencies for Project 'FDCAN', Target 'FDCAN': (DO NOT MODIFY !)
|
Dependencies for Project 'FDCAN', Target 'FDCAN': (DO NOT MODIFY !)
|
||||||
CompilerVersion: 5060960::V5.06 update 7 (build 960)::.\ARMCC
|
CompilerVersion: 5060960::V5.06 update 7 (build 960)::.\ARMCC
|
||||||
F (startup_stm32h723xx.s)(0x694ED3B7)(--cpu Cortex-M7.fp.dp -g --apcs=interwork -I ../Drivers/CMSIS/Include
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
--pd "__UVISION_VERSION SETA 534" --pd "_RTE_ SETA 1" --pd "STM32H723xx SETA 1" --pd "_RTE_ SETA 1"
--list startup_stm32h723xx.lst --xref -o fdcan\startup_stm32h723xx.o --depend fdcan\startup_stm32h723xx.d)
|
F (startup_stm32h723xx.s)(0x694EE382)(--cpu Cortex-M7.fp.dp -g --apcs=interwork -I ../Drivers/CMSIS/Include
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
--pd "__UVISION_VERSION SETA 534" --pd "_RTE_ SETA 1" --pd "STM32H723xx SETA 1" --pd "_RTE_ SETA 1"
--list startup_stm32h723xx.lst --xref -o fdcan\startup_stm32h723xx.o --depend fdcan\startup_stm32h723xx.d)
|
||||||
F (../Core/Src/main.c)(0x694E2F79)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\main.o --omf_browse fdcan\main.crf --depend fdcan\main.d)
|
F (../Core/Src/main.c)(0x694E2F79)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\main.o --omf_browse fdcan\main.crf --depend fdcan\main.d)
|
||||||
I (../Core/Inc/main.h)(0x694E28D6)
|
I (../Core/Inc/main.h)(0x694E28D6)
|
||||||
I (../Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h)(0x6944350B)
|
I (../Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h)(0x6944350B)
|
||||||
@ -1158,7 +1158,7 @@ I (../Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h)(0x694434DA
|
|||||||
I (../Middlewares/Third_Party/FreeRTOS/Source/include/task.h)(0x694434DA)
|
I (../Middlewares/Third_Party/FreeRTOS/Source/include/task.h)(0x694434DA)
|
||||||
I (../Middlewares/Third_Party/FreeRTOS/Source/include/list.h)(0x694434DA)
|
I (../Middlewares/Third_Party/FreeRTOS/Source/include/list.h)(0x694434DA)
|
||||||
F (..\User\bsp\bsp.h)(0x694E34A2)()
|
F (..\User\bsp\bsp.h)(0x694E34A2)()
|
||||||
F (..\User\bsp\fdcan.c)(0x694EDF57)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\fdcan_1.o --omf_browse fdcan\fdcan_1.crf --depend fdcan\fdcan_1.d)
|
F (..\User\bsp\fdcan.c)(0x694EE6C6)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\fdcan_1.o --omf_browse fdcan\fdcan_1.crf --depend fdcan\fdcan_1.d)
|
||||||
I (..\User\bsp\fdcan.h)(0x694ED994)
|
I (..\User\bsp\fdcan.h)(0x694ED994)
|
||||||
I (D:\cangming\ARM\ARMCC\include\stdint.h)(0x5E8E3CC2)
|
I (D:\cangming\ARM\ARMCC\include\stdint.h)(0x5E8E3CC2)
|
||||||
I (D:\cangming\ARM\ARMCC\include\stdbool.h)(0x5E8E3CC2)
|
I (D:\cangming\ARM\ARMCC\include\stdbool.h)(0x5E8E3CC2)
|
||||||
@ -1352,7 +1352,7 @@ I (D:\cangming\ARM\ARMCC\include\stdint.h)(0x5E8E3CC2)
|
|||||||
I (D:\cangming\ARM\ARMCC\include\stddef.h)(0x5E8E3CC2)
|
I (D:\cangming\ARM\ARMCC\include\stddef.h)(0x5E8E3CC2)
|
||||||
I (D:\cangming\ARM\ARMCC\include\string.h)(0x5E8E3CC2)
|
I (D:\cangming\ARM\ARMCC\include\string.h)(0x5E8E3CC2)
|
||||||
F (..\User\component\user_math.h)(0x690DD4C7)()
|
F (..\User\component\user_math.h)(0x690DD4C7)()
|
||||||
F (..\User\task\blink.c)(0x694ED995)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\blink.o --omf_browse fdcan\blink.crf --depend fdcan\blink.d)
|
F (..\User\task\blink.c)(0x694EE409)(--c99 --gnu -c --cpu Cortex-M7.fp.dp -g -O3 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc -I ../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/Third_Party/FreeRTOS/Source/include -I ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F -I ../User
-I.\RTE\_FDCAN
-ID:\cangming\ARM\CMSIS\5.7.0\CMSIS\Core\Include
-D__UVISION_VERSION="534" -D_RTE_ -DSTM32H723xx -D_RTE_ -DUSE_PWR_LDO_SUPPLY -DUSE_HAL_DRIVER -DSTM32H723xx
-o fdcan\blink.o --omf_browse fdcan\blink.crf --depend fdcan\blink.d)
|
||||||
I (../User/task/user_task.h)(0x693967A8)
|
I (../User/task/user_task.h)(0x693967A8)
|
||||||
I (../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h)(0x694434DA)
|
I (../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h)(0x694434DA)
|
||||||
I (D:\cangming\ARM\ARMCC\include\stdint.h)(0x5E8E3CC2)
|
I (D:\cangming\ARM\ARMCC\include\stdint.h)(0x5E8E3CC2)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -33,14 +33,10 @@
|
|||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef __TARGET_FPU_VFP
|
#ifndef __VFP_FP__
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
|
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
@ -51,15 +47,6 @@
|
|||||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Legacy macro for backward compatibility only. This macro used to be used to
|
|
||||||
replace the function that configures the clock used to generate the tick
|
|
||||||
interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so
|
|
||||||
the application writer can override it by simply defining a function of the
|
|
||||||
same name (vApplicationSetupTickInterrupt()). */
|
|
||||||
#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION
|
|
||||||
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
@ -95,25 +82,34 @@ r0p1 port. */
|
|||||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
/* The systick is a 24-bit counter. */
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
|
||||||
calculations. */
|
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
||||||
|
|
||||||
/* For strict compliance with the Cortex-M spec the task start address should
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
|
occurred while the SysTick counter is stopped during tickless idle
|
||||||
|
calculations. */
|
||||||
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
|
debugger. */
|
||||||
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
|
#else
|
||||||
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||||
* file is weak to allow application writers to change the timer used to
|
* file is weak to allow application writers to change the timer used to
|
||||||
@ -124,19 +120,19 @@ void vPortSetupTimerInterrupt( void );
|
|||||||
/*
|
/*
|
||||||
* Exception handlers.
|
* Exception handlers.
|
||||||
*/
|
*/
|
||||||
void xPortPendSVHandler( void );
|
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
||||||
void xPortSysTickHandler( void );
|
void xPortSysTickHandler( void );
|
||||||
void vPortSVCHandler( void );
|
void vPortSVCHandler( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
*/
|
*/
|
||||||
static void prvStartFirstTask( void );
|
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions defined in portasm.s to enable the VFP.
|
* Function to enable the VFP.
|
||||||
*/
|
*/
|
||||||
static void prvEnableVFP( void );
|
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
* Used to catch tasks that attempt to return from their implementing function.
|
||||||
@ -177,10 +173,10 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
|||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
static uint8_t ucMaxSysCallPriority = 0;
|
static uint8_t ucMaxSysCallPriority = 0;
|
||||||
static uint32_t ulMaxPRIGROUPValue = 0;
|
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -201,7 +197,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */
|
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||||
|
|
||||||
/* Save code space by skipping register initialisation. */
|
/* Save code space by skipping register initialisation. */
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
@ -220,6 +216,8 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
|
volatile uint32_t ulDummy = 0;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
@ -228,69 +226,58 @@ static void prvTaskExitError( void )
|
|||||||
defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
while( ulDummy == 0 )
|
||||||
|
{
|
||||||
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
|
started to remove a compiler warning about the function being defined
|
||||||
|
but never called. ulDummy is used purely to quieten other warnings
|
||||||
|
about code appearing after this function is called - making ulDummy
|
||||||
|
volatile makes the compiler think the function could return and
|
||||||
|
therefore not output an 'unreachable code' warning for code that appears
|
||||||
|
after it. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm void vPortSVCHandler( void )
|
void vPortSVCHandler( void )
|
||||||
{
|
{
|
||||||
PRESERVE8
|
__asm volatile (
|
||||||
|
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||||
/* Get the location of the current TCB. */
|
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||||
ldr r3, =pxCurrentTCB
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
ldr r1, [r3]
|
" ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||||
ldr r0, [r1]
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
/* Pop the core registers. */
|
" isb \n"
|
||||||
ldmia r0!, {r4-r11, r14}
|
" mov r0, #0 \n"
|
||||||
msr psp, r0
|
" msr basepri, r0 \n"
|
||||||
isb
|
" bx r14 \n"
|
||||||
mov r0, #0
|
" \n"
|
||||||
msr basepri, r0
|
" .align 4 \n"
|
||||||
bx r14
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm void prvStartFirstTask( void )
|
static void prvPortStartFirstTask( void )
|
||||||
{
|
{
|
||||||
PRESERVE8
|
/* Start the first task. This also clears the bit that indicates the FPU is
|
||||||
|
in use in case the FPU was used before the scheduler was started - which
|
||||||
/* Use the NVIC offset register to locate the stack. */
|
would otherwise result in the unnecessary leaving of space in the SVC stack
|
||||||
ldr r0, =0xE000ED08
|
for lazy saving of FPU registers. */
|
||||||
ldr r0, [r0]
|
__asm volatile(
|
||||||
ldr r0, [r0]
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
/* Set the msp back to the start of the stack. */
|
" ldr r0, [r0] \n"
|
||||||
msr msp, r0
|
" ldr r0, [r0] \n"
|
||||||
/* Clear the bit that indicates the FPU is in use in case the FPU was used
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
before the scheduler was started - which would otherwise result in the
|
" mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
|
||||||
unnecessary leaving of space in the SVC stack for lazy saving of FPU
|
" msr control, r0 \n"
|
||||||
registers. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
mov r0, #0
|
" cpsie f \n"
|
||||||
msr control, r0
|
" dsb \n"
|
||||||
/* Globally enable interrupts. */
|
" isb \n"
|
||||||
cpsie i
|
" svc 0 \n" /* System call to start first task. */
|
||||||
cpsie f
|
" nop \n"
|
||||||
dsb
|
);
|
||||||
isb
|
|
||||||
/* Call SVC to start the first task. */
|
|
||||||
svc 0
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void prvEnableVFP( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* The FPU enable bits are in the CPACR. */
|
|
||||||
ldr.w r0, =0xE000ED88
|
|
||||||
ldr r1, [r0]
|
|
||||||
|
|
||||||
/* Enable CP10 and CP11 coprocessors, then save back. */
|
|
||||||
orr r1, r1, #( 0xf << 20 )
|
|
||||||
str r1, [r0]
|
|
||||||
bx r14
|
|
||||||
nop
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -312,7 +299,7 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
@ -330,10 +317,6 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* The kernel interrupt priority should be set to the lowest
|
|
||||||
priority. */
|
|
||||||
configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) );
|
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
/* Use the same mask on the maximum system call priority. */
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
@ -387,13 +370,22 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
uxCriticalNesting = 0;
|
uxCriticalNesting = 0;
|
||||||
|
|
||||||
/* Ensure the VFP is enabled - it should be anyway. */
|
/* Ensure the VFP is enabled - it should be anyway. */
|
||||||
prvEnableVFP();
|
vPortEnableVFP();
|
||||||
|
|
||||||
/* Lazy save always. */
|
/* Lazy save always. */
|
||||||
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
prvStartFirstTask();
|
prvPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should never get here as the tasks will now be executing! Call the task
|
||||||
|
exit error function to prevent compiler warnings about a static function
|
||||||
|
not being called in the case that the application writer overrides this
|
||||||
|
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
|
vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
|
symbol. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
prvTaskExitError();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
return 0;
|
return 0;
|
||||||
@ -436,65 +428,60 @@ void vPortExitCritical( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm void xPortPendSVHandler( void )
|
void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
extern uxCriticalNesting;
|
/* This is a naked function. */
|
||||||
extern pxCurrentTCB;
|
|
||||||
extern vTaskSwitchContext;
|
|
||||||
|
|
||||||
PRESERVE8
|
__asm volatile
|
||||||
|
(
|
||||||
mrs r0, psp
|
" mrs r0, psp \n"
|
||||||
isb
|
" isb \n"
|
||||||
/* Get the location of the current TCB. */
|
" \n"
|
||||||
ldr r3, =pxCurrentTCB
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
ldr r2, [r3]
|
" ldr r2, [r3] \n"
|
||||||
|
" \n"
|
||||||
/* Is the task using the FPU context? If so, push high vfp registers. */
|
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
|
||||||
tst r14, #0x10
|
" it eq \n"
|
||||||
it eq
|
" vstmdbeq r0!, {s16-s31} \n"
|
||||||
vstmdbeq r0!, {s16-s31}
|
" \n"
|
||||||
|
" stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
|
||||||
/* Save the core registers. */
|
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||||
stmdb r0!, {r4-r11, r14}
|
" \n"
|
||||||
|
" stmdb sp!, {r0, r3} \n"
|
||||||
/* Save the new top of stack into the first member of the TCB. */
|
" mov r0, %0 \n"
|
||||||
str r0, [r2]
|
" msr basepri, r0 \n"
|
||||||
|
" dsb \n"
|
||||||
stmdb sp!, {r0, r3}
|
" isb \n"
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
" bl vTaskSwitchContext \n"
|
||||||
msr basepri, r0
|
" mov r0, #0 \n"
|
||||||
dsb
|
" msr basepri, r0 \n"
|
||||||
isb
|
" ldmia sp!, {r0, r3} \n"
|
||||||
bl vTaskSwitchContext
|
" \n"
|
||||||
mov r0, #0
|
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
msr basepri, r0
|
" ldr r0, [r1] \n"
|
||||||
ldmia sp!, {r0, r3}
|
" \n"
|
||||||
|
" ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */
|
||||||
/* The first item in pxCurrentTCB is the task top of stack. */
|
" \n"
|
||||||
ldr r1, [r3]
|
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */
|
||||||
ldr r0, [r1]
|
" it eq \n"
|
||||||
|
" vldmiaeq r0!, {s16-s31} \n"
|
||||||
/* Pop the core registers. */
|
" \n"
|
||||||
ldmia r0!, {r4-r11, r14}
|
" msr psp, r0 \n"
|
||||||
|
" isb \n"
|
||||||
/* Is the task using the FPU context? If so, pop the high vfp registers
|
" \n"
|
||||||
too. */
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
||||||
tst r14, #0x10
|
|
||||||
it eq
|
|
||||||
vldmiaeq r0!, {s16-s31}
|
|
||||||
|
|
||||||
msr psp, r0
|
|
||||||
isb
|
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
#if WORKAROUND_PMU_CM001 == 1
|
||||||
push { r14 }
|
" push { r14 } \n"
|
||||||
pop { pc }
|
" pop { pc } \n"
|
||||||
nop
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
" \n"
|
||||||
bx r14
|
" bx r14 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 4 \n"
|
||||||
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -503,9 +490,8 @@ void xPortSysTickHandler( void )
|
|||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
executes all interrupts must be unmasked. There is therefore no need to
|
||||||
save and then restore the interrupt mask value as its value is already
|
save and then restore the interrupt mask value as its value is already
|
||||||
known - therefore the slightly faster vPortRaiseBASEPRI() function is used
|
known. */
|
||||||
in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
|
portDISABLE_INTERRUPTS();
|
||||||
vPortRaiseBASEPRI();
|
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
@ -515,13 +501,13 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vPortClearBASEPRIFromISR();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
@ -549,9 +535,9 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
method as that will mask interrupts that should exit sleep mode. */
|
||||||
__disable_irq();
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
__asm volatile( "dsb" );
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
to be unsuspended then abandon the low power entry. */
|
||||||
@ -568,9 +554,9 @@ void xPortSysTickHandler( void )
|
|||||||
periods. */
|
periods. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__enable_irq();
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -593,26 +579,26 @@ void xPortSysTickHandler( void )
|
|||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
__asm volatile( "dsb" ::: "memory" );
|
||||||
__wfi();
|
__asm volatile( "wfi" );
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
__asm volatile( "isb" );
|
||||||
}
|
}
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
out of sleep mode to execute immediately. see comments above
|
out of sleep mode to execute immediately. see comments above
|
||||||
__disable_interrupt() call above. */
|
__disable_interrupt() call above. */
|
||||||
__enable_irq();
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
__asm volatile( "dsb" );
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
and interrupts that execute while the clock is stopped will increase
|
and interrupts that execute while the clock is stopped will increase
|
||||||
any slippage between the time maintained by the RTOS and calendar
|
any slippage between the time maintained by the RTOS and calendar
|
||||||
time. */
|
time. */
|
||||||
__disable_irq();
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
__asm volatile( "dsb" );
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
@ -679,49 +665,50 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__enable_irq();
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
#endif /* #if configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the SysTick timer to generate the tick interrupts at the required
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
* frequency.
|
* frequency.
|
||||||
*/
|
*/
|
||||||
#if( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 )
|
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
__weak void vPortSetupTimerInterrupt( void )
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
{
|
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
|
||||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
|
||||||
}
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/* Stop and clear the SysTick. */
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
|
||||||
}
|
}
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
/* Stop and clear the SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm uint32_t vPortGetIPSR( void )
|
/* This is a naked function. */
|
||||||
|
static void vPortEnableVFP( void )
|
||||||
{
|
{
|
||||||
PRESERVE8
|
__asm volatile
|
||||||
|
(
|
||||||
mrs r0, ipsr
|
" ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */
|
||||||
bx r14
|
" ldr r1, [r0] \n"
|
||||||
|
" \n"
|
||||||
|
" orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */
|
||||||
|
" str r1, [r0] \n"
|
||||||
|
" bx r14 "
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -733,7 +720,7 @@ __asm uint32_t vPortGetIPSR( void )
|
|||||||
uint8_t ucCurrentPriority;
|
uint8_t ucCurrentPriority;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
ulCurrentInterrupt = vPortGetIPSR();
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
/* Is the interrupt number a user defined interrupt? */
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||||
@ -73,24 +73,19 @@ typedef unsigned long UBaseType_t;
|
|||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/* Constants used with memory barrier intrinsics. */
|
|
||||||
#define portSY_FULL_READ_WRITE ( 15 )
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
\
|
\
|
||||||
/* Barriers are normally not required but do ensure the code is completely \
|
/* Barriers are normally not required but do ensure the code is completely \
|
||||||
within the specified behaviour for the architecture. */ \
|
within the specified behaviour for the architecture. */ \
|
||||||
__dsb( portSY_FULL_READ_WRITE ); \
|
__asm volatile( "dsb" ::: "memory" ); \
|
||||||
__isb( portSY_FULL_READ_WRITE ); \
|
__asm volatile( "isb" ); \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
@ -101,16 +96,22 @@ typedef unsigned long UBaseType_t;
|
|||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
|
not necessary for to use this port. They are defined so the common demo files
|
||||||
|
(which build with all the ports) will build. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
@ -118,13 +119,22 @@ extern void vPortExitCritical( void );
|
|||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Port specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Generic helper function. */
|
||||||
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint8_t ucReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
return ucReturn;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
@ -136,16 +146,10 @@ extern void vPortExitCritical( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* taskRECORD_READY_PRIORITY */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
|
||||||
not necessary for to use this port. They are defined so the common demo files
|
|
||||||
(which build with all the ports) will build. */
|
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
@ -156,80 +160,19 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE __forceinline
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||||
|
|
||||||
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
/* Barrier instructions are not used as this function is only used to
|
|
||||||
lower the BASEPRI value. */
|
|
||||||
msr basepri, ulBASEPRI
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static portFORCE_INLINE void vPortRaiseBASEPRI( void )
|
|
||||||
{
|
|
||||||
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
/* Set BASEPRI to the max syscall priority to effect a critical
|
|
||||||
section. */
|
|
||||||
msr basepri, ulNewBASEPRI
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static portFORCE_INLINE void vPortClearBASEPRIFromISR( void )
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
/* Set BASEPRI to 0 so no interrupts are masked. This function is only
|
|
||||||
used to lower the mask in an interrupt, so memory barriers are not
|
|
||||||
used. */
|
|
||||||
msr basepri, #0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
|
|
||||||
{
|
|
||||||
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
/* Set BASEPRI to the max syscall priority to effect a critical
|
|
||||||
section. */
|
|
||||||
mrs ulReturn, basepri
|
|
||||||
msr basepri, ulNewBASEPRI
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
}
|
|
||||||
|
|
||||||
return ulReturn;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void )
|
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
__asm
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
{
|
|
||||||
mrs ulCurrentInterrupt, ipsr
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ulCurrentInterrupt == 0 )
|
if( ulCurrentInterrupt == 0 )
|
||||||
{
|
{
|
||||||
@ -243,6 +186,54 @@ BaseType_t xReturn;
|
|||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mov %0, %1 \n" \
|
||||||
|
" msr basepri, %0 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n" \
|
||||||
|
" mov %1, %2 \n" \
|
||||||
|
" msr basepri, %1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -1,234 +0,0 @@
|
|||||||
#include "bsp_can.h"
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "bsp/bsp.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
typedef struct {
|
|
||||||
FDCAN_RxHeaderTypeDef header;
|
|
||||||
uint8_t data[64];
|
|
||||||
} can_raw_rx_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FDCAN_HandleTypeDef header;
|
|
||||||
uint8_t data[8];
|
|
||||||
} can_raw_tx_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void (*fn)(bsp_can_t can, uint32_t id, uint8_t *data, void *arg);
|
|
||||||
void *arg;
|
|
||||||
} can_callback_t;
|
|
||||||
|
|
||||||
extern FDCAN_HandleTypeDef hfdcan1;
|
|
||||||
extern FDCAN_HandleTypeDef hfdcan2;
|
|
||||||
|
|
||||||
static can_callback_t callback_list[BSP_CAN_NUM][BSP_CAN_CB_NUM];
|
|
||||||
|
|
||||||
static bool bsp_can_initd = false;
|
|
||||||
|
|
||||||
static can_raw_rx_t rx_buff[BSP_CAN_NUM];
|
|
||||||
|
|
||||||
FDCAN_HandleTypeDef *bsp_can_get_handle(bsp_can_t can) {
|
|
||||||
switch (can) {
|
|
||||||
case BSP_CAN_1:
|
|
||||||
return &hfdcan1;
|
|
||||||
case BSP_CAN_2:
|
|
||||||
return &hfdcan2;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bsp_can_t can_get(FDCAN_HandleTypeDef *hcan) {
|
|
||||||
if (hcan->Instance == FDCAN1) {
|
|
||||||
return BSP_CAN_1;
|
|
||||||
} else if (hcan->Instance == FDCAN2) {
|
|
||||||
return BSP_CAN_2;
|
|
||||||
} else {
|
|
||||||
return BSP_CAN_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bsp_can_init(void) {
|
|
||||||
FDCAN_FilterTypeDef can_filter = {0};
|
|
||||||
|
|
||||||
can_filter.IdType = FDCAN_STANDARD_ID;
|
|
||||||
can_filter.FilterIndex = 0;
|
|
||||||
can_filter.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
|
|
||||||
can_filter.FilterID1 = 0x0000;
|
|
||||||
can_filter.FilterID2 = 0x0000;
|
|
||||||
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &can_filter) != HAL_OK) {
|
|
||||||
// XB_ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
can_filter.IdType = FDCAN_EXTENDED_ID;
|
|
||||||
can_filter.FilterIndex = 1;
|
|
||||||
can_filter.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
|
|
||||||
can_filter.FilterID1 = 0x0000;
|
|
||||||
can_filter.FilterID2 = 0x0000;
|
|
||||||
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &can_filter) != HAL_OK) {
|
|
||||||
// XB_ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
can_filter.IdType = FDCAN_STANDARD_ID;
|
|
||||||
can_filter.FilterIndex = 2;
|
|
||||||
can_filter.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
|
||||||
can_filter.FilterID1 = 0x0000;
|
|
||||||
can_filter.FilterID2 = 0x0000;
|
|
||||||
if (HAL_FDCAN_ConfigFilter(&hfdcan2, &can_filter) != HAL_OK) {
|
|
||||||
// XB_ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
can_filter.IdType = FDCAN_EXTENDED_ID;
|
|
||||||
can_filter.FilterIndex = 3;
|
|
||||||
can_filter.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
|
||||||
can_filter.FilterID1 = 0x0000;
|
|
||||||
can_filter.FilterID2 = 0x0000;
|
|
||||||
if (HAL_FDCAN_ConfigFilter(&hfdcan2, &can_filter) != HAL_OK) {
|
|
||||||
// XB_ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
HAL_FDCAN_Start(&hfdcan1); //开启FDCAN
|
|
||||||
HAL_FDCAN_Start(&hfdcan2); //开启FDCAN
|
|
||||||
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
|
|
||||||
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY, 0);
|
|
||||||
HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
|
|
||||||
HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_FIFO_EMPTY, 0);
|
|
||||||
|
|
||||||
bsp_can_initd = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7,
|
|
||||||
8, 12, 16, 20, 24, 32, 48, 64};
|
|
||||||
|
|
||||||
static void can_rx_cb_fn(bsp_can_t can, uint32_t fifo) {
|
|
||||||
while (HAL_FDCAN_GetRxMessage(bsp_can_get_handle(can), fifo,
|
|
||||||
&rx_buff[can].header,
|
|
||||||
rx_buff[can].data) == HAL_OK) {
|
|
||||||
if (rx_buff[can].header.FDFormat == FDCAN_CLASSIC_CAN) {
|
|
||||||
if (callback_list[can][CAN_RX_MSG_CALLBACK].fn) {
|
|
||||||
callback_list[can][CAN_RX_MSG_CALLBACK].fn(
|
|
||||||
can, rx_buff[can].header.Identifier, rx_buff[can].data,
|
|
||||||
callback_list[can][CAN_RX_MSG_CALLBACK].arg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (callback_list[can][CANFD_RX_MSG_CALLBACK].fn) {
|
|
||||||
bsp_canfd_data_t data = {
|
|
||||||
.data = rx_buff[can].data,
|
|
||||||
.size = DLCtoBytes[rx_buff[can].header.DataLength >> 16U]};
|
|
||||||
|
|
||||||
callback_list[can][CANFD_RX_MSG_CALLBACK].fn(
|
|
||||||
can, rx_buff[can].header.Identifier, (uint8_t *)&data,
|
|
||||||
callback_list[can][CANFD_RX_MSG_CALLBACK].arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hcan, uint32_t RxFifo0ITs) {
|
|
||||||
// (void)RxFifo0ITs;
|
|
||||||
// can_rx_cb_fn(can_get(hcan), FDCAN_RX_FIFO0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hcan, uint32_t RxFifo1ITs) {
|
|
||||||
// (void)RxFifo1ITs;
|
|
||||||
// can_rx_cb_fn(can_get(hcan), FDCAN_RX_FIFO1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
int8_t bsp_can_register_callback(
|
|
||||||
bsp_can_t can, bsp_can_callback_t type,
|
|
||||||
void (*callback)(bsp_can_t can, uint32_t id, uint8_t *data, void *arg),
|
|
||||||
void *callback_arg) {
|
|
||||||
assert_param(callback);
|
|
||||||
assert_param(type != BSP_CAN_CB_NUM);
|
|
||||||
|
|
||||||
callback_list[can][type].fn = callback;
|
|
||||||
callback_list[can][type].arg = callback_arg;
|
|
||||||
return BSP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t bsp_can_trans_packet(bsp_can_t can, bsp_can_format_t format,
|
|
||||||
uint32_t id, uint8_t *data) {
|
|
||||||
FDCAN_TxHeaderTypeDef header;
|
|
||||||
|
|
||||||
header.Identifier = id;
|
|
||||||
|
|
||||||
if (format == CAN_FORMAT_STD) {
|
|
||||||
header.IdType = FDCAN_STANDARD_ID;
|
|
||||||
} else {
|
|
||||||
header.IdType = FDCAN_EXTENDED_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.TxFrameType = FDCAN_DATA_FRAME;
|
|
||||||
header.DataLength = FDCAN_DLC_BYTES_8;
|
|
||||||
header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
|
||||||
header.BitRateSwitch = FDCAN_BRS_OFF;
|
|
||||||
header.FDFormat = FDCAN_CLASSIC_CAN;
|
|
||||||
header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
|
|
||||||
header.MessageMarker = 0x01;
|
|
||||||
while ((bsp_can_get_handle(can)->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U) {
|
|
||||||
__NOP();
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_FDCAN_AddMessageToTxFifoQ(bsp_can_get_handle(can), &header,
|
|
||||||
data) == HAL_OK
|
|
||||||
? BSP_OK
|
|
||||||
: BSP_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint32_t FDCAN_PACK_LEN_MAP[16] = {
|
|
||||||
FDCAN_DLC_BYTES_0, FDCAN_DLC_BYTES_1, FDCAN_DLC_BYTES_2,
|
|
||||||
FDCAN_DLC_BYTES_3, FDCAN_DLC_BYTES_4, FDCAN_DLC_BYTES_5,
|
|
||||||
FDCAN_DLC_BYTES_6, FDCAN_DLC_BYTES_7, FDCAN_DLC_BYTES_8,
|
|
||||||
FDCAN_DLC_BYTES_12, FDCAN_DLC_BYTES_16, FDCAN_DLC_BYTES_20,
|
|
||||||
FDCAN_DLC_BYTES_24, FDCAN_DLC_BYTES_32, FDCAN_DLC_BYTES_48,
|
|
||||||
FDCAN_DLC_BYTES_64,
|
|
||||||
};
|
|
||||||
|
|
||||||
int8_t bsp_canfd_trans_packet(bsp_can_t can, bsp_can_format_t format,
|
|
||||||
uint32_t id, uint8_t *data, size_t size) {
|
|
||||||
FDCAN_TxHeaderTypeDef header;
|
|
||||||
|
|
||||||
// XB_ASSERT(size <= 64);
|
|
||||||
|
|
||||||
header.Identifier = id;
|
|
||||||
|
|
||||||
if (format == CAN_FORMAT_STD) {
|
|
||||||
header.IdType = FDCAN_STANDARD_ID;
|
|
||||||
} else {
|
|
||||||
header.IdType = FDCAN_EXTENDED_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.TxFrameType = FDCAN_DATA_FRAME;
|
|
||||||
|
|
||||||
if (size <= 8) {
|
|
||||||
header.DataLength = FDCAN_PACK_LEN_MAP[size];
|
|
||||||
} else if (size <= 24) {
|
|
||||||
header.DataLength = FDCAN_PACK_LEN_MAP[(size - 9) / 4 + 1 + 8];
|
|
||||||
} else if (size < 32) {
|
|
||||||
header.DataLength = FDCAN_DLC_BYTES_32;
|
|
||||||
} else if (size < 48) {
|
|
||||||
header.DataLength = FDCAN_DLC_BYTES_48;
|
|
||||||
} else {
|
|
||||||
header.DataLength = FDCAN_DLC_BYTES_64;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
|
||||||
header.BitRateSwitch = FDCAN_BRS_OFF;
|
|
||||||
header.FDFormat = FDCAN_FD_CAN;
|
|
||||||
header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
|
|
||||||
header.MessageMarker = 0x01;
|
|
||||||
while ((bsp_can_get_handle(can)->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U) {
|
|
||||||
__NOP();
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_FDCAN_AddMessageToTxFifoQ(bsp_can_get_handle(can), &header,
|
|
||||||
data) == HAL_OK
|
|
||||||
? BSP_OK
|
|
||||||
: BSP_ERR;
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "bsp.h"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BSP_CAN_1,
|
|
||||||
BSP_CAN_2,
|
|
||||||
BSP_CAN_NUM,
|
|
||||||
BSP_CAN_ERR,
|
|
||||||
} bsp_can_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CAN_RX_MSG_CALLBACK,
|
|
||||||
CAN_TX_CPLT_CALLBACK,
|
|
||||||
CANFD_RX_MSG_CALLBACK,
|
|
||||||
CANFD_TX_CPLT_CALLBACK,
|
|
||||||
BSP_CAN_CB_NUM
|
|
||||||
} bsp_can_callback_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CAN_FORMAT_STD,
|
|
||||||
CAN_FORMAT_EXT,
|
|
||||||
} bsp_can_format_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t data[8];
|
|
||||||
} bsp_can_data_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t size;
|
|
||||||
uint8_t *data;
|
|
||||||
} bsp_canfd_data_t;
|
|
||||||
|
|
||||||
void bsp_can_init(void);
|
|
||||||
int8_t bsp_can_register_callback(
|
|
||||||
bsp_can_t can, bsp_can_callback_t type,
|
|
||||||
void (*callback)(bsp_can_t can, uint32_t id, uint8_t *data, void *arg),
|
|
||||||
void *callback_arg);
|
|
||||||
int8_t bsp_can_trans_packet(bsp_can_t can, bsp_can_format_t format,
|
|
||||||
uint32_t id, uint8_t *data);
|
|
||||||
|
|
||||||
int8_t bsp_canfd_trans_packet(bsp_can_t can, bsp_can_format_t format,
|
|
||||||
uint32_t id, uint8_t *data, size_t size);
|
|
||||||
|
|
||||||
int8_t bsp_can_get_msg(bsp_can_t can, uint8_t *data, uint32_t *index);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
116
User/bsp/fdcan.c
116
User/bsp/fdcan.c
@ -2,7 +2,6 @@
|
|||||||
#include "fdcan.h"
|
#include "fdcan.h"
|
||||||
#include "bsp/fdcan.h"
|
#include "bsp/fdcan.h"
|
||||||
#include "bsp/bsp.h"
|
#include "bsp/bsp.h"
|
||||||
#include "stm32h7xx_hal_gpio.h"
|
|
||||||
#include <fdcan.h>
|
#include <fdcan.h>
|
||||||
#include <cmsis_os2.h>
|
#include <cmsis_os2.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -38,7 +37,7 @@ static osMessageQueueId_t BSP_FDCAN_FindQueue(BSP_FDCAN_t fdcan, uint32_t can_id
|
|||||||
static int8_t BSP_FDCAN_CreateIdQueue(BSP_FDCAN_t fdcan, uint32_t can_id, uint8_t queue_size);
|
static int8_t BSP_FDCAN_CreateIdQueue(BSP_FDCAN_t fdcan, uint32_t can_id, uint8_t queue_size);
|
||||||
static void BSP_FDCAN_RxFifo0Callback(void);
|
static void BSP_FDCAN_RxFifo0Callback(void);
|
||||||
static void BSP_FDCAN_RxFifo1Callback(void);
|
static void BSP_FDCAN_RxFifo1Callback(void);
|
||||||
static void BSP_FDCAN_TxCompleteCallback(void);
|
// static void BSP_FDCAN_TxCompleteCallback(void);
|
||||||
static BSP_FDCAN_FrameType_t BSP_FDCAN_GetFrameType(FDCAN_RxHeaderTypeDef *header);
|
static BSP_FDCAN_FrameType_t BSP_FDCAN_GetFrameType(FDCAN_RxHeaderTypeDef *header);
|
||||||
static uint32_t BSP_FDCAN_DefaultIdParser(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
|
static uint32_t BSP_FDCAN_DefaultIdParser(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
|
||||||
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan);
|
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan);
|
||||||
@ -102,6 +101,17 @@ static uint32_t BSP_FDCAN_DefaultIdParser(uint32_t original_id, BSP_FDCAN_FrameT
|
|||||||
return original_id;
|
return original_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t BSP_FDCAN_EncodeDLC(uint8_t dlc) {
|
||||||
|
if (dlc <= 8) return dlc;
|
||||||
|
if (dlc <= 12) return FDCAN_DLC_BYTES_12;
|
||||||
|
if (dlc <= 16) return FDCAN_DLC_BYTES_16;
|
||||||
|
if (dlc <= 20) return FDCAN_DLC_BYTES_20;
|
||||||
|
if (dlc <= 24) return FDCAN_DLC_BYTES_24;
|
||||||
|
if (dlc <= 32) return FDCAN_DLC_BYTES_32;
|
||||||
|
if (dlc <= 48) return FDCAN_DLC_BYTES_48;
|
||||||
|
return FDCAN_DLC_BYTES_64;
|
||||||
|
}
|
||||||
|
|
||||||
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan) {
|
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan) {
|
||||||
if (fdcan >= BSP_FDCAN_NUM) return;
|
if (fdcan >= BSP_FDCAN_NUM) return;
|
||||||
tx_queues[fdcan].head = 0;
|
tx_queues[fdcan].head = 0;
|
||||||
@ -131,8 +141,8 @@ static bool BSP_FDCAN_TxQueueIsEmpty(BSP_FDCAN_t fdcan) {
|
|||||||
if (fdcan >= BSP_FDCAN_NUM) return true;
|
if (fdcan >= BSP_FDCAN_NUM) return true;
|
||||||
return tx_queues[fdcan].head == tx_queues[fdcan].tail;
|
return tx_queues[fdcan].head == tx_queues[fdcan].tail;
|
||||||
}
|
}
|
||||||
void BSP_FDCAN_TxCompleteCallback(void) {
|
|
||||||
//static void BSP_FDCAN_TxCompleteCallback(void) {
|
static void BSP_FDCAN_TxCompleteCallback(void) {
|
||||||
for (int i = 0; i < BSP_FDCAN_NUM; i++) {
|
for (int i = 0; i < BSP_FDCAN_NUM; i++) {
|
||||||
BSP_FDCAN_t fdcan = (BSP_FDCAN_t)i;
|
BSP_FDCAN_t fdcan = (BSP_FDCAN_t)i;
|
||||||
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle(fdcan);
|
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle(fdcan);
|
||||||
@ -154,6 +164,7 @@ static bool BSP_FDCAN_TxQueueIsEmpty(BSP_FDCAN_t fdcan) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static const uint8_t fdcan_dlc2len[16] = {0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64};
|
||||||
|
|
||||||
static void BSP_FDCAN_RxFifo0Callback(void) {
|
static void BSP_FDCAN_RxFifo0Callback(void) {
|
||||||
FDCAN_RxHeaderTypeDef rx_header;
|
FDCAN_RxHeaderTypeDef rx_header;
|
||||||
@ -172,8 +183,10 @@ static void BSP_FDCAN_RxFifo0Callback(void) {
|
|||||||
msg.frame_type = frame_type;
|
msg.frame_type = frame_type;
|
||||||
msg.original_id = original_id;
|
msg.original_id = original_id;
|
||||||
msg.parsed_id = parsed_id;
|
msg.parsed_id = parsed_id;
|
||||||
msg.dlc = rx_header.DataLength;
|
uint8_t real_len = fdcan_dlc2len[rx_header.DataLength & 0xF];
|
||||||
|
msg.dlc = real_len;
|
||||||
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
|
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
|
||||||
|
memset(msg.data, 0, BSP_FDCAN_MAX_DLC);//现在是最大缓冲区写法所以全清零
|
||||||
memcpy(msg.data, rx_data, msg.dlc);
|
memcpy(msg.data, rx_data, msg.dlc);
|
||||||
osMessageQueuePut(queue, &msg, 0, 0);
|
osMessageQueuePut(queue, &msg, 0, 0);
|
||||||
}
|
}
|
||||||
@ -187,6 +200,7 @@ static void BSP_FDCAN_RxFifo0Callback(void) {
|
|||||||
static void BSP_FDCAN_RxFifo1Callback(void) {
|
static void BSP_FDCAN_RxFifo1Callback(void) {
|
||||||
FDCAN_RxHeaderTypeDef rx_header;
|
FDCAN_RxHeaderTypeDef rx_header;
|
||||||
uint8_t rx_data[BSP_FDCAN_MAX_DLC];
|
uint8_t rx_data[BSP_FDCAN_MAX_DLC];
|
||||||
|
static const uint8_t fdcan_dlc2len[16] = {0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64};
|
||||||
for (int fdcan_idx = 0; fdcan_idx < BSP_FDCAN_NUM; fdcan_idx++) {
|
for (int fdcan_idx = 0; fdcan_idx < BSP_FDCAN_NUM; fdcan_idx++) {
|
||||||
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle((BSP_FDCAN_t)fdcan_idx);
|
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle((BSP_FDCAN_t)fdcan_idx);
|
||||||
if (hfdcan == NULL) continue;
|
if (hfdcan == NULL) continue;
|
||||||
@ -201,8 +215,10 @@ static void BSP_FDCAN_RxFifo1Callback(void) {
|
|||||||
msg.frame_type = frame_type;
|
msg.frame_type = frame_type;
|
||||||
msg.original_id = original_id;
|
msg.original_id = original_id;
|
||||||
msg.parsed_id = parsed_id;
|
msg.parsed_id = parsed_id;
|
||||||
msg.dlc = rx_header.DataLength;
|
uint8_t real_len = fdcan_dlc2len[rx_header.DataLength & 0xF];
|
||||||
|
msg.dlc = real_len;
|
||||||
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
|
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
|
||||||
|
memset(msg.data, 0, BSP_FDCAN_MAX_DLC);//现在是最大缓冲区写法所以全清零
|
||||||
memcpy(msg.data, rx_data, msg.dlc);
|
memcpy(msg.data, rx_data, msg.dlc);
|
||||||
osMessageQueuePut(queue, &msg, 0, 0);
|
osMessageQueuePut(queue, &msg, 0, 0);
|
||||||
}
|
}
|
||||||
@ -330,19 +346,9 @@ int8_t BSP_FDCAN_Init(void) {
|
|||||||
sFilterConfig.RxBufferIndex = 0;
|
sFilterConfig.RxBufferIndex = 0;
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);
|
HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
|
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
|
||||||
|
|
||||||
sFilterConfig.FilterIndex = 1;
|
|
||||||
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
|
||||||
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
|
|
||||||
sFilterConfig.FilterID1 = 0x000;
|
|
||||||
sFilterConfig.FilterID2 = 0x000;
|
|
||||||
sFilterConfig.RxBufferIndex = 0;
|
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);
|
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
|
|
||||||
/* 配置 FDCAN2 过滤器 */
|
/* 配置 FDCAN2 过滤器 */
|
||||||
/* 索引0;标准ID;掩码模式;存入 FIFO 1(普通优先级);不过滤; */
|
/* 索引0;标准ID;掩码模式;存入 FIFO 1(普通优先级);不过滤; */
|
||||||
sFilterConfig.FilterIndex = 2;
|
sFilterConfig.FilterIndex = 0;
|
||||||
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
||||||
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
||||||
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
||||||
@ -350,20 +356,10 @@ int8_t BSP_FDCAN_Init(void) {
|
|||||||
sFilterConfig.FilterID2 = 0x000;
|
sFilterConfig.FilterID2 = 0x000;
|
||||||
sFilterConfig.RxBufferIndex = 0;
|
sFilterConfig.RxBufferIndex = 0;
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig);
|
HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig);
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,FDCAN_REJECT, FDCAN_REJECT, DISABLE, DISABLE);
|
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
|
||||||
|
|
||||||
sFilterConfig.FilterIndex = 3;
|
|
||||||
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
|
||||||
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
|
||||||
sFilterConfig.FilterID1 = 0x000;
|
|
||||||
sFilterConfig.FilterID2 = 0x000;
|
|
||||||
sFilterConfig.RxBufferIndex = 0;
|
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig);
|
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,FDCAN_REJECT, FDCAN_REJECT, DISABLE, DISABLE);
|
|
||||||
/* 配置 FDCAN3 过滤器 */
|
/* 配置 FDCAN3 过滤器 */
|
||||||
/* 索引0;标准ID;掩码模式;存入 FIFO 1(普通优先级);不过滤; */
|
/* 索引0;标准ID;掩码模式;存入 FIFO 1(普通优先级);不过滤; */
|
||||||
sFilterConfig.FilterIndex = 4;
|
sFilterConfig.FilterIndex = 0;
|
||||||
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
||||||
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
||||||
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
||||||
@ -371,25 +367,8 @@ int8_t BSP_FDCAN_Init(void) {
|
|||||||
sFilterConfig.FilterID2 = 0x000;
|
sFilterConfig.FilterID2 = 0x000;
|
||||||
sFilterConfig.RxBufferIndex = 0;
|
sFilterConfig.RxBufferIndex = 0;
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan3, &sFilterConfig);
|
HAL_FDCAN_ConfigFilter(&hfdcan3, &sFilterConfig);
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan3,FDCAN_REJECT, FDCAN_REJECT, DISABLE, DISABLE);
|
HAL_FDCAN_ConfigGlobalFilter(&hfdcan3,FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
|
||||||
|
|
||||||
sFilterConfig.FilterIndex = 5;
|
|
||||||
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
|
||||||
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
|
|
||||||
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
|
||||||
sFilterConfig.FilterID1 = 0x000;
|
|
||||||
sFilterConfig.FilterID2 = 0x000;
|
|
||||||
sFilterConfig.RxBufferIndex = 0;
|
|
||||||
HAL_FDCAN_ConfigFilter(&hfdcan3, &sFilterConfig);
|
|
||||||
HAL_FDCAN_ConfigGlobalFilter(&hfdcan3,FDCAN_REJECT, FDCAN_REJECT, DISABLE, DISABLE);
|
|
||||||
|
|
||||||
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY, 0);
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_FIFO_EMPTY, 0);
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan3, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
|
|
||||||
// HAL_FDCAN_ActivateNotification(&hfdcan3, FDCAN_IT_TX_FIFO_EMPTY, 0);
|
|
||||||
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE
|
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE
|
||||||
| FDCAN_IT_TX_EVT_FIFO_NEW_DATA
|
| FDCAN_IT_TX_EVT_FIFO_NEW_DATA
|
||||||
| FDCAN_IT_RAM_ACCESS_FAILURE, 0);//加一个RAM访问失败中断
|
| FDCAN_IT_RAM_ACCESS_FAILURE, 0);//加一个RAM访问失败中断
|
||||||
@ -400,11 +379,6 @@ int8_t BSP_FDCAN_Init(void) {
|
|||||||
| FDCAN_IT_TX_EVT_FIFO_NEW_DATA
|
| FDCAN_IT_TX_EVT_FIFO_NEW_DATA
|
||||||
| FDCAN_IT_RAM_ACCESS_FAILURE, 0);
|
| FDCAN_IT_RAM_ACCESS_FAILURE, 0);
|
||||||
|
|
||||||
/* __ ,启动! */
|
|
||||||
HAL_FDCAN_Start(&hfdcan1);
|
|
||||||
HAL_FDCAN_Start(&hfdcan2);
|
|
||||||
HAL_FDCAN_Start(&hfdcan3);
|
|
||||||
|
|
||||||
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, HAL_FDCAN_RX_FIFO0_MSG_PENDING_CB, BSP_FDCAN_RxFifo0Callback);
|
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, HAL_FDCAN_RX_FIFO0_MSG_PENDING_CB, BSP_FDCAN_RxFifo0Callback);
|
||||||
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
|
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
|
||||||
|
|
||||||
@ -414,11 +388,11 @@ int8_t BSP_FDCAN_Init(void) {
|
|||||||
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, HAL_FDCAN_RX_FIFO1_MSG_PENDING_CB, BSP_FDCAN_RxFifo1Callback);
|
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, HAL_FDCAN_RX_FIFO1_MSG_PENDING_CB, BSP_FDCAN_RxFifo1Callback);
|
||||||
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
|
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
|
||||||
|
|
||||||
|
/* __ ,启动! */
|
||||||
|
HAL_FDCAN_Start(&hfdcan1);
|
||||||
|
HAL_FDCAN_Start(&hfdcan2);
|
||||||
|
HAL_FDCAN_Start(&hfdcan3);
|
||||||
|
|
||||||
//POWER ENABLE
|
|
||||||
// HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
|
|
||||||
|
|
||||||
return BSP_OK;
|
return BSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,24 +449,22 @@ int8_t BSP_FDCAN_Transmit(BSP_FDCAN_t fdcan, BSP_FDCAN_Format_t format, uint32_t
|
|||||||
return BSP_ERR;
|
return BSP_ERR;
|
||||||
}
|
}
|
||||||
tx_msg.header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
tx_msg.header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
|
||||||
tx_msg.header.BitRateSwitch = FDCAN_BRS_OFF;
|
|
||||||
tx_msg.header.FDFormat = FDCAN_CLASSIC_CAN;
|
// tx_msg.header.BitRateSwitch = FDCAN_BRS_OFF;
|
||||||
|
// tx_msg.header.FDFormat = FDCAN_CLASSIC_CAN;
|
||||||
|
// tx_msg.header.BitRateSwitch = FDCAN_BRS_ON;
|
||||||
|
// tx_msg.header.FDFormat = FDCAN_FD_CAN;
|
||||||
|
tx_msg.header.BitRateSwitch = FDCAN_BRS_OFF;
|
||||||
|
tx_msg.header.FDFormat = FDCAN_FD_CAN;
|
||||||
|
|
||||||
tx_msg.header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
|
tx_msg.header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
|
||||||
tx_msg.header.MessageMarker = 0x01;
|
tx_msg.header.MessageMarker = 0x01;
|
||||||
// tx_msg.header.DataLength = FDCAN_DLC_BYTES_64;
|
tx_msg.header.DataLength = BSP_FDCAN_EncodeDLC(dlc);
|
||||||
if (dlc <= 8) {
|
|
||||||
tx_msg.header.DataLength = FDCAN_DLC_BYTES_8;
|
memset(tx_msg.data, 0, dlc);
|
||||||
} else if (dlc <= 24) {
|
if (data != NULL && dlc > 0) {
|
||||||
tx_msg.header.DataLength = FDCAN_DLC_BYTES_24;
|
memcpy(tx_msg.data, data, dlc);}
|
||||||
} else if (dlc < 32) {
|
|
||||||
tx_msg.header.DataLength = FDCAN_DLC_BYTES_32;
|
|
||||||
} else if (dlc < 48) {
|
|
||||||
tx_msg.header.DataLength = FDCAN_DLC_BYTES_48;
|
|
||||||
} else {
|
|
||||||
tx_msg.header.DataLength = FDCAN_DLC_BYTES_64;
|
|
||||||
}
|
|
||||||
if (data != NULL && dlc > 0)
|
|
||||||
memcpy(tx_msg.data, data, dlc);
|
|
||||||
fifolevel=HAL_FDCAN_GetTxFifoFreeLevel(hfdcan);
|
fifolevel=HAL_FDCAN_GetTxFifoFreeLevel(hfdcan);
|
||||||
if (HAL_FDCAN_GetTxFifoFreeLevel(hfdcan) > 0) {
|
if (HAL_FDCAN_GetTxFifoFreeLevel(hfdcan) > 0) {
|
||||||
if (HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &tx_msg.header, tx_msg.data) == HAL_OK) return BSP_OK;
|
if (HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &tx_msg.header, tx_msg.data) == HAL_OK) return BSP_OK;
|
||||||
|
|||||||
@ -111,9 +111,6 @@ int32_t BSP_FDCAN_GetQueueCount(BSP_FDCAN_t can, uint32_t can_id);
|
|||||||
int8_t BSP_FDCAN_FlushQueue(BSP_FDCAN_t can, uint32_t can_id);
|
int8_t BSP_FDCAN_FlushQueue(BSP_FDCAN_t can, uint32_t can_id);
|
||||||
int8_t BSP_FDCAN_RegisterIdParser(BSP_FDCAN_IdParser_t parser);
|
int8_t BSP_FDCAN_RegisterIdParser(BSP_FDCAN_IdParser_t parser);
|
||||||
uint32_t BSP_FDCAN_ParseId(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
|
uint32_t BSP_FDCAN_ParseId(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
|
||||||
|
|
||||||
|
|
||||||
void BSP_FDCAN_TxCompleteCallback(void);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
#include "bsp/bsp.h"
|
#include "bsp/bsp.h"
|
||||||
#include "bsp/fdcan.h"
|
#include "bsp/fdcan.h"
|
||||||
// #include "bsp/pwm.h"
|
// #include "bsp/pwm.h"
|
||||||
#include "bsp/bsp_can.h"
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
/* USER INCLUDE END */
|
/* USER INCLUDE END */
|
||||||
|
|
||||||
@ -19,13 +18,13 @@
|
|||||||
/* Private macro ------------------------------------------------------------ */
|
/* Private macro ------------------------------------------------------------ */
|
||||||
/* Private variables -------------------------------------------------------- */
|
/* Private variables -------------------------------------------------------- */
|
||||||
/* USER STRUCT BEGIN */
|
/* USER STRUCT BEGIN */
|
||||||
BSP_FDCAN_Message_t msg;
|
BSP_FDCAN_Message_t msg1={0};
|
||||||
|
BSP_FDCAN_Message_t msg2={0};
|
||||||
|
BSP_FDCAN_Message_t msg3={0};
|
||||||
/* USER STRUCT END */
|
/* USER STRUCT END */
|
||||||
|
float rxlevel=0;
|
||||||
/* Private function --------------------------------------------------------- */
|
/* Private function --------------------------------------------------------- */
|
||||||
void can_rx_callback(bsp_can_t can, uint32_t id, uint8_t *data, void *arg) {
|
|
||||||
// 这里可以打印、断点或设置标志位
|
|
||||||
}
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
/* Exported functions ------------------------------------------------------- */
|
||||||
void Task_blink(void *argument) {
|
void Task_blink(void *argument) {
|
||||||
(void)argument; /* 未使用argument,消除警告 */
|
(void)argument; /* 未使用argument,消除警告 */
|
||||||
@ -44,7 +43,7 @@ void Task_blink(void *argument) {
|
|||||||
// BSP_PWM_Start(BSP_PWM_LED_G);
|
// BSP_PWM_Start(BSP_PWM_LED_G);
|
||||||
|
|
||||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
|
||||||
|
|
||||||
BSP_FDCAN_Init();
|
BSP_FDCAN_Init();
|
||||||
@ -53,10 +52,6 @@ void Task_blink(void *argument) {
|
|||||||
BSP_FDCAN_RegisterId(BSP_FDCAN_2, 0x102, 8);
|
BSP_FDCAN_RegisterId(BSP_FDCAN_2, 0x102, 8);
|
||||||
BSP_FDCAN_RegisterId(BSP_FDCAN_3, 0x103, 8);
|
BSP_FDCAN_RegisterId(BSP_FDCAN_3, 0x103, 8);
|
||||||
|
|
||||||
// bsp_can_init();
|
|
||||||
|
|
||||||
// bsp_can_register_callback(BSP_CAN_1, CAN_RX_MSG_CALLBACK, can_rx_callback, NULL);
|
|
||||||
|
|
||||||
/* USER CODE INIT END */
|
/* USER CODE INIT END */
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -65,30 +60,33 @@ void Task_blink(void *argument) {
|
|||||||
// 呼吸灯 - 基于tick的正弦波
|
// 呼吸灯 - 基于tick的正弦波
|
||||||
// float duty = (sinf(tick * 0.003f) + 1.0f) * 0.5f; // 0到1之间的正弦波,加快频率
|
// float duty = (sinf(tick * 0.003f) + 1.0f) * 0.5f; // 0到1之间的正弦波,加快频率
|
||||||
// BSP_PWM_SetComp(BSP_PWM_LED_G, duty);
|
// BSP_PWM_SetComp(BSP_PWM_LED_G, duty);
|
||||||
// uint8_t tx_data[8] = {1,2,3,4,5,6,7,8};
|
|
||||||
// bsp_can_trans_packet(BSP_CAN_1, CAN_FORMAT_STD, 0x123, tx_data);
|
|
||||||
// 测试:向三路 CAN 周期性发送电机控制帧(示例数据),并轮询接收
|
// 测试:向三路 CAN 周期性发送电机控制帧(示例数据),并轮询接收
|
||||||
{
|
{
|
||||||
uint8_t data1[8] = {0xA1, 0x01, 0x34, 0x12, 0x10, 0x00, 0x00, 0x00};
|
uint8_t data1[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||||
uint8_t data2[8] = {0xA1, 0x02, 0x78, 0x56, 0x20, 0x00, 0x00, 0x00};
|
uint8_t data2[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||||
uint8_t data3[8] = {0xA1, 0x03, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00};
|
uint8_t data3[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
|
||||||
|
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||||
|
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20};
|
||||||
|
|
||||||
// 简单 CRC/校验(可选)
|
// 简单 CRC/校验(可选)
|
||||||
data1[7] = data1[0] ^ data1[1] ^ data1[2];
|
data1[7] = data1[0] ^ data1[1] ^ data1[2];
|
||||||
data2[7] = data2[0] ^ data2[1] ^ data2[2];
|
data2[7] = data2[0] ^ data2[1] ^ data2[2];
|
||||||
data3[7] = data3[0] ^ data3[1] ^ data3[2];
|
// data3[7] = data3[0] ^ data3[1] ^ data3[2];
|
||||||
|
|
||||||
// 使用 BSP 封装的发送接口(非阻塞,若硬件 FIFO 满则内部入队)
|
// 使用 BSP 封装的发送接口(非阻塞,若硬件 FIFO 满则内部入队)
|
||||||
BSP_FDCAN_Transmit(BSP_FDCAN_1, BSP_FDCAN_FORMAT_STD_DATA, 0x101, data1, 8);
|
// BSP_FDCAN_Transmit(BSP_FDCAN_1, BSP_FDCAN_FORMAT_STD_DATA, 0x101, data1, 8);
|
||||||
BSP_FDCAN_Transmit(BSP_FDCAN_2, BSP_FDCAN_FORMAT_STD_DATA, 0x102, data2, 8);
|
// BSP_FDCAN_Transmit(BSP_FDCAN_2, BSP_FDCAN_FORMAT_STD_DATA, 0x102, data2, 8);
|
||||||
BSP_FDCAN_Transmit(BSP_FDCAN_3, BSP_FDCAN_FORMAT_STD_DATA, 0x103, data3, 8);
|
BSP_FDCAN_Transmit(BSP_FDCAN_3, BSP_FDCAN_FORMAT_STD_DATA, 0x103, data3, 13);
|
||||||
|
|
||||||
if (BSP_FDCAN_GetMessage(BSP_FDCAN_1, 0x101, &msg, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
if (BSP_FDCAN_GetMessage(BSP_FDCAN_1, 0x101, &msg1, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
||||||
}
|
}
|
||||||
if (BSP_FDCAN_GetMessage(BSP_FDCAN_2, 0x102, &msg, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
if (BSP_FDCAN_GetMessage(BSP_FDCAN_2, 0x102, &msg2, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
||||||
}
|
}
|
||||||
if (BSP_FDCAN_GetMessage(BSP_FDCAN_3, 0x103, &msg, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
if (BSP_FDCAN_GetMessage(BSP_FDCAN_3, 0x103, &msg3, BSP_FDCAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
|
||||||
}
|
}
|
||||||
|
rxlevel=HAL_FDCAN_GetRxFifoFillLevel(BSP_FDCAN_GetHandle(BSP_FDCAN_2), FDCAN_RX_FIFO1);
|
||||||
}
|
}
|
||||||
// osDelay(10);
|
// osDelay(10);
|
||||||
/* USER CODE END */
|
/* USER CODE END */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user