linux下am335x点亮LED
发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,首先借用一张图说明linux应用程序和内核的关系与裸机程序不同,linux下的应用开发并不直接访问硬件,而是由应用程序调用驱动来访问硬件,这是linux的系统结构,具体可参考《嵌入式linux应用开发
千家信息网最后更新 2024年11月11日linux下am335x点亮LED
首先借用一张图说明linux应用程序和内核的关系
与裸机程序不同,linux下的应用开发并不直接访问硬件,而是由应用程序调用驱动来访问硬件,这是linux的系统结构,具体可参考《嵌入式linux应用开发完全手册》。
回到am335x,已经在uboot实现LED的操作,基本原理一致,设置GPIO输出,低电平点亮LED。如果想通过内核空间操作文件的方式访问GPIO,可参考 BeagleBone的GPIO控制
linux3.2中driver/leds目录下存放有led相关文件,在此编写led驱动模块。代码参照 Am335x 下GPIO控制实例
添加文件leds-run.c
```
#include#include #include #include #include #include #include #include #include #include #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);printk(KERN_INFO"#######LED statu is high.\r\n");}else{gpio_direction_output(TEST_IO_NUM, 0);printk(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 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) {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");
```
driver/leds目录下修改Kconfig,添加一项:
config GPIO_LEDbool "Gpio LED test"helpJust test the Gpio LED status
同目录下Makefile文件修改:
obj-$(CONFIG_GPIO_LED)+=leds-run.o
通过make menuconfig,将驱动模块GPIO_LED编译进内核。
应用程序app.c
#include#include #include #include #include #include #include #include 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);printf("***App run over!\r\n");return 1;}
烧写内核,内核启动后打印"#######GpioTest modules is install!",运行app,可以正常运行,可led没有按照程序进行亮灭操作。
细想整个过程发现,am335x的IO口是复用的,需要先完成mux设置。
再回到linux内核,需要明确linux的运行流程,此次参考了 linux内核代码分析1 TI am335x:
Board-am335xevm.c(./arch/arm/mach-omap2)中开始执行,
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
转到启动程序am335x_evm_init:
am33xx_cpuidle_init();am33xx_mux_init(board_mux);omap_serial_init();am335x_evm_i2c_init();am335x_evm_setup();omap_sdrc_init(NULL, NULL);usb_musb_init(&musb_board_data);
static void am335x_evm_setup(){ setup_general_purpose_evm();}
static void setup_general_purpose_evm(void){ _configure_device(boardid,invt_evm_dev_cfg, -1); }
所以初始化开发板的设置,重点就是invt_evm_dev_cfg
static struct evm_dev_cfginvt_evm_dev_cfg[] = { {enable_ecap0, DEV_ON_BASEBOARD, PROFILE_NONE}, {lcdc_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {mfd_tscadc_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {rmii1_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {rmii2_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {usb0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {usb1_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {evm_nand_init,DEV_ON_BASEBOARD,PROFILE_NONE}, {mmc0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {spi0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {led_init, DEV_ON_BASEBOARD, PROFILE_NONE}, //添加led操作};
static void led_init(int evm_id, int profile){ int err; setup_pin_mux(gpio_led_mux); err = platform_device_register(&leds_gpio); if (err) pr_err("failed to register gpio led device\n");}
static struct pinmux_config gpio_led_mux[] = {{"lcd_ac_bias_en.gpio2_25", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //LED GPIO 配置{NULL, 0},};
修改完成后,重新编译内核,烧写内核,运行程序,成功实现LED的操作。
内核
程序
应用
文件
运行
应用程序
目录
参考
开发
驱动
代码
应用开发
模块
硬件
控制
编译
不同
一致
成功
原理
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海电力系统软件开发
没有根域名服务器影响安全不
数据库记录sql执行时间
网络安全员兼职是干什么的
揭阳点餐软件开发
近3年金融网络安全事件
部落战争服务器不能连接
方块云mc服务器管理系统
吉林最新网络安全
秦皇岛媒体服务器价格
江苏工业点胶软件开发
国家信息网络安全中心校招
湖南工业服务器云主机
山东工控软件开发有用吗
scm数据库初始化
安徽图腾服务器机柜
大学生网络安全通讯稿
数据库中的打开库是什么
无锡软件开发优势
宁海软件开发好吗
部队软件开发
池州求职招聘软件开发外包公司
lol服务器离线
北辰区信息网络技术答疑解惑
服务器在终端上有监听什么意思
大连直播软件开发公司
代理上网服务器安全问题
数据库翻译插件
成都交友软件开发大概多少钱
asp读取根目录数据库文件