Porting the five gpio driver development to Linux in pcsag

Source: Internet
Author: User

After debugging the pcduino led bare-board program, and then debugging the pcduino gpio driver development based on the Linux kernel, the previous problems can be solved. This article is based on the four simple driver development for Linux porting in pcsag, and implements gpio driver development. Then, write an application test program and run the command to control whether or not the Tx LEDs of the pcduino are on or off. At the same time, if you connect gpio4 and gpio5 to an LED, it will also be on and off.

Development Environment:

System: Ubuntu 10.04.4

Board: pc.pdf

Compiler: arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

Objective: To control whether tx_led is on or off the pcduino

I. Hardware Introduction

Take a closer look at the schematic diagram and the pcduino manual on pcduino, and find that the two are not exactly the same, or refer to the schematic diagram. According to the principle diagram, tx_led is connected to ph15 and can be used as a common IO port without jumper.


2. Write gpio driver code

It consists of two parts: the driver code first_drv.c, the application test program firstdrvtest. C, and makefile.

Driver code first_drv.c

# Include <Linux/module. h> # include <Linux/kernel. h> # include <Linux/Fs. h> # include <Linux/init. h> # include <Linux/delay. h> # include <ASM/uaccess. h> # include <ASM/IRQ. h> # include <ASM/Io. h> # include <Mach/gpio. h> # include <Mach/hardware. h> # include <Linux/device. h> static struct class * firstdrv_class; static struct class_device * firstdrv_class_dev; volatile unsigned long * gphcfg1; // 0x100 pH9 [] 001 volatile uns Igned long * gphdat; // 0x10cstatic int first_drv_open (struct inode * inode, struct file * file) {printk ("first_drv_open \ n "); /* configure gph9 as the output pin gpio4 */* gphcfg1 | = (0x1 <4) | (0x1 <8) | (0x1 <28); Return 0;} static ssize_t first_drv_write (struct file * file, const char _ User * Buf, size_t count, loff_t * PPOs) {int val; printk ("first_drv_write \ n"); copy_from_user (& Val, Buf, count); // copy_to_user (); If (val = 1) {// point Lamp * gphdat & = ~ (0x1 <9) | (0x1 <10) | (1 <15 ));} else {// lamp removal * gphdat | = (0x1 <9) | (0x1 <10) | (1 <15 ));} return 0;} static struct file_operations first_drv_fops = {. owner = this_module ,. open = first_drv_open ,. write = first_drv_write,}; int Major; static int first_drv_init (void) {major = register_chrdev (0, "first_drv", & gt; firstdrv_class = class_create (this_module, "firstdrv"); firstdrv_class_dev = device_create (firstdrv_class, null, mkdev (Major, 0), null, "XYZ"); gphcfg1 = (volatile unsigned long *) ioremap (0x01c20900, 16); gphdat = (volatile unsigned long *) ioremap (0x01c2090c, 16); // gphcfg1 + 3; return 0;} static void first_drv_exit (void) {Merge (Major, "first_drv"); device_unregister (batch); class_destroy (firstdrv_class); iounmap (gphcfg1); iounmap (gphdat);} module_init (batch); module_exit (batch ); module_license ("GPL ");

File makefile:

KERN_DIR = /home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0all:make -C $(KERN_DIR) M=`pwd` modulesclean:make -C $(KERN_DIR) M=`pwd`  modules cleanrm -rf modules.orderobj-m+= first_drv.o

Application Test Program firstdrvtest. C:

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>/* firstdrvtest on  * firstdrvtest off  */int main(int argc, char **argv){int fd;int val = 1;fd = open("/dev/xyz", O_RDWR);if (fd < 0){printf("can't open!\n");}if (argc != 2){printf("Usage :\n");printf("%s <on|off>\n", argv[0]);return 0;}if (strcmp(argv[1], "on") == 0){val  = 1;}else{val = 0;}write(fd, &val, 4);return 0;}

Iii. Compile and Test

1. The compilation driver first_drv.c
Change @ change :~ /Si/A10/2_led $ CD ../pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/
Change @ change :~ /Si/A10/pc.pdf/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $ ls
First_drv.c first_drv.mod.c first_drv.o firstdrvtest. c modules. Order
First_drv.ko first_drv.mod.o firstdrvtest makefile module. symvers
Change @ change :~ /Si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $ make clean
Make-C/home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0 M = 'pwd' modules clean
Make [1]: Entering directory '/home/change/si/A10/pc10/linux-sunxi-sunxi-3.0'
LD/home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/built-in.o
CC [m]/home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.o
/Home/change/si/A10/pc1_/ linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_write ':
/Home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 30: Warning: Ignoring return value of 'Copy _ from_user ', declared with attribute warn_unused_result
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_init ':
/Home/change/si/A10/pcment/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 57: Warning: assignment from incompatible pointer type
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_exit ':
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 66: Warning: Passing argument 1 of 'device _ unregister 'from incompatible pointer type
Include/Linux/device. h: 692: Note: Expected 'struct device * 'But argument is of Type 'struct class_device *'
Building modules, stage 2.
Modpost 1 modules
CC/home/change/si/A10/pc1_/ linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.mod.o
LD [m]/home/change/si/A10/pc.pdf/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.ko
Clean/home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/. tmp_versions
Clean/home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/module. symvers
Make [1]: Leaving directory '/home/change/si/A10/pcing/linux-sunxi-sunxi-3.0'
Rm-RF Modules. Order
Change @ change :~ /Si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $ make
Make-C/home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0 M = 'pwd' modules
Make [1]: Entering directory '/home/change/si/A10/pc10/linux-sunxi-sunxi-3.0'
CC [m]/home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.o
/Home/change/si/A10/pc1_/ linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_write ':
/Home/change/si/A10/pcloud/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 30: Warning: Ignoring return value of 'Copy _ from_user ', declared with attribute warn_unused_result
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_init ':
/Home/change/si/A10/pcment/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 57: Warning: assignment from incompatible pointer type
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: In function 'first _ drv_exit ':
/Home/change/si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.c: 66: Warning: Passing argument 1 of 'device _ unregister 'from incompatible pointer type
Include/Linux/device. h: 692: Note: Expected 'struct device * 'But argument is of Type 'struct class_device *'
Building modules, stage 2.
Modpost 1 modules
CC/home/change/si/A10/pc1_/ linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.mod.o
LD [m]/home/change/si/A10/pc.pdf/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv/first_drv.ko
Make [1]: Leaving directory '/home/change/si/A10/pcing/linux-sunxi-sunxi-3.0'

2. Compile the application test program firstdrvtest. C.

Change @ change :~ /Si/A10/pc10/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $/home/change/tools/arm-2009q3/bin/ARM-None-Linux-gnueabi-gcc-O firstdrvtest. c

Here,/home/change/tools/arm-2009q3/bin/ARM-None-Linux-gnueabi-GCC is my cross-compilation path, which can be modified as needed.

Change @ change :~ /Si/A10/pc.pdf/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $ ls
First_drv.c first_drv.mod.c first_drv.o firstdrvtest. c modules. Order
First_drv.ko first_drv.mod.o firstdrvtest makefile module. symvers
Change @ change :~ /Si/A10/pcloud/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $ cpfirst_drv.ko firstdrvtest/home/change/work/rootfs_dir/fs_mini/home/linux3.0.62/pcloud/

Change @ change :~ /Si/A10/pcduino/linux-sunxi-sunxi-3.0/Drivers/mydrv/led_drv $
Here,/home/change/work/rootfs_dir/fs_mini is my NFS shared directory. For detailed configuration, see my Ubuntu Development Environment configuration. The program is relatively simple. If you have any questions, leave a message and start testing.

3. Test

Start the driver development platform built on Linux Port 1, 2, 3, and 4 in the previous pcsag, and enter the pcsag startup console. The serial port output is as follows:
/# Ifconfig eth0 172.16.1.111
<4> wemac wemac.0: Warning: No IRQ resource flags set.
[2, 18.250000] wemac wemac.0: Warning: No IRQ resource flags set.
<6> wemac wemac.0: eth0: link up, 100 Mbps, full-duplex, LPA 0x45e1
[18.400000] wemac wemac.0: eth0: link up, 100 Mbps, full-duplex, LPA 0x45e1
/# Ping 172.16.1 <7> eth0: No IPv6 routers present
[28.860000] eth0: No IPv6 routers present

Ping 172.16.1 (172.16.0.1): 56 data bytes
^ C
--- 172.16.1 Ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
/# Ping 172.16.1.20.
Ping 172.16.1.20.( 172.16.1.20.): 56 data bytes
64 bytes from 172.16.1.20.: seq = 0 TTL = 64 time = 10.015 MS
64 bytes from 172.16.1.20.: seq = 1 TTL = 64 time = 1.013 MS
64 bytes from 172.16.1.20.: seq = 2 TTL = 64 time = 1.735 MS
64 bytes from 172.16.1.20.: seq = 3 TTL = 64 time = 0.814 MS
^ C
--- 172.16.1.20.ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
Round-trip min/AVG/max = 0.814/3.394/10.015 MS
/# Ls
Bin etc lib MNT run sys USR
Dev home linuxrc proc sbin TMP VaR
/# Mount-T nfs-O nolock 172.16.1.20.:/home/change/work/rootfs_dir/fs_mini/Mn
T/
/# Ls/mnt/
Bin etc lib MNT root sys USR
Dev home linuxrc proc sbin TMP
/# Cd/mnt/home/linux-3.0.62/pc.pdf/
/Mnt/home/linux-3.0.62/pcduino # ls
First_drv.ko firstdrvtest gpio_drv.ko gpiodrvtest
/Mnt/home/linux-3.0.62/pcmod # insmod first_drv.ko
/Mnt/home/linux-3.0.62/pcmod # lsmod
First_drv 1768 0-live 0xbf000000
/Mnt/home/linux-3.0.62/pctest #./firstdrvtest off
First_drv_open
[1, 303.610000] first_drv_open
First_drv_write
[1, 303.610000] first_drv_write
/Mnt/home/linux-3.0.62/pctest #./firstdrvtest on
First_drv_open
[1, 309.510000] first_drv_open
First_drv_write
[1, 309.510000] first_drv_write
/Mnt/home/linux-3.0.62/pcduino #
You can see that the execution./firstdrvtest off, the Tx led on the pcsag is off, the execution./firstdrvtest on, and the Tx led on the pcsag is on. The test is basically normal. Uninstall the loaded driver as follows;
/Mnt/home/linux-3.0.62/pcmod # rmmod first_drv
/Mnt/home/linux-3.0.62/pcmod # lsmod
/Mnt/home/linux-3.0.62/pcduino #
Basically OK. Next, continue to improve the driver.

 

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.