Menu Close

Writing Device Tree Driver Test and Application

This article talks about how to write a executable application for the device tree driver that was just written.

For related subjects, please refer to the SOC Table of Contents.

 

Go back to your Ubuntu system and create a folder named test_func in your home directory. Create a .c file called fii_dt_app.c within the test_func directory we just created.

Code download: Driver App

We will edit its contents to the following:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>   /* File Control Definitions           */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h>  /* UNIX Standard Definitions      */
#include <errno.h>   /* ERROR Number Definitions           */
#include <string.h>

// Number of strings in array argv
// int main( int argc,            char *argv[],
// void main(void)

static void print_msg(void)
{
    printf("=============================================================\n");
    printf("Usage :\n");
    printf("./fii_app.o dir <val> : val : 0 => output; 1 => input\n");
    printf("./fii_app.o wr  <val> : val : 0x43c0_0004 address value\n");
    printf("./fii_app.o rd        : \n");
    printf("=============================================================\n");

    return;
}

static void func_read(int fd,  int read_cnt)
{
    char rd_buf[32];        /* Buffer to store the data received              */
    int  bytes_read = 0;    /* Number of bytes read by the read() system call */
    unsigned int temp;

    printf("Press ctrl+C to exit \n");
    tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer */
    lseek(fd, 0, SEEK_SET);

    bytes_read = read(fd, rd_buf, read_cnt);

    printf("\n\nBytes Rxed = %d \n", bytes_read); /* Print the number of bytes read */

    temp = rd_buf[0];
    temp = (temp << 8) | rd_buf[1];
    temp = (temp << 8) | rd_buf[2];
    temp = (temp << 8) | rd_buf[3];

    printf("read value = 0x%08x \n", temp);

    temp = rd_buf[4];
    temp = (temp << 8) | rd_buf[5];
    temp = (temp << 8) | rd_buf[6];
    temp = (temp << 8) | rd_buf[7];

    printf("read dir   = 0x%08x \n", temp);

    printf("\n +----------------------------------+\n\n\n");

//    usleep(1000000);

    return;
}

static void func_write(int fd,  char *p)
{
    char wr_buf[32];
    ssize_t bytes_written = 0;
    unsigned int value;
    memset (wr_buf, 0x0a, 32);
    value = atoi(p);

    printf("value = %x \n" , value);

    wr_buf[0] = 'w';
    wr_buf[1] = ' ';
    wr_buf[2] = value >> 24;
    wr_buf[3] = (value >> 16) & 0xff;
    wr_buf[4] = (value >> 8) & 0xff;
    wr_buf[5] = value & 0xff;

    bytes_written = write(fd, wr_buf, 7);

    return;
}

static void func_direction(int fd,  char *p)
{
    char wr_buf[32];
    ssize_t bytes_written = 0;
    unsigned int value;
    memset (wr_buf, 0x0a, 32);
    value = atoi(p);

    printf("value = %x \n" , value);

    wr_buf[0] = 'd';
    wr_buf[1] = ' ';
    wr_buf[2] = value >> 24;
    wr_buf[3] = (value >> 16) & 0xff;
    wr_buf[3] = (value >> 8) & 0xff;
    wr_buf[5] = value & 0xff;

    bytes_written = write(fd, wr_buf, 7);
}

int main( int argc, char *argv[])
{
    int fd;/*File Descriptor*/
    unsigned int value = 0;
    char * cmd_p;

    /* O_RDWR    - Read/Write access to serial port     */
    /* O_RDONLY  - Read access to serial port           */
    /* O_WRONLY  - Write access to serial port          */
    /* O_NOCTTY  - No terminal will control the process */

    /* Open in blocking mode,read will wait             */

    fd = open("/dev/fii-module",O_RDWR );

    printf("\n +----------------------------------+");
    printf("\n |     fii-driver function          |");
    printf("\n +----------------------------------+");

    if(fd == -1)                             /* Error Checking */
        printf("\n  Error! in Opening swled  \n");

    else
        printf("\n  fii-driver Opened Successfully \n");

    cmd_p = argv[1];

    if(argc == 2)
    {
        if( strcmp (cmd_p , "rd") == 0 )
        {
            func_read(fd,  8);
            return 0;
        }

        else
        {
            print_msg();
            close(fd); /* Close the serial port */
            return 1;
        }
    }

    else if (argc == 3)
    {
        if( strcmp (cmd_p , "wr") == 0 )
        {
            func_write(fd, argv[2]);
            close(fd); /* Close the serial port */
            return 0;
        }

        else if( strcmp (cmd_p , "dir") == 0 )
        {
            func_direction(fd, argv[2]);
            close(fd); /* Close the serial port */
            return 0;
        }
    }

    else
    {
        print_msg();
        close(fd); /* Close the serial port */
        return 1;
    }

    return 0;
}

Next, start up the terminal from the fii_dt_app.c file directory and execute the following commands:

sptl
arm-linux-gnueabihf-gcc fii_dt_app.c -o fii_dt_app.o

This will create a fii_dt_app.o file that you will copy to the SD card.

We will now boot up the development board once more and mount the SD partition where you copied the file. Next, execute the following command to start up fii_dt_app.

./fii_dt_app.o

Note the help instructions that are also displayed, which we wrote in the code. We can read and write operations.

Some examples are:

./fii_dt_app.o dir 0        Sets all gpio as outputs.

./fii_dt_app.o wr 0          Sets the lowest gpio as 0.

./fii_dt_app.o wr 7          Sets the lowest 3 gpio as 0.

./fii_dt_app.o dir 7        Sets the lowest 3 gpio as input. The 3 lights on the left light up (7 is binary 111).

./fii_dt_app.o rd             Reads the gpio value; the user can flip the switches to see gpio status.

Notice how the LED lights on the development board change with the commands.

Posted in Textbook and Training Project

Related Articles

Leave a Reply

Your email address will not be published.

Leave the field below empty!