Question

Modify devmem2.c to work as a function(s) rather than a main function. This function should be able to work with gpio devices

devmem2.c


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
  
#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
__LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char **argv) {
int fd;
void *map_base = NULL, *virt_addr = NULL;
unsigned long read_result, writeval;
off_t target;
int access_type = 'w';
  
if(argc < 2) {
fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n"
"\taddress : memory address to act upon\n"
"\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n"
"\tdata : data to be written\n\n",
argv[0]);
exit(1);
}
target = strtoul(argv[1], 0, 0);

if(argc > 2)
access_type = tolower(argv[2][0]);


if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
printf("/dev/mem opened.\n");
fflush(stdout);
  
/* Map one page */
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
if(map_base == (void *) -1) FATAL;
printf("Memory mapped at address %p.\n", map_base);
fflush(stdout);
  
virt_addr = (void *)((char *)map_base + (target & MAP_MASK));
switch(access_type) {
case 'b':
read_result = *((unsigned char *) virt_addr);
break;
case 'h':
read_result = *((unsigned short *) virt_addr);
break;
case 'w':
read_result = *((unsigned long *) virt_addr);
break;
default:
fprintf(stderr, "Illegal data type '%c'.\n", access_type);
exit(2);
}
printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result);
fflush(stdout);

if(argc > 3) {
writeval = strtoul(argv[3], 0, 0);
switch(access_type) {
case 'b':
*((unsigned char *) virt_addr) = writeval;
read_result = *((unsigned char *) virt_addr);
break;
case 'h':
*((unsigned short *) virt_addr) = writeval;
read_result = *((unsigned short *) virt_addr);
break;
case 'w':
*((unsigned long *) virt_addr) = writeval;
read_result = *((unsigned long *) virt_addr);
break;
}
printf("Written 0x%X; readback 0x%X\n", writeval, read_result);
fflush(stdout);
}
  
if(munmap(map_base, MAP_SIZE) == -1) FATAL;
close(fd);
return 0;
}


————————————————————————————————————————————-




0 0
Add a comment Improve this question Transcribed image text
Answer #1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <inttypes.h>

#define printerr(fmt,...) do { fprintf(stderr, fmt, ## __VA_ARGS__); fflush(stderr); } while(0)

#define VER_STR "devmem version T/C (http://git.io/vZ5iD) rev.0.3e"

int f_dbg = 0;

static void usage(const char *cmd)
{
fprintf(stderr, "\nUsage:\t%s [-switches] address [ type [ data ] ]\n"
"\taddress : memory address to act upon\n"
"\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n"
"\tdata : data to be written\n\n"
"Switches:\n"
"\t-r : read back after write\n"
"\t-a : do not check alignment\n"
"\t--version | -V : print version\n"
"\n",
cmd);
}

int main(int argc, char **argv)
{
int fd;
void *map_base, *virt_addr;
unsigned long read_result = -1, writeval=-1;
uint64_t target;
int access_type = 'w';
int access_size = 4;
unsigned int pagesize = (unsigned)getpagesize(); /* or sysconf(_SC_PAGESIZE) */
unsigned int map_size = pagesize;
unsigned offset;
char *endp = NULL;
int f_readback = 0; // flag to read back after write
int f_align_check = 1; // flag to require alignment
const char *progname = argv[0];
int opt;

opterr = 0;
while ((opt = getopt(argc, argv, "+raAdV")) != -1) {
switch(opt) {
case 'r':
f_readback = 1;
break;
case 'a':
f_align_check = 0;
break;
case 'A':
// Absolute address mode. Does nothing now, for future compat.;
break;
case 'd':
f_dbg = 1;
break;
case 'V':
printf(VER_STR "\n");
exit(0);
default:
if ( (!argv[optind]) || 0 == strcmp(argv[optind], "--help")) {
usage(progname);
exit(1);
}

if (0 == strncmp(argv[optind], "--vers", 6)) {
printf(VER_STR "\n");
exit(0);
}

printerr("Unknown long option: %s\n", argv[optind]);
exit(2);
}
}

argc -= optind - 1;
argv += optind - 1;

if (argc < 2 || argc > 4) {
usage(progname);
exit(1);
}

if (argc > 2) {
if (!isdigit(argv[1][0])) {
// Allow access_type be 1st arg, then swap 1st and 2nd
char *t = argv[2];
argv[2] = argv[1];
argv[1] = t;
}

access_type = tolower(argv[2][0]);
if (argv[2][1] )
access_type = '?';
}

errno = 0;
target = strtoull(argv[1], &endp, 0);
if (errno != 0 || (endp && 0 != *endp)) {
printerr("Invalid memory address: %s\n", argv[1]);
exit(2);
}

switch (access_type) {
case 'b':
access_size = 1;
break;
case 'w':
access_size = 4;
break;
case 'h':
access_size = 2;
break;
default:
printerr("Illegal data type: %s\n", argv[2]);
exit(2);
}

if ((target + access_size -1) < target) {
printerr("ERROR: rolling over end of memory\n");
exit(2);
}

if ( (sizeof(off_t) < sizeof(int64_t)) && (target > UINT32_MAX) ) {
printerr("The address %s > 32 bits. Try to rebuild in 64-bit mode.\n", argv[1]);
// Consider mmap2() instead of this check
exit(2);
}

offset = (unsigned int)(target & (pagesize-1));
if (offset + access_size > pagesize ) {
// Access straddles page boundary: add another page:
map_size += pagesize;
}

if (f_dbg) {
printerr("Address: %#" PRIX64 " op.size=%d\n", target, access_size);
}
if (f_align_check && offset & (access_size - 1)) {
printerr("ERROR: address not aligned on %d!\n", access_size);
exit(2);
}

fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
printerr("Error opening /dev/mem (%d) : %s\n", errno, strerror(errno));
exit(1);
}
//printf("/dev/mem opened.\n");
//fflush(stdout);

map_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd,
target & ~((typeof(target))pagesize-1));
if (map_base == (void *) -1) {
printerr("Error mapping (%d) : %s\n", errno, strerror(errno));
exit(1);
}
//printf("Memory mapped at address %p.\n", map_base);
//fflush(stdout);

virt_addr = map_base + offset;

if (argc > 3) {
errno = 0;
writeval = strtoul(argv[3], &endp, 0);
if (errno || (endp && 0 != *endp)) {
printerr("Invalid data value: %s\n", argv[3]);
exit(2);
}

if (access_size < sizeof(writeval) && 0 != (writeval >> (access_size * 8))) {
printerr("ERROR: Data value %s does not fit in %d byte(s)\n", argv[3], access_size);
exit(2);
}

switch (access_size) {
case 1:
*((volatile uint8_t *) virt_addr) = writeval;
break;
case 2:
*((volatile uint16_t *) virt_addr) = writeval;
break;
case 4:
*((volatile uint32_t *) virt_addr) = writeval;
break;
}

if (f_dbg) {
printerr("Address: %#" PRIX64 " Written: %#lX\n", target, writeval);
fflush(stdout);
}
}
  
if (argc <= 3 || f_readback) {
switch (access_size) {
case 1:
read_result = *((volatile uint8_t *) virt_addr);
break;
case 2:
read_result = *((volatile uint16_t *) virt_addr);
break;
case 4:
read_result = *((volatile uint32_t *) virt_addr);
break;
}

//printf("Value at address 0x%lld (%p): 0x%lu\n", (long long)target, virt_addr, read_result);
//fflush(stdout);
if (f_readback && argc > 3)
printf("Written 0x%lx; readback 0x%lx\n", writeval, read_result);
else
printf("%08lX\n", read_result);
fflush(stdout);
}

if (munmap(map_base, map_size) != 0) {
printerr("ERROR munmap (%d) %s\n", errno, strerror(errno));
}

close(fd);

return 0;
}

Add a comment
Know the answer?
Add Answer to:
devmem2.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Would u help me fixing this CODE With Debugging Code with GDB #include <stdio.h> #include <stdlib.h>...

    Would u help me fixing this CODE With Debugging Code with GDB #include <stdio.h> #include <stdlib.h> #define SIZE (10) typedef struct _debugLab { int i; char c; } debugLab; // Prototypes void PrintUsage(char *); void DebugOption1(void); void DebugOption2(void); int main(int argc, char **argv) { int option = 0; if (argc == 1) { PrintUsage(argv[0]); exit(0); } option = atoi(argv[1]); if (option == 1) { DebugOption1(); } else if (option == 2) { DebugOption2(); } else { PrintUsage(argv[0]); exit(0); } }...

  • #include <stdlib.h> #include <stdio.h> #include "main.h" #define MAX_NUM_LENGTH 11 void usage(int argc, char** argv) { if(argc...

    #include <stdlib.h> #include <stdio.h> #include "main.h" #define MAX_NUM_LENGTH 11 void usage(int argc, char** argv) { if(argc < 4) { fprintf(stderr, "usage: %s <input file 1> <input file 2> <output file>\n", argv[0]); exit(EXIT_FAILURE); } } /* This function takes in the two input file names (stored in argv) and determines the number of integers in each file. If the two files both have N integers, return N, otherwise return -1. If one or both of the files do not exist, it...

  • GIVEN CODE- FILL IN THE BLANK! #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h>...

    GIVEN CODE- FILL IN THE BLANK! #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> // Function ptototypes int readX(); void writeX(int); int main() /// chi read x ---> divi ---> write x into file ---> par read x --> sub--> write x into file---> chi read x-->etc {    int pid;           // pid: used to keep track of the child process    int x = 19530;       // x: our value as integer   ...

  • Combine two codes (code 1) to get names with(code 2) to get info: Code 1: #include<unistd.h>...

    Combine two codes (code 1) to get names with(code 2) to get info: Code 1: #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<dirent.h> #include<stdio.h> #include<stdlib.h> void do_ls(char []); int main(int argc,char *argv[]) { if(argc == 1) do_ls("."); else while(--argc){ printf("%s:\n",*++argv); do_ls(*argv); } } void do_ls(char dirname[]) { DIR *dir_ptr; struct dirent *direntp; if((dir_ptr = opendir(dirname)) == NULL) fprintf(stderr,"ls1:cannot open %s\n",dirname); else { while((direntp = readdir(dir_ptr)) != NULL) printf("%s\n",direntp->d_name); closedir(dir_ptr); } } ____________________________ code 2: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> void show_stat_info(char *,...

  • C Language Programming. Using the program below - When executing on the command line only this...

    C Language Programming. Using the program below - When executing on the command line only this program name, the program will accept keyboard input and display such until the user does control+break to exit the program. The new code should within only this case situation “if (argc == 1){ /* no args; copy standard input */” Replace line #20 “filecopy(stdin, stdout);” with new code. Open read a text file “7NoInputFileResponse.txt” that contains a message “There were no arguments on the...

  • #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> int main(void) { /* Type your code here....

    #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> int main(void) { /* Type your code here. */ int GetNumOfNonWSCharacters(const char usrStr[]) { int length; int i; int count = 0; char c; length=strlen(usrStr); for (i = 0; i < length; i++) { c=usrStr[i]; if ( c!=' ' ) { count++; } }    return count; } int GetNumOfWords(const char usrStr[]) { int counted = 0; // result // state: const char* it = usrStr; int inword = 0; do switch(*it)...

  • include «stdio.h void displaymenu(void) printf(" printf" Enter Choicen") printf Set (a), Clear (c), Toggle (t)\n"): printf("...

    include «stdio.h void displaymenu(void) printf(" printf" Enter Choicen") printf Set (a), Clear (c), Toggle (t)\n"): printf(" void printbinaryfunsigned char x) int main (int argc, char argvl) r mask atoi(argv[1): unsigned char maskatoi(argv[11): ensigned ahao data - ateilargvl21): char operation if argc 3 printf(" printf" n" printf("usage: %s FristArg SecondArgin", argle)); return;

  • Finish function to complete code. #include <stdio.h> #include <stdlib.h> #include<string.h> #define Max_Size 20 void push(char S[],...

    Finish function to complete code. #include <stdio.h> #include <stdlib.h> #include<string.h> #define Max_Size 20 void push(char S[], int *p_top, char value); char pop(char S[], int *p_top); void printCurrentStack(char S[], int *p_top); int validation(char infix[], char S[], int *p_top); char *infix2postfix(char infix[], char postfix[], char S[], int *p_top); int precedence(char symbol); int main() { // int choice; int top1=0; //top for S1 stack int top2=0; //top for S2 stack int *p_top1=&top1; int *p_top2=&top2; char infix[]="(2+3)*(4-3)"; //Stores infix string int n=strlen(infix); //length of...

  • Run the code in Linux and provide the screenshot of the output and input #include <signal.h>...

    Run the code in Linux and provide the screenshot of the output and input #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> static void cleanup(); static void docleanup(int signum); static const char *SERVER_ADDR = "127.0.0.1"; static const int SERVER_PORT = 61234; static int cfd = -1; int main(int argc, char *argv[]) { struct sockaddr_in saddr; char buf[128]; int bufsize = 128, bytesread; struct sigaction sigact; printf("client starts running ...\n"); atexit(cleanup); sigact.sa_handler =...

  • Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be...

    Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or semaphore failures. If you believe there is only one possible output, you just need to write that output. #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <errno.h> sem_t s1; int c=0,x=0; void *UpdateC1(void *arg) {    int i;    for(i=0;i<2000000;i++)   {        sem_wait(&s1);        c++;   x++;        sem_post(&s1);    } } void *UpdateC2(void *arg) {    int i,x=0;    for(i=0;i<2999999;i++)   {        sem_wait(&s1);        c++;   x++;       ...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT