Page 2 of 2 FirstFirst 12
Results 11 to 14 of 14

Thread: Beaglebone board as E1.31 controller

  1. #11
    Join Date
    Dec 2010
    Location
    SF Bay Area
    Posts
    752
    Post Thanks / Like

    Default Re: Beaglebone board as E1.31 controller

    Dan is the man with the resources/links. :-)

    I do remember why I purchased my first BB - the PRUs. Up until that point I had designed and used a controller based on the Parallax Propeller. It's key feature is 100% determinism (timing - no interrupts). The challenges were a) it's dog slow by today's standards, and b) there is no (reasonable) OS - so everything you want, you need to find or build. The BB w/ PRUs was a great mashup for driving pixels: a full Linux OS with lots of high level functionality *and* the PRUs which can provide the deterministic timing for custom protocols.

    My $0.02: while the am335x_pru_package code may be helpful for bootstrapping your understanding of how things work when using the PRUs with Linux, it (the version available when I was investigating) is, IMO, not a robust implementation (the part that deals with setting up the PRUs, not necessarily the PRU code itself). As a specific example, it is writing to physical memory addresses (through /dev/mem) that were not specified by the kernel or any drivers, or any system documentation of the memory map - just a "magic address" that appears to be in memory that Linux is free to allocate to processes. It works, but by sheer luck as best I can tell. Updating a kernel and having a system become inexplicably, profoundly broken is not something I want to content with.

    Good luck and have fun (I think you will) - however you proceed.

  2. #12
    Join Date
    Dec 2010
    Location
    SF Bay Area
    Posts
    752
    Post Thanks / Like

    Default Re: Beaglebone board as E1.31 controller

    @dkulp are you using remoteproc for your work? I followed the link you posted above to the PRUCookbook and that's what it's calling out in the TOC. I decided to go with the uio drivers. It seems to be somewhat of a religious battle in the Linux world. I'm curious what you decided, and why.

  3. #13
    Join Date
    Dec 2012
    Location
    Framingham, MA
    Posts
    462
    Post Thanks / Like

    Default Re: Beaglebone board as E1.31 controller

    Yea... uio vs remoteproc is definitely the "vi vs emacs" thing of the BBB PRU world. I do understand the rational. uio is very "wide open". A malicious app can load a PRU program that reads the entire memory space (including kernel space) very easily. Thus, from a security standpoint, uio is a nightmare. However, for our case, we already run everything as root so we already have all kinds of issues.

    We use uio. The main reason is that no-one has show how to transfer large blocks of data between the arm and pru via remoteproc. A 96 P10 panel matrix require 150K of data each frame. Without being able to write directly to a large buffer and send as one, getting it to perform well would be very hard. In addition, remoteproc require the pru code to be in /lib/firmware. For FPP, we compile custom optimized pru code depending on what settings are used. Thus, we'd have to be writing into /lib/firmware which is also something I try to avoid.

    FYI: the memory addresses in /dev/mem are not "magic". They are allocated by the uio_pruss kernel driver. The am335x_pru_package package reads those from "/sys/class/uio/uio0/maps/map1/addr". That said, you are correct in that the am335x_pru_package is simplistic. We don't use it to initialize the pru's in FPP anymore. Part of the reason is that it doesn't handle using BOTH PRU's very well. The signals and such tend to interfere with each other. I think querying the PRU's 12K of shared ram didn't work either. For FPP, I wrote our own pru initialization stuff that interacts with the pruss calls directly.
    Dan Kulp

  4. #14
    Join Date
    Dec 2010
    Location
    SF Bay Area
    Posts
    752
    Post Thanks / Like

    Default Re: Beaglebone board as E1.31 controller

    @dkulp yes, the uio driver "devices" (files in /sys/class/uio/...) are the proper way to get the base address and size of the PRUSS (the whole thing). The other necessary information is found in the PRUSS documentation, with offsets from the base address to everything else. Here's the kind of "magic number" I'm talking about:

    From file "pru_sw/example_apps/PRU_memAccess_DDR_PRUsharedRAM/PRU_memAcc_DDR_sharedRAM.c"

    Code:
    #define DDR_BASEADDR     0x80000000
    #define OFFSET_DDR	 0x00001000
    
    /*****************************************************************************
    * Local Function Definitions                                                 *
    *****************************************************************************/
    
    static int LOCAL_exampleInit (  )
    {
        void *DDR_regaddr1, *DDR_regaddr2, *DDR_regaddr3;
    
        /* open the device */
        mem_fd = open("/dev/mem", O_RDWR);
        if (mem_fd < 0) {
            printf("Failed to open /dev/mem (%s)\n", strerror(errno));
            return -1;
        }
    
        /* map the DDR memory */
        ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, DDR_BASEADDR);
        if (ddrMem == NULL) {
            printf("Failed to map the device (%s)\n", strerror(errno));
            close(mem_fd);
            return -1;
        }
    
        /* Store Addends in DDR memory location */
        DDR_regaddr1 = ddrMem + OFFSET_DDR;
        DDR_regaddr2 = ddrMem + OFFSET_DDR + 0x00000004;
        DDR_regaddr3 = ddrMem + OFFSET_DDR + 0x00000008;
    
        *(unsigned long*) DDR_regaddr1 = ADDEND1;
        *(unsigned long*) DDR_regaddr2 = ADDEND2;
        *(unsigned long*) DDR_regaddr3 = ADDEND3;
    
        return(0);
    }
    Real memory starts @ 0x80000000. This code maps the entire 500MiB of real memory, and decides that it's OK to use the 12 bytes starting at offset 0x1000. I'm no expert in how Linux carves out the kernel and user space memory pages, but just reading/writing to a location "that looks good" -- even if it works -- is not a reliable implementation. This is why I suggest caution if using code from this package.
    Last edited by ags0000; 01-11-2019 at 02:50 PM.

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •