Skip to content

dsp hangs RedPitaya (caused by zeroing the global timer counter) #11

@carandraug

Description

@carandraug

The current dsp code hangs the RedPitaya. The simplest way to reproduce this is to use an empty action table.

$ touch empty-action-table
$ ./dsp empty-action-table
hello, w
hello, world!
actiontable is 0 lines long
alloc action table
read action table file.
## output stops here, press enter to flush
exec action table
faffing with actiontables
set time
exec action table done.
## At this point, system becomes irresponsive. We can no longer ssh and need to poweroff

I have reproduced this on RedPitaya OS versions 0.94 (oldest we have), 0.95, and 0.97. I have tried Tom's code on the master branch (version after his summer project) and on tom-december-changes (with his work during summer). I have reduced this to the minimal example of setting the global timer counter to zero, with this code:

// build with:
// gcc -Wall -g -O2 -c test.c -o test.o
// gcc -Wall -g -O2 -o test test.o

#include <stdint.h>
#include <stdio.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>

#define XPS_SCU_PERIPH_BASE		0xF8F00000U
#define XPAR_GLOBAL_TMR_BASEADDR	(XPS_SCU_PERIPH_BASE + 0x00000200U)

#define GLOBAL_TMR_BASEADDR               (XPAR_GLOBAL_TMR_BASEADDR-0x200U)
#define GTIMER_COUNTER_LOWER_OFFSET       (0x00U+0x200U)
#define GTIMER_COUNTER_UPPER_OFFSET       (0x04U+0x200U)
#define GTIMER_CONTROL_OFFSET             (0x08U+0x200U)

#define PAGE_SIZE ((size_t)getpagesize())
#define PAGE_MASK ((uint64_t)(long)~(PAGE_SIZE - 1))

int
main(int argc, char *argv[])
{
  int TIMER_FD = open("/dev/mem", O_RDWR|O_SYNC);
  if (TIMER_FD < 0) {
      fprintf(stderr, "open(/dev/mem) failed (%d)\n", errno);
      return 1;
  }

  volatile uint8_t* TIMER_MMAP;
  TIMER_MMAP = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                    TIMER_FD, GLOBAL_TMR_BASEADDR);
  if (TIMER_MMAP == MAP_FAILED) {
      fprintf(stderr, "mmap64(0x%x@0x%x) failed (%d)\n",
              PAGE_SIZE, (uint32_t)(XPAR_GLOBAL_TMR_BASEADDR), errno);
      return 1;
  }

  // Disable Global Timer
  *(volatile uint32_t *)(TIMER_MMAP+GTIMER_CONTROL_OFFSET) = 0x00;

  // Set Global Timer Counter Register to zero
  // Comment out this lines and the system no longer hangs.
  *(volatile uint32_t *)(TIMER_MMAP+GTIMER_COUNTER_LOWER_OFFSET) = (uint32_t)0;
  *(volatile uint32_t *)(TIMER_MMAP+GTIMER_COUNTER_UPPER_OFFSET) = (uint32_t)0;

  // Re-enable Global Timer
  *(volatile uint32_t *)(TIMER_MMAP+GTIMER_CONTROL_OFFSET) = (uint32_t)0x1;
  return 0;
}

Tiago has a version of the dsp program on his redpitaya branch which works but his version never zeros the register counter. His version reads the initial counter value and computes the difference from it.

I have asked Tiago who remembers seeing the same behaviour I do now.

But I guess this must have worked at some point somehow.

@tomparks can you shed some light on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions