0.
0)结构体 指针数组 结构体后定义指针数组???
1)如何用HAL移植:新建HAL模板,移植到原函数,记得添加外设文件,使能宏,包含头文件,初始化
2)static 静态局部变量:使用static修饰的局部变量在函数调用结束后不会被销毁,下次调用函数时仍然可以使用之前的值。这样可以实现变量的持久化,方便在多次函数调用中保持变量的状态。使用static修饰的函数具有内部链接属性,只能在当前文件中调用,其他文件无法调用。
3)使用外部文件定义的函数,要么include其头文件,要么使用extern外部变量,优先声明该函数
4) 判断是否为整数倍:(len %sizeof(KeyEvent))!=0
5)按键读函数,why?
6)MicroLib仅适用于裸机开发,用操作系统禁用MicroLib
7)外设头文件需 #include "stm32f1xx_hal.h"
一、环形缓冲区
0.若环形缓冲区未初始化成功,考虑在xb.s中增大堆和栈的大小
1.根据要素,在.h文件内 定义环形缓冲区结构体
typedef struct{
uint8_t *fifo; //动态分配buffer大小,这里只是一个指向fifo的指针,具体是否动态取决于后续使用这个结构体如何初始化和分配内存
uint16_t pw;
uint16_t pr;
uint16_t buf_size;
}RingBuffer, *ptRingBuffer;
2. 初始化环形缓冲区接口函数
/*
函数名:Driver_Buffer_Init
功能:初始化一个指定的环形缓冲区
输入参数:buffer->目标缓冲区;size->表示要给缓冲区分配的内存大小,单位是字节
输出参数:无
返回值:-1表示错误,0表示成功
*/
int Driver_Buffer_Init(ptRingBuffer buffer, uint16_t size)//int整型,定义一个ptRingBuffer类型的数组buffer
{
if(buffer == NULL || size == 0) return -1; //如果buffer自己本身为空,不合理
if(buffer->fifo == NULL) //理解为buffer指向fifo的数组为空,方需分配内存
{
buffer->fifo = (uint8_t*)malloc(size); //动态为buffer分配内存
}
buffer->pw = buffer->pr = 0; //刚开始未写入,初始化,读写位均为0
buffer->buf_size = size;
return 0;
}
3.环形缓冲区功能函数接口,注意在前面需引入各种非法条件判断,并返回错误值,可根据返回错误值的不同,定义不同的错误处理函数
//环形缓冲区写一个字节数据的接口---------为什么这里需要第三者i,而后续READ部分不需要i?
/*
函数名:Driver_Buffer_Write
功能:往指定环形缓冲区写入一个字节的数据
输入参数:buffer->指向目标缓冲区;data->写入的数据
输出参数:无
返回值:-1->表示错误;0->表示成功
*/
int Driver_Buffer_Write(ptRingBuffer buffer, const uint8_t data)
{
if(buffer == NULL || buffer->fifo==NULL) return -1; //如果buffer自身为空或者指向fifo为空
int i = (buffer->pw + 1) % (buffer->buf_size);
if(i != buffer->pr) //如果写的下一位和读位相同,则写满
{
buffer->fifo[buffer->pw] = data; //写入数据
buffer->pw = i; //更新写位
return 0;
}
return -1;
}
/*
函数名:Driver_Buffer_WriteBytes
功能:往指定环形缓冲区写入多个字节的数据
输入参数:buffer->指向目标缓冲区;data_stream->写入的数据流;len->写入的数据个数,单位是字节
输出参数:无
返回值:-1->表示错误;0->表示成功
*/
int Driver_Buffer_WriteBytes(ptRingBuffer buffer, const uint8_t *data_stream, uint8_t len)
{
int i =0;
if(buffer == NULL || buffer->fifo==NULL) return -1;
if(data_stream == NULL) return -1;
if(len == 0) return -1;
for(i=0; i<len; i++)
{
if(Driver_Buffer_Write(buffer, data_stream[i]) != 0) break;//注意 if内函数会被循环执行,直至条件不成立
}
return i; //判断传出来的i是否与len相等,如果不相等,则表明没有写完。
}
/*
函数名:Driver_Buffer_WriteBytes
功能:往指定环形缓冲区读入多个字节的数据
输入参数:buffer->指向目标缓冲区;data_stream->写入的数据流;len->写入的数据个数,单位是字节
输出参数:无
返回值:-1->表示错误;0->表示成功
*/
int Driver_Buffer_Read(ptRingBuffer buffer, uint8_t *data)//单字节
{
if(buffer == NULL || buffer->fifo==NULL) return -1;
if(data == 0) return -1;
if(buffer->pr == buffer->pw) return -1; //buffer为空,没有写入,读不了
*data = buffer->fifo[buffer->pr]; //把buffer读入的数据赋值给data
buffer->pr = (buffer->pr + 1) % buffer->buf_size; //读地址更新
return 0;
}
int Driver_Buffer_ReadBytes(ptRingBuffer buffer, uint8_t *data_stream, uint8_t len)
{
int i = 0;
if(buffer == NULL || buffer->fifo==NULL) return -1;
if(data_stream == NULL) return -1;
if(len == 0) return -1;
for(i=0; i<len; i++)
{
if(Driver_Buffer_Read(buffer, &data_stream[i]) != 0) break;
}
return i;
}
int Driver_Buffer_Clean(ptRingBuffer buffer)
{
if(buffer == NULL || buffer->fifo==NULL) return -1;
memset(buffer->fifo, 0, buffer->buf_size);
buffer->pw = buffer->pr = 0;
return 0;
}
二、LED、KEY配置
1.在 hal_gpio.c 中找到 HAL_GPIO_Init() ,跟着来在外设.h头文件中配置
2.头文件中,声明宏定义,封装引脚和基本的常用函数,结构体
/* LED */
#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_1
#define LED(STATUS) HAL_GPIO_WritePin(LED_PORT, LED_PIN, STATUS?GPIO_PIN_RESET:GPIO_PIN_SET)
#define LED_SHINE() HAL_GPIO_TogglePin(LED_PORT, LED_PIN)
/* Key */
#define KEY_PORT GPIOA
#define KEY_PIN GPIO_PIN_0
#define KEY_STATUE() HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN)
//定义表示按键按下时相关信息的结构体:按键序号+持续时间
typedef struct{
uint16_t num; //如果有多个按键,则是表示按键序号
uint16_t time; //按下的持续时间
}KeyEvent;
三、USART设置
1.半主机模式(由软件定义一系列指令的集合)
PC主机与ARM开发板有通信连接/PC主机运行ARM的某种程序:ARM写入后,触发异常SVC,主机读取异常,再打印出来
禁用半主机模式,需移除相关函数,复杂,若无需要,不推荐使用。
MicroLib仅适用于裸机开发,用操作系统禁用MicroLib
2.若UART涉及多个外设,初始化均为同一个UART_MspInit函数,则需改名+在初始化函数重新调用一遍。
四、串口通信+WIFI模块设置
AT+CWJAP 设置模式,3种模式?
五、设备层
0.判断前提,指针类型的函数参数均需优先判断不可为空
定义了一个IO设备结构体类型的指针,分别为led key net,
ledDev = IODev_GetDev(LED) ,在输入输出设备表里面获取到该项设备函数的地址,并赋值给ledDev->Init 即为IODev_GetDev 执行Init初始化
六、阿里云与MQTT协议
0.修改MQTTFreeRtos.c/.h