Start by borrowing a diagram to illustrate the relationship between Linux applications and the kernel
! [] (http://i2.51cto.com/images/blog/201807/28/ce7cdc22c42c5b93bd5604c0ba1878db.png?x-oss-process=image/ watermark,size_16,text_qduxq1rp5y2a5a6i,color_ffffff,t_100,g_se,x_10,y_10,shadow_90,type_zmfuz3pozw5nagvpdgk=)
Unlike bare-metal programs, application development under Linux does not directly access hardware, but is driven by application calls to access hardware, which is the system architecture of Linux, and can be found in the complete handbook of embedded Linux application development.
Back to am335x, already in the uboot to achieve led operation, the basic principle of consistent, set GPIO output, low-level lit led. Refer to [Beaglebone Gpio control] (http://blog.sina.com.cn/s/blog_9e16dc4d01012x7z.html) If you want to access the GPIO through kernel space operation files
! [] (http://i2.51cto.com/images/blog/201807/25/3169db826031c0f7bf0be54f26ac0d91.png?x-oss-process=image/ watermark,size_16,text_qduxq1rp5y2a5a6i,color_ffffff,t_100,g_se,x_10,y_10,shadow_90,type_zmfuz3pozw5nagvpdgk=)
linux3.2 in the Driver/leds directory with LED-related files, in this writing led driver module. Code reference [am335x under Gpio Control instance] (16826995)
Add File Leds-run.c
```
#include <linux/gpio.h> #include <linux/module.h> #include <linux/kernel.h># include <linux/moduleparam.h> #include <linux/delay.h> #include <linux/types.h> #include <linux/miscdevice.h> #include <linux/device.h> #include <linux/fs.h># include <linux/init.h> #define TEST_IO_NUM 89#define NAME_MISC "Gpiotest" #define NAME_MOUDULE "GpioTest1" #define use_misc_mode 1static int major = 251 ; void gpiotest (void); Static long gpioioctl (Struct file *filp, unsigned cmd, unsigned long arg) {gpiotest (); return 1;} Void gpiotest (void) {int icount = 0;for (icount = 0; icount <=20; iCount++ ) {if (icount%2 == 0) {gpio_direction_output (test_io_num, 1);p rintk (kern_info " ###### #LED statu is high.\r\n ");} Else{gpio_direction_output (test_io_num, 0);p rintk (kern_info "###### #LED statu is low.\r\n");} Mdelay (3000);} PRINTK (kern_info "###### #App run over!");} Static int gpioopen (struct inode *inode, struct file *file) {Int iRen = -1;iren = gpio_request (test_io_num, "LED"); if (iren < 0) {PRINTK (KERN_ INFO "###### #Failed to request the led!");} ELSE{PRINTK (kern_info "###### #Success to request the led");} Return iren;} Static int gpioclose (struct inode *inode, struct file *file) {PRINTK (KERN_ INFO "###### #Free the led"); Gpio_free (test_io_num); return 1;} Entry point for test gpio modulestatic const struct file_ Operations gpio_test_driver = {.owner = this_module,.unlocked_ioctl= gpioioctl,. llseek = no_llseek,.open = gpioopen,.release = gpioclose,}; #if use_misc_modestatic struct miscdevice gpiotest_misc_device = {.minor = misc_dynamic_minor,.name = name_misc,.fops = &gpio_test_ Driver,}; #endifstatic int __init gpiotestinit (void) {INT&NBSP;IRET;PRINTK (kern_info "####### Gpiotest modules is install!\r\n "); #if use_misc_modeiret = misc_register (& Gpiotest_misc_device);if (iRet) {printk (kern_info "###### #unable to register a Misc device\r\n "); Return iret;} #elseiRet = register_chrdev (major, name_moudule, &gpio_test_driver);if (iRet < 0) &NBSP;{PRINTK (kern_info "###### #unable to register a chr device\r\n" ); Return iret;} #endifreturn iret;} Static void __exit gpiotestexit (void) {#if use_misc_modemisc_deregister (&gpiotest_misc_ device); #elseunregister_chrdev (Major, name_moudule); #endifprintk (kern_info "###### #GpioTest modules is exit!\r\n");} Module_init (Gpiotestinit); Module_exit (Gpiotestexit); Module_author ("xxxxxxxxxxxx"); Module_license ("GPL"); Module_description ("system status led");
```
Modify the Kconfig in the Driver/leds directory to add an entry:
Config Gpio_ledbool "Gpio led test" Helpjust test the Gpio LED status
Makefile file changes in the same directory:
obj-$ (Config_input_
obj-$ (config_gpio_led) +=LEDS-RUN.O
With make Menuconfig, the driver module gpio_led is compiled into the kernel.
Application App.c
#include <stdio.h> #include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <unistd.h> #include <sys/stat.h> #include <linux/input.h> #include <fcntl.h>int main (int argc, Char *argv) {int fd;fd = open ("/dev/gpiotest", O_RDWR), if (FD < 0) {printf ("***can ' t Open the gpiotest!\r\n"); return-1;} IOCTL (FD, 0, 0), close (FD);p rintf ("***app run over!\r\n"); return 1;}
Burning writes the kernel, the kernel starts to print "###### #GpioTest modules is install!", runs the app, may run normally, may the LED does not follow the program to illuminate the operation.
Think of the whole process to find that the am335x IO port is multiplexed, the need to complete the MUX Setup first.
Back to the Linux kernel, you need to clear the Linux running process, this reference to the Linux kernel Code Analysis 1 TI am335x:
BOARD-AM335XEVM.C (./arch/arm/mach-omap2) begins execution,
Machine_start (AM335XEVM, "AM335XEVM")/* Maintainer:texas Instruments */.atag_offset= 0x100,.map_io= am335x_evm_map_ io,.init_early= am33xx_init_early,.init_irq= TI81XX_INIT_IRQ,.HANDLE_IRQ = omap3_intc_handle_irq,.timer= &omap3 _am33xx_timer,.init_machine= Am335x_evm_init,machine_end
Go to Startup program Am335x_evm_init:
Linux under am335x LED light