That is experimental code I have not seen for some months (must first do the hardware)
It shows how to mmap the PRU / shared ram into the ARM memory space and dump the contents to files.
The dumps are somewhat annotated with the data structures I use.
This is ad hoc ripped from the source files, not intended to be compiled as it is.
#include <sys/types.h> /* type definitions used by many programs */
#include <stdio.h> /* standard IO functions */
#include <stdlib.h> /* commonly used functions, EXIT_SUCCESS and EXIT_FAILURE */
#include <errno.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "ltcsrv.h" /* for panic() */
#include "pru_if.h" /* to enforce consistency with .c */
#include "cmnd_stat_codes.h"
#define ADC_BUFFER_SIZE (16*1024)
int dev_mem_fd;
volatile int *shared_ram;
volatile int *pru_ram; // the 8 KB local data = 2 KWORDS
int adc_buffer[ADC_BUFFER_SIZE];
int cmnd_to_send;
int open_pru(){
int i;
//if \(verbose\) printf\("enter open\_pru\(\)\\n"\);
if \(init\_cpld\_pins\(\)\) return 1;
//if\(verbose\) printf\("starting pru 0\\n"\);
// if (!start_pru()) return 1;
// printf("sleeping 1 s\n");
// sleep(1);
// map the shared ram into our virtual memory
//printf\("mapping\.\.\.\\n"\);
dev\_mem\_fd = open\("/dev/mem",O\_RDWR | O\_SYNC\);
// mmap params:
// addres where the kernel creates the mapping\. NULL= do as you like
// size of the mapped region 12288 = 12 KBytes
// protection
// flags
// file descriptor von /dev/mem
// pru\-base = 0x4A30\_0000, shared ram starts at \+0x10000
shared\_ram = \(int \*\) mmap\(NULL, 12\*1024, PROT\_READ | PROT\_WRITE, MAP\_SHARED,
dev\_mem\_fd, 0x4A300000 \+ 0x10000\);
if \(\-1 == \(int\)shared\_ram\) panic\("could not mmap\(\) shared PRU ram"\);
// both PRU local data rams together
pru\_ram = \(int \*\) mmap\(NULL, 2\*8\*1024, PROT\_READ | PROT\_WRITE, MAP\_SHARED,
dev\_mem\_fd, 0x4A300000 \+ 0x00000\);
if \(\-1 == \(int\)pru\_ram\) panic\("could not mmap\(\) local PRU rams"\);
for \(i=0; i< ADC\_BUFFER\_SIZE; i\+\+\)\{ // 12 KB are 3 Kwords
adc\_buffer\[i\] = 0;
\}
return 0;
}
int close_pru(void){
// FIXME: shared RAM must be un-mapped and file descriptors should be closed
if (verbose) printf("enter close_pru()\n");
// if (!stop_pru()) return 1;
if (verbose) printf("leaving close_pru()\n");
return 0;
}
void copy_shared_ram_to_file(char *fn){
FILE \* phyle;
int i, j;
phyle = fopen\(fn, "w"\); // FIXME return value
fprintf\(phyle, "%s\\n", fn\);
fprintf\(phyle, "byte index dec byte index hex word index content\\n\\n"\);
for \(i=0; i< 3\*1024; i\+\+\)\{ // 12 KB are 3 Kwords
fprintf\(phyle, "\\n%12d %8x %8x = 0x%8x %12d", 4\*i, 4\*i, i, shared\_ram\[i\], shared\_ram\[i\]\);
switch\(i\)\{
case 0: fprintf\(phyle, " unused"\); break;
case COMMAND: fprintf\(phyle, " command"\); break;
case STATUS: fprintf\(phyle, " status"\); break;
case PARAM1: fprintf\(phyle, " param1"\); break;
case PARAM2: fprintf\(phyle, " param2"\); break;
case PARAM3: fprintf\(phyle, " param3"\); break;
case TEST1: fprintf\(phyle, " test1"\); break;
case TEST2: fprintf\(phyle, " test2"\); break;
case TEST3: fprintf\(phyle, " test3"\); break;
case PING\_FULL: fprintf\(phyle, " ping\_full"\); break;
case PONG\_FULL: fprintf\(phyle, " pong\_full"\); break;
case PING: fprintf\(phyle, " ping buffer start"\); break;
case PONG: fprintf\(phyle, " pong buffer start"\); break;
\}
\}
fclose\(phyle\); // FIXME return value
}
// thats for all the 2*8 KBytes
void copy_pru_ram_to_file(char *fn){
FILE \* phyle;
int i, j;
phyle = fopen\(fn, "w"\); // FIXME return value
fprintf\(phyle, "%s\\n", fn\);
fprintf\(phyle, "byte index word index content all hex\\n\\n"\);
fprintf\(phyle, "stack lowest and data nil pointer\\n"\);
for \(i=0; i< 4\*1024; i\+\+\)\{ // 2 \* 8 KB are 4 Kwords
if \(0x100/4 == i\) \{ fprintf\(phyle, "\\nstack highest \- heap lowest\\n"\); \}
else if \(0x200/4 == i\) \{ fprintf\(phyle, "\\nheap highest\\n"\); \}
fprintf\(phyle, "%8x %8x = %8x\\n", 4\*i, i, pru\_ram\[i\]\);
\}
fclose\(phyle\); // FIXME return value
}
hope it helps somewhat.
regards,
Gerhard