想要控制Linux GPIO初始狀態的看過來
阿新 • • 發佈:2019-02-02
問題
本人在專案中需要通過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上還是有一個脈衝。