参考内容:通用GPIO设备应用笔记
https://www.rt-thread.org/document/site/rtthread-application-note/driver/gpio/an0002-rtthread-driver-gpio/
问题:#define LED_PIN PIN_LED_R io口是如何一一对应起来的。
在drv_gpio.c文件中 列出了100个引脚的对应关系还有中断的相关关系。
static const struct pin_index pins[] =
{
__STM32_PIN_DEFAULT,
__STM32_PIN(1, E, 2), // PE2: SAI1_MCLK_A --> ES8388
__STM32_PIN(2, E, 3), // PE3: SAI1_SD_B --> ES8388
__STM32_PIN(3, E, 4), // PE4: SAI1_FS_A --> ES8388
__STM32_PIN(4, E, 5), // PE5: SAI1_SCK_A --> ES8388
__STM32_PIN(5, E, 6), // PE6: SAI1_SD_A --> ES8388
__STM32_PIN_DEFAULT, // : VBAT
__STM32_PIN(7, C, 13), //PC13: SD_CS --> SD_CARD
__STM32_PIN(8, C, 14), //PC14: OSC32_IN
__STM32_PIN(9, C, 15), //PC15: OSC32_OUT
__STM32_PIN_DEFAULT, // : VSS
__STM32_PIN_DEFAULT, // : VDD
__STM32_PIN_DEFAULT, // PH0: OSC_IN
__STM32_PIN_DEFAULT, // PH1: OSC_OUT
__STM32_PIN_DEFAULT, // : RESET
__STM32_PIN(15, C, 0), // PC0: I2C_SCL --> ES8388
__STM32_PIN(16, C, 1), // PC1: I2C_SDA --> ES8388
__STM32_PIN(17, C, 2), // PC2: GBC_LED --> ATK MODULE
__STM32_PIN(18, C, 3), // PC3: GBC_KEY --> ATK MODULE
__STM32_PIN_DEFAULT, // : VSSA
__STM32_PIN_DEFAULT, // : VREF-
__STM32_PIN_DEFAULT, // : VREF+
__STM32_PIN_DEFAULT, // : VDDA
__STM32_PIN(23, A, 0), // PA0: MOTOR_A --> MOTOR
__STM32_PIN(24, A, 1), // PA1: MOTOR_B --> MOTOR
__STM32_PIN(25, A, 2), // PA2: UART2_TX --> EXTERNAL MODULE
__STM32_PIN(26, A, 3), // PA3: UART2_RX --> EXTERNAL MODULE
__STM32_PIN_DEFAULT, // : VSS
__STM32_PIN_DEFAULT, // : VDD
__STM32_PIN(29, A, 4), // PA4: ADC12_IN9 --> EXTERNAL MODULE
__STM32_PIN(30, A, 5), // PA5: SPI1_SCK --> SD_CARD
__STM32_PIN(31, A, 6), // PA6: SPI1_MISO --> SD_CARD
__STM32_PIN(32, A, 7), // PA7: SPI1_MOSI --> SD_CARD
__STM32_PIN(33, C, 4), // PC4: GBC_RX --> ATK MODULE
__STM32_PIN(34, C, 5), // PC5: WIFI_INT --> WIFI
__STM32_PIN(35, B, 0), // PB0: EMISSION --> INFRARED EMISSION
__STM32_PIN(36, B, 1), // PB1: RECEPTION --> INFRARED EMISSION
__STM32_PIN(37, B, 2), // PB2: BEEP --> BEEP
__STM32_PIN(38, E, 7), // PE7: LED_R --> LED
__STM32_PIN(39, E, 8), // PE8: LED_G --> LED
__STM32_PIN(40, E, 9), // PE9: LED_B --> LED
__STM32_PIN(41, E, 10), //PE10: QSPI_BK1_CLK --> SPI_FLASH
__STM32_PIN(42, E, 11), //PE11: QSPI_BK1_NCS --> SPI_FLASH
__STM32_PIN(43, E, 12), //PE12: QSPI_BK1_IO0 --> SPI_FLASH
__STM32_PIN(44, E, 13), //PE13: QSPI_BK1_IO1 --> SPI_FLASH
__STM32_PIN(45, E, 14), //PE14: QSPI_BK1_IO2 --> SPI_FLASH
__STM32_PIN(46, E, 15), //PE15: QSPI_BK1_IO3 --> SPI_FLASH
__STM32_PIN(47, B, 10), //PB10: AP_INT --> ALS&PS SENSOR
__STM32_PIN(48, B, 11), //PB11: ICM_INT --> AXIS SENSOR
__STM32_PIN_DEFAULT, // : VSS
__STM32_PIN_DEFAULT, // : VDD
__STM32_PIN(51, B, 12), //PB12: SPI2_CS --> EXTERNAL MODULE
__STM32_PIN(52, B, 13), //PB13: SPI2_SCK --> EXTERNAL MODULE
__STM32_PIN(53, B, 14), //PB14: SPI2_MISO --> EXTERNAL MODULE
__STM32_PIN(54, B, 15), //PB15: SPI2_MOSI --> EXTERNAL MODULE
__STM32_PIN(55, D, 8), // PD8: KEY0 --> KEY
__STM32_PIN(56, D, 9), // PD9: KEY1 --> KEY
__STM32_PIN(57, D, 10), //PD10: KEY2 --> KEY
__STM32_PIN(58, D, 11), //PD11: WK_UP --> KEY
__STM32_PIN(59, D, 12), //PD12: IO_PD12 --> EXTERNAL MODULEL
__STM32_PIN(60, D, 13), //PD13: IO_PD13 --> EXTERNAL MODULE
__STM32_PIN(61, D, 14), //PD14: IO_PD14 --> EXTERNAL MODULE
__STM32_PIN(62, D, 15), //PD15: IO_PD15 --> EXTERNAL MODULE
__STM32_PIN(63, C, 6), // PC6: TIM3_CH1 --> EXTERNAL MODULE
__STM32_PIN(64, C, 7), // PC7: TIM3_CH2 --> EXTERNAL MODULE
__STM32_PIN(65, C, 8), // PC8: SDIO_D0 --> WIFI
__STM32_PIN(66, C, 9), // PC9: SDIO_D1 --> WIFI
__STM32_PIN(67, A, 8), // PA8: IO_PA8 --> EXTERNAL MODULE
__STM32_PIN(68, A, 9), // PA9: UART1_TX --> STLINK_RX
__STM32_PIN(69, A, 10), //PA10: UART1_RX --> STLINK_RX
__STM32_PIN(70,A, 11), // PA11: USB_D- --> USB OTG && EXTERNAL MODULE
__STM32_PIN(71, A, 12), //PA12: USB_D+ --> USB OTG && EXTERNALMODULE
__STM32_PIN(72, A, 13), //PA13: T_JTMS --> STLINK
__STM32_PIN_DEFAULT, // : VDDUSB
__STM32_PIN_DEFAULT, // : VSS
__STM32_PIN_DEFAULT, // : VDD
__STM32_PIN(76, A, 14), //PA14: T_JTCK --> STLINK
__STM32_PIN(77, A, 15), //PA15: AUDIO_PWR --> AUDIO && POWER
__STM32_PIN(78, C, 10), //PC10: SDIO_D2 --> WIFI
__STM32_PIN(79, C, 11), //PC11: SDIO_D3 --> WIFI
__STM32_PIN(80, C, 12), //PC12: SDIO_CLK --> WIFI
__STM32_PIN(81, D, 0), //
__STM32_PIN(82, D, 1), // PD1: WIFI_REG_ON --> WIFI
__STM32_PIN(83, D, 2), // PD2: SDIO_CMD --> WIFI
__STM32_PIN(84, D, 3), // PD3: IO_PD3 --> EXTERNAL MODULE
__STM32_PIN(85, D, 4), // PD4: NRF_IRQ --> WIRELESS
__STM32_PIN(86, D, 5), // PD5: NRF_CE --> WIRELESS
__STM32_PIN(87, D, 6), // PD6: NRF_CS --> WIRELESS
__STM32_PIN(88, D, 7), // PD7: LCD_CS --> LCD
__STM32_PIN(89, B, 3), // PB3: LCD_SPI_SCK --> LCD
__STM32_PIN(90, B, 4), // PB4: LCD_WR --> LCD
__STM32_PIN(91, B, 5), // PB5: LCD_SPI_SDA --> LCD
__STM32_PIN(92, B, 6), // PB6: LCD_RESET --> LCD
__STM32_PIN(93, B, 7), // PB7: LCD_PWR --> LCD
__STM32_PIN_DEFAULT, // : BOOT0
__STM32_PIN(95, B, 8), // PB8: I2C1_SCL --> EXTERNAL MODULE
__STM32_PIN(96, B, 9), // PB9: I2C1_SDA --> EXTERNAL MODULE
__STM32_PIN(97, E, 0), // PE0: IO_PE0 --> EXTERNAL MODULE
__STM32_PIN(98, E, 1), // PE1: IO_PE1 --> EXTERNAL MODULE
__STM32_PIN_DEFAULT, // : VSS
__STM32_PIN_DEFAULT, // : VDD
};
注册初始化
int rt_hw_pin_init(void)
{
return rt_device_pin_register("pin", &_stm32_pin_ops,RT_NULL);
}
const static struct rt_pin_ops_stm32_pin_ops =
{
stm32_pin_mode,
stm32_pin_write,
stm32_pin_read,
stm32_pin_attach_irq,
stm32_pin_dettach_irq,
stm32_pin_irq_enable,
};
IO设备管理框架与通用GPIO设备的联系
RT-Thread 提供了一套简单的I/O 设备管理框架,它把 I/O 设备分成了三层进行处理:应用层、I/O 设备管理层、硬件驱动层。应用程序通过 RT-Thread 的设备操作接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。RT-Thread 提供给上层应用的是一个抽象的设备操作接口,给下层设备提供的是底层驱动框架。对于通用 GPIO 设备,应用程序既可以通过设备操作接口访问,又可以直接通过通用 GPIO 设备驱动来访问。一般来说,我们都是使用第二种方式。那么如何在 RT-Thread 中使用通用 GPIO 设备驱动从而操作 GPIO 呢?
RT-Thread 自动初始化功能依次调用 rt_hw_pin_init ===> rt_device_pin_register ===>rt_device_register 完成了 GPIO 硬件初始化。rt_device_register 注册设备类型为RT_Device_Class_Miscellaneous,即杂类设备,从而我们就可以使用统一的 API 操作 GPIO。
1.png(121.76KB,下载次数:0)
下载附件
2分钟前上传
程序运行流程怎么一步一步开始的?
在rtconfig.h中 配置使用PIN设备。
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 256
#define RT_CONSOLE_DEVICE_NAME"uart1"
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN 启动方式之一
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_USING_PIN
都在components.c中,
从startup_stm32l475xx.s 启动文件中开始。
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit //系统初始化,时钟相关等
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loopswhich can be modified)
由于rtconfig.h配置宏RT_USING_USER_MAIN,表明通过组件的方式跳到main函数,不过此时过程是,先重新定义main函数int $Sub$$main(void),代码先跳到int$Sub$$main(void)执行,
调用rt_application_init();创建main线程,在main线程中调用main函数
详见:components.c中:
#if defined(__CC_ARM) ||defined(__CLANG_ARM)
extern int $Super$$main(void);
/* re-define main function */
int $Sub$$main(void)
{
rt_hw_interrupt_disable();
rtthread_startup();//启动rtos.
return 0;
}
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initialization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();//这里会进行rt_hw_pin_init()stm32_hw_usart_init();注册IO 串口设备
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
/* signal system initialization */
rt_system_signal_init();
#endif
/* create init_thread */
rt_application_init();//在这里创建main.c 的入口函数。
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
#ifdef RT_USING_SMP
rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry,RT_NULL,
main_stack,sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif
rt_thread_startup(tid);//启动这个线程。
}
/* the system main thread */
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
/* RT-Thread components initialization */
rt_components_init();//组件初始化,这个例程暂时没用到。
#ifdef RT_USING_SMP
rt_hw_secondary_cpu_up();
#endif
/* invoke system main function */
#if defined(__CC_ARM) ||defined(__CLANG_ARM)
$Super$$main(); /* for ARMCC. */转到main.c中
#elif defined(__ICCARM__) ||defined(__GNUC__)
main();
#endif
}
由于定义#define RT_USING_COMPONENTS_INIT
/*
*Components Initialization will initialize some driver and components asfollowing
*order:
*rti_start --> 0
*BOARD_EXPORT --> 1
*rti_board_end --> 1.end
*
*DEVICE_EXPORT --> 2
*COMPONENT_EXPORT --> 3
*FS_EXPORT --> 4
*ENV_EXPORT --> 5
*APP_EXPORT --> 6
*
*rti_end --> 6.end
*
*These automatically initialization, the driver or component initial functionmust
* bedefined with:
*INIT_BOARD_EXPORT(fn);
* INIT_DEVICE_EXPORT(fn);
*...
*INIT_APP_EXPORT(fn);
*etc.
*/
int main(void)
{
unsigned int count = 1;
/* set LED pin mode to output */
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
while (count > 0)
{
/* led on */
rt_pin_write(LED_PIN, PIN_LOW);
rt_kprintf("led on, count: %d\n", count);
rt_thread_mdelay(500);
/* led off */
rt_pin_write(LED_PIN, PIN_HIGH);
rt_kprintf("led off\n");
rt_thread_mdelay(500);
count++;
}
return 0;
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。