当前位置:网站首页>【RT-Thread】nxp rt10xx 设备驱动框架之--Pin搭建和使用
【RT-Thread】nxp rt10xx 设备驱动框架之--Pin搭建和使用
2022-07-03 17:07:00 【L_17】
开发前准备
- 硬件平台:nxp rt10xx单片机
- IDE: Keil
1.Kconfig 修改和menuconfig配置
Kconfig中发现PIN 配置默认是选中状态(毕竟最常用的IO驱动设备)
RT-Thread Comonents -> Device Drivers
RT-Thread Components-> On-chip Peripheral Drivers

2.工程添加PIN驱动框架和BSP驱动接口
设备驱动框架:pin.c BSP接口:drv_gpio.c fsl_gpio.c fsl_iomuxc.c

3.添加或修改drv_gpio.c
笔者查阅了文件,该驱动很完善,几乎不用改什么,接下来先了解下基本框架吧
struct rt_pin_ops
{
void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
int (*pin_read)(struct rt_device *device, rt_base_t pin);
rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
rt_base_t (*pin_get)(const char *name);
};
const static struct rt_pin_ops imxrt_pin_ops =
{
imxrt_pin_mode,
imxrt_pin_write,
imxrt_pin_read,
imxrt_pin_attach_irq,
imxrt_pin_detach_irq,
imxrt_pin_irq_enable,
RT_NULL,
};
int rt_hw_pin_init(void)
{
int ret = RT_EOK;
ret = rt_device_pin_register("pin", &imxrt_pin_ops, RT_NULL);
return ret;
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
该bsp基本很完善了,没什么要改的,简单展示一下吧
static void imxrt_isr(rt_int16_t index_offset, rt_int8_t pin_start, GPIO_Type *base)
{
rt_int32_t isr_status, index;
rt_int8_t i, pin_end;
pin_end = pin_start + 15;
isr_status = GPIO_PortGetInterruptFlags(base) & base->IMR;
for (i = pin_start; i <= pin_end ; i++)
{
if (isr_status & (1 << i))
{
GPIO_PortClearInterruptFlags(base, (1 << i));
index = index_offset + i;
if (hdr_tab[index].hdr != RT_NULL)
{
hdr_tab[index].hdr(hdr_tab[index].args);
}
}
}
}
static void imxrt_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
gpio_pin_config_t gpio;
rt_uint32_t config_value = 0;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return;
}
gpio.outputLogic = 0;
gpio.interruptMode = kGPIO_NoIntmode;
switch (mode)
{
case PIN_MODE_OUTPUT:
{
gpio.direction = kGPIO_DigitalOutput;
config_value = 0x0030U; /* Drive Strength R0/6 */
}
break;
case PIN_MODE_INPUT:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0x0830U; /* Open Drain Enable */
}
break;
case PIN_MODE_INPUT_PULLDOWN:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0x3030U; /* 100K Ohm Pull Down */
}
break;
case PIN_MODE_INPUT_PULLUP:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0xB030U; /* 100K Ohm Pull Up */
}
break;
case PIN_MODE_OUTPUT_OD:
{
gpio.direction = kGPIO_DigitalOutput;
config_value = 0x0830U; /* Open Drain Enable */
}
break;
}
if (mask_tab[port].gpio != GPIO5)
{
CLOCK_EnableClock(kCLOCK_Iomuxc);
IOMUXC_SetPinMux(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, 1);
IOMUXC_SetPinConfig(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, config_value);
}
else
{
CLOCK_EnableClock(kCLOCK_IomuxcSnvs);
IOMUXC_SetPinMux(GPIO5_MUX_BASE + pin_num * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_num * 4, 1);
IOMUXC_SetPinConfig(GPIO5_MUX_BASE + pin_num * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_num * 4, config_value);
}
GPIO_PinInit(mask_tab[port].gpio, pin_num, &gpio);
}
static int imxrt_pin_read(rt_device_t dev, rt_base_t pin)
{
int value;
rt_int8_t port, pin_num;
value = PIN_LOW;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return value;
}
return GPIO_PinReadPadStatus(mask_tab[port].gpio, pin_num);
}
static void imxrt_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return;
}
GPIO_PinWrite(mask_tab[port].gpio, pin_num, value);
}
static rt_err_t imxrt_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (hdr_tab[pin].pin == pin &&
hdr_tab[pin].hdr == hdr &&
hdr_tab[pin].mode == mode &&
hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
hdr_tab[pin].pin = pin;
hdr_tab[pin].hdr = hdr;
hdr_tab[pin].mode = mode;
hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t imxrt_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (hdr_tab[pin].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
hdr_tab[pin].pin = -1;
hdr_tab[pin].hdr = RT_NULL;
hdr_tab[pin].mode = 0;
hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t imxrt_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
gpio_interrupt_mode_t int_mode;
rt_int8_t port, pin_num, irq_index;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
if (hdr_tab[pin].pin == -1)
{
LOG_D("rtt pin: %d callback function not initialized!\n", pin);
return RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
switch (hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING:
int_mode = kGPIO_IntRisingEdge;
break;
case PIN_IRQ_MODE_FALLING:
int_mode = kGPIO_IntFallingEdge;
break;
case PIN_IRQ_MODE_RISING_FALLING:
int_mode = kGPIO_IntRisingOrFallingEdge;
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
int_mode = kGPIO_IntHighLevel;
break;
case PIN_IRQ_MODE_LOW_LEVEL:
int_mode = kGPIO_IntLowLevel;
break;
default:
int_mode = kGPIO_IntRisingEdge;
break;
}
irq_index = (port << 1) + (pin_num >> 4);
GPIO_PinSetInterruptConfig(mask_tab[port].gpio, pin_num, int_mode);
GPIO_PortEnableInterrupts(mask_tab[port].gpio, 1U << pin_num);
NVIC_SetPriority(irq_tab[irq_index], NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
EnableIRQ(irq_tab[irq_index]);
}
else if (enabled == PIN_IRQ_DISABLE)
{
GPIO_PortDisableInterrupts(mask_tab[port].gpio, 1U << pin_num);
}
else
{
return RT_EINVAL;
}
return RT_EOK;
}
4.搭建应用层demo
基本功能LED0线程中闪烁,LED1通过KEY0按一次翻转一次IO
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------ Includes */
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
/*------------------------------------------------------------------------------------------------------------------ Macros */
#define THREAD_GPIO_PRIORITY 24
#define THREAD_GPIO_STACK_SIZE 512
#define THREAD_GPIO_TIMESLICE 2
#define LED0_PIN GET_PIN(1, 9)
#define LED1_PIN GET_PIN(1, 24)
#define KEY0_PIN GET_PIN(5, 0) //IOMUXC_SNVS_WAKEUP_GPIO5_IO00
/*------------------------------------------------------------------------------------------------------------------ Variables */
static rt_thread_t h_thread_gpio = RT_NULL;
static uint8_t ledBlink;
/*------------------------------------------------------------------------------------------------------------------ Functions */
/* 中断回调函数 */
void key_irq(void *args)
{
rt_kprintf("key push!\n");
rt_pin_write(LED1_PIN, !rt_pin_read(LED1_PIN));
}
static void thread_gpio(void *parameter)
{
rt_kprintf("thread gpio start\n");
while(1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
// rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
// rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
void xAPP_GpioInit(void)
{
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_pin_mode(KEY0_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_FALLING, key_irq, RT_NULL);
rt_pin_irq_enable(KEY0_PIN, PIN_IRQ_ENABLE);
//创建Audio线程
h_thread_gpio = rt_thread_create("t_gpio",thread_gpio,RT_NULL,THREAD_GPIO_STACK_SIZE,THREAD_GPIO_PRIORITY,THREAD_GPIO_TIMESLICE);
if (h_thread_gpio != RT_NULL)
{
rt_thread_startup(h_thread_gpio);
}
}
/****************************************************END OF FILE*****************************************************/
测试结果

边栏推荐
- 新库上线 | CnOpenData中国观鸟记录数据
- Visual studio "usually, each socket address (Protocol / network address / port) can only be used once“
- What material is sa537cl2? Analysis of mechanical properties of American standard container plate
- Free data | new library online | cnopendata complete data of China's insurance intermediary outlets
- [mathematical logic] equivalent calculus and reasoning calculus of propositional logic (propositional logic | equivalent calculus | principal conjunctive (disjunctive) paradigm | reasoning calculus)**
- [combinatorics] polynomial theorem (polynomial coefficients | full arrangement of multiple sets | number of schemes corresponding to the ball sub model | polynomial coefficient correlation identity)
- New library online | cnopendata China bird watching record data
- 29:第三章:开发通行证服务:12:开发【获得用户账户信息,接口】;(使用VO类包装查到的数据,以符合接口对返回数据的要求)(在多处都会用到的逻辑,在Controller中可以把其抽成一个共用方法)
- 人生还在迷茫?也许这些订阅号里有你需要的答案!
- [combinatorial mathematics] recursive equation (example of recursive equation 2 Hanoi Tower | example of recursive equation 3 insertion sequencing)
猜你喜欢

MySQL Basics

【Try to Hack】主动侦查隐藏技术

新库上线 | CnOpenData中国保险机构网点全集数据
The way of wisdom (unity of knowledge and action)

Depth first search of graph

Build your own website (23)

Meituan side: why does thread crash not cause JVM crash

Fast Ethernet and Gigabit Ethernet: what's the difference?

聊聊接口优化的几个方法
![[combinatorics] polynomial theorem (polynomial theorem | polynomial theorem proof | polynomial theorem inference 1 item number is the number of non negative integer solutions | polynomial theorem infe](/img/9d/6118b699c0d90810638f9b08d4f80a.jpg)
[combinatorics] polynomial theorem (polynomial theorem | polynomial theorem proof | polynomial theorem inference 1 item number is the number of non negative integer solutions | polynomial theorem infe
随机推荐
[combinatorial mathematics] counting model, common combinatorial numbers and combinatorial identities**
[combinatorics] recursive equation (example of solving recursive equation without multiple roots | complete process of solving recursive equation without multiple roots)
RF analyze demo build step by step
Life is still confused? Maybe these subscription numbers have the answers you need!
人生还在迷茫?也许这些订阅号里有你需要的答案!
执行脚本不认\r
New features of C 10
网络安全web渗透技术
Mysql database DDL and DML
[combinatorics] polynomial theorem (polynomial theorem | polynomial theorem proof | polynomial theorem inference 1 item number is the number of non negative integer solutions | polynomial theorem infe
Kotlin学习快速入门(7)——扩展的妙用
[combinatorics] recursive equation (the relationship theorem between the solution of the recursive equation and the characteristic root | the linear property theorem of the solution of the recursive e
What is the material of sa302grc? American standard container plate sa302grc chemical composition
IL Runtime
One brush 148 force deduction hot question-5 longest palindrome substring (m)
Apache service suspended asynchronous acceptex failed
13mnnimo5-4 German standard steel plate 13MnNiMo54 boiler steel 13MnNiMo54 chemical properties
vs code 插件 koroFileHeader
Capacités nécessaires à l'analyse des données
C语言字符串反转