McuY 发表于 2017-3-31 12:57:14

求一个freeRTOS时间戳的函数

在弄segger的system view,CM3核可以直接用,挺好用。CM0的核要自己写一个返回时间戳的函数。

#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
#define SEGGER_SYSVIEW_GET_TIMESTAMP()      (*(U32 *)(0xE0001004))            // Retrieve a system timestamp. Cortex-M cycle counter.
#define SEGGER_SYSVIEW_TIMESTAMP_BITS       32                              // Define number of valid bits low-order delivered by clock source
#else
#define SEGGER_SYSVIEW_GET_TIMESTAMP()      SEGGER_SYSVIEW_X_GetTimestamp()   // Retrieve a system timestamp via user-defined function
#define SEGGER_SYSVIEW_TIMESTAMP_BITS       32                              // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
#endif

SEGGER_SYSVIEW_X_GetTimestamp这个函数要自己实现。
有embOS的实现如下:

/*********************************************************************
*
*       SEGGER_SYSVIEW_X_GetTimestamp()
*
* Function description
*   Returns the current timestamp in ticks using the system tick
*   count and the SysTick counter.
*   All parameters of the SysTick have to be known and are set via
*   configuration defines on top of the file.
*
* Return value
*   The current timestamp.
*
* Additional information
*   SEGGER_SYSVIEW_X_GetTimestamp is always called when interrupts are
*   disabled. Therefore locking here is not required.
*/
U32 SEGGER_SYSVIEW_X_GetTimestamp(void) {
U32 TickCount;
U32 Cycles;
U32 CyclesPerTick;
//
// Get the cycles of the current system tick.
// SysTick is down-counting, subtract the current value from the number of cycles per tick.
//
CyclesPerTick = SYST_RVR + 1;
Cycles = (CyclesPerTick - SYST_CVR);
//
// Get the system tick count.
//
TickCount = SEGGER_SYSVIEW_TickCnt;
//
// If a SysTick interrupt is pending, re-read timer and adjust result
//
if ((SCB_ICSR & SCB_ICSR_PENDSTSET_MASK) != 0) {
    Cycles = (CyclesPerTick - SYST_CVR);
    TickCount++;
}
Cycles += TickCount * CyclesPerTick;

return Cycles;
}


无OS的
/*********************************************************************
*
*       SEGGER_SYSVIEW_X_GetTimestamp()
*
* Function description
*   Returns the current timestamp in ticks using the system tick
*   count and the SysTick counter.
*   All parameters of the SysTick have to be known and are set via
*   configuration defines on top of the file.
*
* Return value
*   The current timestamp.
*
* Additional information
*   SEGGER_SYSVIEW_X_GetTimestamp is always called when interrupts are
*   disabled.
*   Therefore locking here is not required and OS_GetTime_Cycles() may
*   be called.
*/
U32 SEGGER_SYSVIEW_X_GetTimestamp(void) {
U32 Time;
U32 Cnt;

Time = SEGGER_SYSVIEW_TickCnt;
Cnt= CMT0_CMCNT;
//
// Check if timer interrupt pending ...
//
if ((*(volatile U8*)(IRR_BASE_ADDR + OS_TIMER_VECT) & (1u << 0u)) != 0u) {
    Cnt = CMT0_CMCNT;      // Interrupt pending, re-read timer and adjust result
    Time++;
}
return ((SYSVIEW_TIMESTAMP_FREQ/1000) * Time) + Cnt;
}


怎么写freeRTOS的?
或者给个思路?

dreambox 发表于 2017-3-31 13:31:12

不懂帮顶

McuY 发表于 2017-3-31 23:09:59

熟悉embOS版面解释第一个函数什么意思?

McuY 发表于 2017-4-1 00:01:44

顶一下   

security 发表于 2017-4-1 08:54:45

McuY 发表于 2017-3-31 23:09
熟悉embOS版面解释第一个函数什么意思?

我没用过 embOS,也不知道你这个代码的用途,
但我就按照代码来直接翻译一下:
- 这个函数,采用 SysTick 作为定时器,SysTick 定时器是向下递减的模型,
- 一个 TICK,被设计对应于 SysTick,从 RVR 寄存器的取值,递减到 0值的时间,所以 CyclesPerTick = SYST_RVR + 1;
- 而由于是向下递减,所以本轮计数周期流逝的时间,要从顶部,扣除当前计数寄存器的取值,即:Cycles = (CyclesPerTick - SYST_CVR);
- 所以简单来讲,当前总的流逝时间为:历史流逝的时间(SEGGER_SYSVIEW_TickCnt) + 本轮计数周期流逝的时间(Cycles),即:Cycles += TickCount * CyclesPerTick;
- 至于 If a SysTick interrupt is pending, re-read timer and adjust result 的部分,我想你应该明白了。

McuY 发表于 2017-4-1 14:18:12

多谢楼上分析

McuY 发表于 2017-4-1 17:55:26

顶一下

security 发表于 2017-4-1 23:05:33

McuY 发表于 2017-4-1 17:55
顶一下

我有点不明白你顶一下有什么意义。
我在 5 楼的分析,应该很清晰了,依葫芦画瓢,应该不难的啊。

McuY 发表于 2017-4-3 00:08:16

security 发表于 2017-4-1 23:05
我有点不明白你顶一下有什么意义。
我在 5 楼的分析,应该很清晰了,依葫芦画瓢,应该不难的啊。 ...

没有完全明白。
这个时间的单位是什么? 1ms? 1us?

McuY 发表于 2017-4-3 00:12:15

不明白怎么用freertos写
1
  //
  // Check if timer interrupt pending ...
  //
  if ((*(volatile U8*)(IRR_BASE_ADDR + OS_TIMER_VECT) & (1u << 0u)) != 0u)

2
  TickCount = SEGGER_SYSVIEW_TickCnt;

security 发表于 2017-4-5 08:56:08

本帖最后由 security 于 2017-4-5 09:14 编辑

McuY 发表于 2017-4-3 00:08
没有完全明白。
这个时间的单位是什么? 1ms? 1us?

从你贴出的代码,可以推出 SEGGER_SYSVIEW_TickCnt 对应于 ms 数。
那应该就是这样。

而 SEGGER_SYSVIEW_X_GetTimestamp 函数,Returns the current timestamp in ticks using the system tick count and the SysTick counter。

security 发表于 2017-4-5 09:02:37

McuY 发表于 2017-4-3 00:12
不明白怎么用freertos写
1
  //


1 Check if timer interrupt pending,这个跟 RTOS 无关,这是 MCU 硬件相关的。
这个只是去读硬件 timer 的中断标志位,轮询看看有没有发生过中断(因为当前的环境是 SEGGER_SYSVIEW_X_GetTimestamp is always called when interrupts are disabled)

2 SEGGER_SYSVIEW_TickCnt 对应于 ms 的数目,你外部应该有 timer 的 ISR 函数,来负责 SEGGER_SYSVIEW_TickCnt++。
所以有 ((SYSVIEW_TIMESTAMP_FREQ/1000) * Time) + Cnt,来表征 timer 的历史总计数值。

监护王 发表于 2017-4-5 09:05:02

我也一直在找这方面的资料,同问题

security 发表于 2017-4-5 09:07:30

监护王 发表于 2017-4-5 09:05
我也一直在找这方面的资料,同问题

我是从这边第一次看到这东东,
但我想我的直译应该不会错,应该可以解决你的疑虑吧?

huy666 发表于 2017-4-5 14:14:32

freertos有个函数xTaskGetTickCount,单位就是tick。

huy666 发表于 2017-4-5 18:13:09

http://forum.segger.com/index.php?page=Thread&threadID=2761

McuY 发表于 2017-4-6 09:35:30

多谢各位,已按楼上链接写好可以跑了,但是有问题,跑一会会断片。

McuY 发表于 2017-4-6 09:41:32

这个函数返回的单位由SYSVIEW_TIMESTAMP_FREQ定义,默认是CPU时钟周期,就是CPU是48M的话,这个返回值每秒加48 000 000。
串口输出tick的单位是秒。可以看到,trace到的时间,比实际跑的时间多很多。

McuY 发表于 2017-4-6 09:48:12

正常是连续的。
总运行时间基本与串口输出的时间一致。

McuY 发表于 2017-4-6 10:23:29

重新写个帖子说下怎么用。请大伙继续讨论、完善。
http://www.amobbs.com/thread-5671789-1-1.html
页: [1]
查看完整版本: 求一个freeRTOS时间戳的函数