色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > RT_Thread IoT_Board筆記2:LED閃爍例程_通用GPIO設(shè)備

          RT_Thread IoT_Board筆記2:LED閃爍例程_通用GPIO設(shè)備

          發(fā)布人:電子禪石 時(shí)間:2018-12-27 來源:工程師 發(fā)布文章
          參考內(nèi)容:通用GPIO設(shè)備應(yīng)用筆記

          問題:#define LED_PIN             PIN_LED_R   io口是如何一一對(duì)應(yīng)起來的。

          在drv_gpio.c文件中 列出了100個(gè)引腳的對(duì)應(yīng)關(guān)系還有中斷的相關(guān)關(guān)系。
          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
          };
          注冊(cè)初始化
          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設(shè)備管理框架與通用GPIO設(shè)備的聯(lián)系

          RT-Thread 提供了一套簡(jiǎn)單的I/O 設(shè)備管理框架,它把 I/O 設(shè)備分成了三層進(jìn)行處理:應(yīng)用層、I/O 設(shè)備管理層、硬件驅(qū)動(dòng)層。應(yīng)用程序通過 RT-Thread 的設(shè)備操作接口獲得正確的設(shè)備驅(qū)動(dòng),然后通過這個(gè)設(shè)備驅(qū)動(dòng)與底層 I/O 硬件設(shè)備進(jìn)行數(shù)據(jù)(或控制)交互。RT-Thread 提供給上層應(yīng)用的是一個(gè)抽象的設(shè)備操作接口,給下層設(shè)備提供的是底層驅(qū)動(dòng)框架。對(duì)于通用 GPIO 設(shè)備,應(yīng)用程序既可以通過設(shè)備操作接口訪問,又可以直接通過通用 GPIO 設(shè)備驅(qū)動(dòng)來訪問。一般來說,我們都是使用第二種方式。那么如何在 RT-Thread 中使用通用 GPIO 設(shè)備驅(qū)動(dòng)從而操作 GPIO 呢?
          RT-Thread 自動(dòng)初始化功能依次調(diào)用 rt_hw_pin_init ===> rt_device_pin_register ===>rt_device_register 完成了 GPIO 硬件初始化。rt_device_register 注冊(cè)設(shè)備類型為RT_Device_Class_Miscellaneous,即雜類設(shè)備,從而我們就可以使用統(tǒng)一的 API 操作 GPIO。
          1.png 

          程序運(yùn)行流程怎么一步一步開始的?

          在rtconfig.h中 配置使用PIN設(shè)備。
          /* 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           啟動(dòng)方式之一
          #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 啟動(dòng)文件中開始。
          ; Reset handler
          Reset_Handler    PROC
                           EXPORT  Reset_Handler             [WEAK]
                 IMPORT  SystemInit   //系統(tǒng)初始化,時(shí)鐘相關(guān)等
                 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函數(shù),不過此時(shí)過程是,先重新定義main函數(shù)int $Sub$$main(void),代碼先跳到int$Sub$$main(void)執(zhí)行,
          調(diào)用rt_application_init();創(chuàng)建main線程,在main線程中調(diào)用main函數(shù)
          詳見: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();//啟動(dòng)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();//這里會(huì)進(jìn)行rt_hw_pin_init()stm32_hw_usart_init();注冊(cè)IO 串口設(shè)備
             /* 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();//在這里創(chuàng)建main.c 的入口函數(shù)。
             /* 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);//啟動(dòng)這個(gè)線程。
          }
          /* 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();//組件初始化,這個(gè)例程暫時(shí)沒用到。
          #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. */轉(zhuǎn)到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;
          }


          *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



          關(guān)鍵詞:

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉