1. 程式人生 > >想要控制Linux GPIO初始狀態的看過來

想要控制Linux GPIO初始狀態的看過來

問題

本人在專案中需要通過GPIO來控制繼電器的通斷。當裝置上電時,需要保證該GPIO為低電平,一直等到整個系統啟動, 應用程式正常執行後,才能設定該GPIO為高電平。
首先在u-boot中很容易設定GPIO為低電平。但是當Linux啟動後,在示波器上發現,該GPIO又被重新置高了。即Linu核心對GPIO有一個設定值,如何控制該值,從而讓GPIO在整個系統啟動過程一直保持低電平?

步驟

u-boot中的GPIO設定

在板級檔案u-boot/board/set/am335-cfe/mux.c(mux.c檔案位置會依據專案的不同而不同,請參考本部落格u-boot移植的相關文件) 中新增GPIO管腳的複用配置:

static struct module_pin_mux gpio2_2_pin_mux[] = {
    {OFFSET(gpmc_advn_ale), (MODE(7) | PULLUDEN)},  /* GPIO2_2 */
    {-1},
};


...
void enable_board_pin_mux(void)
{
...
    if (board_is_set_cfe()) {
        configure_module_pin_mux(mmc0_pin_mux_cfe);     
        configure_module_pin_mux(rgmii1_pin_mux);       
        configure_module_pin_mux(gpio2_2_pin_mux);
    }
...
}

在此,使用的是GPIO2_2, 這是由具體硬體決定的。

然後再u-boot/board/set/am335-cfe/board.c中設定gpio的值。

...
#define GPIO_TO_PIN(bank, gpio)     (32 * (bank) + (gpio))
#define GPIO_FAIL_SAVE_TIME4_EN     GPIO_TO_PIN(2, 2)
...
void sdram_init(void)
{
...
 if (board_is_set_cfe())
 {
     gpio_request(GPIO_FAIL_SAVE_TIME4_EN, "set_fail_save_low"
); gpio_direction_output(GPIO_FAIL_SAVE_TIME4_EN, 0); } ...

這樣就完成u-boot中對GPIO的控制。
本人將gpio的輸出設定放在函式sdram_init()中主要是考慮到:
1)儘可能早的獲得gpio的控制;
2) 放在RAM初始化後,可以直接呼叫gpio的相關函式。如果放置在彙編程式碼階段, 程式設計難度太大。

Linux 中GPIO的設定

在此貼上具體的patch:

--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -1216,7 +1216,7 @@ static struct omap_hwmod am33xx_gpio0_hwmod = {
        .clkdm_name     = "l4_wkup_clkdm",
        .mpu_irqs       = am33xx_gpio0_irqs,
        .main_clk       = "gpio0_ick",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET | HWMOD_INIT_NO_RESET,
        .prcm           = {
                .omap4  = {
                        .clkctrl_offs   = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,

總結

通過u-boot和Linux來設定啟動時某一個gpio的狀態:
(1)在u-boot中設定好管腳複用,然後操作gpio;
(2)在Linux中需要取消 HWMOD_INIT_NO_RESET功能,這樣才能保持在u-boot中的設定狀態;

其他

為了完全達到置低的狀態,還需要在硬體上通過電阻下拉該gpio,否則在上電的瞬間,在該gpio上還是有一個脈衝。