Bläddra i källkod

[componnets][pin]add pin operate command in MSH (#5892)

* 1. 在AT32的BSP的drv_gpio中增加了at32_pin_get函数,用于实现rt_pin_ops对象中的pin_get
2. 在MSH中增加了PIN的操作命令
3. 为了方便在MSH命令中解析字符串,增加了一些字符串相关的函数
xfwangqiang 2 år sedan
förälder
incheckning
e8d775f888

+ 38 - 1
bsp/at32/libraries/rt_drivers/drv_gpio.c

@@ -102,6 +102,43 @@ static uint32_t pin_irq_enable_mask = 0;
 
 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
 
+static rt_base_t at32_pin_get(const char *name)
+{
+    rt_base_t pin = 0;
+    int hw_port_num, hw_pin_num = 0;
+    int i, name_len;
+
+    name_len = rt_strlen(name);
+
+    if ((name_len < 4) || (name_len >= 6))
+    {
+        return -RT_EINVAL;
+    }
+    if ((name[0] != 'P') || (name[2] != '.'))
+    {
+        return -RT_EINVAL;
+    }
+
+    if ((name[1] >= 'A') && (name[1] <= 'Z'))
+    {
+        hw_port_num = (int)(name[1] - 'A');
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    for (i = 3; i < name_len; i++)
+    {
+        hw_pin_num *= 10;
+        hw_pin_num += name[i] - '0';
+    }
+
+    pin = PIN_NUM(hw_port_num, hw_pin_num);
+
+    return pin;
+}
+
 static void at32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
 {
     gpio_type *gpio_port;
@@ -423,7 +460,7 @@ const static struct rt_pin_ops _at32_pin_ops =
     at32_pin_attach_irq,
     at32_pin_dettach_irq,
     at32_pin_irq_enable,
-    RT_NULL,
+    at32_pin_get,
 };
 
 rt_inline void pin_irq_handler(int irqno)

+ 1 - 0
bsp/stm32/libraries/HAL_Drivers/drv_gpio.c

@@ -161,6 +161,7 @@ static uint32_t pin_irq_enable_mask = 0;
 
 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
 
+/* e.g. PE.7 */
 static rt_base_t stm32_pin_get(const char *name)
 {
     rt_base_t pin = 0;

+ 241 - 22
components/drivers/misc/pin.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -7,14 +7,11 @@
  * Date           Author       Notes
  * 2015-01-20     Bernard      the first version
  * 2021-02-06     Meco Man     fix RT_ENOSYS code in negative
+ * 2022-04-29     WangQiang    add pin operate command in MSH
  */
 
 #include <drivers/pin.h>
 
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-#endif
-
 static struct rt_device_pin _hw_pin;
 static rt_size_t _pin_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
 {
@@ -24,8 +21,9 @@ static rt_size_t _pin_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_
     /* check parameters */
     RT_ASSERT(pin != RT_NULL);
 
-    status = (struct rt_device_pin_status *) buffer;
-    if (status == RT_NULL || size != sizeof(*status)) return 0;
+    status = (struct rt_device_pin_status *)buffer;
+    if (status == RT_NULL || size != sizeof(*status))
+        return 0;
 
     status->status = pin->ops->pin_read(dev, status->pin);
     return size;
@@ -39,8 +37,9 @@ static rt_size_t _pin_write(rt_device_t dev, rt_off_t pos, const void *buffer, r
     /* check parameters */
     RT_ASSERT(pin != RT_NULL);
 
-    status = (struct rt_device_pin_status *) buffer;
-    if (status == RT_NULL || size != sizeof(*status)) return 0;
+    status = (struct rt_device_pin_status *)buffer;
+    if (status == RT_NULL || size != sizeof(*status))
+        return 0;
 
     pin->ops->pin_write(dev, (rt_base_t)status->pin, (rt_base_t)status->status);
 
@@ -55,8 +54,9 @@ static rt_err_t _pin_control(rt_device_t dev, int cmd, void *args)
     /* check parameters */
     RT_ASSERT(pin != RT_NULL);
 
-    mode = (struct rt_device_pin_mode *) args;
-    if (mode == RT_NULL) return -RT_ERROR;
+    mode = (struct rt_device_pin_mode *)args;
+    if (mode == RT_NULL)
+        return -RT_ERROR;
 
     pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode);
 
@@ -102,10 +102,10 @@ int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void
 }
 
 rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
-                             void (*hdr)(void *args), void  *args)
+                           void (*hdr)(void *args), void *args)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
-    if(_hw_pin.ops->pin_attach_irq)
+    if (_hw_pin.ops->pin_attach_irq)
     {
         return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);
     }
@@ -115,7 +115,7 @@ rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
 rt_err_t rt_pin_detach_irq(rt_int32_t pin)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
-    if(_hw_pin.ops->pin_detach_irq)
+    if (_hw_pin.ops->pin_detach_irq)
     {
         return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin);
     }
@@ -125,7 +125,7 @@ rt_err_t rt_pin_detach_irq(rt_int32_t pin)
 rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
-    if(_hw_pin.ops->pin_irq_enable)
+    if (_hw_pin.ops->pin_irq_enable)
     {
         return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled);
     }
@@ -138,32 +138,251 @@ void rt_pin_mode(rt_base_t pin, rt_base_t mode)
     RT_ASSERT(_hw_pin.ops != RT_NULL);
     _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
 }
-FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode);
 
 void rt_pin_write(rt_base_t pin, rt_base_t value)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
     _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
 }
-FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_write, pinWrite, write value to hardware pin);
 
 int rt_pin_read(rt_base_t pin)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
     return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
 }
-FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);
+
 
 rt_base_t rt_pin_get(const char *name)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
-    RT_ASSERT(name[0] == 'P');
 
-    if(_hw_pin.ops->pin_get == RT_NULL)
+    if (name[0] != 'P' && name[0] != 'p')
+    {
+        return -RT_EINVAL;
+    }
+    if (_hw_pin.ops->pin_get == RT_NULL)
     {
         return -RT_ENOSYS;
     }
-
     return _hw_pin.ops->pin_get(name);
 }
-FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_get, pinGet, get pin number from hardware pin);
+
+#ifdef RT_USING_FINSH
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <finsh.h>
+#include <msh_parse.h>
+
+/*
+ * convert function for port name
+ * support PE02, PE2, PE.02, PE.2, pe02, pe2, pe.02, pe.2
+ */
+static rt_base_t _pin_cmd_conv(const char *name)
+{
+    int size = 0;
+    char format_name[6] = { 0 };
+    format_name[0] = toupper(name[0]);
+    format_name[1] = toupper(name[1]);
+
+    size = rt_strlen(name);
+    size = (size > 5) ? 5 : size;
+    size -= 2;
+    if (name[2] != '.')
+    {
+        format_name[2] = '.';
+    }
+    strncat(format_name, name + 2, size);
+    return rt_pin_get(format_name);
+}
+
+static void _pin_cmd_print_usage(void)
+{
+    rt_kprintf("pin [option]\n");
+    rt_kprintf("  num: get pin number from hardware pin\n");
+    rt_kprintf("    num can be PE02, PE2, PE.02, PE.2, pe02, pe2, pe.02, pe.2\n");
+    rt_kprintf("    e.g. MSH >pin num PA.16\n");
+    rt_kprintf("  mode: set pin mode to output/input/input_pullup/input_pulldown/output_od\n    e.g. MSH >pin mode PA.16 output\n");
+    rt_kprintf("  read: read pin level of hardware pin\n    e.g. MSH >pin read PA.16\n");
+    rt_kprintf("  write: write pin level(high/low or on/off) to hardware pin\n    e.g. MSH >pin write PA.16 high\n");
+    rt_kprintf("  help: this help list\n");
+}
+
+/* e.g. MSH >pin num PA.16 */
+static void _pin_cmd_get(int argc, char *argv[])
+{
+    rt_base_t pin;
+    if (argc < 3)
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+    pin = _pin_cmd_conv(argv[2]);
+    if (pin < 0)
+    {
+        rt_kprintf("Parameter invalid : %s!\n", argv[2]);
+        _pin_cmd_print_usage();
+        return ;
+    }
+    rt_kprintf("%s : %d\n", argv[2], pin);
+}
+
+/* e.g. MSH >pin mode PA.16 output */
+static void _pin_cmd_mode(int argc, char *argv[])
+{
+    rt_base_t pin;
+    rt_base_t mode;
+    if (argc < 4)
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+    if (!msh_isint(argv[2]))
+    {
+        pin = _pin_cmd_conv(argv[2]);
+        if (pin < 0)
+        {
+            rt_kprintf("Parameter invalid : %s!\n", argv[2]);
+            _pin_cmd_print_usage();
+            return;
+        }
+    }
+    else
+    {
+        pin = atoi(argv[2]);
+    }
+    if (0 == rt_strcmp("output", argv[3]))
+    {
+        mode = PIN_MODE_OUTPUT;
+    }
+    else if (0 == rt_strcmp("input", argv[3]))
+    {
+        mode = PIN_MODE_INPUT;
+    }
+    else if (0 == rt_strcmp("input_pullup", argv[3]))
+    {
+        mode = PIN_MODE_INPUT_PULLUP;
+    }
+    else if (0 == rt_strcmp("input_pulldown", argv[3]))
+    {
+        mode = PIN_MODE_INPUT_PULLDOWN;
+    }
+    else if (0 == rt_strcmp("output_od", argv[3]))
+    {
+        mode = PIN_MODE_OUTPUT_OD;
+    }
+    else
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+
+    rt_pin_mode(pin, mode);
+}
+
+/* e.g. MSH >pin read PA.16 */
+static void _pin_cmd_read(int argc, char *argv[])
+{
+    rt_base_t pin;
+    rt_base_t value;
+    if (argc < 3)
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+    if (!msh_isint(argv[2]))
+    {
+        pin = _pin_cmd_conv(argv[2]);
+        if (pin < 0)
+        {
+            rt_kprintf("Parameter invalid : %s!\n", argv[2]);
+            _pin_cmd_print_usage();
+            return;
+        }
+    }
+    else
+    {
+        pin = atoi(argv[2]);
+    }
+    value = rt_pin_read(pin);
+    if (value == PIN_HIGH)
+    {
+        rt_kprintf("pin[%d] = on\n", pin);
+    }
+    else
+    {
+        rt_kprintf("pin[%d] = off\n", pin);
+    }
+}
+
+/* e.g. MSH >pin write PA.16 high */
+static void _pin_cmd_write(int argc, char *argv[])
+{
+    rt_base_t pin;
+    rt_base_t value;
+    if (argc < 4)
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+    if (!msh_isint(argv[2]))
+    {
+        pin = _pin_cmd_conv(argv[2]);
+        if (pin < 0)
+        {
+            rt_kprintf("Parameter invalid : %s!\n", argv[2]);
+            _pin_cmd_print_usage();
+            return;
+        }
+    }
+    else
+    {
+        pin = atoi(argv[2]);
+    }
+    if ((0 == rt_strcmp("high", argv[3])) || (0 == rt_strcmp("on", argv[3])))
+    {
+        value = PIN_HIGH;
+    }
+    else if ((0 == rt_strcmp("low", argv[3])) || (0 == rt_strcmp("off", argv[3])))
+    {
+        value = PIN_LOW;
+    }
+    else
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+    rt_pin_write(pin, value);
+}
+
+static void _pin_cmd(int argc, char *argv[])
+{
+    if (argc < 3)
+    {
+        _pin_cmd_print_usage();
+        return ;
+    }
+    if (0 == rt_strcmp("num", argv[1]))
+    {
+        _pin_cmd_get(argc, argv);
+    }
+    else if (0 == rt_strcmp("mode", argv[1]))
+    {
+        _pin_cmd_mode(argc, argv);
+    }
+    else if (0 == rt_strcmp("read", argv[1]))
+    {
+        _pin_cmd_read(argc, argv);
+    }
+    else if (0 == rt_strcmp("write", argv[1]))
+    {
+        _pin_cmd_write(argc, argv);
+    }
+    else
+    {
+        _pin_cmd_print_usage();
+        return;
+    }
+}
+MSH_CMD_EXPORT_ALIAS(_pin_cmd, pin, pin [option]);
+#endif /* RT_USING_FINSH */

+ 1 - 0
components/finsh/SConscript

@@ -4,6 +4,7 @@ cwd     = GetCurrentDir()
 src     = Split('''
 shell.c
 msh.c
+msh_parse.c
 ''')
 
 if GetDepend('MSH_USING_BUILT_IN_COMMANDS'):

+ 6 - 6
components/finsh/finsh.h

@@ -10,17 +10,17 @@
 #ifndef __FINSH_H__
 #define __FINSH_H__
 
-#include <rtthread.h>
+#include <rtdef.h>
 
-#if defined(_MSC_VER)
-    #pragma section("FSymTab$f",read)
-#endif
+#ifdef _MSC_VER
+#pragma section("FSymTab$f",read)
+#endif /* _MSC_VER */
 
 typedef long (*syscall_func)(void);
 #ifdef FINSH_USING_SYMTAB
 #ifdef __TI_COMPILER_VERSION__
-    #define __TI_FINSH_EXPORT_FUNCTION(f)  PRAGMA(DATA_SECTION(f,"FSymTab"))
-#endif
+#define __TI_FINSH_EXPORT_FUNCTION(f)  PRAGMA(DATA_SECTION(f,"FSymTab"))
+#endif /* __TI_COMPILER_VERSION__ */
 #ifdef FINSH_USING_DESCRIPTION
 #ifdef _MSC_VER
 #define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc)      \

+ 96 - 0
components/finsh/msh_parse.c

@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-05-25     WangQiang    the first verion for msh parse
+ */
+
+#include <rtthread.h>
+#include <ctype.h>
+
+#define forstrloop(str) for (; '\0' != *(str); (str)++)
+
+/**
+ * This function will check integer.
+ *
+ * @param strvalue string
+ *
+ * @return true or false
+ */
+rt_bool_t msh_isint(char *strvalue)
+{
+    if ((RT_NULL == strvalue) || ('\0' == strvalue[0]))
+    {
+        return RT_FALSE;
+    }
+    if (('+' == *strvalue) || ('-' == *strvalue))
+    {
+        strvalue++;
+    }
+    forstrloop(strvalue)
+    {
+        if (!isdigit((int)(*strvalue)))
+        {
+            return RT_FALSE;
+        }
+    }
+    return RT_TRUE;
+}
+
+/**
+ * This function will check hex.
+ *
+ * @param strvalue string
+ *
+ * @return true or false
+ */
+rt_bool_t msh_ishex(char *strvalue)
+{
+    int c;
+    if ((RT_NULL == strvalue) || ('\0' == strvalue[0]))
+    {
+        return RT_FALSE;
+    }
+    if ('0' != *(strvalue++))
+    {
+        return RT_FALSE;
+    }
+    if ('x' != *(strvalue++))
+    {
+        return RT_FALSE;
+    }
+
+    forstrloop(strvalue)
+    {
+        c = tolower(*strvalue);
+        if (!isxdigit(c))
+        {
+            return RT_FALSE;
+        }
+    }
+    return RT_TRUE;
+}
+
+/**
+ * This function will transform for string to hex.
+ *
+ * @param strvalue string
+ *
+ * @return true or false
+ */
+int msh_strtohex(char *strvalue)
+{
+    char c = 0;
+    int value = 0;
+    strvalue += 2;
+    forstrloop(strvalue)
+    {
+        value *= 16;
+        c = tolower(*strvalue);
+        value += isdigit(c) ? c - '0' : c - 'a' + 10;
+    }
+    return value;
+}

+ 20 - 0
components/finsh/msh_parse.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-05-25     WangQiang    the first verion for msh parse
+ */
+
+#ifndef MSH_PARSE_H
+#define MSH_PARSE_H
+
+#include <rtdef.h>
+
+rt_bool_t msh_isint(char *strvalue);
+rt_bool_t msh_ishex(char *strvalue);
+int msh_strtohex(char *strvalue);
+
+#endif /* MSH_PARSE_H */