void OSStart (void)

本文详细解析了RTOS启动过程中的关键步骤,包括确定最高优先级任务并进行任务切换的具体实现方式。通过对OSStart函数及OSStartHighRdy汇编程序的分析,揭示了实时操作系统初始化时如何选择并运行首个任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void  OSStart (void)
{
    INT8U y;
    INT8U x;


    if (OSRunning == FALSE) {
        y             = OSUnMapTbl[OSRdyGrp];        /* Find highest priority's task priority number   */
        x             = OSUnMapTbl[OSRdyTbl[y]];
        OSPrioHighRdy = (INT8U)((y << 3) + x);
        OSPrioCur     = OSPrioHighRdy;
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        OSTCBCur      = OSTCBHighRdy;
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}

首先判断若OSRunning 为假,注意此刻OSRunning为假。如果为假,就找出就绪表里的就绪任务的最高优先级,并放入OSPrioHighRdy 里,然后赋给表征表征当前任务优先级的变量OSPrioCur ;然后通过优先级在OSTCBPrioTbl数组里找到最高优先级的任务控制块,并把这个任务控制块交给当前任务控制块OSTCBCur管理,也就是最高优先级的任务成为了当前的任务;然后调用函数OSStartHighRdy( );     

OSStartHighRdy( )是位于OS_CPU_A.S里的一段汇编程序,代码如下:

OSStartHighRdy
 LDR  r0,=OSRunning   
 MOV  r1, #1
 STRB r1, [r0]           ;这三句指令将OSRunning设置为1
  
; LDR  r4, addr_OSTCBCur   ;这句指令源程序中作了屏蔽,和下句指令的作用是一样的
 LDR  r5, addr_OSTCBHighRdy ;把最高优先级的任务控制块的地址给了寄存器;r5=0x0c01322c

 LDR  r5, [r5]                ;r5=0x0c013404
 LDR  sp, [r5]               ;sp=0x0c016c68,sp 指向当前任务的堆栈

; STR  r5, [r4]     ;这句话源程序中被屏蔽掉

 LDMFD sp!,{r4}    ;数据出栈,放入r4中
 MSR  CPSR_cxsf, r4   ; CPSR should be SVC32Mode Panel;
    LDMFD   sp!, {r0-r12, lr, pc }  ;数据出栈,分别放入r0——r12,lr,pc寄存器中,也就是新的任务获得了cpu使                                                  使用权

下面程序就去执行获得了cpu使用权的任务。

;MSR是写状态寄存器指令,在ARM处理器中,只有MSR指令可以直接设置状态寄存器CPSR或者SPSR,cxs分别表示CPSR的0-7,8-15,16-23,24-31位。只有在特权模式下才能修改状态寄存器


 

#include "ucos_ii.h" #include "stm32f10x.h" #include <stdio.h> #include <stdlib.h> #define ITM_PORT (*(volatile unsigned char *)(0xe0000000)) #define DEMCR_ (*(volatile unsigned long *)(0xE000EDFC)) #define TRCENA_ 0X01000000 #define BufferLen 100 typedef struct { void (*task_func)(void *p_arg); void *pdata; OS_STK *ptos; INT8U prio; } TaskCreate; //char buffer[BufferLen]; uint8_t fputcp(char ch) { if(DEMCR_ & TRCENA_) { while(ITM_PORT == 0); ITM_PORT = ch; } else { return 0; } return 1; } uint8_t print_str(char *str) { uint32_t i; i = 0; while(1) { if (*(str+i) == '\0') { return 1; } if(fputcp(*(str+i))==0) { return 0; } i++; } } void *buffer; static void systick_init(void) { RCC_ClocksTypeDef rcc_clocks; RCC_GetClocksFreq(&rcc_clocks); *((uint32_t *)buffer)=rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC; SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC); } static void syscall_systick_init(void) { RCC_ClocksTypeDef rcc_clocks; RCC_GetClocksFreq(&rcc_clocks); *((uint32_t *)buffer)=rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC; __asm { SWI 0x02 } //SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC); } /*void syscall_OSIntExit() { __ASM { SWI 0x06 } }*/ /*void syscall_OSIntEnter() { __ASM { SWI 0x07 } }*/ void syscall_print_str(char *str) { int i=0; while(1) { if (*(str+i) == '\0') { ((char *)buffer)[i] = str[i]; break; } ((char *)buffer)[i] = str[i]; i++; } __ASM{ SWI 0x01 } } void syscall_OSTaskCreate(void (*task)(void *), void *pdata, OS_STK *ptos, INT8U prio) { TaskCreate *partfo = (TaskCreate *)buffer; partfo->task_func = task; partfo->pdata = pdata; partfo->ptos = ptos; partfo->prio = prio; __ASM { SWI 0x03 } } void syscall_OSTimeDly(int time) { *(int*)buffer=time; __ASM { SWI 0x04 } } void syscall_OSStart() { __ASM { SWI 0x05 } } void ASM_Switch_To_Unprivileged(void); //#define FIRST_TASK 1 #define SECOND_TASK 1 #ifdef FIRST_TASK int main(void) { buffer = malloc(BufferLen); ASM_Switch_To_Unprivileged(); syscall_print_str("Hello world!\n"); syscall_systick_init(); while(1){} } #endif #ifdef SECOND_TASK static OS_STK task1_stk[TASK1_STK_SIZE]; static OS_STK task2_stk[TASK2_STK_SIZE]; void task1(void *p_arg); void task2(void *p_arg); int main(void) { OSInit(); buffer = malloc(BufferLen); ASM_Switch_To_Unprivileged(); syscall_print_str("Hello world!\n"); syscall_systick_init(); syscall_OSTaskCreate(task1, (void *)0, &task1_stk[TASK1_STK_SIZE-1], TASK1_PRIO); syscall_OSTaskCreate(task2, (void *)0, &task2_stk[TASK2_STK_SIZE-1], TASK2_PRIO); syscall_OSStart(); return 0; } static void task1(void *p_arg) { for (;;) { syscall_OSTimeDly(100); syscall_print_str("Hello from Task 1!\n"); syscall_OSTimeDly(100); } } static void task2(void *p_arg) { for (;;) { syscall_OSTimeDly(100); syscall_print_str("Hello from Task 2!\n"); syscall_OSTimeDly(100); } } #endif /*END OF THE FILE*/
最新发布
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值