Reference samsung_s3c2410 serial driver

Source: Internet
Author: User

Reference samsung_s3c2410 serial driver

From: http://blog.chinaunix.net/u/7971/showart_548176.html

Reference

Serial Port driver of akem samsung_s3c2410

Today I wrote a 2410 serial port driver. Here I will summarize it as a review. I will not talk much nonsense.
2410 three comports are supported, and COM1 has been enabled in U-boot, so now you need to open the com2 port. load the driver as a module. and print the test at the com2 port. the Development Board has two serial ports, so we need to test them on two PCs. one host machine COM1 and one test serial port read/write com2.

The linux2.4 kernel has been downloaded from the Development Board. through the NFS file system. develop and communicate with the host. that is to say, develop and cross-compile the target file on a PC and load it to the development version through NFS.

Procedure:

Serial Data Transmission

1. Set the serial port to work in the interrupt and rotation Modes

2. Set the serial port's data bit length, stop bit, and whether there is a parity bit

3. Set the baud rate for sending and receiving data through the serial port

4. Write Data to the sending register

5. Check whether the Status Register bit is sent successfully.

Serial Port Data Reading

1. Set the serial port to work in the interrupt and polling Modes

2. Set the length of the Data bit sent and received by the serial port, stop bit, and check for parity

3. Set the baud rate for sending and receiving data through the serial port.

4. Check whether the Status Register has data

5. Read data


Code

----------------------------------------------------------------------
Utrs_driver.h configure related registers
-------------------------------------------------------------------------------

# Include <ASM/hardware. h>

/* The serial port Register address obtained through the 2410 Manual. The registers to be set by the driver */

/* Control register: Set the data bit, stop bit, and check bit 0x50004000 */
# Define uart_ulcon1 _ reg (0x50004000 + 0x00)
/* Set the serial port working mode. ucon1 is the second serial port, and the offset 0x04 is used to set the interrupt polling mode */
# Define uart_ucon1 _ reg (0x50004000 + 0x04)
/* Set the receiving register. The sending data offset 0x24 is in the L mode */
# Define uart_urxh1 _ reg (0x50004000 + 0x24)
/* Set the receiving register, sending and receiving status. The offset 0x20 indicates the L mode */
# Define uart_utxh1 _ reg (0x50004000 + 0x20)
/* Set the baud rate register for serial communication */
# Define uart_ubrdiv1 _ reg (0x50004000 + 0x28)
/* Set the accept status offset 0x10 to clear the buffer */
# Define uart_utrstat1 _ reg (0x50004000 + 0x10)

Int s3c2410_serial_open (void );
Int s3c2410_serial_release (void );
Int s3c2410_serial_read (unsigned char * Buf, int count );
Int s3c2410_serial_write (unsigned char * Buf, int count );

Bytes ---------------------------------------------------------------------------------------
Utrs_driver.c Driver Module
Bytes ---------------------------------------------------------------------------------------
# Include <Linux/config. h>
# Include <Linux/module. h>
# Include <Linux/kernel. h>
# Include <Linux/init. h>
# Include "utrs_driver.h"

/* Open the serial port and initialize */
Int s3c2410_serial_open (void)
{

Uart_ucon1 = 0x05;/* initialize the [3: 0] read/write mode of the control register to interrupt polling */
Uart_ulcon1 = 0x03;/* initialize the line control register [1: 0] to read and write 8-bit, that is, a character */
Uart_ubrdiv1 = 26;/* initialize the serial port. The baud rate is 26, 115200 */

Return 0;
}

Int s3c2410_serial_release (void)
{
Return 0;
}

/* Receiving module */
Int s3c2410_serial_read (unsigned char * Buf, int count)
{
Int I;
Unsigned char ch;

For (I = 0; I <count; I ++)
{
While (! (Uart_utrstat1 & 0x1);/* monitor whether the receiving register has data */

Ch = uart_urxh1;/* If data exists, save it with one character */

* (BUF + I) = CH;/* put it in the buffer zone */
}
Return count;
}

/* Sending module */
Int s3c2410_serial_write (unsigned char * Buf, int count)
{
Int I;
Unsigned char ch;

For (I = 0; I <count; I ++)
{
Ch = * (BUF + I);/* read a character from the buffer */

While (! (Uart_utrstat1 & 0x2) = 0x2);/* determines whether the receiving register is empty */

Uart_utxh1 = CH;/* write data to the Register if it is null */
}
Return 0;
}

/* The read/write modules of the serial port are separated, which does not mean that the write sends the read to receive the read. When the write is done, the com2 screen is printed, read is the data written in com2 and printed on the host */

Bytes ---------------------------------------------------------------------------------------
Utrs_test.c Test Module
Bytes ---------------------------------------------------------------------------------------
# Include <Linux/kernel. h>
# Include <Linux/module. h>
# Include <Linux/string. h>
# Include "utrs_driver.h"

Int s3c2410_serial_init (void)
{
Unsigned char STR [200] = "Hello fuck! /R/N ";
Unsigned char ch;
Int Len;

Len = strlen (STR );

Printk ("init Moule! /N ");

S3c2410_serial_open ();/* Open the serial port */
S3c2410_serial_release ();
S3c2410_serial_write (STR, Len);/* write data to the serial port. At this time, the PC Connected to com2 will print Hello fuck! */

While (Ch! = '#')
{
S3c2410_serial_read (& Ch, 1);/* input data on the com2 PC will be written to the receiving register and printed on the host */

/* Registers are read and written in one byte */
Printk ("% C", CH);/* print the data written in com2 to the Host */
}
Return 0;
}

Void s3c2410_serial_cleanup (void)
{
Printk ("clean Moule! /N ");
}

Int init_module (void)/* load module */
{
S3c2410_serial_init ();
Return 0;
}

Void cleanup_module (void)/* uninstall module */
{
S3c2410_serial_cleanup ();
}
Bytes -------------------------------------------------------------------------------------------

When the kernel is started, the driver creates a device file through a system script, and the application must open the corresponding device file to deal with the driver. The above example is not a complete driver, because the device is operated by Loading modules, and no device file is created. That is to say, manually load the data. The following example shows how to create a real device file, so it is a genuine driver.

Bytes ----------------------------------------------------------------------------------------------------------------

Utrs_driver.h

Bytes ----------------------------------------------------------------------------------------------------------------

# Include <ASM/hardware. h>

# Define uart_ulcon1 _ reg (0x50004000 + 0x00)
# Define uart_ucon1 _ reg (0x50004000 + 0x04)
# Define uart_urxh1 _ reg (0x50004000 + 0x24)
# Define uart_utxh1 _ reg (0x50004000 + 0x20)
# Define uart_ubrdiv1 _ reg (0x50004000 + 0x28)
# Define uart_utrstat1 _ reg (0x50004000 + 0x10)

Bytes ----------------------------------------------------------------------------------------------------------------

Utrs_driver.c

Bytes ----------------------------------------------------------------------------------------------------------------

# Include <Linux/config. h>
# Include <Linux/module. h>
# Include <Linux/kernel. h>
# Include <Linux/init. h>
# Include <Linux/sched. h>
# Include <Linux/miscdevice. h>
# Include <Linux/delay. h>
# Include <Linux/poll. h>
# Include <ASM/hardware. h>
# Include "utrs_driver.h"
 
# Define device_name "akem" // Device File Name
# Define button_major 232 // master device number
 

/* Open the drive inode structure to internally represent the file. The file structure is to open the file structure corresponding to the file descriptor FD sent above. The file structure points to a single inode */
Static int akem_open (struct inode * inode, struct file * file)
{

/* Set REGISTERS */
Uart_ucon1 = 0x05;
Uart_ulcon1 = 0x03;
 
Printk ("kernel: in open, we do nothing.../N ");
Return 0;
}
 

/* When reading data from a device, the upper-layer READ function will call this function. file is the FD structure of read, and PPOs is the system callback */
Static int akem_read (struct file * file, char * buff, size_t count, loff_t * PPOs)
{
Int I;
Unsigned char ch;

For (I = 0; I <count; I ++)
{
While (! (Uart_utrstat1 & 0x1);/* scan the register for Data */
Ch = uart_urxh1;/* read a byte from the register */
* (Buff + I) = CH;/* store in Buff */
}
Return strlen (buff);/* return the length of the buff */
}

/* Write data to the device. The upper-layer write function will call this function. file is the structure of the write FD, and OFFP is the system callback */
Int akem_write (struct file * filp, const char * buff, size_t count, loff_t * OFFP)
{
Int I;
Unsigned char ch;

For (I = 0; I <count; I ++)
{
Ch = * (buff + I );
While (! (Uart_utrstat1 & 0x2) = 0x2);/* scan register for Data */
Uart_utxh1 = CH;/* write one byte to the Register */
}
Return 0;
}
/* Set the baud rate of the serial port */
Static int akem_ioctl (struct inode * inode, struct file * file, unsigned int cmd, unsigned long Arg)
{
Int ret;
Ret =-einval;
Switch (CMD)
{
Case 111:/* configure the baud rate with a successful command */
{
If (ARG = 115200)
{
Uart_ubrdiv1 = 26;
Ret = 0;
}
}; Break;
 
Default:
Return-einval;
}
 
Printk ("kernel: In ioctl, (% d, % d)/n", CMD, ARG );
}
 
Int akem_release (struct inode * inode, struct file * filp)
{
Printk ("Release !! /N ");
Return 0;
}
/* The file_operations structure is used to establish a connection between the driver program and the device number. It contains a set of function pointers. Each opened file, that is, the file structure, is associated with a group of functions, these operations are mainly used to implement system calls */
Static struct file_operations akae_fops = {
 
Owner: this_module,
Open: akae_open,
IOCTL: akae_ioctl,
Read: akae_read,
Write: akae_write,
Release: akae_release
 
};
/* Initialize the driver module. The driver must register a device file and perform operations on it */
Static int _ init akem_init (void)
{
Int ret;
Int ready = 0;

/* Register a character device and assign the device number. Major indicates the device number, and name indicates the driver name. fops indicates the file_operations structure */
Ret = register_chrdev (button_major, device_name, & akae_fops );

If (Ret <0)
{
Printk (device_name "can't register major number/N ");
Return ret;
}
Printk ("init OK !...... /N ");
Return 0;/* return 0 after successful registration */
}
/* Uninstall the module */
Static void _ exit akem_exit (void)
{

/* If this device is not used, release the number */
Unregister_chrdev (button_major, device_name );
Printk ("Bye! /N ");
}
 
Module_init (akem_init );
Module_exit (akem_exit );
Module_license ("GPL ");

Bytes ----------------------------------------------------------------------------------------------------------------

Test. C Test Module

This testing model is fast driven by application calls instead of modules. Therefore, this is the driving essence.

Bytes ----------------------------------------------------------------------------------------------------------------

# Include <stdio. h>
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <fcntl. h>

# Define boundrate 111/* set the Bert rate command parameter */

Int main (void)
{
Int FD;
Int ret = 0;
Char Buf [100] = "Hello fuck! /N/R ";
Char ch;

FD = open ("/temp/akem", o_rdwr);/* Open will directly call the akem_open */
If (FD =-1)
{
Perror ("open ");
Exit (1 );
}

Ret = IOCTL (FD, boundrate, 115200);/* set Bert's law 115200 */

Ret = write (FD, Buf, strlen (BUF);/* write will call the akem_write */
If (ret =-1)
{
Perror ("write error ");
Exit (1 );
}

While (Ch! = '#')
{
Read (FD, & Ch, 1 );
Printf ("% C", CH );
Fflush (stdout );
}

Close (FD );
}

Created at: 11:23:20, modified at: 11:23:20, viewed 823 times, with one comment

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.