精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

pikascript GPIO接口如何基于rtt pin設備實現呢?

冬至子 ? 來源:IcyFeather ? 作者:IcyFeather ? 2023-08-07 17:47 ? 次閱讀

介紹

Pikascript 是 RT-Thread 軟件包中心 - 編程語言 中的一個包,是一個對單片機友好的輕量級 python 腳本支持工具,類似 micropython。

在 Pikascript 中,架構如下:

1.jpg

對于不同的平臺,我們需要手動為平臺適配 pika_hal 的設備抽象層接口。今天以 packages/pikascript-latest/pikaRTDevice/pika_hal_RTT_GPIO.c 為例,講解 Pikascript GPIO 接口如何基于 RT-Thread Pin 設備 rt-thread/components/misc/pin.c 實現。

講解

模型如下:

1.jpg

所有設備均遵循類 linux 文件的編程模型,所有類型的設備均使用 pika_dev 結構體來作為設備句柄。

pika_dev 類型定義:

typedef struct {
PIKA_HAL_DEV_TYPE type;
PIKA_BOOL is_enabled;
void* ioctl_config;
void* platform_data;
} pika_dev;

在 RT-Thread 的文檔中可以得知,應用程序通過 RT-Thread 提供的 PIN 設備管理接口來訪問 GPIO,相關接口如下所示:

1.jpg

// 通過設備名,返回 pin num
rt_base_t rt_pin_get(const char *name);
// 通過 pin num,返回該 pin 的數據
int rt_pin_read(rt_base_t pin);
// 把 value 電平信息寫到對應 pin 上
void rt_pin_write(rt_base_t pin, rt_base_t value);
// 把 pin 的模式設置為 mode
void rt_pin_mode(rt_base_t pin, rt_base_t mode)
所以經過分析,不難看出我們在 open 中要通過 rt_pin_get() 獲取引腳編號,獲取設備信息;在 read 中要通過 rt_pin_read() 讀取引腳電平;在 write 中要通過 rt_pin_write() 設置引腳電平。

在 pika_hal_RTT_GPIO.c 中,我們一共有 7 個接口要實現:

int pika_hal_platform_GPIO_open(pika_dev* dev, char* name);
int pika_hal_platform_GPIO_close(pika_dev* dev);
int pika_hal_platform_GPIO_read(pika_dev* dev, void* buf, size_t count);
int pika_hal_platform_GPIO_write(pika_dev* dev, void* buf, size_t count);
int pika_hal_platform_GPIO_ioctl_enable(pika_dev* dev);
int pika_hal_platform_GPIO_ioctl_disable(pika_dev* dev);
int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, pika_hal_GPIO_config* cfg);
下面我們依次進行講解。

dev->platform_io 中存儲的數據
首先定義一個結構體 platform_data_GPIO 用來存在 dev->platform_data 中,由上面對 rtt pin 接口的簡單調用分析可知,只需要 pin 的數據:

typedef struct platform_data_GPIO {
uint32_t pin_num;
} platform_data_GPIO;
pika_hal_platform_GPIO_open
函數的原型為: int pika_hal_platform_GPIO_open(pika_dev* dev, char* name);

參數

pika_dev* dev: 要操作的設備句柄
char* name: GPIO 設備名
函數功能:

根據 GPIO 設備名,找到對應的 GPIO 設備的 pin
把設備 pin 數據存在 dev->platform_data 里面
實現:

int pika_hal_platform_GPIO_open(pika_dev* dev, char* name) {
// 打印當前信息
rt_kprintf("rn=%s==%s=%d=name:%s==rn", FILE , FUNCTION , LINE ,name);
// 打印一下日志信息,當前正在打開哪個設備
__platform_printf("Open: %s rn", name);
// 調用 pikaMalloc 分配內存,創建一個 platform_data_GPIO 結構體,用來存放這個 GPIO 設備的信息
platform_data_GPIO* data = pikaMalloc(sizeof(platform_data_GPIO));
// 在 RT_USING_PIN 這個宏定義存在時,通過 rt_pin_get 函數獲取這個 GPIO 設備的引腳號,存放在 platform_data_GPIO 結構體的 pin_num 成員中。
#ifdef RT_USING_PIN
data->pin_num = rt_pin_get(name) ;
#endif
// 將創建的 platform_data_GPIO 結構體賦值給 dev->platform_data
dev->platform_data = data;
return 0;
}
pika_hal_platform_GPIO_close
函數的原型為:int pika_hal_platform_GPIO_close(pika_dev* dev);

參數:
pika_dev* dev: 要操作的設備句柄

函數功能:
清除這個 GPIO 設備的信息,即清空 dev->platform_data 中的數據

實現:

int pika_hal_platform_GPIO_close(pika_dev* dev) {
rt_kprintf("rn=%s==%s=%d===rn", FILE , FUNCTION , LINE );
// 如果現在有 GPIO 設備數據,就清空
if (NULL != dev->platform_data) {
pikaFree(dev->platform_data, sizeof(platform_data_GPIO));
dev->platform_data = NULL;
}
return 0;
}
pika_hal_platform_GPIO_read
函數的原型為:int pika_hal_platform_GPIO_write(pika_dev* dev, void* buf, size_t count);

參數:
pika_dev dev:要操作的設備句柄
void buf:讀取緩沖區
size_t count:讀取數據長度,對于 GPIO、ADC 這樣只能讀取單個數據的設備,長度為 sizeof(uint32_t)

函數功能:

根據之前存到 dev->platform_data 中的 pin num 數據,調用 rt_pin_read() 函數來獲取該 pin 的數據
把讀取到的數據存到 buf 緩沖區中
實現:

int pika_hal_platform_GPIO_read(pika_dev* dev, void* buf, size_t count) {
// 獲取之前存放的platform_data_GPIO結構體指針
platform_data_GPIO* data = dev->platform_data;
uint32_t level;
rt_kprintf("rn=%s==%s=%d=gpio:%d==rn", FILE , FUNCTION , LINE ,data->pin_num);
#ifdef RT_USING_PIN
// 根據 pin num 讀取電平
level = rt_pin_read(data->pin_num);
#endif
// 只有可能是 0 或 1
if (level != 1 && level != 0) {
return -1;
}
// 把 &level 處的 count 個(sizeof(uint32_t) 個)數據拷貝到 buf 緩存區,memcpy 函數不關心 buf 和 src 指向的內存是什么類型,它只根據 count 拷貝內存
memcpy(buf, &level, count);
return 0;
}
注意:
在文檔中指出,GPIO 設備 read 時讀取的數據 count 應該為 sizeof(uin32_t),在 pika_hal_platform_GPIO_read 中,level 的類型設置為 uint32_t,這是和文檔要求一致的。而給 level 賦值的 rt_pin_read() 函數的返回類型為 int,這里進行了一個隱式類型轉換。

pika_hal_platform_GPIO_write
函數的原型為:int pika_hal_platform_GPIO_write(pika_dev* dev, void* buf, size_t count);

參數:
pika_dev dev:要操作的設備句柄
oid buf:寫入緩沖區
size_t count:寫入數據長度,對于 GPIO、ADC 這樣只能讀取單個數據的設備,長度為 sizeof(uint32_t)

函數功能:
1.根據之前存儲的 dev->platform_data 信息獲取 pin num
2.獲取之前 buf 中存儲的電平信息
3.把電平信息寫到對應 pin 上

實現:

int pika_hal_platform_GPIO_write(pika_dev* dev, void* buf, size_t count) {
// 獲取之前 platform_data 數據
platform_data_GPIO* data = dev->platform_data;
// 獲取 buf 緩存區存儲的高低電平信息
uint32_t level = 0;
memcpy(&level, buf, count);
// 把電平寫到對應 pin 上
#ifdef RT_USING_PIN
if (level == 0) {
rt_pin_write(data->pin_num, PIN_LOW);
return 0;
}
if (level == 1) {
rt_pin_write(data->pin_num, PIN_HIGH);
return 0;
}
#endif
return 0;
}
pika_hal_platform_GPIO_ioctl_enable
函數的原型為:int pika_hal_platform_GPIO_ioctl_enable(pika_dev* dev);

參數:
pika_dev* dev:被操作的設備句柄

函數功能:
這個函數其實對應的是 pika_hal_ioctl(pika_dev* dev, PIKA_HAL_IOCTL_ENABLE) 這里的情況,使能了這個配置函數
所以要初始化一下 GPIO 的 pin num、輸入輸出模式、推挽模式、波特率等數據

實現:

目前只實現了打印日志

int pika_hal_platform_GPIO_ioctl_enable(pika_dev* dev) {
platform_data_GPIO* data = dev->platform_data;
rt_kprintf("rn=%s==%s=%d=pin_num:%x==rn", FILE , FUNCTION , LINE ,data->pin_num);
/* TODO /
return 0;
}
pika_hal_platform_GPIO_ioctl_disable
函數的原型為:int pika_hal_platform_GPIO_ioctl_disable(pika_dev
dev);

參數:
pika_dev* dev:被操作的設備句柄

函數功能:
這個函數其實對應的是 pika_hal_ioctl(pika_dev* dev, PIKA_HAL_IOCTL_DISABLE) 這里的情況

實現:

同 enable 部分,disable 也只是打印了日志

int pika_hal_platform_GPIO_ioctl_disable(pika_dev* dev) {
rt_kprintf("rn=%s==%s=%d===rn", FILE , FUNCTION , LINE );
platform_data_GPIO* data = dev->platform_data;
return -1;
}
pika_hal_platform_GPIO_ioctl_config
函數的原型為:int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, pika_hal_GPIO_config* cfg);

參數:
pika_dev dev:被操作的設備句柄
pika_hal_GPIO_config cfg:GPIO 配置,具體定義如下:

typedef struct {
PIKA_HAL_GPIO_DIR dir;//輸入輸出
PIKA_HAL_GPIO_PULL pull;//推挽模式
PIKA_HAL_GPIO_SPEED speed;//數據傳輸速率
void (event_callback)(pika_dev dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal);//事件回調函數
PIKA_HAL_GPIO_EVENT_SIGNAL event_callback_filter;//上升沿還是下降沿
//事件回調是否使能
PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena;
} pika_hal_GPIO_config;
函數功能:
1.對輸入輸出進行討論,分為 PIKA_HAL_GPIO_DIR_OUT、PIKA_HAL_GPIO_DIR_IN 兩種
2.對推挽模式進行討論,分為 PIKA_HAL_GPIO_PULL_NONE、PIKA_HAL_GPIO_PULL_UP、PIKA_HAL_GPIO_PULL_DOWN 三種
3.討論事件回調是否使能、是否設置了回調函數
4.討論回調函數是上升沿觸發還是下降沿觸發(PIKA_HAL_GPIO_EVENT_SIGNAL_RISING 以及 PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING)

實現:

現有實現中并沒有管回調函數的部分,所以相對簡單

RT-Thread 文檔中關于 void rt_pin_mode(rt_base_t pin, rt_base_t mode); 函數的 mode 可選項為:

#define PIN_MODE_OUTPUT 0x00 /* 輸出 /
#define PIN_MODE_INPUT 0x01 /
輸入 /
#define PIN_MODE_INPUT_PULLUP 0x02 /
上拉輸入 /
#define PIN_MODE_INPUT_PULLDOWN 0x03 /
下拉輸入 /
#define PIN_MODE_OUTPUT_OD 0x04 /
開漏輸出 */
所以最外層討論輸入輸出,內層討論上拉下拉即可。

int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev,
pika_hal_GPIO_config* cfg) {
rt_kprintf("rn=%s==%s=%d=dir:%d==rn", FILE , FUNCTION , LINE ,cfg->dir);
platform_data_GPIO* data = dev->platform_data;
uint8_t pinMode = 0;
// 對 cfg 中各項分類討論,從而確定 pinMode
switch (cfg->dir) {
case PIKA_HAL_GPIO_DIR_IN:
switch(cfg->pull)
{
case PIKA_HAL_GPIO_PULL_UP:
pinMode = PIN_MODE_INPUT_PULLUP;
break;
case PIKA_HAL_GPIO_PULL_DOWN:
pinMode = PIN_MODE_INPUT_PULLDOWN;
break;
default:
pinMode = PIN_MODE_INPUT;
}
break;
case PIKA_HAL_GPIO_DIR_OUT:
pinMode = PIN_MODE_OUTPUT;
break;
default:
pinMode = PIN_MODE_OUTPUT;
}
// 將 pin 的模式設置為 pinMode
#ifdef RT_USING_PIN
rt_pin_mode(data->pin_num, pinMode);
#endif
return 0;
}
Todo

作者也在閱讀源碼的過程中發現了一些問題:

1.對失敗的情況有時候沒有做討論,如 pika_hal_platform_GPIO_open 函數中,顯然 rt_pin_get() 是可能獲取不到的,此時應該返回 -1 表示出錯并打印有關日志信息,但現有代碼中沒有這部分處理

2.pika_hal_platform_GPIO_ioctl_config 中沒有配置為開漏模式的情況,這意味著無法使用 pikascript 腳本將 GPIO 模式設置為開漏模式。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7454

    瀏覽量

    163613
  • 緩沖器
    +關注

    關注

    6

    文章

    1920

    瀏覽量

    45450
  • GPIO
    +關注

    關注

    16

    文章

    1196

    瀏覽量

    51924
  • python
    +關注

    關注

    56

    文章

    4782

    瀏覽量

    84468
  • RTThread
    +關注

    關注

    8

    文章

    132

    瀏覽量

    40811
收藏 人收藏

    評論

    相關推薦

    基于GPIO模擬的SPI接口驅動設計與實現

    SPI總線是我們常用的串行設備接口,一般情況下我們都會適應硬件SPI接口,但有些時候當硬件端口不足時,我們也希望可以使用軟件來模擬SPI硬件接口,特別是要求不是很高的時候。在這一篇中我
    發表于 12-07 16:21 ?6232次閱讀
    基于<b class='flag-5'>GPIO</b>模擬的SPI<b class='flag-5'>接口</b>驅動設計與<b class='flag-5'>實現</b>

    如何通過RT-Thred提供的pin設備管理接口來操作GPIO

    PIN設備的操作方法應用程序通過RT-Thred提供的pin設備管理接口來操作GPIO,函數
    發表于 01-12 07:01

    RT-Thread PIN設備學習資料分享

    一、PIN 設備學習 PIN 設備RTT 最簡單的一個設備,通過
    發表于 03-29 11:12

    RT Thread PIN組件的物理操作

    。RT HAL HAL interface 用于MCU 和RTT特定的 PIN接口之間的解耦最后由MCU 官方HAL庫實現PIN 組件的物理
    發表于 05-16 16:03

    怎樣通過RT-Thread提供的PIN設備管理接口來訪問GPIO

    :訪問 PIN 設備應用程序通過 RT-Thread 提供的 PIN 設備管理接口來訪問 GPIO
    發表于 07-15 11:16

    RTT系統初始化后_hw_pin指針總是為空這是為什么

    RTT Studio建立項目,設備是STM32WB55 Nucleo。按照RTT的流程,在rtthread_startup()函數中已經有對board的各種接口的初始化。main()
    發表于 08-12 11:08

    GPIO設備接口主要有哪些功能

    的功能,程序會自動配置這些引腳。pinmux table 位于 bsp/board/xxx_board 目錄下 pinmux_config.h 文件。通過標準的 GPIO 設備接口配置引腳,缺點是只能
    發表于 08-18 17:18

    使用RTT設備框架PIN設備去設置邊沿觸發無法關閉這是什么原因

    我手上有兩個光電傳感器。使用STM32外部中斷,邊沿觸發(上升沿和下降沿都觸發)反饋傳感器有沒有被碰到。使用cube+裸機編程沒有問題.使用RTT設備框架PIN設備去設置邊沿觸發(上
    發表于 09-06 10:57

    使用RT-Thread與N32G457實現SPI接口的驅動設計

    前言參加創新“芯”引擎 | 國民技術N32G457 RT-Thread設計大賽,使用到了spi但是,spi接口使用rtt的還是頭一次,所以還是學習。在使用spi的時候使用RT-Th
    發表于 09-23 11:42

    pikascript移植報錯不知道是哪里的問題?

    想在fm33lx基礎上應用pikaScript做腳本開發,通過env添加了pikaScript的軟件包,工程里也出現了對應的文件,但是在編譯的時候提示錯誤,不知道哪里的問題,請大咖指教。
    發表于 05-05 11:49

    TD-SCDMA RTT的空間接口技術綜述

    TD-SCDMA RTT的空間接口技術綜述:
    發表于 05-21 13:22 ?20次下載
    TD-SCDMA <b class='flag-5'>RTT</b>的空間<b class='flag-5'>接口</b>技術綜述

    STM32 通用GPIO模擬I2C實現

    STM32 模擬I2C實現#通用GPIO模擬I2C通信實現樣例1 GPIO初始化``#ifdef HW_I2C1 //硬件I2C初始化//PA8-I2C1_SCLGPIO_Struct
    發表于 11-29 15:21 ?29次下載
    STM32 通用<b class='flag-5'>GPIO</b>模擬I2C<b class='flag-5'>實現</b>

    為什么要在芯片中配置GPIO

    為什么要在芯片中配置GPIO 作為一種基礎的控制接口GPIO(General Purpose Input/Output)即通用輸入輸出端口,可用于控制數字
    的頭像 發表于 09-13 15:28 ?1157次閱讀

    RTT_Draco的外置uart接口(TXD,RXD)怎么配置和使用

    RTT_Draco的外置uart接口(TXD,RXD)怎么配置和使用? RT-Thread的RTT_Draco是一款高性能的MCU芯片,它提供了外置UART
    的頭像 發表于 01-16 17:11 ?981次閱讀

    gpio接口是干什么的 gpio四種輸入輸出模式怎么選擇

    這些引腳的電平狀態,實現與外部設備的通信和交互。GPIO接口在嵌入式系統、物聯網設備、樹莓派項目等領域有著廣泛的應用,為電子
    的頭像 發表于 10-06 16:07 ?1928次閱讀