简体   繁体   English

ARM Cortex M4处理器中经过时间的测试C代码中的错误SEGV

[英]Error SEGV in test C code on elapsed time in ARM Cortex M4 processor

I'm writing a code for embedded OS for my stm32f429 board. 我正在为stm32f429板编写嵌入式操作系统的代码。 I'm testing this code for elapsed time: 我正在测试这段代码的经过时间:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> 
#include <fcntl.h>
#include <time.h>
#include <stdint.h>


#define DEFAULT_DELAY   1

uint32_t m_nStart;               //DEBUG Stopwatch start cycle counter value
uint32_t m_nStop;   //DEBUG Stopwatch stop cycle counter value             
#define DEMCR_TRCENA    0x01000000

/* Core Debug registers */
#define DEMCR           (*((volatile uint32_t *)0xE000EDFC))
#define DWT_CTRL        (*(volatile uint32_t *)0xE0001000)
#define CYCCNTENA       (1<<0)
#define DWT_CYCCNT      ((volatile uint32_t *)0xE0001004)
#define CPU_CYCLES      *DWT_CYCCNT



#define STOPWATCH_START { m_nStart = *(*(volatile unsigned int*)0xE0001004);}//DWT_CYCCNT;}
#define STOPWATCH_STOP  { m_nStop = *(*(volatile unsigned int *)0xE0001004);}




static inline void stopwatch_reset(void)
{
    /* Enable DWT */
    DEMCR |= DEMCR_TRCENA; 
    *DWT_CYCCNT = 0;             
    /* Enable CPU cycle counter */
    DWT_CTRL |= CYCCNTENA;
}

static inline uint32_t stopwatch_getticks()
{
    return CPU_CYCLES;
}

static inline void stopwatch_delay(uint32_t ticks)
{
    stopwatch_reset();
    while(1)
    {
        if (stopwatch_getticks() >= ticks)
                break;
    }
}

uint32_t CalcNanosecondsFromStopwatch(uint32_t nStart, uint32_t nStop)
{
    uint32_t nTemp;
    uint32_t n;
    uint32_t SystemCoreClock = 180000000;
    nTemp = nStop - nStart;

    nTemp *= 1000;                          // Scale cycles by 1000.
    n = SystemCoreClock / 1000000;          // Convert Hz to MHz
   nTemp = nTemp / n;                      // nanosec = (Cycles * 1000) / (Cycles/microsec)

   return nTemp;
} 



int main( int argc, char **argv )
{
    int delay = DEFAULT_DELAY;  // Initial value for the delay

    int timeDiff = 0;

    STOPWATCH_START;
    printf("Try\n\n");
    STOPWATCH_STOP;
    timeDiff = CalcNanosecondsFromStopwatch(m_nStart, m_nStop);
    printf("My function took %d nanoseconds\n", timeDiff);  


   return( 0 );
}

It compiles without errors, but when I run this program on my stm32f429, I obtain a SEGV error, probably in the #define STOPWATCH_START. 它编译时没有错误,但是当我在stm32f429上运行该程序时,我发现SEGV错误,可能是在#define STOPWATCH_START中。 Maybe I have problems on registers (?). 也许我在寄存器(?)上有问题。

The code is http://pastebin.com/qr6sF9eU (It deleted the calling to system call that I use) 代码为http://pastebin.com/qr6sF9eU (它删除了我使用的系统调用的调用)

The output of make is: http://pastebin.com/Q14xTaXH make的输出是: http : //pastebin.com/Q14xTaXH

The output when I run my test on stm32f429 board is: http://pastebin.com/sGmjZjxj 当我在stm32f429板上运行测试时,输出为: http ://pastebin.com/sGmjZjxj

Can you help me? 你能帮助我吗?

You cannot get a SEGV in a #define as the #define is a preprocessor directive and doesn't form part of the output. 您无法在#define获得SEGV ,因为#define是预处理程序指令,不构成输出的一部分。 It may be in the code produced by the #define. 它可能在#define生成的代码中。 Are you deliberately reading an address from 0xE0001004 , reading what's at that address as another address, then reading the contents of that? 您是否故意从0xE0001004读取一个地址 ,将该地址中的内容读取为另一个地址,然后读取其内容? That sounds a pretty unlikely way to operate a clock. 这听起来不太可能操作时钟。

The macros STOPWATCH_START; STOPWATCH_START; and STOPWATCH_STOP; STOPWATCH_STOP; are causing "illegal indirection" errors from my compiler. 导致我的编译器出现“非法间接访问”错误。 The double pointer reference is causing the counter value read to be used as a pointer. 双指针引用导致读取的计数器值用作指针。

#define STOPWATCH_START { m_nStart = *(*(volatile unsigned int*)0xE0001004);}
#define STOPWATCH_STOP  { m_nStop = *(*(volatile unsigned int *)0xE0001004);}

Based on your other #define statements and the addresses therein, should these be 根据您的其他#define语句及其中的地址,这些应该是

#define STOPWATCH_START { m_nStart = CPU_CYCLES;}
#define STOPWATCH_STOP  { m_nStop = CPU_CYCLES;}

as you have used elsewhere in the code? 就像您在代码的其他地方使用的一样?

NVIC registers are most likely protected by MPU and not accessible to user code. NVIC寄存器很可能受MPU保护,并且用户代码不可访问。 You cannot mess with everything when using an operating system. 使用操作系统时,您不可能一无所获。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM