調試完pcDuino的led裸板程序,再調pcDuino基於linux內核的gpio驅動開發,之前的問題迎刃而解。本文是在pcDuino的linux移植四簡單驅動開發的基礎上,作GPIO驅動開發。而後寫一個應用測試程序,經過敲命令控制pcduino的TX led亮、滅。同時若是你GPIO四、GPIO5接個LED,也會跟着亮、滅。node
開發環境:
系統:ubuntu 10.04.4
單板:pcDuino
編譯器:arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
linux
目標:敲命令控制pcDuino上的TX_LED亮、滅web
1、硬件介紹ubuntu
仔細看pcDuino上的原理圖和pcDuino的手冊,發現兩者不是徹底對應的,仍是以原理圖爲準。根據原理圖知道TX_LED是接到PH15上,能夠當作普通IO口用,不須要連跳線app
2、編寫GPIO驅動代碼oop
主要包括2部分,驅動代碼first_drv.c和應用測試程序firstdrvtest.c以及Makefile。測試
驅動代碼first_drv.cui
文件Makefile:spa
應用測試程序firstdrvtest.c:.net
3、編譯測試
1.編譯驅動first_drv.c
change@change :~/Si/A10/2_led$ cd ../pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/
change@change :~/Si/A10/pcduino/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/pcduino/linux-sunxi-sunxi-3.0 M=`pwd` modules clean
make[1]: Entering directory `/home/change/Si/A10/pcduino/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/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.o
/home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.c: In function 'first_drv_write':
/home/change/Si/A10/pcduino/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/pcduino/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/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.mod.o
LD [M] /home/change/Si/A10/pcduino/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/pcduino/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/pcduino/linux-sunxi-sunxi-3.0 M=`pwd` modules
make[1]: Entering directory `/home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0'
CC [M] /home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.o
/home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.c: In function 'first_drv_write':
/home/change/Si/A10/pcduino/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/pcduino/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/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.mod.o
LD [M] /home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv/first_drv.ko
make[1]: Leaving directory `/home/change/Si/A10/pcduino/linux-sunxi-sunxi-3.0'
2.編譯應用測試程序firstdrvtest.c
change@change:~/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv$ /home/change/tools/arm-2009q3/bin/arm-none-linux-gnueabi-gcc -o firstdrvtest firstdrvtest.c
其中/home/change/tools/arm-2009q3/bin/arm-none-linux-gnueabi-gcc是個人交叉編譯路徑,根據本身狀況修改。
change@change:~/Si/A10/pcduino/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$ cp first_drv.ko firstdrvtest /home/change/work/rootfs_dir/fs_mini/home/linux-3.0.62/pcduino/
change@change:~/Si/A10/pcduino/linux-sunxi-sunxi-3.0/drivers/mydrv/led_drv$
其中/home/change/work/rootfs_dir/fs_mini是個人NFS共享目錄,詳細配置見個人ubuntu 開發環境配置。程序比較簡單,就不分析了,有問題直接留言吧,開始測試吧。
3.測試
啓動前面pcDuino的linux移植1、2、3、四搭建的驅動開發平臺,上電進入pcDuino啓動控制檯,串口輸出以下
/ # ifconfig eth0 172.16.1.111
<4>wemac wemac.0: WARNING: no IRQ resource flags set.
[ 18.250000] wemac wemac.0: WARNING: no IRQ resource flags set.
<6>wemac wemac.0: eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[ 18.400000] wemac wemac.0: eth0: link up, 100Mbps, 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.137
PING 172.16.1.137 (172.16.1.137): 56 data bytes
64 bytes from 172.16.1.137: seq=0 ttl=64 time=10.015 ms
64 bytes from 172.16.1.137: seq=1 ttl=64 time=1.013 ms
64 bytes from 172.16.1.137: seq=2 ttl=64 time=1.735 ms
64 bytes from 172.16.1.137: seq=3 ttl=64 time=0.814 ms
^C
--- 172.16.1.137 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.137:/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/pcduino/
/mnt/home/linux-3.0.62/pcduino # ls
first_drv.ko firstdrvtest gpio_drv.ko gpiodrvtest
/mnt/home/linux-3.0.62/pcduino # insmod first_drv.ko
/mnt/home/linux-3.0.62/pcduino # lsmod
first_drv 1768 0 - Live 0xbf000000
/mnt/home/linux-3.0.62/pcduino # ./firstdrvtest off
first_drv_open
[ 303.610000] first_drv_open
first_drv_write
[ 303.610000] first_drv_write
/mnt/home/linux-3.0.62/pcduino # ./firstdrvtest on
first_drv_open
[ 309.510000] first_drv_open
first_drv_write
[ 309.510000] first_drv_write
/mnt/home/linux-3.0.62/pcduino #
能夠看到執行./firstdrvtest off ,pcDuino上的TX LED就滅,執行./firstdrvtest on,pcDuino上的TX LED就亮。測試基本正常,卸載剛剛加載的驅動以下;
/mnt/home/linux-3.0.62/pcduino # rmmod first_drv
/mnt/home/linux-3.0.62/pcduino # lsmod
/mnt/home/linux-3.0.62/pcduino #
基本OK了,下一步繼續完善驅動。