想学RTOS,看着介绍不错,能用汇编写吗?
前面有个前辈说学高级单片机要向RTOS方向发展,我百度搜了一下感觉不错啊,写程序比裸机编程容易。这个要怎么学啊,不会C语言能不能学,我看别的论坛的发的那些东西完全看不懂,感觉好复杂啊。
焊接电路搞实物成本太高,玩玩写程序也就浪费个电钱,贴出来这两天搞的个小程序。
自己瞎写个简单多任务调度, 目前创建了两个任务,一个空闲任务一直保持就绪状态,另一个每隔一段时间执行一次。
我这个是完全手打的不是网上抄袭的也不是反汇编的, 修改了上百次才成功
单片机还是STM32F030F4P6,系统时钟8M,程序占用476字节储存空间
@ stm32f030f4p6 asm
@ os
.thumb
.syntax unified
.section .data
.equ duizhanding, 0x20001000 @ 堆栈顶
.equ dqrwyxj, 0x20000044 @ 当前任务优先级
.equ xtzgyxj, 0x20000048 @ 系统里最高优先级
.equ dangqian, 0x2000004c @ 当前任务指向控制块里指针
.equ dengyunxing, 0x20000050 @ 待运行任务指向控制块里指针
.equ jiuxubiao, 0x20000054 @ 就绪查找表8个任务
@ 保留0X20
.equ renwubiao, 0x20000074 @ 指向任务控制块地址的指针表
@保留0x20
.equ renwukongzhikuai,0x20000094 @ 任务控制块地址
@每个控制块4个数据,+0堆栈顶,+4任务时间,+8优先级,+C
.equ renwuduizhan, 0x20000500 @ 任务堆栈顶
.section .text
vectors: @向量表
.word duizhanding
.word _start + 1 @复位向量
.word _nmi_handler + 1
.word _hard_fault+ 1
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word _svc + 1
.word 0
.word 0
.word _pendsvzhongduan + 1
.word _systickzhongduan + 1
_start:
_shizhong: @时钟设置
ldr r2, = 0x40022000 @FLASH访问控制
movs r1, # 0x32
str r1,
ldr r0, = 0x40021000 @ rcc
@0x34时钟控制寄存器 2 (RCC_CR2)
movs r1, # 0x01
str r1, @ HSI开14M时钟
_dengdai14mshizhongwending: @等14M时钟稳定
ldr r1,
lsls r1, r1, # 30 @ 左移30位
bpl _dengdai14mshizhongwending@ 等待14M时钟稳定
_neicunqingling: @ 0x1000的内存清零
@ 1K=1024BIT=0X400
ldr r0, = 0x20000000
movs r1, # 0
ldr r3, = 0x1000
_neicunqinglingxunhuan: @ 内存清零循环
subs r3, # 4
str r1,
bne _neicunqinglingxunhuan @
_systick: @ systick定时器初始化
@ 0xe000ed20 30-31 youxianji
@ 22-23 PENDSV
ldr r0, = 0xe000ed20
ldr r1, = 0x00c00000
str r1, @设置优先级
ldr r0, = 0xe000e010
ldr r1, = 100
str r1,
str r1,
movs r1, # 0x07
str r1,
_renwuchushihua1: @ 空闲任务初始化
ldr r0, = renwuduizhan @ 任务堆栈顶
ldr r1, = _kongxianrenwu @ 空闲任务地址
adds r1, r1, # 1 @ +1进入thumb
ldr r2, = 0x01000000 @ xpsr
movs r3, # 0
mov r7, r2 @ pc
mov r6, r1
mov r5, r3
mov r4, r3
mov r12, sp @ 当前堆栈指针放到R12
mov sp, r0 @ 当前堆栈指针等于任务堆栈顶
push {r0-r7} @ 把刚才数据保存到任务堆栈
push {r4-r7}
ldr r0, = renwukongzhikuai @ 任务控制块地址
ldr r1, = renwuduizhan @ 任务堆栈顶
str r1, @ 空闲任务的堆栈顶写到任务控制块
ldr r1, = renwubiao @ 任务表
str r0, @ 把任务控制块地址写到任务表
_renwu1chushihua: @ 同上面一样,只是地址偏移
ldr r0, = renwuduizhan
ldr r1, = 0x100
subs r0, r0, r1
ldr r1, = _renwu1
adds r1, r1, # 1
ldr r2, = 0x01000000
movs r3, # 0
mov r7, r2
mov r6, r1
mov r5, r3
mov r4, r3
mov sp, r0
push {r0-r7}
push {r0-r3}
ldr r0, = renwukongzhikuai
ldr r1, = renwuduizhan
ldr r2, = 0x100
subs r1, r2
adds r0, # 0x10
str r1,
ldr r1, = renwubiao
str r0,
ldr r0, = jiuxubiao @ 就绪表
movs r1, # 1
str r1, @ 空闲任务一直就绪
str r1, @ 任务1就绪
mov sp, r12 @ 恢复堆栈指针
movs r0, # 0
msr psp, r0 @ PSP清零
bl _diaodu @ 自动调度
_dddd:
b _dddd
_kongxianrenwu: @ 空闲任务
ldr r0, = 0x100 @ 任务1延时时间
bl _renwushijian @ 判断任务1到没到,到了执行调度
ldr r0, = 0x20000704 @ 空闲任务执行次数
ldr r1,
adds r1, r1, # 4
str r1,
b _kongxianrenwu
_renwu1:
ldr r0, = jiuxubiao @ 就绪表
movs r1, # 0
str r1, @ 任务1放开CPU
ldr r0, = 0x20000700 @ 任务1执行次数
ldr r1,
adds r1, r1, # 1
str r1,
bl _diaodu @ 调度
b _renwu1
_renwushijian: @ 任务多长时间执行一次
ldr r2, = renwukongzhikuai @ 任务控制块
ldr r1, @ 读出任务1时间
cmp r1, r0 @ 等不等于R0
bls _renwushijianfanhui @ 小于返回
ldr r0, = jiuxubiao @ 大于执行我
movs r1, # 1
str r1, @ 就绪表里面任务1写1表示就绪
movs r1, # 0
str r1, @ 清零任务1时间
b _diaodu @ 调度
_renwushijianfanhui:
bx lr
_diaodu:
ldr r0, = jiuxubiao @就绪表
movs r1, # 0x08 @ 8个任务, 每个任务用32位表示
lsls r1, # 2 @ R1等于32
_zhaozuigao: @ 从高开始减,找最高优先级任务
subs r1, r1, # 4
ldr r2,
cmp r2, # 1
bne _zhaozuigao @循环找,由于空闲任务一直就绪
@没有别的任务就执行空闲的
_zhaodaozuigao: @ 找到了最高优先级的了
ldr r0, = renwubiao @ 任务表
adds r0, r1 @ 任务表指针偏移
ldr r2, = dengyunxing @ 等运行
str r0, @ 任务表偏移指针写道等运行
ldr r0, = 0xe000ed04 @ 触发pendsv中断
ldr r1, = 0x10000000
str r1,
bx lr
_nmi_handler:
bx lr
_hard_fault:
bx lr
_svc:
bx lr
_pendsvzhongduan: @PENDSV中断
cpsid i @ 关中断
mrs r0, psp @ 读PSP当前地址到R0
cmp r0, # 0 @ r0和0比较
beq _qiehuanrenwu @ 等于0执行任务切换
mov r12, sp @ 堆栈指针保存到R12
mov sp, r0 @ SP等于r0
push {r4-r7} @ 把R4-R7保存到堆栈最低四个32位
_qiehuanrenwu: @ 切换任务
ldr r0, = dangqian @ 当前任务指针
ldr r1, = dengyunxing @ 等待运行指针
ldr r2, @ 取出任务表里的指针
str r2, @ 任务表里的指针写到待运行指针
ldr r0, @ R0等于任务控制块地址表
ldr r0, @ 取出任务堆栈顶
subs r0, # 0x30 @ R0等于堆栈底
mov sp, r0 @ SP等于R0
pop {r4-r7} @ 弹出R4-R7
mov r1, lr @ lr写到R1
movs r2, # 0x04 @ R2等于0X04 选择LR第2位
orrs r1, r2 @ R1或R2
mov lr, r1 @ 写回到LR
mov r0, sp @ R0等于堆栈底加0X10
msr psp, r0 @ 写到PSP
mov sp, r12 @ 恢复SP
cpsie i @ 开中断
bx lr @ 返回
_systickzhongduan:
ldr r0, = 0xe0000d04
ldr r1, = 0x02000000
str r1, @ 清除SYSTICK中断
ldr r0, = renwukongzhikuai @ 任务控制块
ldr r1, @ 任务1的任务时间
adds r1, r1, # 1 @ 加1
str r1, @ 写回去
bx lr @ 返回
高亮显示执行结果
0X20000704是空闲任务执行次数
0x20000700是任务1执行次数
程序文件
据说RTOS价格昂贵,比如VxWorks,要上数百万元。不过,要适合多种CPU,就要用高级语言编写。期待楼主更成熟的RTOS。 汇编难度大,但代码精练,执行效率高。 还是用FreeRTOS吧,完全免费的。 la45088d1 发表于 2017-9-3 09:26
你可以自己写一个操作系统,没问题。但是,一,你对操作系统了解有多少,涉及到很多的概念还有许多技巧,没 ...
没打算搞操作系统原理还不懂呢,就算操作系统再好也打不了坦克打不了飞机。
还是学实物的东西好,比如电机和液压控制,单片机上挂上个操作系统除了多占用资源有啥用 雪冬 发表于 2017-9-3 10:03
据说RTOS价格昂贵,比如VxWorks,要上数百万元。不过,要适合多种CPU,就要用高级语言编写。期待楼主更成熟 ...
搞不出来啊,原理动不懂得。 还是想学实物的东西,能代替人干活的东西 用汇编当然可以做RTOS,avrx就是用汇编写的。汇编的最大问题是移植性不好,所以主流的跨平台rtos的实现都是用C实现的,只有一小部分依赖平台的用汇编。现在网络这么发达,楼主可以参考ucos,freertos的实现,这些都是开源的,当然感兴趣也可以找avrx这类的参考一下任务调度,切换是如何实现的。 Paktu 发表于 2017-9-3 11:08
还是用FreeRTOS吧,完全免费的。
感觉太复杂没打算用就是研究下玩玩,还是感觉裸机好 yangsen 发表于 2017-9-3 11:43
用汇编当然可以做RTOS,avrx就是用汇编写的。汇编的最大问题是移植性不好,所以主流的跨平台rtos的实现都是 ...
已经放弃了,感觉没什么用 la45088d1 发表于 2017-9-3 10:00
我说大哥,磨刀不误砍柴工,你先把该学的学了好吗,推荐一本书:
嘿嘿 其实ARM汇编的书还真一本没看过,看过的一本叫 汇编语言程序设计(美)布鲁姆 著,马朝晖 等译
la45088d1 发表于 2017-9-3 15:53
呵呵,老兄,这回你就真的太自大了。且不说为什么那么多的嵌入式操作系统面世,而且版权不菲;就是你搞一 ...
我本来就是外行啊,我专业是种地的也就会打农药,地我都种不好,我是村里出名的懒人。
村里人电脑装个系统都不相信我,尽管我都是免费帮他们。
vonRundstedt 发表于 2017-9-3 21:06
简单的东西当然不需要RTOS,复杂的项目不上RTOS不行。比如FATFS和TCPIP协议栈里面大量delay,你要是用死循 ...
确实啊我只会写点简单小程序所以感觉没用,网络什么一点也不懂。。
页:
[1]