在龙芯1c上使用RT-Thread统一标准的gpio接口

本文首先介绍几个常用的RTT统一标准的GPIO接口,然后使用这几个接口控制led的亮灭,以此演示如何使用这几个接口。最后简单介绍一下是如何移植的,使其支持RTT统一标准的GPIO接口。
【龙芯1c库】封装gpio接口和使用示例

http://blog.csdn.net/caogos/article/details/70240878

用龙芯1c库在RT-Thread下实现外部中断(GPIO中断、按键中断)

http://blog.csdn.net/caogos/article/details/75648063

RTT统一的标准的GPIO接口简介

在RTT中gpio相关操作,通常叫xxx_pin_xxx。也就是用pin表示是gpio相关的函数。

RTT的PIN模块初始化

函数原型

int hw_pin_init(void)

本函数的作用是向RTT注册pin相关的接口,对于普通开发者来说,只需要在使用pin相关接口之前,调用一下就行。想知道更多信息,可以查看相关源码,源码位于bsp\ls1cdev\drivers\drv_gpio.c

使用示例

hw_pin_init();

在使用pin相关接口之前调用一下就行。当有多个任务都需要使用pin接口时,只需要在最早使用的那个任务中调用一下。

设置PIN模式(输入或输出)

函数原型

void rt_pin_mode(rt_base_t pin, rt_base_t mode)

设置pin的输入输出模式
第一个参数pin为gpio编号,比如gpio32,则入参为32
第二个参数mode为输入输出模式,可能的取值为

#define PIN_MODE_OUTPUT         0x00
#define PIN_MODE_INPUT          0x01

使用示例

rt_base_t pin_led = 32;

rt_pin_mode(pin_led, PIN_MODE_OUTPUT);
把gpio32设为输出模式

输出高低电平

函数原型

void rt_pin_write(rt_base_t pin, rt_base_t value)

在指定引脚输出高电平或低电平
第一个参数pin为gpio编号
第二个参数为电平值可能的取值有

#define PIN_LOW                 0x00
#define PIN_HIGH                0x01

使用示例

rt_base_t pin_led = 32;
rt_pin_write(pin_led, PIN_LOW);
rt_pin_write(pin_led, PIN_HIGH);

读取PIN的状态

函数原型

int  rt_pin_read(rt_base_t pin)

读取指定pin的状态,入参pin为gpio编号

使用示例

int status;

status = rt_pin_read(32);

综合应用示例——控制LED

点灯的源码很简单,这里就直接贴源码了

测试源码清单

bsp\ls1cdev\applications\application.c

/*
 * File      : application.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006-2012, RT-Thread Develop Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date                Author         Notes
 * 2010-06-25          Bernard        first version
 * 2011-08-08          lgnq           modified for Loongson LS1B
 * 2015-07-06          chinesebear    modified for Loongson LS1C
 */

#include <rtthread.h>
#include "net/synopGMAC.h"
#include <lwip/api.h>
#include <drivers/pin.h>
#include "../drivers/drv_gpio.h"


// 测试用的线程  
#define THREAD_TEST_PRIORITY                    (25)  
#define THREAD_TEST_STACK_SIZE                  (4*1024)        // 4k  
#define THREAD_TEST_TIMESLICE                   (10)  

struct rt_thread thread_test;  
ALIGN(8) rt_uint8_t thread_test_stack[THREAD_TEST_STACK_SIZE];  



// 测试用的线程的入口  
void thread_test_entry(void *parameter)  
{
    rt_base_t pin_led = 32;
    
    // pin初始化
    hw_pin_init();

    // 把相应gpio设为输出模式
    rt_pin_mode(pin_led, PIN_MODE_OUTPUT);
    
    while (1)  
    {
        rt_pin_write(pin_led, PIN_LOW);
        rt_thread_delay(1 * RT_TICK_PER_SECOND);  

        rt_pin_write(pin_led, PIN_HIGH);
        rt_thread_delay(1 * RT_TICK_PER_SECOND);
    }  
}  



void rt_init_thread_entry(void *parameter)
{
	/* initialization RT-Thread Components */
	rt_components_init();

    // 网口EMAC初始化
	rt_hw_eth_init();
}

int rt_application_init(void)
{
	rt_thread_t tid;
    rt_err_t result;

	/* create initialization thread */
	tid = rt_thread_create("init",
							rt_init_thread_entry, RT_NULL,
							4096, RT_THREAD_PRIORITY_MAX/3, 20);
	if (tid != RT_NULL)
		rt_thread_startup(tid);

  
    // 初始化测试用的线程  
    result = rt_thread_init(&thread_test,   
                            "thread_test",  
                            thread_test_entry,  
                            RT_NULL,  
                            &thread_test_stack[0],  
                            sizeof(thread_test_stack),  
                            THREAD_TEST_PRIORITY,  
                            THREAD_TEST_TIMESLICE);  
    if (RT_EOK == result)  
    {  
        rt_thread_startup(&thread_test);  
    }  
    else  
    {  
        return -1;  
    }  

	return 0;
}

把RTT统一的标准的GPIO接口移植到龙芯1C上

移植要点

移植时,只需要实现设置模式,输出,和读取状态三个接口,即

const static struct rt_pin_ops _ls1c_pin_ops = 
{
    ls1c_pin_mode,
    ls1c_pin_write,
    ls1c_pin_read,
};

然后,需要想RTT注册这个ops,如下

int hw_pin_init(void)
{
    rt_device_pin_register("pin", &_ls1c_pin_ops, RT_NULL);
    return 0;
}

这就是整个的移植过程。
其中,ls1c_pin_mode(), ls1c_pin_write(), ls1c_pin_read()分别对应龙芯1c库中的gpio_init(), gpio_set()和gpio_get()。看下面的源码清单,一看就明白

源码清单

drv_gpio.c

bsp\ls1cdev\drivers\drv_gpio.c

/*
 * File      : drv_gpio.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-11-24     勤为本       first version
 */

#include <rtthread.h>
#include <drivers/pin.h>
#include "../libraries/ls1c_gpio.h"


void ls1c_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
{
    unsigned int gpio = pin;
    
    if (PIN_MODE_OUTPUT == mode)
    {
        gpio_init(gpio, gpio_mode_output);
    }
    else
    {
        gpio_init(gpio, gpio_mode_input);
    }

    return ;
}


void ls1c_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
{
    unsigned int gpio = pin;
    
    if (PIN_LOW == value)
    {
        gpio_set(gpio, gpio_level_low);
    }
    else
    {
        gpio_set(gpio, gpio_level_high);
    }

    return ;
}


int ls1c_pin_read(struct rt_device *device, rt_base_t pin)
{
    unsigned int gpio = pin;
    int value = PIN_LOW;

    if (0 == gpio_get(gpio))
    {
        value = PIN_LOW;
    }
    else
    {
        value = PIN_HIGH;
    }

    return value;
}


const static struct rt_pin_ops _ls1c_pin_ops = 
{
    ls1c_pin_mode,
    ls1c_pin_write,
    ls1c_pin_read,
};


int hw_pin_init(void)
{
    rt_device_pin_register("pin", &_ls1c_pin_ops, RT_NULL);
    return 0;
}
INIT_BOARD_EXPORT(hw_pin_init);



感谢阅读!








猜你喜欢

转载自blog.csdn.net/caogos/article/details/78647452