yjmwxwx 发表于 2017-9-2 23:15:59

想学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                        @ 返回

yjmwxwx 发表于 2017-9-2 23:24:17

高亮显示执行结果
0X20000704是空闲任务执行次数
0x20000700是任务1执行次数



程序文件




雪冬 发表于 2017-9-3 10:03:04

据说RTOS价格昂贵,比如VxWorks,要上数百万元。不过,要适合多种CPU,就要用高级语言编写。期待楼主更成熟的RTOS。

zystbbs 发表于 2017-9-3 10:51:04

汇编难度大,但代码精练,执行效率高。

Paktu 发表于 2017-9-3 11:08:22

还是用FreeRTOS吧,完全免费的。

yjmwxwx 发表于 2017-9-3 11:39:00

la45088d1 发表于 2017-9-3 09:26
你可以自己写一个操作系统,没问题。但是,一,你对操作系统了解有多少,涉及到很多的概念还有许多技巧,没 ...

没打算搞操作系统原理还不懂呢,就算操作系统再好也打不了坦克打不了飞机。

还是学实物的东西好,比如电机和液压控制,单片机上挂上个操作系统除了多占用资源有啥用

yjmwxwx 发表于 2017-9-3 11:41:03

雪冬 发表于 2017-9-3 10:03
据说RTOS价格昂贵,比如VxWorks,要上数百万元。不过,要适合多种CPU,就要用高级语言编写。期待楼主更成熟 ...

搞不出来啊,原理动不懂得。 还是想学实物的东西,能代替人干活的东西

yangsen 发表于 2017-9-3 11:43:49

用汇编当然可以做RTOS,avrx就是用汇编写的。汇编的最大问题是移植性不好,所以主流的跨平台rtos的实现都是用C实现的,只有一小部分依赖平台的用汇编。现在网络这么发达,楼主可以参考ucos,freertos的实现,这些都是开源的,当然感兴趣也可以找avrx这类的参考一下任务调度,切换是如何实现的。

yjmwxwx 发表于 2017-9-3 11:44:10

Paktu 发表于 2017-9-3 11:08
还是用FreeRTOS吧,完全免费的。

感觉太复杂没打算用就是研究下玩玩,还是感觉裸机好

yjmwxwx 发表于 2017-9-3 11:47:04

yangsen 发表于 2017-9-3 11:43
用汇编当然可以做RTOS,avrx就是用汇编写的。汇编的最大问题是移植性不好,所以主流的跨平台rtos的实现都是 ...

已经放弃了,感觉没什么用

yjmwxwx 发表于 2017-9-3 11:51:07

la45088d1 发表于 2017-9-3 10:00
我说大哥,磨刀不误砍柴工,你先把该学的学了好吗,推荐一本书:

嘿嘿 其实ARM汇编的书还真一本没看过,看过的一本叫 汇编语言程序设计(美)布鲁姆 著,马朝晖 等译

yjmwxwx 发表于 2017-9-3 17:20:43

la45088d1 发表于 2017-9-3 15:53
呵呵,老兄,这回你就真的太自大了。且不说为什么那么多的嵌入式操作系统面世,而且版权不菲;就是你搞一 ...

我本来就是外行啊,我专业是种地的也就会打农药,地我都种不好,我是村里出名的懒人。

村里人电脑装个系统都不相信我,尽管我都是免费帮他们。


vonRundstedt 发表于 2017-9-3 21:06:44

yjmwxwx 发表于 2017-9-3 23:22:14

vonRundstedt 发表于 2017-9-3 21:06
简单的东西当然不需要RTOS,复杂的项目不上RTOS不行。比如FATFS和TCPIP协议栈里面大量delay,你要是用死循 ...

确实啊我只会写点简单小程序所以感觉没用,网络什么一点也不懂。。

页: [1]
查看完整版本: 想学RTOS,看着介绍不错,能用汇编写吗?