tangqianfeng 发表于 2023-10-20 12:37:38

请教下如下代码要怎么样才能节省空间?

本帖最后由 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这样应该可以对齐访问的


木偶 发表于 2023-10-20 12:59:40

__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式

2360985396 发表于 2023-10-20 14:05:16

木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式

取消结构体对齐到有一定的弊端,访问结构体的速度降低了,时间换空间。也可以可以使用联合体或者位域。

tangqianfeng 发表于 2023-10-20 14:35:59

木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式

我期望的意思是最后那个DEBUG_UART_QUEUE要尽可能地少,我想表达的是那个数组原则上只需要8个字节,就能实现,而且是能对齐的操作

tangqianfeng 发表于 2023-10-20 14:37:18

2360985396 发表于 2023-10-20 14:05
取消结构体对齐到有一定的弊端,访问结构体的速度降低了,时间换空间。也可以可以使用联合体或者位域。

你说的是对的,但我最后的那个结构体,我没有实现既对齐又字节最少,

2360985396 发表于 2023-10-20 15:22:04

tangqianfeng 发表于 2023-10-20 14:37
你说的是对的,但我最后的那个结构体,我没有实现既对齐又字节最少,

结构体要最少也要看你储存的顺序比如
typedef struct in
{
    char a;
    intb;
    char c;
}aaa;
typedef struct in
{
    char a;
    char c;
    intb;
   
}aaa; 这两个大小都不一样,第一个的空间大小明显比第二个大

tangqianfeng 发表于 2023-10-20 16:25:15

2360985396 发表于 2023-10-20 15:22
结构体要最少也要看你储存的顺序比如
typedef struct in
{


你看我最后一个结构体,我这样排应该是最合理的啊, uint8,uint8,uint16,uint32,应该是都对齐的啊

2360985396 发表于 2023-10-20 16:36:49

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;多大?最大的那个就是整个联合体的大小,另外联合体大小也是要对齐的

WALL_E 发表于 2023-10-20 16:36:49

// 枚举一般是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;

tangqianfeng 发表于 2023-10-20 16:53:52

WALL_E 发表于 2023-10-20 16:36
// 枚举一般是int型的
typedef unsigned char UART_EVENT_ID;
#define UART_RX 0


ticktype_t 是4字节的整形

tangqianfeng 发表于 2023-10-20 16:54:39

2360985396 发表于 2023-10-20 16:36
结构体大小的是最大成员的整数倍,
union {
      DEBUG_UART_RX_QUEUE;


但我加了__packed__也没用,

glory 发表于 2023-10-20 17:49:40

//别用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;

glory 发表于 2023-10-20 17:50:56

sizeof(DEBUG_UART_QUEUE) is 8bytes

tangqianfeng 发表于 2023-10-20 19:29:38

glory 发表于 2023-10-20 17:50
sizeof(DEBUG_UART_QUEUE) is 8bytes

我想把上面的id加上,占用padding的一个字节,真好也能对齐

glory 发表于 2023-10-20 19:43:43

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;

glory 发表于 2023-10-20 19:47:10

就这么用就是了
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:20:55

本帖最后由 tangqianfeng 于 2023-10-20 21:29 编辑

glory 发表于 2023-10-20 19:47
就这么用就是了
DEBUG_UART_QUEUE item;
switch(item.EventId){

瞬间明朗了,谢谢,像我顶楼的写法,为何在联合里定义的两个结构体加__packed__也没用?

tangqianfeng 发表于 2023-10-20 21:24:26

WALL_E 发表于 2023-10-20 16:36
// 枚举一般是int型的
typedef unsigned char UART_EVENT_ID;
#define UART_RX 0


你这样这个结构体的长度应该是9

glory 发表于 2023-10-21 09:33:00

tangqianfeng 发表于 2023-10-20 21:24
你这样这个结构体的长度应该是9

你编译一下,用sizeof测试一下就知道了

Edmund1964 发表于 2023-10-22 16:09:54

你把u8* 当成 u8 来对齐?
页: [1]
查看完整版本: 请教下如下代码要怎么样才能节省空间?