嵌入式技术论坛
直播中

安德森大

8年用户 1281经验值
擅长:接口/总线/驱动
私信 关注
[经验]

为N32G457添加rt_pin_get接口支持的过程记录

N32G457芯片简介

国民技术官网的简介:

N32G457系列 (工业互联型) 采用32-bit ARM Cortex-M4内核,集成高达512KB 片内FLASH,144KB SRAM,多达17个高性能模拟器件,18个数字通讯接口,同时集成10/100M以太网接口,数字摄像头接口,内置10余种密码算法硬件加速引擎,支持存储加密、用户分区保护、安全启动等多种安全特性,可广泛应用于网络打印机、3D打印机、门禁考勤系统、LED户外显示屏、工业小型网关、DTU、PLC、充电桩等消费及工业互联应用领域。

以及该系列不同信号芯片的参数表:

1.jpg

本次活动开发板的主控芯片是——N32G457VEL7,对照上面的表格,可以知道:

片内Flash容量是512KB,片内SRAM容量是144KB;
CPU是ARM Cortex M4,最高频率144MHz;
有80个GPIO;
其他参数也可以在表格上看到。

直接通过pin id点灯

RT-Thread Studio创建项目后,简单修改一下drv_gpio.c和main.c就可以了,

总结起来就是以下几处修改:

drv_gpio.c里面的N32G45X_PIN_NUMBERS宏的值修改为100;
LED1_PIN的具体数字参考drv_gpio.c里面pins数组各成员第一列的值;

PB4复位的默认功能是JTAG复位功能(NJTRST),需要重新设置才能作为GPIO使用;

改完的main.c为:

#include <stdint.h>
#include <rtthread.h>
#include <rtdevice.h>
#define LED1_PIN 91 // PB5
//#define LED1_PIN 90 // PB4
//#define LED1_PIN 67 // PA8
int main(void)
{
uint32_t Speed = 200;
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);
/* set LED1 pin mode to output */
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(Speed);
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(Speed);
}
}

添加rt_pin_get支持

上面的点灯已经可以正常运行了,但是总觉得手动查引脚编号使用起来不是很方便,于是想着能不能像之前的AB32那样——通过rt_pin_get接口查询编号?看了一眼drv_gpio.c发现n32_hw_pin_init函数里面注册的_n32_pin_ops没有赋值get_pin函数指针,那就意味着——rt_pin_get不能直接使用。

于是我在原有代码的基础上实现了一个简单的n32_get_pin,实现方式也很简单:

在原有pin上下文struct pin_index类型中,添加一个const char* name成员;
在__N32_PIN宏中,添加对name成员值的填充,采用宏拼接的方式实现;
添加n32_pin_get函数,函数中遍历pins数组,查到name匹配的条目后,返回下标;
将n32_pin_get函数绑定到struct rt_pin_ops _n32_pin_ops变量的pin_get函数指针上;
具体修改:

diff --git a/Libraries/rt_drivers/drv_gpio.c b/Libraries/rt_drivers/drv_gpio.c
index 87975f9..cc81bec 100644
--- a/Libraries/rt_drivers/drv_gpio.c
+++ b/Libraries/rt_drivers/drv_gpio.c
[url=home.php?mod=space&uid=1999721]@@[/url] -15,14 +15,14 @@
#ifdef RT_USING_PIN
-#define N32F10X_PIN_NUMBERS 64 //[48, 64, 100, 144 ]
+#define N32F10X_PIN_NUMBERS 100 //[48, 64, 100, 144 ]
#define _N32_PIN(index, rcc, gpio, gpio_index)
{
0, RCC
##rcc##_PERIPH_GPIO##gpio, GPIO##gpio, GPIO_PIN_##gpio_index
-, GPIO##gpio##_PORT_SOURCE, GPIO_PIN_SOURCE##gpio_index
+, GPIO##gpio##_PORT_SOURCE, GPIO_PIN_SOURCE##gpio_index, "P" #gpio "." #gpio_index
}
-#define __N32_PIN_DEFAULT {-1, 0, 0, 0, 0, 0}
+#define __N32_PIN_DEFAULT {-1, 0, 0, 0, 0, 0, ""}
/* N32 GPIO driver */
struct pin_index
@@ -33,6 +33,7 @@ struct pin_index
uint32_t pin;
uint8_t port_source;
uint8_t pin_source;

  • const char* name;
    };
    static const struct pin_index pins[] =
    @@ -473,6 +474,23 @@ const struct pin_index *get_pin(uint8_t pin)
    return index;
    };
    +rt_base_t n32_pin_get(const char *name)
    +{
  • rt_base_t i;
  • for (i = 0; i < ITEM_NUM(pins); i++)
  • {
  • if (rt_strcmp(pins[i].name, name) == 0)
    
  • {
    
  • /* in get_pin function, use pin parameter as index of pins array */
    
  • return i;
    
  • }
    
  • }
  • /* refers content of pins array, map to __N32_PIN_DEFAULT */
  • return 0;
    +}

void n32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
const struct pin_index *index;
@@ -754,6 +772,7 @@ const static struct rt_pin_ops _n32_pin_ops =
n32_pin_attach_irq,
n32_pin_dettach_irq,
n32_pin_irq_enable,

  • n32_pin_get
    };
    int n32_hw_pin_init(void)
    目前这个修改已在github提交PR,并被合并了——本人的第一个RT-Thread PR,虽然有点水。

验证rt_pin_get接口
简单修改完成后,测试了一下,工作正常,终于可以优雅的点灯了:

#include <rtthread.h>
#include <rtdevice.h>
/* defined the LED1 pin: PB5 /
#define LED1_PIN_NAME "PB.5"
rt_base_t led1_pin;
int main(void)
{
rt_uint32_t delay = 500;
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);
led1_pin = rt_pin_get(LED1_PIN_NAME);
/
set LED1 pin mode to output */
rt_pin_mode(led1_pin, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(led1_pin, PIN_LOW);
rt_thread_mdelay(delay);
rt_pin_write(led1_pin, PIN_HIGH);
rt_thread_mdelay(delay);
}
}
点亮全部LED灯
有了rt_get_pin之后,点灯的程序看着舒服多了:

#include "n32g45x.h"
#include <rtthread.h>
#include <rtdevice.h>
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
static const char* led_pin_names[] = { "PB.5", "PB.4", "PA.8" };
rt_base_t led_pin_ids[ARRAY_SIZE(led_pin_names)];
int main(void)
{
rt_size_t i;
rt_uint32_t delay = 200;
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);
for (i = 0; i < ARRAY_SIZE(led_pin_names); i++)
{
rt_base_t pin = rt_pin_get(led_pin_names[i]);
led_pin_ids[i] = pin;
rt_pin_mode(pin, PIN_MODE_OUTPUT);
}
while (1)
{
for (i = 0; i < ARRAY_SIZE(led_pin_names); i++)
{
rt_pin_write(led_pin_ids[i], PIN_HIGH);
rt_thread_mdelay(delay);
rt_pin_write(led_pin_ids[i], PIN_LOW);
rt_thread_mdelay(delay);
}
}
}

更优雅的方式——使用RT-Thread主线代码

上面的点灯代码里面还有两行关于JTAG的设置,显得不太优雅,不过GitHub上已经有小伙伴修改为KConfig配置了。所以使用最新GitHub代码的话,则可以更加优雅,具体操作步骤如下:

克隆RT-Thread的GitHub代码

打开env控制台,跳转到n32g452xx-mini-system子目录:cd bsp/n32g452xx/n32g452xx-mini-system/

使用scons命令创建RT-Thread Studio项目:scons --dist-ide --project-name=n32_blink --project-path=D:\n32_blink

跳转到刚刚创建的目录内,编译:cd D:\n32_blink; scons -j 9

原作者:xusiwei1236

更多回帖

发帖
×
20
完善资料,
赚取积分