1. 今天在阅读nrf53832源码时, 又学到了知识点: 代码中有关fifo的写法, 将数组队列抽象成一个结构体, 用结构体的成员来指向创建的对象.
typedef struct
{
uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
} app_fifo_t;
这样我只需要定义一个app_fifo_t的对象, 然后初始化内部成员(p_buf指向一个数组, buf_size_mask保存数组长度, read_pos, write_pos读写指针)就可以, 这样就可以弄很多队列, 公用一个接口.
2. 以上给我的启发就是我们每次写代码的时候, 想想是不是可以抽象以下, 把他写成一个类, 这样可以写出更高效更健壮的代码, 当代码在不断的被考验测试, 就能将逻辑漏洞检测出来.
3. 在实际项目中, 这种抽象会照成一丢丢的资源浪费, 在这里给大家提醒,在8位单片机千万别搞这种, 很容易导致内存爆掉.
4.还有实际上很多变量, 用const修饰就可以, 很多代码却没用const修饰, 导致内存被浪费掉了.
typedef struct {
init int;
write write;
read read;
}ops_t;
const ops_t uart_ops = {
.int = uart_inti,
.write = uart_send,
.read = uart_recieve,
};
typedef struct {
const ops_t *ops;
int port;
}uart_t;
uart_t uart = {
.ops = &uart_ops;
.port = 1;
};
通过封装一层ops, 就可以将内存占降下去, 这样也有面向对象的思想. 将一个东西封装起来.看得代码多了, 会发现以前的项目写的真的很low, 但这是每个人必经之路.也许过段时间我也会觉得现在的想法太low..
5. 还有种降低内存的方法, 就是使用动态内存分配(内存池, 内存堆), 可以将一些占用大内存的, 而使用时间短的内存, 用内存分配来解决, 这样可以降低内存的消耗.但是在裸机项目中, 消耗大内存的机会很小, 至少我以前遇到的都是小内存, 都只需要几个字节就行, 一切皆可控.而在物联网产品中, 需要的都是大内存来接收数据, 因此内存动态分配就是最优解(如果反复需要申请和分配的, 我觉得还是用内存池来做比较合理, 而内存堆用来那种分配一次就不释放的场景, 可以最大程度的降低内存碎片)
//2024/1/28
6. 最近一直在思考串口回调怎么写, 串口回调用来接收串口的数据, 我们可以通过注册的方式实现, 但是这种方法会损害模块化, 直到今天无意间看到了__attribute__((weak)).瞬间就找到了解决方法.这样完全解耦了.我们在串口bsp层写一个回调weak函数, 再在中间层再写一个
//bsp_uart.c
__attribute__((weak)) void uart_recieve(char value)
{
printf("weak fun: void uart_recieve");
}
//mid_uart.c
void uart_recieve(char value)
{
//串口数据处理
}