Giao tiếp USB Webcam, Camera

Giao tiếp USB Webcam, Camera Có nhiều bạn hỏi mua một số loại camera chuyên dụng như UART camera, ISI image sensor. Những loại này đặc biệt, chỉ có bán ở nước ngoài và giá cỡ trăm USD không kể tiền ship. Tại sao ta không tận dụng những USB camera có sẵn của máy vi tính? Giá cỡ 150-250K, thấp không thể tin được !!! Ta chỉ cần trang bị một số kiến thức về Linux embedded system, như vậy có thể sử dụng ngon lành những thứ có sẵn này rồi. Với kernel 2.6 và hệ thống có hỗ trợ USB host (full speed 2.0 vẫn chạy ngon lành) là có thể áp chạy được, và ta có thể khám phá một số điều thú vị về mảng này.

doc43 trang | Chia sẻ: maiphuongtt | Lượt xem: 1810 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Giao tiếp USB Webcam, Camera, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Giao tiếp USB Webcam, Camera MỤC LỤC Giao tiếp USB Webcam, Camera Có nhiều bạn hỏi mua một số loại camera chuyên dụng như UART camera, ISI image sensor... Những loại này đặc biệt, chỉ có bán ở nước ngoài và giá cỡ trăm USD không kể tiền ship. Tại sao ta không tận dụng những USB camera có sẵn của máy vi tính? Giá cỡ 150-250K, thấp không thể tin được !!! Ta chỉ cần trang bị một số kiến thức về Linux embedded system, như vậy có thể sử dụng ngon lành những thứ có sẵn này rồi. Với kernel 2.6 và hệ thống có hỗ trợ USB host (full speed 2.0 vẫn chạy ngon lành) là có thể áp chạy được, và ta có thể khám phá một số điều thú vị về mảng này. Ở máy tính, có thể kernel được build sẵn driver cho các loại USB camera thông thường. Đối với hệ thống nhúng, ta cần cấu hình và build driver này, các bước cấu hình cho linux-2.6.27 (áp dụng cho KM9260) được thực hiện như sau: Code: Code: $ cd linux-2.6.27 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig Cấu hình kernel như sau: Code: Code: Device Driver ---> Multimedia devices ---> Video For Linux [*] Enable Video For Linux API 1 (DEPRECATED) ...[*] Video capture adapters --->[*] V4L USB devices ---> USB Video Class (UVC)[*] UVC input events device support USB GSPCA driver Sau khi cấu hình xong, build uImage và reboot hệ thống: Code: [CODE] $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage [CODE] Sau khi reboot hệ thống, ta gắn USB camera vào, kernel sẽ tự động nhận dạng thiết bị, và tạo ra device file trong thư mục /dev, giá trị default là "/dev/video0". Tới bước này ta hoàn tất driver cho hệ thống, ta cần đến chương trình ứng dụng tương tác với driver này và thực hiện capture ảnh theo mong muốn. Những ứng dụng này sử dụng thư viện V4L (video for Linux) và có rất nhiều source nguồn mở trên internet, ta có thể download source về build và chạy, hoặc có thể tự tham khảo các V4L API tự viết cho mình. Kernel linux-2.6.27 hiện nay hỗ trợ driver thích hợp cho phiên bản V4L2 (phên bản sau của V4L) và một số ứng dụng cũ trên mạng vẫn dùng V4L vì thế không thể vận hành được driver trên. Đối với board nhúng KM9260 không hỗ trợ GLCD display, làm sao hiển thị kết quả thu được từ USB camera ? Có 2 giải pháp: 1> Hiển thị lên X server chạy trên máy tính, lúc này ta cần phải export biến môi trường DISPLAY. 2> Stream kết quả lên trang web, dùng trình duyệt FireFox để hiển thị. Ta sử dụng cách thứ 2 băng cách download source chương trình ứng dụng ở link sau: Sau khi build và chạy chương trình ứng dụng ta có kết quả sau: Thêm nữa, hiện nay các module wireless hỗ trợ cho hệ thống VĐK bao gồm các module ZigBee...Nhưng giá thành vẫn còn đắt đỏ, có vẽ còn xa vời. Tuy nhiên, hiện nay trên thị trường vi tính hiện nay xuất hiện USB Wireless apdapter có nhãn hiệu Tenda W541U V2.0, chuẩn G 54Mbps, giá cỡ dưới 200K tùy vào chỗ bán. Không may, theo trang web của Tenda họ nói chỉ hỗ trợ cho Windows, không hỗ trợ cho Linux. Gắn USB adapter này vào hệ thống, dùng lệnh "lsusb -vv" nó hiện ra chipset của Ralink. Sau 2 ngày vò đầu bức tóc, xào nấu... cuối cùng K cũng làm cho nó chạy được với KM9260 . Do source kernel không hỗ trợ driver cho loại chipset này vì vậy việc build driver theo kiểu external module là điều cần thiết. Để làm điều đó cần phải cấu hình lại kernel, add phần mục hỗ trợ wireless. Code: Code: Vendor, chip ID: 0x148F,0x2070 Chipset: Ralink 2070L Code: Code: $ cd linux-2.6.27 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig Cấu hình kernel: Code: Code: Device Driver --->[*] Network device support ---> Wireless LAN --->[*] Wireless LAN (IEEE 802.11) IEEE 802.11 for host AP ...[*] Support for downloading firmware images with host AP driver[*] Support for non-volatile firmware download Build kernel: Code: Code: $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage Build module: Code: Code: $ cd W541U $ make Sau khi build xong kernel, reboot hệ thống, gắn USB wireless apdator vào KM9260, chép firmware .bin và file cấu hình .dat vào thư mục /etc/wireless... ta cần phải insert module driver: Code: Code: $ insmod rt3070sta.ko $ iwconfig $ ifconfig ra0 inet 192.168.1.25 up Originally Posted by ttk84 Tôi đã đọc tài liệu kỹ thuật board của anh và xem qua về chức năng của Chip ARM ma anh sử dụng. Nhưng chưa thấy nói kỹ về phần lập trình sử dụng cho board(giao tiếp ADC, giao tiếp rs232,...) và làm cách nào để load và run chương trình theo ý đồ của mình(trong tài liệu hình như mới chỉ đề cập đến quá trình set cấu hình cho board). Nếu lập trình thì sử dụng ngôn ngữ nào trên nền Linux và sử dụng trình biên dịch nào? Trình biên dịch đó có thể giao tiếp được thông qua win XP khong? Chào bạn, Câu hỏi của bạn khá thú vị đấy, manual thực chất là tài liệu mô tả đặc tính, tài nguyên của board hiện có. Về phần lập trình biên dịch, load chương trình để chạy, K sẽ đề cập ở tài liệu khác (Technical reference) hiện nay tài liệu này chưa được công bố. Về việc điều khiển các thiết bị, đòi hỏi bạn phải có kiến thức về hệ điều hành Linux, tức là làm việc có liên quan đến driver... Vấn đề này nó trở thành kiến thức chung và được cộng đồng phát triển Linux tài liệu hóa và công bố trên mạng internet. Đối với Linux không đơn thuần viết code C set các thanh ghi của CPU như kiểu lập trình VĐK thông thường. Người phát triển viết các chương trình ứng dụng tác động đến driver và điều khiển các thiết bị theo mong muốn. Điều này được thực hiện thông qua các hàm API và được gọi là system call. Về ngôn ngữ lập trình thì, nếu làm việc với kernel, driver thì bắc buộc phải dùng ngôn ngữ C. Còn đối với các chương trình ứng dụng chạy trên Linux có thể được viết bằng những ngôn ngữ khác (đi kèm với trình biên dịch tương ứng). Về trình biên dịch, nó sẽ là gcc nếu bạn dùng ngôn ngữ C. Nếu bạn có kiến thức cơ bản về Linux, thì khi đọc manual của km9260 bạn sẽ biết trình biên dịch nó được trình bày ở mục nào. Có lẽ hiện nay các trường đại học chưa đưa embedded Linux vào chương trình giảng dạy. Vì thế việc truyền thụ kiến thức gặp nhiều khó khăn. K có ý định hỗ trợ cho một số giảng viên trong trường đại học Sư Phạm Kỹ Thuật với mong muốn phổ cập embedded Linux cho cộng đồng. Theo ý kiến của K thì, nếu bạn muốn làm với embedded Linux thì cần có sự nỗ lực nhiều từ phía bạn. Bạn sẽ cần đến máy tính có kết nối internet dùng cho việc tìm kiếm thông tin, học hỏi nhiều kiến thức. Theo kinh nghiệm của K thì chỉ cần có GOOGLE là đủ. Khi muốn điều khiển cổng UART của hệ thống, bạn sẽ thấy hơi khó chịu thay vì truy xuất các thanh ghi cho con CPU theo kiểu truyền thống, ta phải tìm hiểu các hàm API trong Linux để điều khiển thiết bị này. Tuy nhiêm việc này có lợi điểm bạn không cần phải ngồi đọc datasheet hàng trăm trang của con CPU đề tìm hiểu các thanh ghi điều khiển UART nó nằm ở chỗ nào. Ngay cả con CPU AT91SAM9260 K vẫn chưa nắm hết các thanh ghi của nó, điều khiển nó như thế nào... Vì thực ra tìm hiểu hết những thứ này không mang lại ý nghĩa gì. Vấn đề ở chỗ làm cách nào ta giải quyết nhanh được bài toán đã được đặc ra. Linux có vẽ như là công việc của nhiều người hơn là công việc cá nhân. cám ơn anh đã giúp đỡ rất chi tiết! Theo tôi nghi việc nắm vững phần cứng(đặc biệt là địa chỉ mà CPU cấp) có ý nghĩa hết sức quan trọng, nó cho ta hiểu một cách thấu đáo về những dòng code Driver mà cộng đồng Linux đã phát triển. Có thể không hiểu hết được tất cả các dòng lệnh trong đó, nhưng về mặt ý tưởng ta có thể nắm được. Hơn thế nữa, tôi nhận thấy board của anh có rất nhiều I/O, vậy việc nắm phần cứng, địa chỉ phần cứng là một việc cần thiết khi ta tiến hành sử dụng các I/O cho những mục đích cụ thể. Tất nhiên, khi đứng ở vị trí của hệ điều hành Linux, việc kế thừa những kết quả đã có của cộng đồng là hoàn toàn hợp lý. Và hiện tại, theo tôi nghĩ, chúng ta có lẽ mới đang ở mức độ sử dụng một cách hợp lý những kết quả đó thôi. Tôi cũng chỉ bắt đầu tiếp cận và có những khái niệm hết sức mơ hồ. Vì vậy rất mong nhận được sự giúp đỡ của anh. Tôi có đọc qua tôi có câu hỏi cho anh được không a? Tôi có đọc qua về Ecos và Redboot trong quá trình khởi động linux trong thời gian một vài giây. Tại sao lại nhanh vậy? Trong khi tôi thấy quá trình khởi động của Linux không thể có được tốc độ như vậy, dẫu rằng anh có thể giảm thiểu tối đa các driver sử dụng. Bạn tham khảo datasheet AT91SAM9260 trên trang ATMEL để thêm chi tiết. Nhiệm vụ của boot loader là thực hiện khởi động một số tài nguyên trên hệ thống, load file ảnh của hệ điều hành vào bộ nhớ, thực hiện giải nén file ảnh, trao cho hệ điều hành 1 vài tham số cần thiết (boot arg) và sau cùng là thực hiện lệnh nhảy để chạy hệ điều hành. Đối với Linux thì hàm init được kích hoạt đầu tiên, rồi đến việc đăng ký driver, chạy các dịch vụ (deamon)... Boot loader chỉ chiếm thời gian khi load file ảnh kernel từ các thiết bị NAND Flash, MMC... vào RAM. Về phía Linux, tốc độ khởi động tùy thuộc vào s61 lượng driver, khởi động các dịch vụ trong quá trình boot Linux. Chính vì thế tốc độ boot không chỉ đơn thuần do boot loader quyết định mà nó còn phụ thuộc vào nhiều yếu tố khác. Theo K thì U-Boot là boot loader thông dụng nhất và được xài rộng rãi trong các hệ thống nhúng hiện nay. một vài chú ý khi thao tác trên KM9260:: - với rootfs debian thì bạn phải sử dụng thẻ nhớ >=2gb, và không nên dùng thẻ nhớ nhái của Tàu(không nhãn), nên dùng thẻ nhớ nào có nhãn hiệu vì có thể linux kernel sẽ không nhận biết được - nếu bạn nào dùng colinux thì nên tạo root của mình có dung lượng lớn 1 tí, . vì mình sẽ phải cài ứng dụng mà - địa chỉ partition 1 của nand flash trên km9260 là 0x300000- manual 1.0 bị nhầm 1 tí ở đây - nếu bạn dùng winscp để kết nối linux trên km9260 với winxp thì khi connect nếu là báo warning ".không thấy sự trả lời của bỏad sau 15 giây..." bạn cứ để im, đừng nhấn abort, nó sẽ kết nối ngay thui ---> nói chung thì KM9260 được a P thiết kế rất tốt nên hầu như phần cứng không có sai sót nào cả. Để tìm hiểu thế nào là hệ thống nhúng, thế nào là lập trình nhúng chúng ta cần phải đầu tư về thiết bị. Tuy nhiên, ở VN, hệ thống nhúng vẫn còn là khái niệm mới mẻ. Việc tiếp cận với hệ thống nhúng cũng gặp khó khăn do ở VN không có sẵn các thiết bị phụ trợ. Hệ thống nhúng không đơn thuần là hệ thống VĐK thông thường, được phát triển bởi 1 chương trình đơn lẻ. Hệ thống nhúng thông thường có mặt hệ điều hành (gọi là hệ điều hành nhúng). Với xu hướng toàn cầu hóa hệ thống nhúng không chỉ là 1 sản phẩm làm ra từ một cá nhân, mà nó là hệ thống bao gồm hardware và sofware, là sản phẩm của nhiều người tạo ra. Với bối cảnh thị trường khởi đầu ở VN, EEES tìm ra cho mình hướng đi mới. Hiểu được tầm quan trọng của lĩnh vực embedded Linux. Cty mạnh dạn đầu tư với hy vọng phục vụ cho cộng đồng điện tử VN phát triển phần mềm nhúng. Vì sao embeddd Linux là sự lựa chọn cho chúng ta ? + Mã nguồn mở. + Chi phí thấp. + Tính năng mạnh. + Hỗ trợ rất nhiều platform. + Phổ dụng. + Mã nguồn mở: Linux là hệ điều hành mã nguồn mở (Theo hệ UNIX, POSIX APIs ...) , các source, kernel được quản lý chặc chẽ và được chia ra thành nhiều version khác nhau, điều này cho thấy linux là hệ điều hành được phát triển liên tục theo thời gian. + Chi phí thấp: Do là nguồn mở nên việc đầu tư các tool phần mềm phát triển trở nên dễ dàng hơn và hầu như free, vì thế chi phí nghiên cứu phát triển cho dự án, chi phí sản xuất ra sản phẩm được giảm đáng kể. + Tính năng mạnh : Các thiết bị liên quan đến máy tính ví dụ như USB, Wifi, IEEE1394, Ethernet, PCI, UART, SPI... Tất cả điều được Linux hỗ trợ, và số luợng driver trong linux kernel source đang được tăng dần theo thời gian. + Hỗ trợ rất nhiều platform: Hiện nay trên thế giới có rất nhiều chủng loại CPU với nhiều cấu trúc khác nhau. Từ những cấu trúc CPU này, các nhà sản xuất hardware đã cho ra nhiều board nhúng khác nhau (gọi là platform, phần xác của hệ thống nhúng). Kernel Linux có thể tập hợp hàng chục cấu trúc CPU, hàng trăm platform này lại thành một hệ thống source C và ASM hoàn chỉnh. Chính vì tính năng hỗ trợ nhiều platform và tính cấu hình cao tạo nên sức mạnh cho hệ điều hành Linux. + Phổ dụng: Khi ta search những từ khóa có liên quan đến Linux trên trang tìm kiếm Google thì số lượng kết quả rất lớn, điều này cho thấy cộng đồng phát triển Linux có số lượng người lớn. Vì thế trong quá trình phát triển dự án về Linux ta vẫn an tâm bởi vì nguồn support rất dồi dào. -- T.Năm 17 Tháng 12, 2009 9:07 pm -- -- T.Năm 17 Tháng 12, 2009 9:08 pm -- CÀI ĐẶT DEBIAN CHO KM9260: Đối với user mới làm quen với embedded Linux, thì Debian rootfs là lựa chọn hoàn hảo, do tính ưu việt về số lượng lớn gói phần mềm mà Debian support, cơ chế quản lý các gói phần mềm chặt chẽ và hệ thống, cộng đồng phát triển rộng. Debian rootfs có dung lượng khá lớn, vì thế ta nên dùng thẻ nhớ có dung lượng 2GB trở lên. Phần này chỉ cách cài đặt và boot Debian trên KM9260 sử dụng thẻ nhớ microSD. Trước tiên ta chép “Debian_km9260_rootfs_121209.tar.bz2” vào máy PC Linux, gắn đầu đọc thẻ microSD vào. Giả sử khi cắm vào máy PC Linux có thiết bị mới có tên gọi là /dev/sdb1, trước tiên ta format card microSD theo định dạng ext2, và mount vào thư mục “mnt/rootfs” chẳng hạn. Mã: [color=#000000]$ mkfs.ext2 /dev/sdb1[/color] [color=#000000]$ mkdir –p /mnt/rootfs[/color] [font=Times New Roman][color=#000000]$ mount /dev/sdb1 /mnt/rootfs[/color][/font] Copy gói tarball Debian rootfs vào thư mục mnt và tiến hành giải nén. Mã: [color=#000000]$ cp Debian_km9260_rootfs_121209.tar.bz2 /mnt[/color] [color=#000000]$ cd /mnt/rootfs[/color] [color=#000000][font=Times New Roman]$ tar –jxvf ../[/font][size=3][font=Times New Roman]Debian_km9260_rootfs_121209.tar.bz2[/font][/size][/color] Sau khi kết thúc giải nén ta đã hoàn tất việc chép Debian rootfs vào thẻ nhớ microSD. Phải đảm bảo rằng trong thư mục gốc của microSD phải tồn tại những thư mục cơ bản của Linux rootfs ví dụ như: bin, dev, home, lib, etc… Điều này thực hiện bằng cách dùng lệnh “ls” để kiểm tra, trước khi tháo microSD ra khỏi máy Linux PC ta nên unmount thư mục /mnt/rootfs trên: Mã: [color=#000000]$ ls /mnt/rootfs[/color] [font=Times New Roman][color=#000000]$ umount /mnt/rootfs[/color][/font] Sau khi hoàn tất các bước trên, ta có thể tiến hành boot thử Debian: - Gắn microSD vào socket trên KM9260 (chú ý thực hiện tháo gỡ nắp đậy theo chiều mũi lên kéo lên-xuống được ghi trên socket microSD của KM9260). - Kết nối cổng COM (115200) với máy tính, dùng putty.exe ở mode serial làm console chính. - Bật công tắc nguồn, ấn nút reset để board KM9260 có thể vào màn hình U-Boot. - Khai báo biến môi trường bootargs thông qua lệnh sau: Ấn nút reset để boot hệ thống, thông tin đang nhập như sau: Username: root Password: km9260 -- T.Năm 17 Tháng 12, 2009 9:13 pm -- Cấu hình mạng cho Debian: Có thể cấu hình mạng cho Debian thông qua việc edit file interfaces Mã: [font=Times New Roman]$ [/font][size=3][font=Times New Roman]nano /etc/network/interfaces[/font][/size] Dùng DHCP: Mã: [/u] [color=#000000]# The primary network interface[/color] [color=#000000]allow-hotplug eth0[/color] [color=#000000]auto eth0[/color] [color=#000000]iface eth0 inet dhcp[/color] [color=#000000]pre-up ifconfig eth0 hw ether AA:AA:AA:AA:AA:AA[/color]   [u] Trong đó AA:AA:AA:AA:AA:AA là địa chỉ MAC address. Hoặc dùng IP tĩnh: Mã: [/u] [color=#000000]# Use for home network[/color] [color=#000000]auto eth0[/color] [color=#000000]iface eth0 inet static[/color] [color=#000000]      address 192.168.1.35[/color] [color=#000000]      netmask 255.255.255.0[/color] [color=#000000]      network 192.168.1.1[/color] [color=#000000]      broadcast 192.168.1.255[/color] [size=3][font=Times New Roman][color=#000000]      gateway 192.168.1.1[/color][/font][/size]   [u] Khai báo nameserver: Mã: [/u] [color=#000000]$ nano /etc/resolv.conf[/color] [size=3][font=Times New Roman][color=#000000]   nameserver 192.168.1.1[/color][/font][/size]   [u] Lưu file bằng cách ấn CTR-O, Enter, CTR-X Restart mang cho he thong Mã: /etc/init.d/networking restart -- T.Năm 17 Tháng 12, 2009 9:27 pm -- GPIO IRQ: Đôi khi ta muốn giao tiếp KM9260 với thiết bị bên ngoài ví dụ như các thiết bị chuyển đổi, thiết bị đọc thẻ smart card... Thông thường các thiết bị này có chân interrupt dùng cho việc giao tiếp với host và tạo ra một xung tín hiệu điện nhằm thông báo cho host trạng thái thiết bị đã chuyển đổi hoàn tất. Các MPU trong các thệ thống VĐK thông thường có số lượng pin (có thể cấu hình thành external interrupt source) hạn chế. Đối với hệ thống Linux, ta có thể sử dụng 1 pin GPIO thông thường như một external interrupt source. Điều này có thể thực hiện bên kernel space. Đối với user space, ta có thể gửi tính hiệu từ kernel space (soft interrupt) thông qua cơ chế SIGNAL (sẽ được đề cập sau). Việc sử dụng các GPIO như các nguồn ngắt ngoài tạo nên sự linh hoạt và tiện lợi cho các hệ thống vận hành với Linux OS. Chương trình sau (gpio_irq.c) minh họa cách khai báo và sử dụng pin "AT91_PIN_PB16" (pin 5 trên Externtion J17), khi có xung cạnh lên hoặc cạnh xuống thì chương trình phục vụ ngắt được gọi và in ra thông báo "gpio isr handler in irq XX". Sau đây là source của chương trình: Mã: [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2] [/size] [size=2]/* For GPIO and interrupt */[/size] [size=2]#include [/size] [size=2]#include [/size] [size=2]#include [/size] [size=2] [/size] [size=2]#define PIN  AT91_PIN_PB16[/size] [size=2] [/size] [size=2]static int irq;[/size] [size=2] [/size] [size=2]static irqreturn_t gpio_irq_handler (int irq, void *dev_id)[/size] [size=2]{[/size] [size=2]    printk (KERN_ALERT "gpio isr handler in irq %d\n", irq);[/size] [size=2]    /* ack the irq here so it stops generating */[/size] [size=2] [/size] [size=2]    return IRQ_HANDLED;[/size] [size=2]}[/size] [size=2] [/size] [size=2]static int gpio_irq_init(void)[/size] [size=2]{[/size] [size=2]   int ret;[/size] [size=2] [/size] [size=2]   ret = gpio_request (PIN, "IRQ"); /* GPIO request*/[/size] [size=2] [/size] [size=2]   if (ret) {[/size] [size=2]     printk (KERN_ALERT "Unable to request PC6\n");[/size] [size=2]   }[/size] [size=2] [/size] [size=2]   at91_set_GPIO_periph (PIN, 1);    // PIN as GPIO  and Pull Up[/size] [size=2]   at91_set_gpio_input  (PIN, 1);       // PIN as input and Pull Up[/size] [size=2]   at91_set_deglitch    (PIN, 1);       // PIN deglitch[/size] [size=2] [/size] [size=2]   irq = gpio_to_irq  (PIN);            /* Get IRQ number */[/size] [size=2] [/size] [size=2]   printk (KERN_ALERT "IRQ = %d\n", irq);[/size] [size=2] [/size] [size=2]   ret = request_irq (irq, gpio_irq_handler,[/size] [size=2]              IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,[/size] [size=2]              "MyIRQ", NULL);[/size] [size=2] [/size] [size=2]   if (ret)  {[/size] [size=2]      printk (KERN_ALERT "IRQ %d is not free\n", irq);[/size] [size=2]      return ret;[/size] [size=2]   }[/size] [size=2] [/size] [size=2]   return 0;[/size] [size=2]}[/size] [size=2] [/size] [size=2]static void gpio_irq_exit(void)[/size] [size=2]{[/size] [size=2]   printk (KERN_ALERT "exit gpio_irq module\n");[/size] [size=2]   free_irq  (irq, NULL);[/size] [size=2]   gpio_free (PIN);[/size] [size=2] [/size] [size=2]}[/size] [size=2] [/size] [size=2]module_init(gpio_irq_init);[/size] [size=2]module_exit(gpio_irq_exit);[/size] [size=2] [/size] [size=2]MODULE_LICENSE("GPL");[/size] [size=2]MODULE_AUTHOR("kamejoko80");[/size] [size=2]MODULE_DESCRIPTION("gpio irq example");[/size] Makefile như sau: Mã: [size=2]export ARCH=arm[/size] [size=2]export CROSS_COMPILE=arm-none-linux-gnueabi-[/size] [size=2] [/size] [size=2]obj-m += gpio_irq.o[/size] [size=2] [/size] [size=2]all:[/size] [size=2]          make -C /home/AT91SAM9260/KERNEL/linux-2.6.27 M=$(PWD) modules[/size] [size=2]clean:[/size] [size=2][font=Times New Roman]          make -C /home/AT91SAM9260/