Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
栈stack
小白求助,关于rtt 的一段源码
发布于 2022-04-26 17:05:23 浏览:1367
订阅该版
![726D57B0-D92E-43CD-B5B4-4A9AE0AAE886.jpeg](https://oss-club.rt-thread.org/uploads/20220426/960b207db01cd24959f1814bce6e2ccd.jpeg.webp) 请问这里为什么要减4呢,没有想明白
查看更多
lchnu
2022-04-26
Witness, Understand, Skill
看了这个问题,我专门去Github上找了一下RTT Release v1.2.0版本的源代码来看。 先说个人观点: 1. 堆栈有满递增,满递减、空递增、空递减4种。 2. 可能,在RTT开发的早期,主要面向递减堆栈的CPU做了移植,证据是v1.2.0中的`_rt_thread_init`甚至没有`ARCH_CPU_STACK_GROWS_UPWARD`的预编译指令。 3. 可能,在RTT开发的更早期,大神移植的第一款CPU就是支持空递减堆栈的。随着RTT的不停发展,代码更新,面向已经做好了适配的各种CPU,去修改thread.c的核心代码不太现实,`否则对于所有已经适配的CPU要重来一遍,于是成了一个历史遗留问题。` 有一种搞科研的感觉。可能这个问题得要创始人来回答了。哈哈。 - thread.c中的rt_hw_stack_init堆栈减了4,且不支持递增堆栈 ```c static rt_err_t _rt_thread_init(struct rt_thread *thread, const char *name, void (*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick) { /* init thread list */ rt_list_init(&(thread->tlist)); thread->entry = (void *)entry; thread->parameter = parameter; /* stack init */ thread->stack_addr = stack_start; thread->stack_size = (rt_uint16_t)stack_size; /* init thread stack */ rt_memset(thread->stack_addr, '#', thread->stack_size); thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter, (void *)((char *)thread->stack_addr + thread->stack_size - 4), (void *)rt_thread_exit); .... ``` - 查看cortex-m4的cpuport.c, 对栈指针加了4处理。因为m4是满递减堆栈。 ```c rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { struct stack_frame *stack_frame; rt_uint8_t *stk; unsigned long i; stk = stack_addr + sizeof(rt_uint32_t); ``` - 查看sep4020的stack.c,没有处理,因为sep4020是空递减堆栈。 ```c rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { rt_uint32_t *stk; stk = (rt_uint32_t*)stack_addr; *(stk) = (rt_uint32_t)tentry; /* entry point */ *(--stk) = (rt_uint32_t)texit; /* lr */ ```
4
个回答
默认排序
按发布时间排序
crystal266
2022-04-26
嵌入式
为什么减去 4 我也不太懂,但是在函数 `rt_hw_stack_init` 最开始又把传进去的 `stack_addr` 加上了4个字节(这一减一加是不是可以认为没操作😂),加了四字节之后按照8字节向下取整对齐。 ```c thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter, (rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)), // 减了4字节 sizeof(unsigned long) (void *)_thread_exit); ``` ```c rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { struct stack_frame *stack_frame; rt_uint8_t *stk; unsigned long i; stk = stack_addr + sizeof(rt_uint32_t); // 加上了 sizeof(rt_uint32_t),也就是4字节 stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); // 向下按照 8 字节对齐 stk -= sizeof(struct stack_frame); stack_frame = (struct stack_frame *)stk; /* init all register */ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) { ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; } stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ stack_frame->exception_stack_frame.r1 = 0; /* r1 */ stack_frame->exception_stack_frame.r2 = 0; /* r2 */ stack_frame->exception_stack_frame.r3 = 0; /* r3 */ stack_frame->exception_stack_frame.r12 = 0; /* r12 */ stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */ stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */ stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */ #if USE_FPU stack_frame->flag = 0; #endif /* USE_FPU */ /* return task's current stack address */ return stk; } ```
文武斌
2022-04-26
这家伙很懒,什么也没写!
见证历史了,哈哈哈
123
认证专家
2022-04-27
这家伙很懒,什么也没写!
也可以理解为兼容性考虑,先减去4字节 (sizeof(rt_ubase_t))作为统一的公共代码, 具体是哪种栈结构交给port层考虑: 对于空减栈来讲,cpuport直接拿stack_addr即可; 对于满减栈来讲,cpuport将stack_addr加上先前减去的4字节即可。
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
fight
吼吼
提问
2
回答
0
被采纳
0
关注TA
发私信
相关问题
1
局部变量的存储在哪段内存区域
2
内联函数不压栈,会因为中断导致栈内现场被破坏吗
3
串口输出线程输出异常
4
idle->sp被改写,导致内存溢出
5
如何在调试状态下查看线程堆栈的占用量?
6
map文件堆栈分配查看
7
请教线程堆栈的作用以及大小设置
8
如何打印出函数调用栈
9
线程初始化时栈地址为什么加4
10
rtthread中的栈设置请教?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部