0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

學(xué)技術(shù)|SemiDrive X9H GPIO 驅(qū)動學(xué)習(xí)篇

大大通 ? 2023-01-13 10:42 ? 次閱讀

一、概述

SemiDrive X9H 擁有不同的 domain 域,例如 AP,Safety,Secure 等等。對于 GPIO 資源,不同 domain 之間 gpio 控制器是不同的,本次主要是使用的 AP 使用的是 gpio4 控制器。除了GPIO 控制器在不同 domain 之間不同以外,pin 也是有各自不同的 domain 的,但是當(dāng)它作為 gpio 使用時(shí),可以通過設(shè)置掛靠到對應(yīng)域下的 gpio 控制器上來在對應(yīng) domain 下使用。具體 pin 的 gpio 控制器的設(shè)置是通過 PC 工具 SDConfigTool 來進(jìn)行。

本文主要是講述將 pin 作為 GPIO 使用,之后編寫字符設(shè)備驅(qū)動,測試。

二、適用環(huán)境

硬件:SemiDrive SD003_X9H REF_A03 DEMO Board

軟件:X9 PTG3.9

三、設(shè)備樹匹配

1、復(fù)用管腳為 GPIO

路徑:

/buildsystem/yocto/source/linux/arch/arm64/boot/dts/semidrive/x9_high_ref_native_serdes_nobt.dts

在上面 dts 文件的 &pinctrl 的 sdx9-evk 中添加管腳復(fù)用,主要是將 GPIO_C1 管腳復(fù)用成 GPIO。

pinctrl_gpio_learning: gpiogrp_learning {

kunlun,pins = <

X9_PINCTRL_GPIO_C1__GPIO_MUX2_IO1_1 0x00

>;

};

2、配置一個(gè)新節(jié)點(diǎn)

路徑:

/buildsystem/yocto/source/linux/arch/arm64/boot/dts/semidrive/x9_high_ref_native_serdes_nobt.dts

在上面 dts 文件里面的根節(jié)點(diǎn) / 下新建一個(gè)節(jié)點(diǎn),添加屬性,獲取 gpio 編號。

gpio_learning {

#address-cells = <1>;

#size-cells = <1>;

compatible = "gpioled_learning";

pinctrl-0 = <&pinctrl_gpio_learning>;

gpio = <&port4b 17 GPIO_ACTIVE_HIGH>;

status = "okay";

};

四、驅(qū)動編寫

1、模塊出/入口函數(shù)

其中 module_init 是驅(qū)動入口函數(shù),主要進(jìn)行 platform 平臺驅(qū)動注冊,module_exit 是驅(qū)動出口函數(shù),主要是進(jìn)行 platform 平臺驅(qū)動注銷;

其中 MODULE_LICENSE 主要是聲明模塊許可證,一般為 GPL。

/*設(shè)備入口函數(shù)*/

static int __init gpio_learning_init(void)

{

return platform_driver_register(&gpio_learning_driver);

}

/*設(shè)備出口函數(shù)*/

static void __exit gpio_learning_exit(void)

{

platform_driver_unregister(&gpio_learning_driver);

}

/*指定上面的入口和出口函數(shù)*/

module_init(gpio_learning_init);

module_exit(gpio_learning_exit);

MODULE_LICENSE("GPL"); //LICENSE 采用 GPL 協(xié)議

2、platform 平臺驅(qū)動結(jié)構(gòu)體

主要是通過 match 函數(shù)和對應(yīng)的設(shè)備樹里面節(jié)點(diǎn)匹配,只要 compatible 屬性匹配成功即可,匹配成功就執(zhí)行 probe 函數(shù)。

/*匹配列表*/

static const struct of_device_id gpio_learning_of_match[] = {

{ .compatible = "gpioled_learning" },

{ /*sentinel*/}

};

/*

* platform 平臺驅(qū)動結(jié)構(gòu)體

*/

static struct platform_driver gpio_learning_driver ={

.driver = {

.name = "gpio_learning_device",

.of_match_table = gpio_learning_of_match,

},

.probe = gpio_learning_probe,

.remove = gpio_learning_remove,

};

3、probe 函數(shù)

主要是注冊字符設(shè)備,通過獲取設(shè)備樹的節(jié)點(diǎn),獲取 gpio 屬性,從而獲得 gpio編號,之后請求使用該 gpio,設(shè)置 gpio 模式。

/*

* platform 驅(qū)動的 probe 函數(shù)

* 驅(qū)動與設(shè)備匹配成功以后此函數(shù)就會執(zhí)行

*/

static int gpio_learning_probe(struct platform_device *dev)

{

printk("led driver and device was matched!\r\n");

/* 1、設(shè)置設(shè)備號 */

if (gpiodev.major) { //如果定義了主設(shè)備號

gpiodev.devid = MKDEV(gpiodev.major, 0);//次設(shè)備號號默認(rèn) 0,構(gòu)建設(shè)備號

register_chrdev_region(gpiodev.devid, GPIODEV_CNT,GPIODEV_NAME);//注冊設(shè)備號

} else {

alloc_chrdev_region(&gpiodev.devid, 0, GPIODEV_CNT,GPIODEV_NAME);//動態(tài)申請?jiān)O(shè)備號

gpiodev.major = MAJOR(gpiodev.devid);//獲取主設(shè)備號

}

/* 2、注冊設(shè)備 */

cdev_init(&gpiodev.cdev,&gpio_learning_fops);

cdev_add(&gpiodev.cdev, gpiodev.devid, GPIODEV_CNT);

/* 3、創(chuàng)建類 */

gpiodev.class = class_create(THIS_MODULE, GPIODEV_NAME);

if (IS_ERR(gpiodev.class)) {

return PTR_ERR(gpiodev.class);

}

/* 4、創(chuàng)建設(shè)備 */

gpiodev.device = device_create(gpiodev.class, NULL, gpiodev.devid,NULL, GPIODEV_NAME);

if (IS_ERR(gpiodev.device)) {

return PTR_ERR(gpiodev.device);

}

/* 5、初始化 IO */

gpiodev.node = of_find_node_by_path("/gpio_learning");

if (gpiodev.node == NULL){

printk("gpio_learning node nost find!\r\n");

return -EINVAL;

}

gpiodev.led0 = of_get_named_gpio(gpiodev.node, "gpio", 0);/*獲取要使用的 GPIO 編號 */

if (gpiodev.led0 < 0) {

printk("can't get gpio\r\n");

return -EINVAL;

}

printk("led0 = %d\r\n",gpiodev.led0);

int ret = gpio_request(gpiodev.led0, "led0");/*申請gpio管腳 */

if(ret == 0)

{

printk("gpio_request success\r\n");

}

else

{

printk("gpio_request fail\r\n");

return -1;

}

ret = gpio_direction_output(gpiodev.led0, 1); /*設(shè)置為輸出,默認(rèn)高電平 */

if(ret == 0)

{

printk("gpio_direction_output success\r\n");

}

else

{

printk("gpio_direction_output fail\r\n");

return -1;

}

return 0;

}

4、設(shè)備函數(shù)操作結(jié)構(gòu)體

主要是一個(gè) open 和 write 的函數(shù)。

/*

* 設(shè)備操作函數(shù)結(jié)構(gòu)體

*/

static struct file_operations gpio_learning_fops = {

.owner = THIS_MODULE,

.open = gpio_learning_open,

.write = gpio_learning_write,

};

5、設(shè)備操作 open 和 write函數(shù)

主要 open 函數(shù)是將 private_data 指向設(shè)備結(jié)構(gòu)體。

主要 write 函數(shù)是接受用戶層傳來的數(shù)據(jù),之后根據(jù)數(shù)據(jù)設(shè)置 gpio 操作。

#define GPIODEV_CNT 1 /* 設(shè)備號長度 */

#define GPIODEV_NAME "gpio_learning" /* 設(shè)備名字 */

#define GPIOOFF 0

#define GPIOON 1

//設(shè)備結(jié)構(gòu)體

struct gpiodev_dev{

dev_t devid; /* 設(shè)備號 */

struct cdev cdev; /* cdev */

struct class *class; /* 類 */

struct device *device; /* 設(shè)備 */

int major; /* 主設(shè)備號 */

struct device_node *node; /* 設(shè)備節(jié)點(diǎn) */

int led0; /* LED 燈 GPIO 標(biāo)號 */

};

struct gpiodev_dev gpiodev;

/*

* @description : LED 打開/關(guān)閉

* @param - sta : LEDON(0) 打開 LED,LEDOFF(1) 關(guān)閉 LED

* @return : 無

*/

void led0_switch(u8 sta)

{

if (sta == GPIOON )

{

gpio_set_value(gpiodev.led0, 1);

printk("gpio_set_value = 1!\r\n");

}

else if (sta == GPIOOFF)

{

gpio_set_value(gpiodev.led0, 0);

printk("gpio_set_value = 0!\r\n");

}

return 0;

}

/*

* @description : 打開設(shè)備

* @param – inode : 傳遞給驅(qū)動的 inode

* @param - filp : 設(shè)備文件,file 結(jié)構(gòu)體有個(gè)叫做 private_data 的成員變量

* 一般在 open 的時(shí)候?qū)?private_data 指向設(shè)備結(jié)構(gòu)體。

* @return : 0 成功;其他 失敗

*/

static int gpio_learning_open(struct inode *inode,struct file *filp)

{

filp->private_data = &gpiodev; /* 設(shè)置私有數(shù)據(jù) */

return 0;

}

static ssize_t gpio_learning_write(struct file *filp,const char __user *buf,size_t cnt,loff_t *offt)

{

int retvalue;

unsigned char databuf[2];

unsigned char ledstat;

retvalue = copy_from_user(databuf, buf, cnt);

if(retvalue < 0) {

printk("kernel write failed!\r\n");

return -EFAULT;

}

printk("retvalue = %d\r\n",retvalue);

ledstat = databuf[0];

if (ledstat == GPIOON) {

printk("ledstat = 1\r\n");

led0_switch(GPIOON);

} else if (ledstat == GPIOOFF) {

printk("ledstat = 0\r\n");

led0_switch(GPIOOFF);

}

return 0;

}

五、Kernel 配置

1、Makefile 文件

obj-$(CONFIG_GPIO_LEARNING) += gpio_learning.o

2、Kconfig 文件

config GPIO_LEARNING

tristate "GPIO learning block support"

default m

help

This is enable gpio learning test

3、引用

在自己編寫文件的上一級目錄 Makefile 和 Kconfig 添加對應(yīng)引用,并在對應(yīng) deconfig 配置。

Makefile 文件引用

obj-$(CONFIG_GPIO_LEARNING) += gpio_learning/

Kconfig 文件引用

source "drivers/gpio_learning/Kconfig"

deconfig 文件配置

路徑:

/buildsystem/yocto/source/linux/arch/arm64/configs/x9_ref_linux_defconfig

等于 m 表示編譯成 ko 文件,等于 y 表示編譯進(jìn)內(nèi)核。

CONFIG_GPIO_LEARNING=m

六、APP 測試

主要是傳入三個(gè)參數(shù),一個(gè)是運(yùn)行的 app,一個(gè)是對應(yīng)的 /dev/xxx,一個(gè)是對 gpio 的操作(1/0),通過 /dev/xxx 打開對應(yīng)驅(qū)動文件,通過 write 發(fā)送對應(yīng)的操作。

#include "stdio.h"

#include "unistd.h"

#include "sys/types.h"

#include "sys/stat.h"

#include "fcntl.h"

#include "stdlib.h"

#include "string.h"

int main(int argc, char *argv[])

{

int fd, retvalue;

char *filename;

unsigned char databuf[2];

if(argc != 3){ //傳入三個(gè)參數(shù):運(yùn)行的app /dev/xxx 操作

printf("Error Usage!\r\n");

return -1;

}

filename = argv[1];

/* 打開 /dev/xxx 驅(qū)動文件 */

fd = open(filename, O_RDWR);

if(fd < 0){

printf("file %s open failed!\r\n", argv[1]);

return -1;

}

databuf[0] = atoi(argv[2]); /* 要執(zhí)行的操作:打開或關(guān)閉 */

retvalue = write(fd, databuf, sizeof(databuf));

if(retvalue < 0){

printf("LED Control Failed!\r\n");

close(fd);

return -1;

}

retvalue = close(fd); /* 關(guān)閉文件 */

if(retvalue < 0){

printf("file %s close failed!\r\n", argv[1]);

return -1;

}

return 0;

}

以上完成了 SemiDrive X9H GPIO 功能的實(shí)現(xiàn)。

接下來將會更新更多關(guān)于 SemiDrive X9H 的開發(fā)博文,如有相關(guān)技術(shù)問題,可在評論區(qū)留言。

七、參考文檔

《 SemiDrive_9_Series_GPIO使用手冊_Rev01.00.pdf 》

《 X9H處理器數(shù)據(jù)手冊_Rev04.00.pdf 》

《 SD003_X9H_REF_A03_SCH.pdf 》

《 X9_Processor_TRM_Rev00.07.pdf 》

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16041

    瀏覽量

    176772
  • 驅(qū)動
    +關(guān)注

    關(guān)注

    12

    文章

    1814

    瀏覽量

    85062
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1184

    瀏覽量

    51766
收藏 人收藏

    評論

    相關(guān)推薦

    使用LP875230C-Q1 和 LP87565V-Q1 的 Semidrive X9H 電源設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《使用LP875230C-Q1 和 LP87565V-Q1 的 Semidrive X9H 電源設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 09-12 11:08 ?0次下載
    使用LP875230C-Q1 和 LP87565V-Q1 的 <b class='flag-5'>Semidrive</b> <b class='flag-5'>X9H</b> 電源設(shè)計(jì)

    Semidrive X9P/X9U 電源設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《Semidrive X9P/X9U 電源設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 09-11 10:21 ?0次下載
    <b class='flag-5'>Semidrive</b> <b class='flag-5'>X9</b>P/<b class='flag-5'>X9</b>U 電源設(shè)計(jì)

    SemiDrive X9 AI 開發(fā)環(huán)境搭建

    SemiDrivex9AI開發(fā)環(huán)境搭建分開發(fā)機(jī)端,開發(fā)板端。主要的工具是SDNN,它是一個(gè)基于開源編譯器框架TVM的端到端的AI編譯器框架,Semidrive對TVM編譯器框架做了適配,主要特性如下
    的頭像 發(fā)表于 08-03 08:27 ?280次閱讀
    <b class='flag-5'>SemiDrive</b> <b class='flag-5'>X9</b> AI 開發(fā)環(huán)境搭建

    MGMF444L1H9M-MINAS A6B 系列 (EtherCAT) 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF444L1H9M-MINAS A6B 系列 (EtherCAT) 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-27 18:42
    MGMF444L1<b class='flag-5'>H9</b>M-MINAS A6B 系列 (EtherCAT)  <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF444A1H9M-MINAS A6BN 系列 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF444A1H9M-MINAS A6BN 系列 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-22 19:20
    MGMF444A1<b class='flag-5'>H9</b>M-MINAS A6BN 系列 <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF444A1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF444A1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-22 19:13
    MGMF444A1<b class='flag-5'>H9</b>M-MINAS A6NL系列 (RTEX) <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF444A1H9M-MINAS A6S 系列 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF444A1H9M-MINAS A6S 系列 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-22 19:07
    MGMF444A1<b class='flag-5'>H9</b>M-MINAS A6S 系列 <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294L1H9M-MINAS A6BN 系列 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294L1H9M-MINAS A6BN 系列 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-08 18:48
    MGMF294L1<b class='flag-5'>H9</b>M-MINAS A6BN 系列 <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294L1H9M-MINAS A6BU 系列 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294L1H9M-MINAS A6BU 系列 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-08 18:46
    MGMF294L1<b class='flag-5'>H9</b>M-MINAS A6BU 系列 <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294L1H9M-MINAS A6BU 系列 技術(shù)資料 -EtherCAT 通信規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294L1H9M-MINAS A6BU 系列 技術(shù)資料 -EtherCAT 通信規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-08 18:45
    MGMF294L1<b class='flag-5'>H9</b>M-MINAS A6BU 系列 <b class='flag-5'>技術(shù)</b>資料 -EtherCAT 通信規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294L1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294L1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-08 18:39
    MGMF294L1<b class='flag-5'>H9</b>M-MINAS A6NL系列 (RTEX) <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294A1H9M-MINAS A6N系列 (RTEX) 技術(shù)資料 -RTEX通信規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294A1H9M-MINAS A6N系列 (RTEX) 技術(shù)資料 -RTEX通信規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-03 19:13
    MGMF294A1<b class='flag-5'>H9</b>M-MINAS A6N系列 (RTEX) <b class='flag-5'>技術(shù)</b>資料 -RTEX通信規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF294A1H9M-MINAS A6S 系列 技術(shù)資料 -Modbus通信規(guī)格?Block 動作功能- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF294A1H9M-MINAS A6S 系列 技術(shù)資料 -Modbus通信規(guī)格?Block 動作功能-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 05-03 19:09
    MGMF294A1<b class='flag-5'>H9</b>M-MINAS A6S 系列 <b class='flag-5'>技術(shù)</b>資料 -Modbus通信規(guī)格?Block 動作功能<b class='flag-5'>篇</b>- 松下

    MGMF244L1H9M-MINAS A6BU 系列 技術(shù)資料 -EtherCAT 通信規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF244L1H9M-MINAS A6BU 系列 技術(shù)資料 -EtherCAT 通信規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 04-19 18:46
    MGMF244L1<b class='flag-5'>H9</b>M-MINAS A6BU 系列 <b class='flag-5'>技術(shù)</b>資料 -EtherCAT 通信規(guī)格<b class='flag-5'>篇</b>- 松下

    MGMF244L1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格- 松下

    電子發(fā)燒友網(wǎng)為你提供Panasonic(Panasonic)MGMF244L1H9M-MINAS A6NL系列 (RTEX) 技術(shù)資料 -基本功能規(guī)格-相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有
    發(fā)表于 04-19 18:42
    MGMF244L1<b class='flag-5'>H9</b>M-MINAS A6NL系列 (RTEX) <b class='flag-5'>技術(shù)</b>資料 -基本功能規(guī)格<b class='flag-5'>篇</b>- 松下