简介:
根据之前在ARM-CORTEXM 架构上使用perf_counter 的经验,perf_counter 最新的代码已经将依赖的定时器计数相关的接口剥离出来,在risc-v 使用cycle 对接到对应的接口就可以将perf_counter 应用到RISC-V架构的芯片上了。
依赖计时模块的接口如下:
接口1void perfc_port_clear_system_timer_counter(void)
该接口主要用在perf 需要重新初始化配置的场景,本地使用的场景没有这方年的需求,对该接口时限为空函数,对应接口调用只有此函数一处调用。

接口2:void perfc_port_stop_system_timer_counting(void)
该接口跟接口1一样只有在perf 需要重新初始化配置的场景调用,我们对该函数实现为空函数即可。
接口3:void perfc_port_clear_system_timer_ovf_pending(void)
该接口主要用于timer 超时溢出清除处理,因本地使用的cycle 为64bit 的计数器,我们暂不考虑溢出的问题,该接口实现为空函数即可。
接口4:int64_t perfc_port_get_system_timer_elapsed(void)
该接口用于获取timer 计数当前时间计数值,对接为cycle 寄存器数据的读取处理实现如下:
int64_t perfc_port_get_system_timer_elapsed(void)
{
int64_t counter = 0,tmp = 0;
counter = read_csr(cycle);
tmp = read_csr(0xc80);
counter |= tmp<<32u;
return (int64_t)counter;
}接口5 int64_t perfc_port_get_system_timer_top(void)
用于读取定时器的最大计数周期为多少,配合溢出标志来使用,本地不考虑溢出该函式实现未返回0处理。
int64_t perfc_port_get_system_timer_top(void)
{
/* the 64bit cycle counter is not overflow */
return 0;
}接口6:bool perfc_port_is_system_timer_ovf_pending(void)
该接口用于获取定时器的溢出状态,因本地认为64bit 的计数周期足够长对于程序运行一次来说,该函数固定返回false
bool perfc_port_is_system_timer_ovf_pending(void)
{
/* whether the system timer overflow is pending */
return false;
}接口7: uint32_t perfc_port_get_system_timer_freq(void)
该接口用于获取timer 的工作时钟频率,cycle 对应频率核CPU主频一致,对应实现如下
uint32_t perfc_port_get_system_timer_freq(void)
{
extern uint32_t SystemCoreClock;
/* return the system timer frequency */
return SystemCoreClock;
}接口8:bool perfc_port_init_system_timer(bool bIsTimeOccupied)
该接口用于timer 定时器初始化,对接为开启cycle ,对应实现如下:
bool perfc_port_init_system_timer(bool bIsTimeOccupied)
{
/* enable risc-v cpu cycle counter */
asm volatile ("csrci 0x320, 0x5");
return true;
}除了上述接口外,perf_counter 还依赖了部分CMSIS的接口,GD32VF103 实现了兼容CMSIS的驱动接口,我们使用对应的接口来适配即可,工程中添加如下修改代码.
Application/main.c | 15 +-
.../RISCV/drivers/n200_func.h | 103 +++++++++-
.../RISCV/drivers/nmsis_compiler.h | 105 +++++++++++
.../RISCV/drivers/nmsis_core.h | 111 +++++++++++
.../RISCV/drivers/nmsis_gcc.h | 210 +++++++++++++++++++++
Makefile | 1 -
perf_counter/perfc_port_riscv_cycle.h | 4 +-
7 files changed, 533 insertions(+), 16 deletions(-)
diff --git a/Application/main.c b/Application/main.c
index d7941ab..e8b0272 100644
--- a/Application/main.c
+++ b/Application/main.c
@@ -87,9 +87,6 @@ void task2(void *p)
{
int i = 0;
- uint64_t start = 0;
- uint64_t end = 0;
- uint64_t tmp = 0;
for(i = 0;i < 6000000;i++)
{
atomic_add1(-1, (unsigned int *)&p1);
@@ -102,15 +99,10 @@ void task2(void *p)
for(;;)
{
- start = 0,end = 0;
- start = read_csr(cycle);
- tmp = read_csr(0xc80);
- start |= tmp<<32u;
+ start_cycle_counter();
vTaskDelay(pdMS_TO_TICKS(5000));
- end = read_csr(cycle);
- tmp = read_csr(0xc80);
- end |= tmp<<32u;
- printf("%lu\n",(uint32_t)(end -start));
+ int64_t lCycleUsed = stop_cycle_counter();
+ printf("cycle counter %ld.\n",(uint32_t)lCycleUsed);
}
//char *taskStatus = (char *)pvPortMalloc( uxTaskGetNumberOfTasks() * sizeof( TaskStatus_t ) );
@@ -237,6 +229,7 @@ int main(void)
#if UARTLOGEN
uart_log_init();
#endif
+ init_cycle_counter(false);
show_version();
/* 初始化led PA1/PA2/PC13 */
rcu_periph_clock_enable(RCU_GPIOA);
diff --git a/GD32VF103_Firmware_Library/RISCV/drivers/n200_func.h b/GD32VF103_Firmware_Library/RISCV/drivers/n200_func.h
index 6531d0b..07b69f7 100644
--- a/GD32VF103_Firmware_Library/RISCV/drivers/n200_func.h
+++ b/GD32VF103_Firmware_Library/RISCV/drivers/n200_func.h
@@ -7,6 +7,7 @@
#include <stddef.h>
#include "n200_timer.h"
#include "n200_eclic.h"
+#include "nmsis_compiler.h"
#define ECLIC_GROUP_LEVEL0_PRIO4 0
#define ECLIC_GROUP_LEVEL1_PRIO3 1
@@ -58,11 +59,11 @@ uint8_t eclic_get_cliccfg ();
void eclic_set_mth (uint8_t mth);
uint8_t eclic_get_mth();
-//sets nlbits
+//sets nlbits
void eclic_set_nlbits(uint8_t nlbits);
-//get nlbits
+//get nlbits
uint8_t eclic_get_nlbits();
void eclic_set_irq_lvl(uint32_t source, uint8_t lvl);
@@ -105,5 +106,103 @@ __attribute__( ( always_inline ) ) static inline void __WFE(void) {
__asm volatile ("csrc 0x810, 0x1");
}
+#define __STR(s) #s
+#define STRINGIFY(s) __STR(s)
+
+/** \brief Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V */
+typedef unsigned long rv_csr_t;
+
+/**
+ * \brief CSR operation Macro for csrs instruction.
+ * \details
+ * Set csr register to be csr_content | val
+ * \param csr CSR macro definition defined in
+ * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
+ * \param val Mask value to be used wih csrs instruction
+ */
+#define __RV_CSR_SET(csr, val) \
+ ({ \
+ rv_csr_t __v = (rv_csr_t)(val); \
+ __ASM volatile("csrs " STRINGIFY(csr) ", %0" \
+ : \
+ : "rK"(__v) \
+ : "memory"); \
+ })
+
+/**
+ * \brief CSR operation Macro for csrc instruction.
+ * \details
+ * Set csr register to be csr_content & ~val
+ * \param csr CSR macro definition defined in
+ * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
+ * \param val Mask value to be used wih csrc instruction
+ */
+#define __RV_CSR_CLEAR(csr, val) \
+ ({ \
+ rv_csr_t __v = (rv_csr_t)(val); \
+ __ASM volatile("csrc " STRINGIFY(csr) ", %0" \
+ : \
+ : "rK"(__v) \
+ : "memory"); \
+ })
+
+/**
+ * \brief Enable IRQ Interrupts
+ * \details Enables IRQ interrupts by setting the MIE-bit in the MSTATUS Register.
+ * \remarks
+ * Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __enable_irq(void)
+{
+ __RV_CSR_SET(CSR_MSTATUS, MSTATUS_MIE);
+}
+
+/**
+ * \brief Disable IRQ Interrupts
+ * \details Disables IRQ interrupts by clearing the MIE-bit in the MSTATUS Register.
+ * \remarks
+ * Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __disable_irq(void)
+{
+ __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
+}
+
+
+/* ===== ARM Compatiable Functions ===== */
+/**
+ * \defgroup NMSIS_Core_ARMCompatiable_Functions ARM Compatiable Functions
+ * \ingroup NMSIS_Core
+ * \brief A few functions that compatiable with ARM CMSIS-Core.
+ * \details
+ *
+ * Here we provided a few functions that compatiable with ARM CMSIS-Core,
+ * mostly used in the DSP and NN library.
+ * @{
+ */
+
+/**
+ * \brief Execute fence instruction, p -> pred, s -> succ
+ * \details
+ * the FENCE instruction ensures that all memory accesses from instructions preceding
+ * the fence in program order (the `predecessor set`) appear earlier in the global memory order than
+ * memory accesses from instructions appearing after the fence in program order (the `successor set`).
+ * For details, please refer to The RISC-V Instruction Set Manual
+ * \param p predecessor set, such as iorw, rw, r, w
+ * \param s successor set, such as iorw, rw, r, w
+ **/
+#define __FENCE(p, s) __ASM volatile ("fence " #p "," #s : : : "memory")
+
+/** \brief Read & Write Memory barrier */
+#define __RWMB() __FENCE(iorw,iorw)
+
+/** \brief Instruction Synchronization Barrier, compatiable with ARM */
+#define __ISB() __RWMB()
+
+/** \brief Data Synchronization Barrier, compatiable with ARM */
+#define __DSB() __RWMB()
+
+/** \brief Data Memory Barrier, compatiable with ARM */
+#define __DMB() __RWMB()
#endif
diff --git a/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_compiler.h b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_compiler.h
new file mode 100644
index 0000000..869d753
--- /dev/null
+++ b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_compiler.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019 Nuclei Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NMSIS_COMPILER_H
+#define __NMSIS_COMPILER_H
+
+#include <stdint.h>
+
+/*!
+ * @file nmsis_compiler.h
+ * @brief NMSIS compiler generic header file
+ */
+#if defined ( __GNUC__ )
+ /* GNU GCC Compiler */
+ #include "nmsis_gcc.h"
+#elif defined ( __ICCRISCV__ )
+ /* IAR Compiler */
+ #include "nmsis_iar.h"
+#else
+ #error Unknown compiler.
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ * \defgroup NMSIS_Core_PeriphAccess Peripheral Access
+ * \brief Naming conventions and optional features for accessing peripherals.
+ *
+ * The section below describes the naming conventions, requirements, and optional features
+ * for accessing device specific peripherals.
+ * Most of the rules also apply to the core peripherals.
+ *
+ * The **Device Header File <device.h>** contains typically these definition
+ * and also includes the core specific header files.
+ *
+ * @{
+ */
+/** \brief Defines 'read only' permissions */
+#ifdef __cplusplus
+ #define __I volatile
+#else
+ #define __I volatile const
+#endif
+/** \brief Defines 'write only' permissions */
+#define __O volatile
+/** \brief Defines 'read / write' permissions */
+#define __IO volatile
+
+/* following defines should be used for structure members */
+/** \brief Defines 'read only' structure member permissions */
+#define __IM volatile const
+/** \brief Defines 'write only' structure member permissions */
+#define __OM volatile
+/** \brief Defines 'read/write' structure member permissions */
+#define __IOM volatile
+
+/**
+ * \brief Mask and shift a bit field value for use in a register bit range.
+ * \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit
+ * field to shift bit-field values for assigning to a register.
+ *
+ * **Example**:
+ * \code
+ * ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3);
+ * \endcode
+ * \param[in] field Name of the register bit field.
+ * \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
+ * \return Masked and shifted value.
+ */
+#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
+
+/**
+ * \brief Mask and shift a register value to extract a bit filed value.
+ * \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit
+ * field to extract the value of a bit field from a register.
+ *
+ * **Example**:
+ * \code
+ * nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG);
+ * \endcode
+ * \param[in] field Name of the register bit field.
+ * \param[in] value Value of register. This parameter is interpreted as an uint32_t type.
+ * \return Masked and shifted bit field value.
+ */
+#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
+
+/** @} */ /* end of group NMSIS_Core_PeriphAccess */
+
+
+#endif /* __NMSIS_COMPILER_H */
+
diff --git a/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_core.h b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_core.h
new file mode 100644
index 0000000..16ed438
--- /dev/null
+++ b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_core.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
+ * -- Adaptable modifications made for Nuclei Processors. --
+ * Copyright (c) 2019 Nuclei Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "nmsis_version.h"
+
+/**
+ * \ingroup NMSIS_Core_VersionControl
+ * @{
+ */
+/* The following macro __NUCLEI_N_REV/__NUCLEI_NX_REV/
+ * __NUCLEI_CPU_REV/__NUCLEI_CPU_SERIES definition in this file
+ * is only used for doxygen documentation generation,
+ * The <Device>.h is the real file to define it by vendor
+ */
+#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__)
+/**
+ * \brief Nuclei N class core revision number
+ * \details
+ * Reversion number format: [15:8] revision number, [7:0] patch number
+ * \attention
+ * Deprecated, this define is exclusive with \ref __NUCLEI_NX_REV
+ */
+#define __NUCLEI_N_REV (0x0309)
+/**
+ * \brief Nuclei NX class core revision number
+ * \details
+ * Reversion number format: [15:8] revision number, [7:0] patch number
+ * \attention
+ * Deprecated, this define is exclusive with \ref __NUCLEI_N_REV
+ */
+#define __NUCLEI_NX_REV (0x0207)
+/**
+ * \brief Nuclei CPU core revision number
+ * \details
+ * Nuclei RISC-V CPU Revision Number vX.Y.Z, eg. v3.10.1
+ * \attention
+ * This define is exclusive with \ref __NUCLEI_CPU_SERIES
+ */
+#define __NUCLEI_CPU_REV (0x030A01)
+/**
+ * \brief Nuclei CPU core series
+ * \details
+ * Nuclei RISC-V CPU Series Number, eg, 0x200, 0x300, 0x600, 0x900
+ * for 200, 300, 600, 900 series.
+ * \attention
+ * This define is used together with \ref __NUCLEI_CPU_REV
+ */
+#define __NUCLEI_CPU_SERIES (0x0200)
+#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */
+/** @} */ /* End of Group NMSIS_Core_VersionControl */
+
+#include "nmsis_compiler.h" /* NMSIS compiler specific defines */
+
+/* === Include Nuclei Core Related Headers === */
+/* Include core base feature header file */
+#include "core_feature_base.h"
+
+/* Include core fpu feature header file */
+#include "core_feature_fpu.h"
+/* Include core dsp feature header file */
+#include "core_feature_dsp.h"
+/* Include core vector feature header file */
+#include "core_feature_vector.h"
+/* Include core bitmanip feature header file */
+#include "core_feature_bitmanip.h"
+/* Include core pmp feature header file */
+#include "core_feature_pmp.h"
+/* Include core spmp feature header file */
+ #include "core_feature_spmp.h"
+/* Include core cache feature header file */
+#include "core_feature_cache.h"
+/* Include core cidu feature header file */
+ #include "core_feature_cidu.h"
+
+/* Include compatiable functions header file */
+#include "core_compatiable.h"
+
+#ifndef __NMSIS_GENERIC
+/* Include core eclic feature header file */
+#include "core_feature_eclic.h"
+/* Include core plic feature header file */
+#include "core_feature_plic.h"
+/* Include core systimer feature header file */
+#include "core_feature_timer.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_gcc.h b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_gcc.h
new file mode 100644
index 0000000..b53775d
--- /dev/null
+++ b/GD32VF103_Firmware_Library/RISCV/drivers/nmsis_gcc.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2019 Nuclei Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NMSIS_GCC_H__
+#define __NMSIS_GCC_H__
+/*!
+ * @file nmsis_gcc.h
+ * @brief NMSIS compiler GCC header file
+ */
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "riscv_encoding.h"
+
+/* ######################### Startup and Lowlevel Init ######################## */
+/**
+ * \defgroup NMSIS_Core_CompilerControl Compiler Control
+ * \ingroup NMSIS_Core
+ * \brief Compiler agnostic \#define symbols for generic c/c++ source code
+ * \details
+ *
+ * The NMSIS-Core provides the header file <b>nmsis_compiler.h</b> with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic.
+ * Each NMSIS compliant compiler should support the functionality described in this section.
+ *
+ * The header file <b>nmsis_compiler.h</b> is also included by each Device Header File <device.h> so that these definitions are available.
+ * @{
+ */
+
+/* Fallback for __has_builtin */
+#ifndef __has_builtin
+ #define __has_builtin(x) (0)
+#endif
+
+/* NMSIS compiler specific defines */
+/** \brief Pass information from the compiler to the assembler. */
+#ifndef __ASM
+ #define __ASM __asm
+#endif
+
+/** \brief Recommend that function should be inlined by the compiler. */
+#ifndef __INLINE
+ #define __INLINE inline
+#endif
+
+/** \brief Define a static function that may be inlined by the compiler. */
+#ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static inline
+#endif
+
+/** \brief Define a static function that should be always inlined by the compiler. */
+#ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
+#endif
+
+/** \brief Inform the compiler that a function does not return. */
+#ifndef __NO_RETURN
+ #define __NO_RETURN __attribute__((__noreturn__))
+#endif
+
+/** \brief Inform that a variable shall be retained in executable image. */
+#ifndef __USED
+ #define __USED __attribute__((used))
+#endif
+
+/** \brief restrict pointer qualifier to enable additional optimizations. */
+#ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+#endif
+
+/** \brief specified the vector size of the variable, measured in bytes */
+#ifndef __VECTOR_SIZE
+ #define __VECTOR_SIZE(x) __attribute__((vector_size(x)))
+#endif
+
+/** \brief Request smallest possible alignment. */
+#ifndef __PACKED
+ #define __PACKED __attribute__((packed, aligned(1)))
+#endif
+
+/** \brief Request smallest possible alignment for a structure. */
+#ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
+#endif
+
+/** \brief Request smallest possible alignment for a union. */
+#ifndef __PACKED_UNION
+ #define __PACKED_UNION union __attribute__((packed, aligned(1)))
+#endif
+
+#ifndef __UNALIGNED_UINT16_WRITE
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ /** \brief Packed struct for unaligned uint16_t write access */
+ __PACKED_STRUCT T_UINT16_WRITE {
+ uint16_t v;
+ };
+ #pragma GCC diagnostic pop
+ /** \brief Pointer for unaligned write of a uint16_t variable. */
+ #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+#endif
+
+#ifndef __UNALIGNED_UINT16_READ
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ /** \brief Packed struct for unaligned uint16_t read access */
+ __PACKED_STRUCT T_UINT16_READ {
+ uint16_t v;
+ };
+ #pragma GCC diagnostic pop
+ /** \brief Pointer for unaligned read of a uint16_t variable. */
+ #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+#endif
+
+#ifndef __UNALIGNED_UINT32_WRITE
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ /** \brief Packed struct for unaligned uint32_t write access */
+ __PACKED_STRUCT T_UINT32_WRITE {
+ uint32_t v;
+ };
+ #pragma GCC diagnostic pop
+ /** \brief Pointer for unaligned write of a uint32_t variable. */
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+#endif
+
+#ifndef __UNALIGNED_UINT32_READ
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ /** \brief Packed struct for unaligned uint32_t read access */
+ __PACKED_STRUCT T_UINT32_READ {
+ uint32_t v;
+ };
+ #pragma GCC diagnostic pop
+ /** \brief Pointer for unaligned read of a uint32_t variable. */
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+#endif
+
+/** \brief Minimum `x` bytes alignment for a variable. */
+#ifndef __ALIGNED
+ #define __ALIGNED(x) __attribute__((aligned(x)))
+#endif
+
+/** \brief restrict pointer qualifier to enable additional optimizations. */
+#ifndef __RESTRICT
+ #define __RESTRICT __restrict
+#endif
+
+/** \brief Barrier to prevent compiler from reordering instructions. */
+#ifndef __COMPILER_BARRIER
+ #define __COMPILER_BARRIER() __ASM volatile("":::"memory")
+#endif
+
+/** \brief provide the compiler with branch prediction information, the branch is usually true */
+#ifndef __USUALLY
+ #define __USUALLY(exp) __builtin_expect((exp), 1)
+#endif
+
+/** \brief provide the compiler with branch prediction information, the branch is rarely true */
+#ifndef __RARELY
+ #define __RARELY(exp) __builtin_expect((exp), 0)
+#endif
+
+/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */
+#ifndef __INTERRUPT
+ #define __INTERRUPT __attribute__((interrupt))
+#endif
+
+/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */
+#ifndef __MACHINE_INTERRUPT
+ #define __MACHINE_INTERRUPT __attribute__ ((interrupt ("machine")))
+#endif
+
+/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */
+#ifndef __SUPERVISOR_INTERRUPT
+ #define __SUPERVISOR_INTERRUPT __attribute__ ((interrupt ("supervisor")))
+#endif
+
+/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */
+#ifndef __USER_INTERRUPT
+ #define __USER_INTERRUPT __attribute__ ((interrupt ("user")))
+#endif
+
+/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __NMSIS_GCC_H__ */
diff --git a/Makefile b/Makefile
index cc5311a..91cb873 100644
--- a/Makefile
+++ b/Makefile
@@ -132,7 +132,6 @@ C_INCLUDES = \
-I $(TOP_DIR)/GD32VF103_Firmware_Library/GD32VF103_standard_peripheral \
-I $(TOP_DIR)/GD32VF103_Firmware_Library/GD32VF103_standard_peripheral/Include \
-I $(TOP_DIR)/GD32VF103_Firmware_Library/RISCV/drivers \
- -I $(TOP_DIR)/GD32VF103_Firmware_Library/NMSIS/Core/Include \
-I $(TOP_DIR)/freertos/include \
-I $(TOP_DIR)/freertos/portable/GCC/N200 \
-I $(TOP_DIR)/SEGGER \
diff --git a/perf_counter/perfc_port_riscv_cycle.h b/perf_counter/perfc_port_riscv_cycle.h
index 99ce782..82de942 100644
--- a/perf_counter/perfc_port_riscv_cycle.h
+++ b/perf_counter/perfc_port_riscv_cycle.h
@@ -1,8 +1,8 @@
#ifndef PERFC_PORT_RISCV_CYCLE_H
#define PERFC_PORT_RISCV_CYCLE_H
-#include "core_feature_base.h"
-#include "core_compatiable.h"
+#include "n200_func.h"
+
/*============================ MACROS ========================================*/
/*============================ MACROFIED FUNCTIONS ===========================*/添加上述代码后添加如下测试代码,使用perf_counter 来测量如下5S sleep 的CPU耗时。
start_cycle_counter();
vTaskDelay(pdMS_TO_TICKS(5000));
int64_t lCycleUsed = stop_cycle_counter();
printf("cycle counter %ld.\n",(uint32_t)lCycleUsed);
测试结果跟之前单独使用cycle 测试结果保持一致,至此简单的修改即可将perf_counter适配到RISC-V的处理器上运行。
我要赚赏金
