木子剑
生命不熄,学习不止!

关于CONTIKI NG的LEDS,我们首先把它的概念、目的搞清楚。LEDS是\os\dev标准驱动库,主要是用于管理所有LED灯的,有三大文件

\os\dev内核的:leds.h、leds.c

\user\src用户实现的: leds-arch.c

 

leds.h都是一些功能函数的申请明,而leds.c则实现它功能,发现leds.c里面是在使用\user\cc2538-dev的gpio-hal-arch.h操作,

这个\user\cc2538-dev的gpio-hal-arch.h此前已经研究过了,可回顾篇  https://www.cnblogs.com/lijianGX/p/13681844.html  。

 

leds-arch.c是实现了一个结构体类型的数组,因为它在leds.c被使用到,即然内核都使用到了,它可能是标准的方法了

 

我们把这它们都放在一起,看看它们的模样:

  1 /************* \os\dev内核的:leds.h,部份代码*******/
  2 /*---------------------------------------------------------------------------*/
  3 /**
  4  * \brief 不存在的LED的默认LED颜色
  5  */
  6 #define LEDS_COLOUR_NONE 0x00
  7 
  8 
  9 /*----------------------红+绿+蓝+黄+橙---------------------------------------*/
 10 /* LED 颜色到数字映射。适用于两个 API */
 11 #ifdef LEDS_CONF_RED
 12 #define LEDS_RED LEDS_CONF_RED
 13 #else
 14 #define LEDS_RED LEDS_COLOUR_NONE
 15 #endif
 16 
 17 #ifdef LEDS_CONF_GREEN                //如果有配置绿色LED
 18 #define LEDS_GREEN LEDS_CONF_GREEN    //有,定义绿色
 19 #else
 20 #define LEDS_GREEN LEDS_COLOUR_NONE   //无,不存在绿色
 21 #endif
 22 
 23 #ifdef LEDS_CONF_BLUE
 24 #define LEDS_BLUE LEDS_CONF_BLUE
 25 #else
 26 #define LEDS_BLUE LEDS_COLOUR_NONE
 27 #endif
 28 
 29 #ifdef LEDS_CONF_YELLOW
 30 #define LEDS_YELLOW LEDS_CONF_YELLOW
 31 #else
 32 #define LEDS_YELLOW LEDS_COLOUR_NONE
 33 #endif
 34 
 35 #ifdef LEDS_CONF_ORANGE
 36 #define LEDS_ORANGE LEDS_CONF_ORANGE
 37 #else
 38 #define LEDS_ORANGE LEDS_COLOUR_NONE
 39 #endif
 40 
 41 
 42 typedef uint8_t leds_num_t;
 43 typedef uint8_t leds_mask_t;
 44 
 45 /*---------------------------------------------------------------------------*/
 46 #ifdef LEDS_CONF_COUNT
 47 #define LEDS_COUNT LEDS_CONF_COUNT
 48 #else
 49 /**
 50  * \brief 设备上存在的 LED 数量
 51  */
 52 #define LEDS_COUNT 0
 53 #endif
 54 
 55 /*---------------------------------------------------------------------------*/
 56 /**
 57  * \brief 所有设备 LED 的 OR 掩码表示
 58  */
 59 #define LEDS_ALL ((1 << LEDS_COUNT) - 1)
 60 
 61 
 62 /*----------------------------就是LINE:xx的5个灯-----------------------------*/
 63 #define LEDS_LED1     0x00 /**< Convenience macro to refer    到第一个LED(LED 1)*/
 64 #define LEDS_LED2     0x01 /**< Convenience macro to refer to the 2nd LED (LED 2) */
 65 #define LEDS_LED3     0x02 /**< Convenience macro to refer to the 3rd LED (LED 3) */
 66 #define LEDS_LED4     0x03 /**< Convenience macro to refer to the 4th LED (LED 4) */
 67 #define LEDS_LED5     0x04 /**< Convenience macro to refer to the 5th LED (LED 5) */
 68 
 69 
 70 // leds-arch.c有用到这个leds_t
 71 typedef struct leds_s {
 72   gpio_hal_pin_t pin;
 73 #if GPIO_HAL_PORT_PIN_NUMBERING
 74   gpio_hal_port_t port;
 75 #endif
 76   bool negative_logic;
 77 } leds_t;
 78 
 79 
 80 /*---------------------------------------------------------------------------*/
 81 /**
 82  * [简要 将 LED 编号转换为掩码表示形式
 83  * =param l 引脚编号(通常是类型leds_num_t)
 84  * = 返回类型为 leds_mask_t
 85  */
 86 #define LEDS_NUM_TO_MASK(l) (1 << (l))
 87 
 88 
 89 /*---------------------------------------------------------------------------*/
 90 /**
 91  * [ 简要初始化 LED
 92  *
 93  * 此功能将设置相应的 LED GPIO 引脚输出,也将
 94  * 将所有 LED 的初始状态设置为关闭。
 95  */
 96 void leds_init(void);
 97 
 98 
 99 
100 
101 /************* \os\dev内核的:leds.c,部份代码   */
102 /*------------------------------全是新版的LEDS-------------------------------*/
103 #if LEDS_COUNT  // leds的总数量
104 extern const leds_t leds_arch_leds[];
105 #else
106 static const leds_t *leds_arch_leds = NULL; // static const去修饰指针,能变动吗?
107 #endif
108 
109 
110 /*---------------------------------------------------------------------------*/
111 #if GPIO_HAL_PORT_PIN_NUMBERING   // 为0的
112 #define LED_PORT(led) (led).port
113 #else
114 #define LED_PORT(led) GPIO_HAL_NULL_PORT // 就CC2538来看,是选定这一项,不用PORT
115 #endif
116 
117 
118 /*---------------------------------------------------------------------------*/
119 void
120 leds_init()
121 {
122   leds_num_t led;
123 
124   for(led = 0; led < LEDS_COUNT; led++) { //执行完这个功能后,LED才会有作用!!
125     gpio_hal_arch_pin_set_output(LED_PORT(leds_arch_leds[led]),
126                                  leds_arch_leds[led].pin);
127   }
128   //leds_off(LEDS_ALL); 硬件反的
129    leds_on(LEDS_ALL); //硬件反的,ON才是OFF
130 }
131 
132 
133 
134 /******** \user\src用户实现的: leds-arch.c  */
135 /*---------------------------------------------------------------------------*/
136 const leds_t leds_arch_leds[] = {
137   {
138     .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L1_PORT, LEDS_ARCH_L1_PIN),
139     .negative_logic = false   // 所谓的负逻辑就是,当低电平时,LED才亮起来
140   },
141   {
142     .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L2_PORT, LEDS_ARCH_L2_PIN),
143     .negative_logic = false  // 当为true时,为正逻辑,高电平时灯亮起
144   },
145   {
146     .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L3_PORT, LEDS_ARCH_L3_PIN),
147     .negative_logic = false
148   },
149 #if !USB_SERIAL_CONF_ENABLE
150   {
151     .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L4_PORT, LEDS_ARCH_L4_PIN),
152     .negative_logic = false
153   },
154 #endif
155 };

可以看到,要用户实现内容比较少了,leds-arch.c值得好好分析一下,leds.h、leds.c属OS的内核部份,为了通用性我们不要去更改它。最近在搬家,晚些日子再深入研究。。。

 

日期2020-10-26

要重新研究一下,有几个特别的宏定义,很重要:

  1 /*****************************************************************************
  2  Function    : C03测试
  3  Description : 用CONTIKI的ubuntu进行测试,GCC用makefile方式的,
  4                在这里写好代码后gcc 03.c&&./a.out看执行效果
  5  Input       : None
  6  Output      : None
  7  Return      : None
  8  *****************************************************************************/
  9 
 10 // ALL Includes
 11 #include "stdio.h"
 12 #include "stdlib.h"
 13 #include "string.h"
 14 #include <stdint.h>
 15 #include <stdbool.h>
 16 #include <stddef.h>
 17 
 18 //reg.h
 19 #define REG(x)         (*((volatile unsigned long *)(x)))
 20 #define REG_H(x)       (*((volatile unsigned short *)(x)))
 21 #define REG_B(x)       (*((volatile unsigned char *)(x)))
 22 #define REG_BIT_W(x, b)                                                     \
 23         REG(((unsigned long)(x) & 0xF0000000) | 0x02000000 |                \
 24               (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))
 25 #define REG_BIT_H(x, b)                                                     \
 26         REG_H(((unsigned long)(x) & 0xF0000000) | 0x02000000 |              \
 27                (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))
 28 #define REG_BIT_B(x, b)                                                     \
 29         REG_B(((unsigned long)(x) & 0xF0000000) | 0x02000000 |              \
 30                (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))
 31 
 32 
 33 //gpio.h
 34 #define GPIO_A_NUM              0 /**< GPIO_A: 0 */
 35 #define GPIO_B_NUM              1 /**< GPIO_B: 1 */
 36 #define GPIO_C_NUM              2 /**< GPIO_C: 2 */
 37 #define GPIO_D_NUM              3 /**< GPIO_D: 3 */
 38 
 39 #define GPIO_DATA               0x00000000  /**< 数据寄存器 */
 40 #define GPIO_DIR                0x00000400  /**< 数据方向寄存器 */
 41 #define GPIO_IS                 0x00000404  /**< 中断感*/
 42 #define GPIO_IBE                0x00000408  /**< 中断两个边缘 */
 43 #define GPIO_IEV                0x0000040C  /**< 中断事件 */
 44 #define GPIO_IE                 0x00000410  /**< 中断屏蔽 */
 45 #define GPIO_RIS                0x00000414  /**< 中断状态 - 原始 */
 46 #define GPIO_MIS                0x00000418  /**< 中断状态-已屏蔽*/
 47 #define GPIO_IC                 0x0000041C  /**< 中断清除 */
 48 #define GPIO_AFSEL              0x00000420  /**< 模式控制选择 */
 49 #define GPIO_GPIOLOCK           0x00000520  /**< GPIO 提交解锁 */
 50 #define GPIO_GPIOCR             0x00000524  /**< GPIO提交 */
 51 #define GPIO_PMUX               0x00000700  /**< PMUX寄存器 */
 52 #define GPIO_P_EDGE_CTRL        0x00000704  /**< 端口边缘控制 */
 53 #define GPIO_USB_CTRL           0x00000708  /**< USB输入上电边缘ctrl */
 54 #define GPIO_PI_IEN             0x00000710  /**< 上电中断使能 */
 55 #define GPIO_IRQ_DETECT_ACK     0x00000718  /**< IRQ detect ACK - I/O ports */
 56 #define GPIO_USB_IRQ_ACK        0x0000071C  /**< IRQ detect ACK - USB */
 57 #define GPIO_IRQ_DETECT_UNMASK  0x00000720  /**< IRQ detect ACK - masked */
 58 
 59 #define GPIO_A_BASE             0x400D9000 /**< GPIO_A 与数据手册上一致的 */
 60 #define GPIO_B_BASE             0x400DA000 /**< GPIO_B */
 61 #define GPIO_C_BASE             0x400DB000 /**< GPIO_C */
 62 #define GPIO_D_BASE             0x400DC000 /**< GPIO_D */
 63 
 64 #define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK) \
 65   do { REG((PORT_BASE) + GPIO_AFSEL) &= ~(PIN_MASK); } while(0)
 66 
 67 
 68 #define GPIO_PIN_MASK(PIN) (1 << (PIN))
 69 
 70 
 71 #define GPIO_PORT_TO_BASE(PORT) (GPIO_A_BASE + ((PORT) << 12))
 72 
 73 
 74 #define GPIO_PORT_PIN_TO_GPIO_HAL_PIN(PORT, PIN) (((PORT) << 3) + (PIN))
 75 
 76 
 77 #define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK) \
 78   do { REG((PORT_BASE) + GPIO_DIR) |= (PIN_MASK); } while(0)
 79 
 80 
 81 //gpio-hal-arch.h
 82 #define gpio_hal_arch_pin_set_output(port, p) do { \
 83   GPIO_SOFTWARE_CONTROL(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
 84   GPIO_SET_OUTPUT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
 85 } while(0);
 86 
 87 
 88 //gpio-hal.h
 89 #define GPIO_HAL_NULL_PORT      0   //暂时理解为,不使用PORT端口参数
 90 
 91 
 92 //board.h
 93 #define LEDS_CONF_YELLOW           1       //黄灯
 94 #define LEDS_CONF_GREEN            2       //绿灯
 95 #define LEDS_CONF_ORANGE           4       //橘黄色,在开发板上是蓝色灯
 96 
 97 #define LEDS_ARCH_L1_PORT GPIO_C_NUM    //C端口的第1  PIN
 98 #define LEDS_ARCH_L1_PIN           1
 99 #define LEDS_ARCH_L2_PORT GPIO_C_NUM
100 #define LEDS_ARCH_L2_PIN           2
101 #define LEDS_ARCH_L3_PORT GPIO_C_NUM
102 #define LEDS_ARCH_L3_PIN           3
103 
104 
105 //gpio-hal-arch.h
106 #define PIN_TO_PORT(pin) (pin >> 3)
107 #define PIN_TO_NUM(pin) (pin % 8)
108 #define PIN_TO_PORT_BASE(pin) GPIO_PORT_TO_BASE(PIN_TO_PORT(pin))
109 #define GPIO_PORT_TO_BASE(PORT) (GPIO_A_BASE + ((PORT) << 12))
110 
111 //主main
112 int main(void) {
113     
114 
115     gpio_hal_arch_pin_set_output(GPIO_HAL_NULL_PORT,GPIO_PORT_PIN_TO_GPIO_HAL_PIN(GPIO_C_NUM, LEDS_ARCH_L3_PIN));     //OK     0, 2, 3
116    // gpio_hal_arch_pin_set_output(0,13);     //OK     0, 2, 3
117     printf("This is C dbg 43 PASS!\r\n\r\n\r\n");//执行到这一步,说明测试正常退出!
118     return 0;
119 }

以上就是LEDS的所有内容了,但是在单独执行时,会报错!这个太难了。。这个是高级错误。我只是想单独仿真一下看看,竟然报这个core dumped错误!!!

 

日期2020-11-2

 我们用GPIO.H操作时,如之前的所示

GPIO_SET_OUTPUT(GPIO_C_BASE, GPIO_PIN_MASK(3));//操作PORTC-PIN3为输出

 

当我们用操作系统LEDS时,在gpio-hal-arch.h就成这样了

GPIO_SET_OUTPUT(PIN_TO_PORT_BASE(GPIO_PORT_PIN_TO_GPIO_HAL_PIN(GPIO_C_NUM, LEDS_ARCH_L3_PIN)),\
GPIO_PIN_MASK((GPIO_PORT_PIN_TO_GPIO_HAL_PIN(GPIO_C_NUM, LEDS_ARCH_L3_PIN)) % 8)); 

为什么要把简单的事情搞复杂,有点无耐了。GPIO_SET_OUTPUT(x,x)可以很简单,也可以很复杂!系统源码多处提示不建议直接寄存PORT,哈哈!!

回顾一下知识点,在gpio-hal-arch.h中

1 /*  端口引脚配置成输出  */
2 #define gpio_hal_arch_pin_set_output(port, p) do { \
3   GPIO_SOFTWARE_CONTROL(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
4   GPIO_SET_OUTPUT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
5 } while(0);

GPIO_SOFTWARE_CONTROL这是模式选择,是软件直接操作GPIO?还是接入外设,如IIC  ADC等?默认是软件操作的,所以我们不用去管它。

 

日期2020-11-3

虽然我们还是比较喜欢直接操作寄存,说白这是裸机编程留下的习惯;但是我们在学NG操作系统,必须学习系统的方法,再难也要慢慢磨下去!!

我手上的CONTIKI NG版本,实现了4个LEDS

 * - LED1 (Red)    -> PC0
 * - LED2 (Yellow) -> PC1
 * - LED3 (Green)  -> PC2
 * - LED4 (Orange) -> PC3

现在要自己实现BLUE蓝灯,说实话!随便用哪个GPIO都行,我就用随意一下,就PORTD口的PIN4脚吧。

你会发现非常的简单,在board.h编写:

/*---------------------------------------------------------------------------*/
/** \name SmartRF LED configuration
 *
 * LEDs on the SmartRF06 (EB and BB) are connected as follows:
 * - LED1 (Red)    -> PC0
 * - LED2 (Yellow) -> PC1
 * - LED3 (Green)  -> PC2
 * - LED4 (Orange) -> PC3
 * - LED5 (BLUE)   -> PD4    // 2020-11-2增加
 * LED1 shares the same pin with the USB pullup
 * @{
 */
/*---------------------------------------------------------------------------*/
#define LEDS_CONF_YELLOW           1       //黄灯
#define LEDS_CONF_GREEN            2       //绿灯
#define LEDS_CONF_ORANGE           4       //橘黄色,在开发板上是蓝色灯
#define LEDS_CONF_BLUE             5       //蓝灯   2020-11-2增加

#define LEDS_ARCH_L1_PORT GPIO_C_NUM    //C端口的第1  PIN
#define LEDS_ARCH_L1_PIN           1
#define LEDS_ARCH_L2_PORT GPIO_C_NUM
#define LEDS_ARCH_L2_PIN           2
#define LEDS_ARCH_L3_PORT GPIO_C_NUM
#define LEDS_ARCH_L3_PIN           3

#define LEDS_ARCH_L5_PORT GPIO_D_NUM    //  2020-11-2增加
#define LEDS_ARCH_L5_PIN           4

#if USB_SERIAL_CONF_ENABLE
#define LEDS_CONF_COUNT            3
#else
#define LEDS_ARCH_L4_PORT GPIO_C_NUM
#define LEDS_ARCH_L4_PIN           0
#define LEDS_CONF_RED              8      //红灯
#define LEDS_CONF_COUNT            5      //原来是4,2020-11-2增加改成5  
#endif

上面有“2020-11-2增加”就是新加的,灯的总数量5个(0-4);

 

接着在leds-arch.c编写:

const leds_t leds_arch_leds[] = {
  {
    .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L1_PORT, LEDS_ARCH_L1_PIN),
    .negative_logic = false   // 所谓的负逻辑就是,当低电平时,LED才亮起来
  },
  {
    .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L2_PORT, LEDS_ARCH_L2_PIN),
    .negative_logic = false  // 当为true时,为正逻辑,高电平时灯亮起
  },
  {
    .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L3_PORT, LEDS_ARCH_L3_PIN),
    .negative_logic = false
  },
#if !USB_SERIAL_CONF_ENABLE
  {
    .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L4_PORT, LEDS_ARCH_L4_PIN),
    .negative_logic = false
  },
#endif
    {
    .pin = GPIO_PORT_PIN_TO_GPIO_HAL_PIN(LEDS_ARCH_L5_PORT, LEDS_ARCH_L5_PIN),
    .negative_logic = false   //2020-11-02增加
  },
};

同样道理,上面有“2020-11-2增加”就是新加的,为什么要写这个,因为系统在初次化LEDS时,会使用的。

 

给出contiki-main.c关键源码部分,只是测试,没跑系统的。

  gpio_hal_arch_pin_set_output(GPIO_HAL_NULL_PORT,GPIO_PORT_PIN_TO_GPIO_HAL_PIN(GPIO_D_NUM, LEDS_ARCH_L5_PIN));
  
  GPIO_WRITE_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4), ~GPIO_READ_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4)));
  GPIO_WRITE_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4), ~GPIO_READ_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4)));
  GPIO_WRITE_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4), ~GPIO_READ_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4)));
  GPIO_WRITE_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4), ~GPIO_READ_PIN(GPIO_D_BASE, GPIO_PIN_MASK(4)));

  UARTprintf("HAL NO:0x%x\r\n",GPIO_PORT_PIN_TO_GPIO_HAL_PIN(GPIO_D_NUM, LEDS_ARCH_L5_PIN)); //换为GPIO HAL引脚号:0x13,这个3就是引脚号3

  while(1);//测试LEDS的

 

在IAR单步仿真时,示波器测到的波形

 

 PORTD口的PIN4脚已经实现了,这里LEDS的学习到此结束! 

 

深入研究,NG系统级的LEDS只开放了5个LEDS,我们要开放10个也可以的,去leds.h内核文件里改一下就行了。

一般5个确实也够用了。还想玩LEDS的话,就移植到STM32上面去吧,算了,我么有太多时间,继续研究NG系统的其他功能要紧。

 

posted on 2020-10-22 18:53  木子剑  阅读(460)  评论(0)    收藏  举报