Lab 3. Programming with GPIO 1. Mc ch: - Vit cc ng dng vi cc giao tip vo ra c bn (GPIO) trn KIT, s dng cc GPIO driver c sn, nh: giao tip led, button, Bin dch, np v thc thi ng dng trn KIT - Vit cc ng dng giao tip GPIO m rng s dng th vin gpiolib trn linux (giao din gpio sysfs) - Pht trin cc ng dng t cc v d n gin. 2. Chun b: - PC Linux (Ubuntu) with arm-linux-gcc - KIT FriendlyArm mini/micro2440 - D liu: Cc v d tham kho 3. Lp trnh giao tip gpio vi driver c sn: 3.1. Vit chng trnh iu khin tt/bt led n 3.1.1. M t: - Dy 4 led n trn KIT ghp ni qua cng GPIO (GP5,6,7,8) c sn driver trn Embedded Linux.
- Driver cung cp hm iu khin (ioctl) tt/bt tng led n. to cc hiu ng led (nhy, chy ui, p tng, ) cn x l thut ton lp trnh + s dng cc hm tr (delay) to hiu ng (s dng th vin sys/time.h trn linux, cc hm tr usleep(us) hoc sleep(s). - M hnh giao tip: Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 2
3.1.2. M ngun tham kho: V d sau minh ha m file thit b leds v iu khin tt/bt 1 led c s hiu led_no (0,3) (File tham kho: leds.c) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> int main(int argc, char **argv) { int on; int led_no; int fd; //kim tra cc tham s truyn t dng lnh c ph hp if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no > 3) { fprintf(stderr, "Usage: leds led_no 0|1\n"); //cch s dng exit(1); } fd = open("/dev/leds", 0); //M file thit b leds s dng if (fd < 0) { perror("open device leds"); Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 3
exit(1); } ioctl(fd, on, led_no); //Hm iu khin tng on/off led n close(fd); //ng file thit b sau khi s dng return 0; }
3.1.3. Yu cu: Da trn v d trn, vit chng trnh iu khin tt, bt dy led n. Bin dch, np chng trnh ln KIT v thc thi, quan st kt qu. Ch : Mc nh trn KIT khi ng s chy ng dng led_player trn nn Qtopia, cn tt ng dng ny trnh xung t. 3.2. Vit chng trnh c trng thi nt bm 3.2.1. M t: - Dy nt bm K1, K2, K3, K4, K5, K6 trn KIT c ghp ni qua GPIO, c sn driver trn h iu hnh Linux nhng.
- C th c trng thi cc nt bm ny (pressed/release or not ?) v c x l thch hp. - M hnh lp trnh vi nt bm: Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 4
3.2.2. M ngun tham kho - Driver button cung cp hm read() cho php c trng thi ca 6 nt bm (gi tr tr v l 0 hoc 1 tng ng nt c nhn (pressed) hay nh (released). - Mt cch n gin c th s dng c ch poll (thm d) c trng thi nt bm. Vi phng php ny, chng trnh s lin tc c trng thi nt bm xem c c bm hay khng (s kin c bm tng ng vi gi tr ca nt tr v s b thay i 1-> 0 -> 1). - Tham kho m ngun sau: (File buttons.c) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> int main(void) { Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 5
int buttons_fd; //mng cha gi tr tr v ca 6 nt bm (gi tr l k t 0, 1) char buttons[6] = {'0', '0', '0', '0', '0', '0'}; buttons_fd = open("/dev/buttons", 0); //m file thit b button if (buttons_fd < 0) { perror("open device buttons"); exit(1); } for (;;) {//Vng lp lin tc c trng thi nt bm (poll) char current_buttons[6]; //mng cha gi tr hin ti c c int i; //lin tc gi hm c if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) { perror("read buttons:"); exit(1); } //duyt mng cha gi tr 6 nt bm for (i = 0; i < sizeof buttons / sizeof buttons[0]; i++) { if (buttons[i] != current_buttons[i]) { //nu c s thay i //nt tng ng c bm buttons[i] = current_buttons[i]; //cp nht li trng thi nt //hin thng tin ra mn hnh printf(key %d is %s\n", i+1, buttons[i] == '0' ? "up" : "down"); } } } close(buttons_fd); return 0; } 3.2.3. Yu cu. Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 6
Da trn v d tham kho, vit chng trnh c trng thi ca cc nt bm, a ra thng bo nt no c nhn/nh. Bin dch, np v thc thi chng trnh trn KIT. 3.3. Vit chng trnh kt hp giao tip leds v buttons Yu cu: Da trn 2 v d trn vit chng trnh kt hp 2 giao tip vi leds v buttons. - S dng cc nt K1, K2, K3, K4 bt/tt 4 led n tng ng (mi ln bm nt, led tng ng s chuyn trng thi t tt -> bt hoc ngc li) - Hoc s dng 2 nt bm iu khin cho 1 led vi 1 nt dng tt v 1 nt dng bt. Bi tp lm thm. Bi 1: Vit chng trnh LedDuoi to hiu ng led ui vi mt tham s i km l tc chy (tnh bng ms). Chng trnh cho php in ra thng bo hng dn s dng nu ngi dng la chn option help. LedDuoi help -> in ra hng dn s dng LedDuoi 1000 ->chy hiu ng led ui vi tr l 1000ms Bi 2: Vit chng trnh to hiu ng led ui, c th thay i tc bng nt bm (1 nt tng tc , mt nt gim tc ) 4. Lp trnh giao tip gpio sysfs t Linux user space - Kim tra linux h tr giao tip gpio sysfs bng lnh: ls /sys/class/gpio
Nu cha c cn bin dch v ci t li nhn linux h tr giao din ny. Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 7
4.1. Xy dng th vin c gm cc hm giao tip gpio - Tham kho m ngun sau cung cp 1 th vin cc hm truy cp gpio s dng gpio sysfs t khng gian ngi dng (user space): gpio.h #ifndef GPIO_H #define GPIO_H int gpio_export(unsigned gpio); //Hm export pin ra user space int gpio_unexport(unsigned gpio); //Hm gii phng pin khi khng cn s dng int gpio_dir_out(unsigned gpio); //Cu hnh pin l output int gpio_dir_in(unsigned gpio); //Cu hnh pin l input int gpio_value(unsigned gpio, unsigned value); //c/ghi gi tr ca pin gpio #endif gpio.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <fcntl.h>
#define GPIO_DIR_IN 0 #define GPIO_DIR_OUT 1 /************************************************* Hm ng k (export) chn gpio mun s dng ra khng gian ngi dng *************************************************/ int gpio_export(unsigned gpio) { int fd, len; char buf[11];
len = snprintf(buf, sizeof(buf), "%d", gpio) write(fd, buf, len); //Ghi s hiu (ID) pin mun s dng vo file /sys/class/gpio/export khi ng k s dng close(fd); return 0; } Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 8
/************************************************* Hm gii phng (unexport) chn gpio khi khng cn s dng *************************************************/ int gpio_unexport(unsigned gpio) { int fd, len; char buf[11]; fd = open("/sys/class/gpio/unexport", O_WRONLY); if (fd < 0) { perror("gpio/export"); return fd; } len = snprintf(buf, sizeof(buf), "%d", gpio); write(fd, buf, len); //Ghi s hiu (ID) pin mun s dng vo file /sys/class/gpio/unexport khi gii phng close(fd); return 0; } /************************************************* Hm cu hnh chn gpio l in hay out (dir) *************************************************/
int gpio_dir(unsigned gpio, unsigned dir) { int fd, len; char buf[60]; len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { perror("gpio/direction"); return fd; } //Cu hnh pin l input/output bng cch ghi gi tr (ASCII) in, out vo file /sys/class/gpio/gpio[ID]/diriection if (dir == GPIO_DIR_OUT) write(fd, "out", 4); else write(fd, "in", 3); close(fd); return 0; } /************************************************* Hm thit lp chn gpio out *************************************************/ int gpio_dir_out(unsigned gpio) { Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 9
return gpio_dir(gpio, GPIO_DIR_OUT); //trng hp l output } /************************************************* Hm thit lp chn gpio in *************************************************/
int gpio_dir_in(unsigned gpio) { return gpio_dir(gpio, GPIO_DIR_IN); //trng hp l input } /************************************************* Hm ghi ra tr ra chn gpio out (tng ng xut 0 , 1) *************************************************/
int gpio_value(unsigned gpio, unsigned value) { int fd, len; char buf[60]; len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { perror("gpio/value"); return fd; } //Xut gi tr 1, 0 bng cch ghi ra file value tng ng vi pin cu hnh if (value) write(fd, "1", 2); else write(fd, "0", 2); close(fd); return 0; } /************************************************* Chng trnh chnh test cc hm ny t if 1 khi mun s dng *************************************************/
#if 0 int main(int argc, char *argv[]) { int i = 20; int pin_no = 160 //S dng chn 160 (tng ng vi GPF0 trn FriendlyArm mini/micro 2440) gpio_export( pin_no ); gpio_dir_out( pin_no ); while(i--) { Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 10
gpio_value( pin_no , i & 1); //toggle on GPF0 sleep(1); } gpio_unexport( pin_no ); } #endif
4.2. Vit ng dng giao tip board m rng (leds, 7 segment, buttons) - Hnh nh board m rng nh sau (xem schematic i km)
Board m rng c ghp ni vi KIT FriendlyArm micro2440 qua header CON6. S chn nh sau: Embedded247 Lab 3. Programming with GPIO
Lp trnh nhng ARM Linux DCE, SOICT, HUST Page 11
Yu cu: S dng 7 chn GPIO t GPF0-GPF6 (EINT0-EINT6) iu khin 7 led tng ng trn board (ch output) hoc c trng thi 7 nt bm tng ng (ch input). (Tham kho m ngun ti https://sites.google.com/site/embedded247/ddcourse/giao-tiep- gpio-mo-rong-su-dung-gpiolib ) Bin dch: + ng dng iu khin led n/led 7 thanh: arm-linux-gcc o gpio_led gpio.c gpio_led.c + ng dng polling trng thi 7 nt bm: arm-linux-gcc -o gpio_button gpio.c gpio_button.c Thc thi ng dng trn KIT v quan st kt qu.