imx6 项目的按键驱动程序

IMX6ULL按键控制LED灯亮灭(基于韦东山嵌入式Linux教程) 在linux中,一切皆文件,设备也是作为文件存在于linux里面的,我们在应用层对设备进行各种操作就相当于对文件进行读写操作,所以为了让应用层能够通过对文件的操作来控制设备,我们要提供接口给应用层(如open,read,write等等),比如通过read读取引脚电平(按键是否按下),通过write来让引脚为高电平或者低电平(控制led是否打开)。 阅读详情
/**
 * filename:imx6_key_drv.c
 * description: matrix key driver for imx6.
 * author:shell.albert@gmail.com
 * date: September 1,2015.
 *
 * three gpio keys are connected to imx6 through different GPIO.
 * up/down key: GPIO04/SLEEP_WAKE
 * led key:EIM_BCLK/VOL+
 * left/right key:CSI0_DATA_EN/VOL-
 * ok key:NANDF_CS0
 * return key:NANDF_CS1
 *
 * attention here.
 * the mdev rules must be enabled before use this driver.
 * do the following work to make it works.
 *     /etc/init.d/rcS
 *     #mount partitions
 *     mkdir /dev/pts -p
 *     mount -t devpts devpts /dev/pts
 *     mount -a
 *     echo /sbin/mdev > /proc/sys/kernel/hotplug
 *     mdev -s
 *
 *     /etc/mdev.conf
 *     # system all-writable devices
 *      full            0:0     0666
 *      null            0:0     0666
 *          ptmx            0:0     0666
 *      random          0:0     0666
 *        tty             0:0     0666
 *        zero            0:0     0666


 *        # i2c devices
 *        i2c-0           0:0     0666    =i2c/0
 *        i2c-1           0:0     0666    =i2c/1

 *        # frame buffer devices
 *        fb[0-9]         0:0     0666

 *        # input devices
 *        mice            0:0     0660    =input/
 *        mouse.*         0:0     0660    =input/
 *        event.*         0:0     0660    =input/
 *        ts.*            0:0     0660    =input/
 */

/**
Event: time 1441159728.919925, -------------- Report Sync ------------
Event: time 1441159733.423896, type 4 (Misc), code 4 (ScanCode), value 70052
Event: time 1441159733.423896, type 1 (Key), code 103 (Up), value 1
Event: time 1441159733.423896, -------------- Report Sync ------------
Event: time 1441159733.511935, type 4 (Misc), code 4 (ScanCode), value 70052
Event: time 1441159733.511935, type 1 (Key), code 103 (Up), value 0
Event: time 1441159733.511935, -------------- Report Sync ------------
Event: time 1441159735.431922, type 4 (Misc), code 4 (ScanCode), value 70050
Event: time 1441159735.431922, type 1 (Key), code 105 (Left), value 1
Event: time 1441159735.431922, -------------- Report Sync ------------
Event: time 1441159735.503919, type 4 (Misc), code 4 (ScanCode), value 70050
Event: time 1441159735.503919, type 1 (Key), code 105 (Left), value 0
Event: time 1441159735.503919, -------------- Report Sync ------------
Event: time 1441159739.127894, type 4 (Misc), code 4 (ScanCode), value 700e4
Event: time 1441159739.127894, type 1 (Key), code 97 (RightCtrl), value 1
Event: time 1441159739.127894, -------------- Report Sync ------------
Event: time 1441159739.263894, type 4 (Misc), code 4 (ScanCode), value 700e4
Event: time 1441159739.263894, type 1 (Key), code 97 (RightCtrl), value 0
Event: time 1441159739.263894, -------------- Report Sync ------------
Event: time 1441159742.103834, type 4 (Misc), code 4 (ScanCode), value 700e0
Event: time 1441159742.103834, type 1 (Key), code 29 (LeftControl), value 1
Event: time 1441159742.103834, -------------- Report Sync ------------
Event: time 1441159742.207873, type 4 (Misc), code 4 (ScanCode), value 700e0
Event: time 1441159742.207873, type 1 (Key), code 29 (LeftControl), value 0
Event: time 1441159742.207873, -------------- Report Sync ------------
 */

/**
 * PAD Mux registers.
 * related register define here.
 * I/O are multiplex,so we choose the right mode.
 */
#define IOMUXC_SW_MUX_CTL_PAD_GPIO04                0x20E0238 //GPIO1_IO04
#define IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK                0x20E0158 //GPIO6_IO31
#define IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN            0x20E0260 //GPIO5_IO20
#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B            0x20E02E4 //GPIO6_IO11
#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B            0x20E02E8 //GPIO6_IO14
/**
 * PAD Control registers.
 * used to control the pad physical features.
 */
#define IOMUXC_SW_PAD_CTL_PAD_GPIO04                    0x20E0608
#define IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK                    0x20E046C
#define IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN                0x20E0630
#define IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B                0x20E06CC
#define IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B                0x20E06D0

//register size,it's always 32-bit,4 bytes in 32-bit CPU.
#define REG_SIZE        0x4

#define MODULE_NAME        "imx6_key_drv"

#define print_debug(fmt,arg...)     printk(KERN_DEBUG fmt,##arg)
#define print_error(fmt,arg...)        printk(KERN_ERR fmt,##arg)

//GPIO related register define here.
//up/down key,GPIO1[4].
#define GPIO1_GDIR        0x209C004
#define GPIO1_PSR        0x209C008
#define GPIO1_IMR        0x209C014
//left/right key,GPIO5[20].
#define GPIO5_GDIR        0x20AC004
#define GPIO5_PSR        0x20AC008
#define GPIO5_IMR        0x20AC014
//led key:GPIO6[31].
//ok key: GPIO6[11].
//return key: GPIO6[14].
#define GPIO6_GDIR        0x20B0004
#define GPIO6_PSR        0x20B0008
#define GPIO6_IMR        0x20B0014

//for module.
#include <linux/module.h>
#include <linux/init.h>
//for IRQ.
#include <linux/irq.h>
#include <linux/interrupt.h>
//for timer.
#include <linux/timer.h>
#include <linux/jiffies.h>

//for input framework.
#include <linux/input.h>

//for ioremap.
#include <linux/io.h>
//for kzalloc.
#include <linux/slab.h>
//for ulong.
#include <linux/types.h>

struct imx6_keys_dev {
    //virtual address after mapping.
    volatile ulong *up_down_vir_addr; //GPIO1[4].
    volatile ulong up_down_status;

    volatile ulong *left_right_vir_addr; //GPIO5[20].
    volatile ulong left_right_status;

    volatile ulong *led_ok_return_vir_addr;//GPIO6[11/14/31].
    volatile ulong led_ok_return_status;
    //scan timer.
    struct timer_list scan_timer;

    //input core.
    struct input_dev *input_device;
};
struct imx6_keys_dev *key_dev;
/**
 * configure the register at initial stage.
 * these registers should only be configured once.
 */
int imx6_config_reg(ulong phy_addr, int bits_mask, int bits_value) {
    volatile ulong *pbase = NULL;
    volatile int ret;
    int i;
    int reg_bits_num = sizeof(ret);
    pbase = (ulong*) ioremap(phy_addr, REG_SIZE);
    if (!pbase) {
        print_error("error accord when ioremap()!\n");
        return -1;
    }
    ret = ioread32(pbase);
    for (i = 0; i < reg_bits_num; i++) {
        if (bits_mask & (0x1 << i)) {
            ret &= (~(0x1 << i));
        }
    }
    ret |= bits_value;
    iowrite32(ret, pbase);
    iounmap(pbase);
    pbase = NULL;
    return 0;
}
/**
 * configure the IOMUX registers to choose the right pin mode.
 */
int imx6_config_all_iomuxcs(void) {
    //IOMUXC_SW_MUX_CTL_PAD_GPIO04.[2:0]=101=0x5,GPIO1[4].
    //bits_mask=111=0x7,
    if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_GPIO04, 0x7, 0x5) < 0) {
        return -1;
    }
    
    //IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK,[2:0]=101=0x5,GPIO6[31].
    //bits_mask=111=0x7.
    if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, 0x7, 0x5) < 0) {
        return -1;
    }
    
    //IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN,[2:0]=101=0x5,ALT5,GPIO5[20].
    //bits_mask=111=0x7.
    if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN, 0x7, 0x5) < 0) {
        return -1;
    }

    //IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B,[2:0]=101=0x5,ALT5,GPIO6[11].
    //bits_mask=111=0x7.
    if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B, 0x7, 0x5) < 0) {
        return -1;
    }
    
    //IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B,[2:0]=101=0x5,ALT5,GPIO6[14].
    //bits_mask=111=0x7.
    if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B, 0x7, 0x5) < 0) {
        return -1;
    }
    return 0;
}

//configure pad's physical feature.
int imx6_config_all_pads(void) {
    //[16]=1,Schmitt trigger input.
    //[15:14]=10,100Kohm pull up.
    //[13]=1,pull enabled.
    //[12]=1,pull/keeper enabled.
    //bits_mask= 1,1111,0000,0000,0000=0x1F000.
    //bits_value=1,1011,0000,0000,0000=0x1B000.

    //IOMUXC_SW_PAD_CTL_PAD_GPIO04.
    if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_GPIO04, 0x1F000, 0x1B000) < 0) {
        return -1;
    }
    //IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK.
    if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, 0x1F000, 0x1B000) < 0) {
        return -1;
    }
    //IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN.
    if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN, 0x1F000, 0x1B000) < 0) {
        return -1;
    }
    
    //IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B.
    if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B, 0x1F000, 0x1B000) < 0) {
        return -1;
    }
    
    //IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B.
    if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B, 0x1F000, 0x1B000) < 0) {
        return -1;
    }
    return 0;
}

//configure GPIO registers.
int imx6_config_all_gpios(void) {
    //up/down key,GPIO1[4].
    //[4]=0,direction:input.
    //bits_mask=0001,0000=0x10.
    //bits_value=0000,0000=0x0.
    if (imx6_config_reg(GPIO1_GDIR, 0x10, 0x0) < 0) {
        return -1;
    }
    //[4]=0,disable interrupt.
    if (imx6_config_reg(GPIO1_IMR, 0x10, 0x0) < 0) {
        return -1;
    }

    //left/right key,GPIO5[20].
    //[20]=0,direction,input.
    //bits_mask=1,0000,0000,0000,0000,0000=0x100000.
    //bits_value=0,0000,0000,0000,0000,0000=0x0.
    if (imx6_config_reg(GPIO5_GDIR, 0x100000, 0x0) < 0) {
        return -1;
    }
    //[4]=0,disable interrupt.
    if (imx6_config_reg(GPIO5_IMR, 0x100000, 0x0) < 0) {
        return -1;
    }

    //led key:GPIO6[31].
    //ok key: GPIO6[11].
    //return key: GPIO6[14].
    //[31]=0,direction input.
    //[11]=0,direction input.
    //[14]=0,direction input.
    //bits_mask=1000,0000,0000,0000,0100,1000,0000,0000=0x80004800.
    //bits_value=0000,0000,0000,0000,0000,0000,0000,0000=0x0.
    if (imx6_config_reg(GPIO6_GDIR, 0x80004800, 0x0) < 0) {
        return -1;
    }
    //[31]=0,disable interrupt.
    //[14]=0,disable interrupt.
    //[11]=0,disable interrupt.
    if (imx6_config_reg(GPIO6_IMR, 0x80004800, 0x0) < 0) {
        return -1;
    }

    //do ioremap for virtual address.
    if (!(key_dev->up_down_vir_addr = (ulong*) ioremap(GPIO1_PSR, REG_SIZE))) {
        return -1;
    }
    if (!(key_dev->left_right_vir_addr = (ulong*) ioremap(GPIO5_PSR, REG_SIZE))) {
        return -1;
    }
    if (!(key_dev->led_ok_return_vir_addr = (ulong*) ioremap(GPIO6_PSR, REG_SIZE))) {
        return -1;
    }
    key_dev->up_down_status=1;
    key_dev->left_right_status=1;
    key_dev->led_ok_return_status=1;
    return 0;
}

//timer function.
//used to poll key status.
void key_status_scan_function(unsigned long arg) {

    struct imx6_keys_dev *pkey_dev = (struct imx6_keys_dev*) (arg);
    volatile int ret;

    //the up/down key,GPIO1[4].
    ret = ioread32(pkey_dev->up_down_vir_addr);
    if(!(ret & (0x1 << 4)) && pkey_dev->up_down_status)
    {
        //key was pressed.
        pkey_dev->up_down_status=0;
        input_report_key(pkey_dev->input_device, KEY_UP, 1);
        input_sync(pkey_dev->input_device);
    }else if((ret&(0x1 << 4)) && !pkey_dev->up_down_status)
    {
        //key was released.
        pkey_dev->up_down_status=1;
        input_report_key(pkey_dev->input_device, KEY_UP, 0);
        input_sync(pkey_dev->input_device);
    }

    //the left/right key,GPIO5[20].
    ret = ioread32(pkey_dev->left_right_vir_addr);
    if(!(ret & (0x1 << 20)) && pkey_dev->left_right_status)
    {
        //key was pressed.
        pkey_dev->left_right_status=0;
        input_report_key(pkey_dev->input_device, KEY_LEFT, 1);
        input_sync(pkey_dev->input_device);
    }else if((ret&(0x1<<20)) && !pkey_dev->left_right_status)
    {
        //key was released.
        pkey_dev->left_right_status=1;
        input_report_key(pkey_dev->input_device, KEY_LEFT, 0);
        input_sync(pkey_dev->input_device);
    }

    //led key:GPIO6[31],open or close led.
    //ok key: GPIO6[11],left ctrl.
    //return key: GPIO6[14],left shift.
    ret = ioread32(pkey_dev->led_ok_return_vir_addr);
    if(!(ret & (0x1 << 11)) && (pkey_dev->led_ok_return_status&(0x1<<11)))
    {
        //key was pressed.
        pkey_dev->led_ok_return_status&=~(0x1<<11);
        input_report_key(pkey_dev->input_device, KEY_LEFTCTRL, 1);
        input_sync(pkey_dev->input_device);
    }else if( (ret&(0x1<<11)) && !(pkey_dev->led_ok_return_status&(0x1<<11)))
    {
        //key was released.
        pkey_dev->led_ok_return_status|=(0x1<<11);
        input_report_key(pkey_dev->input_device, KEY_LEFTCTRL, 0);
        input_sync(pkey_dev->input_device);
    }
    /////////////////////////////////////////////////////////////
    ret = ioread32(pkey_dev->led_ok_return_vir_addr);
    if(!(ret & (0x1 << 14)) && (pkey_dev->led_ok_return_status&(0x1<<14)))
    {
        //key was pressed.
        pkey_dev->led_ok_return_status&=~(0x1<<14);
        input_report_key(pkey_dev->input_device, KEY_LEFTSHIFT, 1);
        input_sync(pkey_dev->input_device);
    }else if( (ret&(0x1<<14)) && !(pkey_dev->led_ok_return_status&(0x1<<14)))
    {
        //key was released.
        pkey_dev->led_ok_return_status|=(0x1<<14);
        input_report_key(pkey_dev->input_device, KEY_LEFTSHIFT, 0);
        input_sync(pkey_dev->input_device);
    }
    //////////////////////////////////////////////////////////////
    ret = ioread32(pkey_dev->led_ok_return_vir_addr);
    if(!(ret & (0x1 << 31)) && (pkey_dev->led_ok_return_status&(0x1<<31)))
    {
        //key was pressed to open led.
        pkey_dev->led_ok_return_status&=~(0x1<<31);
    }else if( (ret&(0x1<<31)) && !(pkey_dev->led_ok_return_status&(0x1<<31)))
    {
        //key was released to close led.
        pkey_dev->led_ok_return_status|=(0x1<<31);
    }

#if 1
    //restart the scan routine.
    pkey_dev->scan_timer.expires = jiffies + HZ / 4;    //500ms.
    add_timer(&pkey_dev->scan_timer);
#endif

}

static int __init imx6_key_drv_init(void)
{
    key_dev=(struct imx6_keys_dev *)kzalloc(sizeof(struct imx6_keys_dev),GFP_KERNEL);
    if(!key_dev)
    {
        print_error("kzalloc() failed!\n");goto error_exit_1;
    }
    key_dev->input_device=input_allocate_device();
    if(!key_dev->input_device)
    {
        print_error(
        "allocate input device failed!\n");goto error_exit_2;
    }

#if 1
    if(imx6_config_all_iomuxcs()<0)
    {
        goto  error_exit_3;
        return -1;
    }
    if(imx6_config_all_pads()<0)
    {
        goto  error_exit_3;
        return -1;
    }
    if(imx6_config_all_gpios()<0)
    {
        goto  error_exit_3;
        return -1;
    }
#endif

    //input device name.
    key_dev->input_device->name=MODULE_NAME;

    //key event.
    set_bit(EV_KEY,key_dev->input_device->evbit);
    //key value.
    set_bit(KEY_UP,key_dev->input_device->keybit);
    set_bit(KEY_LEFT,key_dev->input_device->keybit);
    set_bit(KEY_LEFTCTRL,key_dev->input_device->keybit);
    set_bit(KEY_LEFTSHIFT,key_dev->input_device->keybit);
    if(input_register_device(key_dev->input_device))
    {
        print_error("input register device failed!\n");goto error_exit_3;
    }

    //start timer.
    init_timer(&key_dev->scan_timer);key_dev->scan_timer.data=(ulong)key_dev;
    key_dev->scan_timer.function=key_status_scan_function;
    key_dev->scan_timer.expires=jiffies+HZ/2;//500ms.
    add_timer(&key_dev->scan_timer);

    print_debug("imx6_key_drv load successfully!\n");
return 0;
/**
 * exit flow when errors occured.
 */
error_exit_3:
input_free_device(key_dev->input_device);
error_exit_2:
kfree(key_dev);
error_exit_1:
return -1;
}

static void __exit imx6_key_drv_exit(void)
{
    del_timer_sync(&key_dev->scan_timer);input_unregister_device(key_dev->input_device);
    input_free_device(key_dev->input_device);
    kfree(key_dev);
}

module_init(imx6_key_drv_init);
module_exit(imx6_key_drv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangshaoyan <shell.albert@gmail.com>");
MODULE_DESCRIPTION("Keyboard driver for Freescale iMX6 GPIOs");
MODULE_ALIAS("platform:imx6 key driver");


IMX6Q平台的GPIO驱动开发详解 i.MX6Q是由NXP半导体公司推出的一款高性能、低功耗的多核处理器。该平台拥有四个ARM Cortex-A9核心,运行频率高达1.2GHz,支持广泛的I/O接口,并集成了多种硬件加速器,为多任务处理和高效率图形显示提供了强大支持。飞凌开发板是基于ARM架构的高性能嵌入式开发板,被广泛应用于教学、科研和工业控制等领域。它通常配备有丰富的接口资源和强大的处理能力,能够支持多种操作系统和复杂的软件应用。飞凌开发板以其高可靠性和高稳定性,成为了嵌入式领域开发者的优选平台之一。 阅读详情

相关推荐

动态博弈、威胁与承诺(博弈论入门学习笔记四)

0 动态博弈 动态博弈:行动有先后顺序,不同的参与人在不同时点行动,先行动者的选择影响后行动者的选择空间,后行动者可以观察到先行动者做了什么选择。例如下棋、消费者和商家讨价还价、谈婚论嫁、企业之间的价格战等等。 因此,为了做出最优的行动选择,每个参与人都应该思考:如果我如此选择,对方将如何应对?如果我是他,我将会如何行动?给定他的应对,什么是我的最优选择? 动态博弈中的战略:在博弈开始之前就...

stepho的博客 1万+

使用gpio子系统和pinctrl子系统实现按键的操作

使用gpio子系统和pinctrl子系统实现按键的操作 步骤一:看硬件原理图,获知按键用到的IO口。由以下两图可知key0用的是UART_CTS 步骤二:查imx6ull的参考手册,获取寄存器相关信息。 第一张图显示的寄存器设置的IO复用的信息,也就是将IO复用为GPIO1_IO18,对应的寄存器的值为0x05. 下边的图设置的是GPIO1_IO18的电器属性,如:上拉、下拉、开漏、频率。。。。对应寄存器的值为0xF080. 步骤三:设备树配置。 上图中MX6UL_PAD_UART1_CTS_B

peifeng 433

山石网科Hillstone防火墙基础上网配置_CLI命令行(最新版)

山石网科Hillstone防火墙安全网关基础上网基础网络配置_CLI命令行(最新版)

路与肥的博客 1万+

【全志T113-S3_100ask】4-编写按键驱动(atomic + poll)

【全志T113-S3_100ask】4-编写按键驱动 前言 (一)查看原理图 (二)修改设备树 (三)编写驱动 key_drv.c (四)编写测试应用 key_drv_test.c (五)编写Makefile (六)测试 前言 本来想写一下点灯的驱动的,结果发现板子上没有用户的led灯?????那就试着写一下按键的驱动吧。 (一)查看原理图 在原理图里,找到了用户按键USER KEY的内容.........

第四维度的博客 3596

多周期路径及set_multicycle_path详解

默认情况下,每条路径都被定义为单周期,即源触发器在时钟的任一边沿启动(launch)的数据都应该由目的触发器在时钟的下一上升沿捕获(capture)。 有的设计需要在数据被捕获前提供一些额外的周期,这类路径被称为多周期路径。 一、set_multicycle_path命令 命令格式如下: set_multicycle_path .........

Jackiezhang1993的博客 4万+

Arduino蜂鸣器播放《Astronomia》:从乐谱到代码的嵌入式音乐实现

在嵌入式系统开发中,通过编程控制硬件执行特定任务是核心基础。其原理在于利用微控制器生成精确的时序和频率信号,驱动执行器(如蜂鸣器、电机)完成预定动作。这项技术的价值在于实现了软件逻辑与物理世界的直接交互,是物联网设备、智能硬件开发的基石。常见的应用场景包括电子玩具的音效生成、报警器设计以及交互式艺术装置。本文以热门歌曲《Astronomia》的播放为例,具体展示了如何运用Arduino的`tone()`函数和数组数据结构,将抽象的乐谱转化为可执行的频率与延时控制代码,完整呈现了从**核心硬件解析**到**软

weixin_29796279的博客 347

IMX6ULL裸机篇之按键中断实验

IMX6ULL裸机篇之按键中断实验

wojiaxiaohuang2014的博客 811

科研级YOLOv8 Neck革新:BiFPN双向特征金字塔赋能,让多尺度融合更高效的实战指南

在文件夹下新建BiFPN.py,将上述BiFPNLayer和BiFPN类的代码写入其中。这一步是为了让YOLOv8的代码架构能识别我们的自定义Neck模块。

m0_64661770的博客 152

imx6驱动实验之按键驱动gpio-keys

个人能力有限,此博文只当记录实验过程,如有错误,请大家指正。 一、硬件连接 根据飞凌嵌入式的板子添加一个8位的旋转开关,需要8个gpio,所以去除SD3接口,改成GPIO。 需要修改的引脚为 SD3_DATA0 SD3_DATA1 SD3_DATA2 SD3_DATA3 SD3_DATA4 SD3_DATA5 SD3_CMD SD3_CLK 查看电路图,可以...

straw10620的专栏 1698

企业级大数据平台的数据网格(Data Mesh)转型之路

随着企业数字化转型的深入,传统大数据平台面临数据孤岛化、治理成本高、业务响应慢等核心痛点。数据网格作为一种新兴的分布式数据管理架构,通过领域驱动设计(DDD)、数据产品化和联邦治理模式,为企业提供了打破数据壁垒、提升数据生产力的全新路径。本文聚焦企业级数据平台从传统架构(数据湖/数据仓库)向数据网格转型的关键技术、实施步骤和组织配套,涵盖技术架构设计、核心算法实现、项目实战案例及工具链推荐。背景介绍:定义转型目标、术语体系与核心挑战核心概念与联系:解析数据网格四大支柱及技术架构图谱核心算法原理。

AI 领航者的博客 1083

基于 FastAPI + LangGraph + LLM 大语言模型的通用 Agent 多智能体系统架构设计与开发实战、产业应用

FastAPI是一个现代、快速(高性能)的Python Web框架,专门用于构建API。它由Sebastián Ramírez(@tiangolo)创建,基于Starlette(用于Web部分)和Pydantic(用于数据部分)构建。性能优先:FastAPI是当前最快的Python Web框架之一,性能与NodeJS和Go相当。这得益于其基于Starlette的异步架构,能够充分利用Python 3.6+的async/await特性。开发效率。

AI天才研究院 230

正点原子imx6ull-mini-Linux驱动之按键输入实验(9)

define KEY_CNT 1 /* 设备号个数 */#define KEY_NAME "key" /* 名字 *//* 定义按键值 */#define KEY0VALUE 0XF0 /* 按键值 */#define INVAKEY 0X00 /* 无效的按键值 *//* 定义按键值 */

NEWEVA__zzera22的博客 1462

在 SAP ABAP 里可靠地对接 FTP 服务器:从连接、命令到传输与排错的完整实战

本文详细介绍了在SAP ABAP中实现FTP文件交换的完整技术方案。文章首先解析了FTP协议的双连接特性(控制连接与数据连接),强调保持控制连接的重要性。随后详细说明了ABAP中FTP操作的四步标准流程:建立连接(包含HTTP_SCRAMBLE加密)、执行命令、断开连接和关闭RFC通道。文章提供了实战案例代码,演示如何将FTP文件复制到应用服务器再读取进内表处理,特别指出后台作业与前台操作的关键差异。最后总结了常见错误排查要点,包括连接模型、路径设置和资源释放等问题。全文通过SAP标准函数模块的调用顺序、典

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 303

【Linux】按键驱动程序

深入学习按键驱动程序,熟悉读取数据的方式。

希希雾里 2314

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

imx6ull-驱动开发篇21——Linux 按键输入实验

本文介绍了在Linux下开发GPIO按键输入驱动程序的实现过程。通过正点原子I.MX6U-ALPHA开发板的按键实验,详细讲解了从设备树配置到驱动编写的完整流程。

m0_62228566的博客 1025

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序①RK3288的按键驱动程序

APP直接通过调用读取,导致驱动中的读取函数,这样的结构易于扩展,对于不同的单板,只需要替换 board_xxx.c提供自己的 button_operations结构体即可,构造一个file_operations结构体;drv_open配置GPIO为输入模式; drv_read返回预设状态; APP直接通过调用读取,要把GPIO1_25对应的引脚设置为 GPIO模式,要设置 conf_gpmc_a9寄存器的bit[5]为1,bit[2:0]为 7,这个寄存器的地址是 0x44E10000+0x864。

华为奋斗者精神 3375

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十五)具体单板的按键驱动程序(查询方式)

文章目录1.具体单板的按键驱动程序(查询方式)1.1 GPIO操作回顾1.5 百问网IMX6ULL的按键驱动程序(查询方式)1.5.1 先看原理图确定引脚及操作方法1.5.2 再看芯片手册确定寄存器及操作方法1.5.3 编程1.5.3.1 程序框架1.5.3.2 硬件相关的代码1.5.4 测试1.5.5 课后作业 1.具体单板的按键驱动程序(查询方式) 1.1 GPIO操作回顾 参考章节《第四章 普适的GPIO引脚操作方法》、《第五章 具体单板的GPIO操作方法》。 1.5 百问网IMX6ULL的按键驱动

da.的博客 701

Linux 按键输入实验-基于正点原子IMX6ULL开发板

I.MX6U-ALPHA 开发板上有一个按键,我们 就使用此按键来完成 GPIO 输入驱动程序,同时利用第四十七章讲的原子操作来对按键值进行保护。 1 Linux 下按键驱动原理 按键驱动和 LED 驱动原理上来讲基本都是一样的,都是操作 GPIO,只不过一个是读取 GPIO 的高低电平,一个是从 GPIO 输出高低电平。本章我们实现按键输入,在驱动程序中使用 一个整形变量来表示按键值,应用程序通过 read 函数来读取按键值,判断按键有没有按下。在 这里,这个保存按键...

shengnan89的博客 508

四、IMX6ULL按键输入

一、IMX6LL裸机点亮一颗LED二、移植IMX6ULL_SDK点亮LED三、IMX6ULL BSP工程管理。

qq_43570266的博客 328

imx6ull-驱动开发篇39——Linux INPUT 子系统实验

本文使用正点原子imx6ull开发板,编写基于linux驱动input子框架的测试代码。

m0_62228566的博客 1175

按键演示休眠与唤醒场景--基于IMX6ULL

按键演示休眠与唤醒场景--基于IMX6ULL

holdtao的博客 792

iMX6ULL —按键输入捕获与GPIO输入配置与高低电平读取

i.MX6ULL 按键输入捕获与GPIO输入配置与高低电平读取

yaningli的博客 1994

嵌入式Linux应用开发-第十八章系统对中断的处理③按键驱动程序

写在前面的话:对于 GPIO按键,我们并不需要去写驱动程序,使用内核自带的驱动程序drivers/input/keyboard/gpio_keys.c就可以,然后你需要做的只是修改设备树指定引脚及键值。但是我还是要教你怎么从头写按键驱动,特别是如何使用中断。因为中断是引入其他基础知识的前提,后面要讲的这些内容都离不开中断:休眠-唤醒、POLL机制、异步通知、定时器、中断的线程化处理。这些基础知识是更复杂的驱动程序的基础要素,以后的复杂驱动也就是对硬件操作的封装彼此不同,但是用到的基础编程知识是一样的。

华为奋斗者精神 2927

具体单板的按键驱动程序(查询方式)-以IMX6ull单板为例子

具体单板的按键驱动程序(查询方式)-以IMX6ull单板为例子

holdtao的博客 300

20150218【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序 2015-02-18 李海沿   按键驱动程序中,如果不使用read函数中使程序休眠的,而是还是使用查询方式的话,可以使用Poll函数,来控制一定时间内,如果有按键发生,则立即返回键值。 同时,poll也可以同时监控多个(比如说按键,鼠标,等)一旦发生事件则立即返回。 我们在linux查看帮助: 从...

|~~~热爱生活、努力学习的小伙汁~~~| 670
上一篇: Qt继电器控制板代码
下一篇: busybox passwd修改密码
Yantai666
博客等级 码龄15年 45粉丝 271原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值