C/C++中有很多基本的数据类型,比如,int,char,float等等,在学习SimpliciTI-IAR-1.2.0的Simple_Peer_to_Peer过程中,遇到了几种用户自定义数据类型,下面结合以前学习的C++的基础知识,作一个简单回顾。在Simple_Peer_to_Peer中主要遇到了3中自定义数据类型:结构体类型、共用体和枚举类型
1,结构体:比如
struct Student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student1;
不同类型的数据组合在一起,而这些数据又都是互相关联的,都是学生 student1的属性(学号、姓名、性别、年龄、分数和家庭住址)。
而在Simple_Peer_to_Peer>nwk>nwk_types.h中使用了很多结构体类型,比如:
typedef uint8_t linkID_t;
typedef int8_t rssi_t;
typedef struct
{
rssi_t rssi;
uint8_t lqi;
} rxMetrics_t;
typedef struct
{
linkID_t lid;
rxMetrics_t sigInfo;
} ioctlRadioSiginfo_t;
可以看到rssi、lqi和lid都是ioctlRadioSiginfo_t的属性,都是octlRadioSiginfo_t携带的信息。
2,共用体 union
比如:
union data
{
int i;
char ch;
double d;
}a,b,c;
共用体union和结构体类似,它们的区别在于:结构体变量所占的内存长度是各成员所占内存长度之和,每个成员分别占着自己的内存单元。而共用体所占内存
长度是最长的成员的长度。
也就是说如果上面改成
struct data
{
int i;
char ch;
double d;
}a,b,c;
那么一个变量所占的内存就是4+1+8=13个字节,而共用体结构中,一个变量所占的内存长度是8,因为double变量所占内存最长,为8个字节。
几点说明:
(1)使用共用体变量的目的是希望同一个内存段中存放几种不同类型的数据。值得注意的是:在每一瞬时只能存放其中一种,而不是同时存放几种。
也就是说,内存中放的要么是整型i,要么是字符型ch,要么是 双精度d,但它们不可能共存在内存当中。
(2)能够访问的是共用体变量中最后一次被赋值的成员,在对一个新的成员赋值后原有的成员就失去作用。
在Simple_Peer_to_Peer>nwk>nwk_types.h中,有如下共用体类型定义
typedef union
{
uint32_t linkToken;
uint32_t joinToken;
} token_t;
可以知道,标签要么是连接标签,要么是加入标签,两个标签不能共存。
3,枚举类型enum
如果一个变量有几种可能的值,就可以定义为枚举类型。
enum smplStatus {
SMPL_SUCCESS,
SMPL_TIMEOUT,
SMPL_BAD_PARAM,
SMPL_NOMEM,
SMPL_NO_FRAME,
SMPL_NO_LINK,
SMPL_NO_JOIN,
SMPL_NO_CHANNEL,
SMPL_NO_PEER_UNLINK,
SMPL_TX_CCA_FAIL,
SMPL_NO_PAYLOAD,
SMPL_NO_AP_ADDRESS,
SMPL_NO_ACK
};
列举了SimpliciTI运行时可能返回的所有状态。
看过eeworld中很多前辈的帖子,大致看懂了bsp中的程序。我在这里也作一下小总结吧
SimpliciTI-IAR-1.2.0中提供的bsp中主要包括bsp_generic_leds.h\bsp_leds.h\bsp_leds.c\bsp_led_defs.h(这些都是关于LED的,如果硬件配置与软件不对应,那么我们是在bsp_led_defs.h中修改相关配置)
bsp_generic_buttons.h\bsp_buttons.h\bsp_buttons.h\bsp_button_defs.h(这些都是关于button的,如果硬件配置与软件不对应,我们是在bsp_button_defs.h进行修改)
就以LED为例来讲一下,button类似。
/******bsp_generic_leds.h*******/
#define __bsp_LED_TURN_ON__(bit,port,ddr,low) \
st( if (low) { port &= ~BV(bit); } else { port |= BV(bit); } )
#define __bsp_LED_TURN_OFF__(bit,port,ddr,low) \
st( if (low) { port |= BV(bit); } else { port &= ~BV(bit); } )
#define __bsp_LED_IS_ON__(bit,port,ddr,low) \
( (low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) )
#define __bsp_LED_TOGGLE__(bit,port,ddr,low) st( port ^= BV(bit); )
#define __bsp_LED_CONFIG__(bit,port,ddr,low) st( ddr |= BV(bit)
#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \
(defined __bsp_LED1_PORT__) + \
(defined __bsp_LED1_DDR__) + \
(defined __bsp_LED1_IS_ACTIVE_LOW__))
#if (__bsp_NUM_LED1_DEFINES__ == 4)
#define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ )
#define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ )
#define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ )
#define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ )
#define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ )
上面主要是为了实现LED1的一些基本操作,比如TURN_ON(开)\TURN_OFF(关)\TOGGLE(取反)\GONFIG(简单配置)。说明一下:
"\"在这里是分行的意思。有时候语句太长,一行写不下,可以把它拆分为两行甚至多行,于是在每一分行后面加一个反斜杠。“\”在Simple_Peer_to_Peer的.h文件中出现的次数还是很多的。
BV在bsp_macros.h中定义的,
#ifndef BV
#define BV(n) (1 << (n)) //0x01左移n位,低位补0,主要是为了实现"位"操作
#endif
/*******bsp_leds.h******/
/* LED1 */
#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__()
#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__()
#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__()
#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__()
只是为了改一下名字而已,比如将__bsp_LED1_TURN_ON__()换成BSP_TURN_ON_LED1()
/****bsp_led_defs.h******/
* LED #1
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Schematic : LED1 (D461)
* Color : Green
* Polarity : Active Low
* GPIO : P1.0
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define __bsp_LED1_BIT__ 0
#define __bsp_LED1_PORT__ P1
#define __bsp_LED1_DDR__ P1DIR
#define __bsp_LED1_IS_ACTIVE_LOW__ 1
这个是最值得我们关注的,因为当我们的硬件与例程中软件不对应时,就是在这里修改。可以看到例程中LED1连接到MCU的P1.0引脚上,而且是低电平有效(active low),也就是当P1.0为低电平时LED1才会被点亮。
/******bsp_leds.c*******/
void BSP_InitLeds(void)
{
BSP_CONFIG_LED1();
BSP_TURN_OFF_LED1();
}
#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__()
上面主要是进行了LED1初始化,且初始化为熄灭。
以上都只是以LED1为例,LED2、LED3、LED4...LED8和上面都是一样的。
按键button的整个初始化过程和LED类似.
bsp作为板级程序包,主要是为了实现板上资源的初始化和驱动,即函数BSP_Init(),BSP_Init()中包含 BSP_INIT_BOARD() 和BSP_INIT_DRIVERS()
/*****bsp.c*****/
void BSP_Init(void)
{
BSP_INIT_BOARD(); //板的初始化
BSP_INIT_DRIVERS(); //驱动初始化
/*-------------------------------------------------------------
* Run time integrity checks. Perform only if asserts
* are enabled.
*/
#ifdef BSP_ASSERTS_ARE_ON
/* verify endianess is correctly specified */ #ifdef和#endif之间的内容没有看懂,希望懂的朋友能够指点一下!!
{
uint16_t test = 0x00AA; /* first storage byte of 'test' is non-zero for little endian */
BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */
}
#endif
}
/****bsp_board_defs.h*******/
#define BSP_INIT_BOARD() BSP_InitBoard() //换个名儿
/****bsp_driver_defs.h******/
#define BSP_INIT_DRIVERS() BSP_InitDriver() //换个名儿
而BSP_InitBoard() 、BSP_InitDriver() 函数都在bsp_board.c和bsp_driver.c中,
/******bsp_driver.c*********/
void BSP_InitDrivers(void)
{
#if (!defined BSP_NO_LEDS)
BSP_InitLeds(); //LED初始化
#endif
#if (!defined BSP_NO_BUTTONS)
BSP_InitButtons(); //button初始化
#endif
}
/*****bsp_board.c******/
void BSP_InitBoard(void) //板初始化这块没有看懂???
{
#ifndef MRFI_TIMER_ALWAYS_ACTIVE
#if defined(SW_TIMER)
#define MHZ_CLOCKS_PER_USEC BSP_CLOCK_MHZ
#define MHZ_CLOCKS_PER_ITERATION 35
sIterationsPerUsec = (uint8_t)(((MHZ_CLOCKS_PER_USEC)/(MHZ_CLOCKS_PER_ITERATION))+.5);
if (!sIterationsPerUsec)
{
sIterationsPerUsec = 1;
}
#endif /* SW_TIMER */
#endif /* MRFI_TIMER_ALWAYS_ACTIVE */
}
Simple_Peer_to_Peer是SimpliciTI中实现点对点通信,没有AP,只有两个终端设备。
会继续发帖,有不懂的希望论坛朋友能够多多指点。