硬汉嵌入式论坛

 找回密码
 立即注册
查看: 644|回复: 19
收起左侧

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

[复制链接]

59

主题

282

回帖

459

积分

高级会员

积分
459
发表于 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_t  RecvTick;
}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这样应该可以对齐访问的


回复

使用道具 举报

2

主题

33

回帖

39

积分

新手上路

积分
39
发表于 2023-10-20 12:59:40 | 显示全部楼层
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式
回复

使用道具 举报

22

主题

66

回帖

132

积分

初级会员

积分
132
发表于 2023-10-20 14:05:16 | 显示全部楼层
木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式

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

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 14:35:59 | 显示全部楼层
木偶 发表于 2023-10-20 12:59
__attribute__((packed))
取消结构体的内存对齐,使用紧凑方式

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

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 14:37:18 | 显示全部楼层
2360985396 发表于 2023-10-20 14:05
取消结构体对齐到有一定的弊端,访问结构体的速度降低了,时间换空间。也可以可以使用联合体或者位域。

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

使用道具 举报

22

主题

66

回帖

132

积分

初级会员

积分
132
发表于 2023-10-20 15:22:04 | 显示全部楼层
tangqianfeng 发表于 2023-10-20 14:37
你说的是对的,但我最后的那个结构体,我没有实现既对齐又字节最少,

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

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 16:25:15 | 显示全部楼层
2360985396 发表于 2023-10-20 15:22
结构体要最少也要看你储存的顺序比如
typedef struct in
{

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

使用道具 举报

22

主题

66

回帖

132

积分

初级会员

积分
132
发表于 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;多大?最大的那个就是整个联合体的大小,另外联合体大小也是要对齐的
回复

使用道具 举报

9

主题

81

回帖

113

积分

初级会员

积分
113
发表于 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_t  RecvTick;        // ??什么类型
}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;

回复

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 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字节的整形
回复

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 16:54:39 | 显示全部楼层
2360985396 发表于 2023-10-20 16:36
结构体大小的是最大成员的整数倍,
union {
        DEBUG_UART_RX_QUEUE;

但我加了__packed__也没用,
回复

使用道具 举报

3

主题

335

回帖

344

积分

高级会员

积分
344
发表于 2023-10-20 17:49:40 | 显示全部楼层
[C] 纯文本查看 复制代码
//别用enum,因为它在很多编译器中是int型(4字节)
typedef enum {
    UART_RX = 0,
    UART_TX
}UART_EVENT_ID;
//应该这样
typedef unsigned char UART_EVENT_ID;
#define EVTID_UART_RX  0
#define EVTID_UART_TX  1

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_ID  EventId;
  DEBUG_UART_RX_QUEUE rx;
  DEBUG_UART_TX_QUEUE tx;
} DEBUG_UART_QUEUE;
回复

使用道具 举报

3

主题

335

回帖

344

积分

高级会员

积分
344
发表于 2023-10-20 17:50:56 | 显示全部楼层
sizeof(DEBUG_UART_QUEUE) is 8bytes
回复

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 19:29:38 | 显示全部楼层
glory 发表于 2023-10-20 17:50
sizeof(DEBUG_UART_QUEUE) is 8bytes

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

使用道具 举报

3

主题

335

回帖

344

积分

高级会员

积分
344
发表于 2023-10-20 19:43:43 | 显示全部楼层
tangqianfeng 发表于 2023-10-20 19:29
我想把上面的id加上,占用padding的一个字节,真好也能对齐

这就已经包含EventId了呀
[C] 纯文本查看 复制代码
typedef union {
  UART_EVENT_ID  EventId;
  DEBUG_UART_RX_QUEUE rx;
  DEBUG_UART_TX_QUEUE tx;
} DEBUG_UART_QUEUE;
回复

使用道具 举报

3

主题

335

回帖

344

积分

高级会员

积分
344
发表于 2023-10-20 19:47:10 | 显示全部楼层
就这么用就是了
[C] 纯文本查看 复制代码
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[0]...
  break;
}
回复

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 2023-10-20 21:20:55 | 显示全部楼层
本帖最后由 tangqianfeng 于 2023-10-20 21:29 编辑
glory 发表于 2023-10-20 19:47
就这么用就是了
[mw_shl_code=c,true]DEBUG_UART_QUEUE item;
switch(item.EventId){

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

使用道具 举报

59

主题

282

回帖

459

积分

高级会员

积分
459
 楼主| 发表于 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
回复

使用道具 举报

3

主题

335

回帖

344

积分

高级会员

积分
344
发表于 2023-10-21 09:33:00 | 显示全部楼层
tangqianfeng 发表于 2023-10-20 21:24
你这样这个结构体的长度应该是9

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

使用道具 举报

0

主题

124

回帖

124

积分

初级会员

积分
124
发表于 2023-10-22 16:09:54 | 显示全部楼层
你把u8* 当成 u8 来对齐?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 05:02 , Processed in 0.295788 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表