有关RT-Thread学习过程中不理解的地方

Meursault639 2022-12-29 11:20:04

在看官方文档的时候,发现出现大量如下代码,特别是这一句:

ALIGN(RT_ALIGN_SIZE)
ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;

这个应该是他的定义 部分,但是还是不懂。

    #define ALIGN(n)                    __attribute__((aligned(n))

在网上找了一下,好像是对齐用的,但是不是特别理解什么意思,而且还有,就是定义之后全局都可以对齐还是只能后一个数据对齐。

 RT-Thread-ALIGN(RT_ALIGN_SIZE)问题RT-Thread问答社区 - RT-Thread

在这段代码中就出现了两次 ,而且为什么不要分号啊啊啊啊啊啊!

 

 

...全文
2307 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
架构师李肯 2023-01-03
  • 打赏
  • 举报
回复 6

简单复刻了一段代码



#include <stdio.h>

#define RT_ALIGN_SIZE                 4

#define ALIGN(n)                    __attribute__((aligned(n)))

typedef struct rt_thread {
    int test;
} rt_thread_t;

ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static char test1[2];
static char thread2_stack[1024];
static char test2[3];
static char thread3_stack[1024];
static struct rt_thread thread1;

int main(void)
{
    printf("thread1_stack: %p\n", thread1_stack);
    printf("thread2_stack: %p\n", thread2_stack);
    printf("thread3_stack: %p\n", thread3_stack);

    return 0;
}

直接gcc编译,把预编译后的文件同步输出,看下宏定义展开后的代码长啥样:

# 9 "xxx.c"
typedef struct rt_thread {
 int test;
} rt_thread_t;

__attribute__((aligned(4)))
static char thread1_stack[1024];
static char test1[2];
static char thread2_stack[1024];
static char test2[3];
static char thread3_stack[1024];
static struct rt_thread thread1;

int main(void)
{
 printf("thread1_stack: %p\n", thread1_stack);
 printf("thread2_stack: %p\n", thread2_stack);
 printf("thread3_stack: %p\n", thread3_stack);

 return 0;
}

很明显在无语法错误的前提下,attribute((aligned(4))) 只能与最近的一行拼在一起;
即应该是 attribute((aligned(4))) static char thread1_stack[1024];

而帖子中提及,ALIGN(RT_ALIGN_SIZE) 后为何不加分号啊???

从这里就可以知道,加了分号是有语法问题的。比如gcc下报警告就是这样:

> gcc -o test xxx.c -save-temps=obj
xxx.c:13:1: warning: empty declaration
   13 | ALIGN(RT_ALIGN_SIZE);
      | ^~~~~~~~~~~~~

再来说说,这个 attribute((aligned(4))) 究竟干啥用的!
就像它的名字的含义一样,就是告诉编译器,我这个定义是要按4字节对齐的。
比如帖子中的1024字节的thread1_stack数组;在极度紧凑的时候,编译器是完全可以给你分配一个非对齐的地址的,比如0x1234587作为该数组的起始地址。
那么地址对齐与不对齐,对我们的代码究竟影响怎么样呢?
自然是有影响的,一般32位平台的处理器对4字节对齐是友好的,有些处理场景不对齐还会报 UNALIGNED的硬件异常。
曾经,我遇到一个问题就是由这个引发的。
很简单,我定义了一个128字节的字节数组,然后强制转换为一个结构体指针,通过结构体指针去访问,这种处理方式在处理通讯协议的时候很常见,
当时我的结构体定义大概是这样的:

typedef struct _test_t {
    uint8_t     u8index;
    uint16_t     u16_index;
    uint32_t     u32_index;
} test_t;

强转之后,通过指针访问u16_index就出现异常了,原理就是此时u16_index的地址可能不是一个对齐的地址,触发了硬件异常。
后面通过修饰128字节的字节数组,强制让它N字节对齐,这个问题得到解决。

Meursault639 2023-01-03
  • 举报
回复 1
@架构师李肯 感谢大佬,理解了
不爱吃香菜哦 2023-01-02
  • 打赏
  • 举报
回复

已投五星(可查记录),欢迎给五星、诚信互访:https://bbs.csdn.net/topics/611389800

Meursault639 2022-12-29
  • 打赏
  • 举报
回复 1

希望各位大佬能回答一下

趣享先生 2023-01-05
  • 举报
回复
@Meursault639 老铁,我支持你有好几天了,您还没回我,能否回个,感谢!已五星支持!!https://bbs.csdn.net/topics/611387347
Meursault639 2023-01-05
  • 举报
回复
@趣享先生 抱歉哈,没太注意这个,已经给了,谢谢啦
RT-Thread作品秀】基于stm32的简易示波器 作者:詹敏 概述(说明应用产生的背景、实现功能)简易示波器基于STM32F103芯片及自带ADC开发。可实现电压范围0-3.3V,频率范围1Hz-10kHz正弦波和方波显示,提供自动、普通以及单次三种采样模式,上升沿和下降沿两种触发方式,0~3.3V触发阀值。该系统可满足常见场合使用需求。 开发环境(所采用的软、硬件方案)硬件:stm32f103-指南者,3.2寸ILI9341液晶显示 RT-Thread版本:3.0.3 开发工具及版:MDK 5.26 RT-Thread使用情况概述(简要总结下应用RT-Thread使用情况:内核部分、组件部分、软件包部分、内核、其他)内核部分:调度器,信号量,消息队列。 调度器:创建多个线程来实现不同的工作。 信号量:用来同步线程。 消息队列:用来实现线程之间传递的数据。 硬件框架(概述应用所采用的硬件方案框图,并对核心部分做介绍)ADC采集波形发生器信号经过stm32f103芯片处理后显示到3.2寸ILI9341液晶屏。 软件框架说明(介绍应用所采用的软件方案框图、流程图等,并加以解说) 软件模块说明(介绍应用软件关键部分的逻辑、采用的实现方式等)线程: GetWave_thread:波形采样线程;根据所设置的屏幕每一格代表的时间确定采样频率,根据触发阀值和触发模式确定采样开始点,对波形进行采样保存。PlotWave_thread:波形显示线程;根据屏幕区域划分进行波形显示。 KeyScan_thread:按键扫描线程;读取按键值进行转换并发送给设置执行线程。 Setting_thread:设置操作执行线程;执行设置项修改操作并刷新显示信息。 消息队列: setting_data_queue:将按键扫描线程读取并转换后的设置信息传递给设置执行线程,以完成设置更改和显示信息刷新。 getwave_status_queue:用于波形采样线程和波形显示线程之间通信,确保采样波形及时显示刷新。 key_scan_queue:用于设置线程和按键检测线程之间通信,确保按键信号及时被读取同时避免按键检测线程占用过多资源。 演示效果(演示效果请采用3张高清图片,并录制一段不少于1min视频解说应用所实现的效果,视频上传至B站或者腾讯视频或其他视频平台,给出链接即可) 比赛感悟(可以围绕这次比赛学到了什么,克服了哪些困难,有哪些收获,不低于200字) 本次比赛信息我是通过微信公众号了解到的,看到比赛时间刚好在准备开题期间又考虑到我本身不是控制专业,所以刚开始有点打退堂鼓。但那时候也正是刚刚完成一段时间的理论学习,确实需要一个实践项目来巩固,所以最后抱着试一试的心态没有申请板卡报名了。在截止日期也勉强完成了,但由于过程匆忙,系统仍有很多不完善的地方,算是一点遗憾了。 不过,总的来说收获肯定是不小的,学习如此优秀的国产操作系统RT-Thread并用它完成了自己的作品本身这件事足以让这段时间称得上有意义了。过程也将之前所学知识应用到时间,加深了理解。虽然比赛已经结束了,后面还是会对作品进行继续优化改进。 最后感谢主办方为我们提供了一个自我锻炼的机会,学习的机会。感谢RT-Thread团队提供的优秀操作系统,后续还会继续深入学习
RT-Thread作品秀】RedClock 作者:iysheng 概述 我开发RedClock这个作品的背景主要有两个: 1.我想开发一下墨水屏,想体验下新奇的事物; 2.想在传统wifi时钟的基础上添加一个番茄时钟的功能,尝试提高工作效率,让其不单单具备提供时间和天气的功能 目前RedClock实现的功能,可以概括为4条: 1.通过墨水屏同步显示时间、天气图标(时间信息通过ntp校时,天气信息通过js语言从和风天气获取) 2.一键切换番茄时钟模式,番茄时钟的默认周期是25分钟,到实践通过屏幕提示 3.通过外接氣壓传感器lps22hh获取温度和气压信息并通過墨水屏幕 4.時間、天氣、温度和气压信息支持通过网络访问ART-Pi的设备IP同步显示 开发环境 硬件:ART-Pi、LPS22HH、SSD1619 RT-Thread版本:V4.0.3 开发工具及版本: 编译工具:arm-none-eabi-gcc、arm-none-eabi-binutils 编辑工具:vim 烧录、调试工具:openocd 0.10+ dirty(打过补丁才可以烧录程序到ART-Pi的外部flash)、kermit(串口工具)、telnet(调试工具)、gdb 硬件开发工具:Kicad(RedClock扩展板开发工具) RT-Thread使用情况概述 使用到的内核模块部分: 互斥锁、信号量、mempool、device 组件部分: cJSON、EasyFlash、webnet 软件包部分: lps22hb(传感器) 其他: 使用到的总线接口:I2C(传感器)、SPI(墨水屏) 硬件框架 软件框架说明 软件的实现设计到两个层次,设备驱动层(墨水屏驱动层开发),APP层(天气、传感器和时间的更新显示分别在不同的线程完成,线程间的数据交换通过函数完成,全局变量均为static类型,依据高内聚、低耦合分层设计理念开发) 软件模块说明 本软件主要的软件设计理念是创建多个线程,根据功能划分各个线程实现的功能: 在factory工程的基础上,添加了red_monitor_thread这个线程,完成传感器数据周期一分钟获取一次、以及更新tomato显示相关的内容。还有一个redclock_lcd_thread线程周期性的刷新屏幕,目前从屏幕寿命考虑,设置为3分钟刷新一次。还有一个线程完成对按键的扫描(目前仅仅支持番茄时钟快速切换的按键)。 考虑到为了实现一次配网,重启后自动联网,开启了easyflash保存wifi帐号和密码。联网为了消除跨域访问设备的问题,替换了原始ART-Pi的index.html文件为自己的文件,这样将对应的js和css部署在自己电脑这端完成开发和调试,借助webnet通过CGI的方式完成时间、温度、气压的上报(支持同步通过浏览器访问ART-Pi查看)和天气的下发(天气通过js连接和风天气服务获取)。 墨水屏的开发,通过注册了一个device完成,通过SPI接口访问。更新墨水瓶内容相关的动作,放在了四个函数完成(分别完成天气图标更新、时间更新]、传感器数据更新、番茄时钟状态更新), 这些函数指挥更新墨水屏显示的内容,不会刷新墨水屏显示,刷新墨水屏显示的时候,更新才会有效。 演示效果 演示视频: 圖片展示: 比赛感悟 比赛过程,我使用Kicad画了两版PCB,并作PCB然后焊接,整个开发过程大部分都是在Linux下完成的,初了开发墨水屏显示界面的时候使用了磨刀这个原型开发工具以及Image2Lcd整个软件将图片转换为C语言。 感觉自己收获最多的地方有两个方面,第一个方面当然是软件了,印象最深刻的是通过在openocd的代码仓库察看不同的branch和patch,给openocd打补丁然后修改对应的配置文件,支持直接烧录程序到ART-Pi的外部flash。通过这个工作,让我对openocd的使用有了更多的了解(通过访问openocd的网站以及看对应的manual), 这个是我最激动的。其他的软件方面就是对easyflash和webnet这两个组件有了学习,通过阅读对应的代码,学到了在32上进行KV类型的数值保存的新方法,之前我接触32保存配置数据使用的方法是从内部flash的尾部划分64KB虚拟为快设备,然后来格式化为elm文件系统,然后以cJSON格式保存,现在看来浪费了很多空间,easyflash也是我以后工作替换之前这种方案新的可取的方法。通过对Webnet的学习,我真正接触到了通过http服务,远程通过浏览器和32进行数据通讯的方法。围绕webnet, 我还真正开发了一波js和css代码,开发js代码的时候,学会了通过jquery实现post和get请求,然后ART-Pi这端通过CGI完成HTTP通讯。 硬件方面,我感觉很开心的是自己

441

社区成员

发帖
与我相关
我的任务
社区描述
物联网架构师李肯,CSDN博客专家,带你一起玩转嵌入式和物联网。
物联网嵌入式硬件51单片机 个人社区 广东省·深圳市
社区管理员
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

物联网架构师李肯,CSDN博客专家,带你一起玩转嵌入式和物联网。

试试用AI创作助手写篇文章吧