请教下如下代码要怎么样才能节省空间?
本帖最后由 tangqianfeng 于 2023-10-20 12:38 编辑typedef enum {
UART_RX = 0,
UART_TX
}UART_EVENT_ID;
typedef struct {
uint16_t Data;
TickType_tRecvTick;
}DEBUG_UART_RX_QUEUE;
typedef struct {
uint16_t Len;
uint8_t* Buffer;
}DEBUG_UART_TX_QUEUE;
typedef struct {
UART_EVENT_ID EventId;
uint8_t : 8;
union {
DEBUG_UART_RX_QUEUE;
DEBUG_UART_TX_QUEUE;
};
}DEBUG_UART_QUEUE;
在cortex M0, 定义这几个节构体,都会分别实例化使用,请教要怎么做才能节省ram的空间,而且能正常访问呢?按照我的理解,DEBUG_UART_QUEUE这样应该可以对齐访问的
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式 木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式
取消结构体对齐到有一定的弊端,访问结构体的速度降低了,时间换空间。也可以可以使用联合体或者位域。 木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式
我期望的意思是最后那个DEBUG_UART_QUEUE要尽可能地少,我想表达的是那个数组原则上只需要8个字节,就能实现,而且是能对齐的操作 2360985396 发表于 2023-10-20 14:05
取消结构体对齐到有一定的弊端,访问结构体的速度降低了,时间换空间。也可以可以使用联合体或者位域。
你说的是对的,但我最后的那个结构体,我没有实现既对齐又字节最少, tangqianfeng 发表于 2023-10-20 14:37
你说的是对的,但我最后的那个结构体,我没有实现既对齐又字节最少,
结构体要最少也要看你储存的顺序比如
typedef struct in
{
char a;
intb;
char c;
}aaa;
typedef struct in
{
char a;
char c;
intb;
}aaa; 这两个大小都不一样,第一个的空间大小明显比第二个大 2360985396 发表于 2023-10-20 15:22
结构体要最少也要看你储存的顺序比如
typedef struct in
{
你看我最后一个结构体,我这样排应该是最合理的啊, uint8,uint8,uint16,uint32,应该是都对齐的啊 tangqianfeng 发表于 2023-10-20 16:25
你看我最后一个结构体,我这样排应该是最合理的啊, uint8,uint8,uint16,uint32,应该是都对齐的啊
结构体大小的是最大成员的整数倍,
union {
DEBUG_UART_RX_QUEUE;
DEBUG_UART_TX_QUEUE;
};整个联合体看作一个整体 DEBUG_UART_RX_QUEUE; 多大? DEBUG_UART_RX_QUEUE;多大?最大的那个就是整个联合体的大小,另外联合体大小也是要对齐的 // 枚举一般是int型的
typedef unsigned char UART_EVENT_ID;
#define UART_RX 0
#define UART_TX 1
typedef struct {
uint16_t Data;
TickType_tRecvTick; // ??什么类型
}DEBUG_UART_RX_QUEUE;
typedef struct {
uint8_t* Buffer; // 指针是4个字节
uint16_t Len;
}DEBUG_UART_TX_QUEUE;
typedef struct {
union {
DEBUG_UART_RX_QUEUE;
DEBUG_UART_TX_QUEUE;
};
UART_EVENT_ID EventId;
}DEBUG_UART_QUEUE;
WALL_E 发表于 2023-10-20 16:36
// 枚举一般是int型的
typedef unsigned char UART_EVENT_ID;
#define UART_RX 0
ticktype_t 是4字节的整形 2360985396 发表于 2023-10-20 16:36
结构体大小的是最大成员的整数倍,
union {
DEBUG_UART_RX_QUEUE;
但我加了__packed__也没用, //别用enum,因为它在很多编译器中是int型(4字节)
typedef enum {
UART_RX = 0,
UART_TX
}UART_EVENT_ID;
//应该这样
typedef unsigned char UART_EVENT_ID;
#define EVTID_UART_RX0
#define EVTID_UART_TX1
typedef struct {
uint16_t padding;
uint16_t Data;
TickType_t RecvTick;
}DEBUG_UART_RX_QUEUE;
typedef struct {
uint16_t padding;
uint16_t Len;
uint8_t* Buffer;
}DEBUG_UART_TX_QUEUE;
typedef union {
UART_EVENT_IDEventId;
DEBUG_UART_RX_QUEUE rx;
DEBUG_UART_TX_QUEUE tx;
} DEBUG_UART_QUEUE; sizeof(DEBUG_UART_QUEUE) is 8bytes glory 发表于 2023-10-20 17:50
sizeof(DEBUG_UART_QUEUE) is 8bytes
我想把上面的id加上,占用padding的一个字节,真好也能对齐 tangqianfeng 发表于 2023-10-20 19:29
我想把上面的id加上,占用padding的一个字节,真好也能对齐
这就已经包含EventId了呀
typedef union {
UART_EVENT_IDEventId;
DEBUG_UART_RX_QUEUE rx;
DEBUG_UART_TX_QUEUE tx;
} DEBUG_UART_QUEUE; 就这么用就是了
DEBUG_UART_QUEUE item;
switch(item.EventId){
case EVTID_UART_RX:
item.rx.Data...
item.rx.RecvTick...
break;
case EVTID_UART_TX:
item.tx.Len...
item.tx.Buffer...
break;
}
本帖最后由 tangqianfeng 于 2023-10-20 21:29 编辑
glory 发表于 2023-10-20 19:47
就这么用就是了
DEBUG_UART_QUEUE item;
switch(item.EventId){
瞬间明朗了,谢谢,像我顶楼的写法,为何在联合里定义的两个结构体加__packed__也没用? WALL_E 发表于 2023-10-20 16:36
// 枚举一般是int型的
typedef unsigned char UART_EVENT_ID;
#define UART_RX 0
你这样这个结构体的长度应该是9 tangqianfeng 发表于 2023-10-20 21:24
你这样这个结构体的长度应该是9
你编译一下,用sizeof测试一下就知道了 你把u8* 当成 u8 来对齐?
页:
[1]