




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于UC/OS-II的移植网上介绍的已经很多了,比较流行的几款处理器(例如ARM)在网上都可以直接下载移植好的代码。由于最近选修了一门嵌入式系统的课,用的处理器是EPSON公司的S1C33系列,做实验的时候要进行操作系统的移植,这个周末花了一天半的时间学习了一下,因为毕业设计的时候做过ARM上的移植,于是将两者比较了一下,给出一般的移植要点。由于将来实验还要设计到GUI的移植以及文件系统的移植和网络协议的移植,我会将自己的学习笔记都记录下来。大家下载到源码后,针对Intel 80x86的代码在uCOS-IIIx86L目录下。代码是80x86实模式,且在编译器大模式下编译的。移植部分的代码可在下述文件中找到:OS_CPU.H, OS_CPU_C.C, 和 OS_CPU_A.ASM。大家可以参考这个例子,对它进行修改。INCLUDES.H 是主头文件,在所有后缀名为.C的文件的开始都包含INCLUDES.H文件。使用INCLUDES.H的好处是所有的.C文件都只包含一个头文件,程序简洁,可读性强。缺点是.C文件可能会包含一些它并不需要的头文件,额外的增加编译时间。与优点相比,多一些编译时间还是可以接受的。用户可以改写INCLUDES.H文件,增加自己的头文件,但必须加在文件末尾。/一、(1)OS_CPU.H文件的移植 (针对S1C33209)/OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT /全局变量#else#define OS_CPU_EXT extern#endif/由于不同的处理器有不同的字长,C/OS-II的移植需要重新定义一系列的数据结构。这部分是和处理器相关的.typedef unsigned char BOOLEAN;typedef unsigned char INT8U;typedef signed char INT8S;typedef unsigned short INT16U;typedef signed short INT16S;typedef unsigned int INT32U;typedef signed int INT32S;/因为没有浮点运算所以删掉typedef unsigned int OS_STK;/定义 堆栈的 宽度为 16位typedef unsigned int OS_CPU_SR;/定义 状态寄存器的宽度为16位/下面的部分主要是为了和UC/OS 第一版的兼容#define BYTE INT8S#define UBYTE INT8U#define WORD INT16S#define UWORD INT16U#define LONG INT32S#define ULONG INT32U/与其他实时系统一样,C/OS-II在进入系统临界代码区之前要关闭中断,等到退出临界区后再打开。从而保护核心数据不被多任务环境下的其他任务或中断破坏。Borland C/C+支持嵌入汇编语句,所以加入关闭/打开中断的语句是很方便的。C/OS-II定义了两个宏用来关闭/打开中断:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。下面定义了三种方法,具体的可以查阅相关书籍./#define OS_CRITICAL_METHOD 2 /使用第二种方法/#if OS_CRITICAL_METHOD = 1 /第一种方法,由于没有用到,我们不用去修改,可以注释掉#define OS_ENTER_CRITICAL() asm CLI#define OS_EXIT_CRITICAL() asm STI#endif/#if OS_CRITICAL_METHOD = 2 /第二种方法,这个是我们用到的,要修改,一般用汇编写,根据各个处理器的不同而不同,下面是S1C33系列的汇编#define OS_ENTER_CRITICAL()asm( ld.w %r4, %psr);asm( xld.w %r5, 0xffffffef);asm( and %r4, %r5);/关中断,保持状态寄存器的其它状态不变asm( ld.w %psr, %r4);#define OS_EXIT_CRITICAL()asm( ld.w %r4, %psr);asm( or %r4, 0b10000);asm( ld.w %psr, %r4); /开中断,保持状态寄存器的其它状态不变#endif/#if OS_CRITICAL_METHOD = 3 /第三种方法,由于没有用到,我们不用去修改,可以直接注视掉#define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR()#define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr)#endif/#define OS_STK_GROWTH 1 /堆栈的增长方向,由高相低,这个也是和处理器相关的,有的处理器堆栈是由低向高变,只要定义为零即可/在 C/OS-II中, 就绪任务的堆栈初始化应该模拟一次中断发生后的样子,堆栈中应该按进栈次序设置好各个寄存器的内容。OS_TASK_SW()函数模拟一次中断过程,在中断返回的时候进行任务切换。中断服务程序(ISR)(也称为例外处理过程)的入口点必须指向汇编函数OSCtxSw(),参看文件OS_CPU_A.ASM.在中断向量表vector.c的代码中修改向量表如下 (unsigned long) OSCtxSw, / 48 12 software exception 0/#define uCOS 0#define OS_TASK_SW() asm( int 0); / /使用零号中断来进行任务切换/可以注释掉,主要是用于在PC机上模拟时钟节拍OS_CPU_EXT INT8U OSTickDOSCtr; /全局变量/可以注释掉#if OS_CRITICAL_METHOD = 3OS_CPU_SR OSCPUSaveSR(void);void OSCPURestoreSR(OS_CPU_SR cpu_sr);#endif/(2)OS_CPU.H文件的移植 (针对ARM核的S3C44BOX )/typedef unsigned char BOOLEAN;typedef unsigned char INT8U; /*8位无符号整数*/typedef signed char INT8S; /*8位有符号整数*/typedef unsigned short INT16U; /*16位有符号整数*/typedef signed short INT16S; /*16位无符号整数*/typedef unsigned long INT32U; /*32位无符号整数*/typedef signed long INT32S; /*32位有符号整数*/typedef float FP32; /*单精度浮点数*/typedef double FP64; /*双精度浮点数*/typedef unsigned int OS_STK;/*堆栈入口宽度为16位*/与ARM处理器相关的代码:/具体的实现见第二步, 在OS_CPU_A.ASM中实现#define OS_ENTER_CRITICAL () ARMDisableInt() /*关中断在OS_CPU.A.S中定义,可以参 考下面的程序*/#define OS_EXIT_CRITICAL () ARMEnableInt() /*开启中断*/#define OS_STK_GROWTH 1 /*堆栈由高地址向低地址增长*/定义宏OS_TASK_SW(),这个宏实际上被定义为os_CPU_a.s中的函数OSCtxSw()。由此可以了解OSCtxSw()的任务:保存当前任务上下文,装入新任务上下文。这里并没有用到模拟软中断#define OS_TASK_SW OSCtxSw/ Definitions specific to ARM/uHAL#define SVC32MODE 0x13/定义空闲任务堆栈的大小,可以不用定义这部分#define SEMIHOSTED_STACK_NEEDS 1024/ idle task stack size (words)#ifdef SEMIHOSTED#define OS_IDLE_STK_SIZE (32+SEMIHOSTED_STACK_NEEDS)#else#define OS_IDLE_STK_SIZE 32#endif/ defined in os_cpu_a.s 声明这些函数,在后面都有所定义extern void OSCtxSw(void); / task switch routineextern void OSIntCtxSw(void); / interrupt context switchextern void ARMDisableInt(void); / disable global interruptsextern void ARMEnableInt(void); / enable global interruptsextern void OSTickISR(void); / timer interrupt routine/二、(1)OS_CPU.A.S文件的移植 (针对S1C33209)/C/OS-II 的移植需要用户改写OS_CPU_A.ASM中的四个函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()/该函数由SStart()函数调用,功能是运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OSInit(),并且已经至少创建了一个任务(请参考OSTaskCreate()和OSTaskCreateExt()函数)。OSStartHighRdy()默认指针OSTCBHighRdy指向优先级最高就绪任务的任务控制块(OS_TCB)(在这之前OSTCBHighRdy已由OSStart()设置好了)。OSTCBHighRdy-OSTCBStkPtr指向的是任务堆栈的顶端OSStartHighRdy:xcall OSTaskSwHook /调用OSTaskSwHook ,此时OSRunning为FALSEld.w %r4, 0x1xld.w %r5, OSRunningxld.b %r5, %r4 /使OSRunning的状态为TRUE ,以后调用OSTaskSwHook时会先保存寄存器再恢复xld.w %r5, OSTCBHighRdy;ld.w %sp, %r5;/得到最高优先级任务的堆栈指针xld.w %r4, %sp+0x0;ld.w %sp, %r4;/偏移量为0popn %r15 /恢复r15-r0,这个是S1C33209的汇编语句reti; /返回,此命名执行时,处理器会自动恢复PC和状态寄存器的值,至此新任务/OSCtxSw()是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw())。它通过执行一条软中断的指令来实现任务切换。软中断向量指向OSCtxSw()。在C/OS-II中,如果任务调用了某个函数,而该函数的执行结果可能造成系统任务重新调度(例如试图唤醒了一个优先级更高的任务),则在函数的末尾会调用OSSched(),如果OSSched()判断需要进行任务调度,会找到该任务控制块OS_TCB的地址,并将该地址拷贝到OSTCBHighRdy,然后通过宏OS_TASK_SW()执行软中断进行任务切换。注意到在此过程中,变量OSTCBCur始终包含一个指向当前运行任务OS_TCB的指针。大部分解释同上,只是多了寄存器的保存这一段。OSCtxSw:xcall OSTaskSwHook /中断时,PC和寄存器的值S1C33209处理器已经自动保存了pushn %r15;/ Save current tasks contextxld.w %r4, OSTCBCur;/指向当前的运行任务ld.w %r5, %sp; Save the SP to R5ld.w %sp, %r4;/ 保存当前任务的堆栈指针ld.w %sp+0x0, %r5 ; /Save the SP to OSTCBCurxld.w %r4, OSTCBHighRdy ; /OSTCBCur = OSTCBHighRdyxld.w %r5, OSTCBCur;ld.w %r5, %r4 ;xld.w %r4, OSPrioHighRdy; /OSPrioCur = OSPrioHighRdy,把任务优先级也保存xld.w %r5, OSPrioCur ;ld.b %r5, %r4xld.w %r4, OSTCBCur;/载入新的任务ld.w %sp, %r4ld.w %r5, %sp+0x0;/恢复新任务的堆栈ld.w %sp, %r5popn %r15 ;reti ; /运行新的任务/在C/OS-II中,由于中断的产生可能会引起任务切换,在中断服务程序的最后会调用OSIntExit()函数检查任务就绪状态,如果需要进行任务切换,将调用OSIntCtxSw()。所以OSIntCtxSw()又称为中断级的任务切换函数。由于在调用OSIntCtxSw()之前已经发生了中断,OSIntCtxSw()将默认CPU寄存器已经保存在被中断任务的堆栈中了。因此在中断服务程序中要保存寄存器,PC和状态寄存器的值已经被处理器自动保存。OSIntCtxSw()大部分程序和OSCtxSw()相同只是不用保存寄存器,它也可直接用OSCtxSw()来实现OSIntCtxSw:xcall OSTaskSwHook ; /Call user defined task switch hookxld.w %r4, OSTCBHighRdy ;/ OSTCBCur = OSTCBHighRdyxld.w %r5, OSTCBCur ;ld.w %r5, %r4 ;xld.w %r4, OSPrioHighRdy ; /OSPrioCur = OSPrioHighRdy,把任务优先级也保存xld.w %r5, OSPrioCur ;ld.b %r5, %r4xld.w %r4, OSTCBCur /载入新的任务ld.w %sp, %r4ld.w %r5, %sp+0x0ld.w %sp, %r5popn %r15 ;reti /Return to new task/和C/OS-II中的其他中断服务程序一样,OSTickISR()首先在被中断任务堆栈中保存CPU寄存器的值,然后调用OSIntEnter()。C/OS-II要求在中断服务程序开头调用OSIntEnter(),其作用是将记录中断嵌套层数的全局变量OSIntNesting加1。如果不调用OSIntEnter(),直接将OSIntNesting加1也是允许的。OSTickISR()调用OSTimeTick(),检查所有处于延时等待状态的任务,判断是否有延时结束就绪的任务。在OSTickISR()的最后调用OSIntExit(),如果在中断中(或其他嵌套的中断)有更高优先级的任务就绪,并且当前中断为中断嵌套的最后一层。OSIntExit()将进行任务调度。注意如果进行了任务调度,OSIntExit()将不再返回调用者,而是用新任务的堆栈中的寄存器数值恢复CPU现场,然后用IRET实现任务切换。如果当前中断不是中断嵌套的最后一层,或中断中没有改变任务的就绪状态,OSIntExit()将返回调用者OSTickISR(),最后OSTickISR()返回被中断的任务。如果编译器支持C语言和汇编的混合编程,则这段代码可以放到OS_CPU_C.C中,针对S1C33209的移植这部分放在OS_CPU_C.C中。为了连续性就在这里顺便写吧。void OSTickISR() asm( pushn %r15);/保存中断的任务的寄存器/在这个移植中以8位定时器TIME2 作为时钟节拍,2MS发生一次中断,在中断向量表vector.c 中在timer2的入口地址处放入(unsigned long)OSTickISR, 发生中断后程学将会跳到此程序处执行。*(volatile unsigned char*)0x40285 |= 0x04; / 清除timer2的中断标志位 OSIntEnter();/处理中断嵌套曾数的增加也可以直接 给OSIntNesting加一 if (OSIntNesting = 1) asm( ld.w %r4, %sp);/如果嵌套层数为1 则在当前的任务控制块中保存堆栈指针 asm( xld.w %r10, OSTCBCur); asm( ld.w %sp, %r10); asm( ld.w %sp+0x0, %r4); asm( ld.w %sp, %r4); OSTimeTick(); / 给等待延迟时间的任务的参数减1OSIntExit(); /调用这个函数,如果ISR使更高优先级的任务进入就绪态或者ISR脱离 / 了中断嵌套,则此函数不会返回,而是由进行中断级任务切换,否/此函数返回OSTickISR,然后恢复寄存器 asm( popn %r15);/恢复寄存器 asm( reti);/返回中断的任务继续运行/为了更清楚一点这里面的过程,顺便付上这里用到TIMER2 的程序,最好有个感性的认识这部分程序应该在驱动程序里或者放在初始化程序里。始终节拍中断的启动(定时器2的启动)应该放在OSStart()运行之后,但是OSStart()不会返回,所以应该放在OSStart()之前建立的任务中的优先级最高的任务中启动,如果放在 OSInit()和OSStart() 之间启动,程序容易崩溃。/* Prototype */void init_timer(void);void Start_Timer(void);/定时器2 的初始化,完成定时时间等一下设置,每隔2ms发生一次的中断void init_timer(void)*(volatile unsigned char *)0x4014E |= 0x0F;*(volatile unsigned char *)0x40169 = 0x92;/*(volatile unsigned char *)0x40168 |= 0x02;*(volatile unsigned char *)0x40285 &= 0xFB;*(volatile unsigned char *)0x40275 |= 0x04;/启动定时器2void Start_Timer(void) *(volatile unsigned char*)0x40168 |= 0x01;/(2)OS_CPU.A.S文件的移植 (针对ARM核的S3C44BOX )/C/OS-II 的移植需要用户改写OS_CPU_A.ASM中的四个函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()同时对于ARM的开关中断(ARMEnableInt,ARMDisableInt)的定义也是放在这个文件下的关于ARM的程序就不用解释那么清楚了,相信英文大家都能看懂,也可以参考上面的程序实现的功能都是相同的/EXPORT OSStartHighRdy IMPORT OSTaskSwHook IMPORT OSTCBHighRdy IMPORT OSRunningOSStartHighRdy BL OSTaskSwHook /Call user-defined hook function LDR r4,=OSRunning / Indicate that multitasking has started MOV r5, #1 STRB r5, r4 / OSRunning = true LDR r4, =OSTCBHighRdy / Get highest priority task TCB address LDR r4, r4 / get stack pointer LDR sp, r4 / switch to the new stackLDMFD sp!, r4 ;/ CPSR特殊,只能用MRS或MSR在寄存器间操作 MSR cpsr_cxsf, r4 /从r4中恢复cpsr/SVC模式下ARM处理器不会自动保存PC的所以需要自己保存和恢复 LDMFD sp!, r0-r12,lr,pc ; pop new task s r0-r12,lr & pc/ EXPORT OSCtxSw /这个函数别的文件要用 IMPORT OSPrioCur /这是在别的文件定义的变量,当前任务优先级 IMPORT OSPrioHighRdy /将要恢复执行的任务的优先级 IMPORT OSTCBCur /当前任务的TCB的指针 IMPORT OSTaskSwHook /调用用户定义HOOK IMPORT OSTCBHighRdy /将要恢复执行的任务的TCB指针OSCtxSw STMFD sp!, lr / push pc (lr is actually be pushed in place of PC) 因为是从OS_Sched() BL到这里的 STMFD sp!, r0-r12,lr / push lr & register file MRS r4, cpsr / CPSR特殊,只能用MRS或MSR在寄存器间操作 STMFD sp!, r4 / push current psr LDR r4, =OSTCBCur / Get current task TCB address LDR r5, r4 STR sp, r5 / store sp in preempted tasks s TCB/ 以下程序段和OSIntCtxSw相同,可以共用一段BL OSTaskSwHook / call Task Switch Hook LDR r5, =OSTCBHighRdy / 得到就绪任务中的最高优先级的任务 LDR r5, r5 STR r5, r4 /使当前任务指针指向最高优先级的任务OSTCBCur = OSTCBHighRdy LDR r6, =OSPrioHighRdy LDRB r6, r6 LDR r4, =OSPrioCur STRB r6, r4 /保存优先级到当前的优先级 LDR sp, r5 /get new task s stack pointer LDMFD sp!, r4 /pop new task cpsr MSR cpsr_cxsf, r4LDMFD sp!, r0-r12,lr,pc /切换到新的任务/关于OSIntCtxSw()就是上面那下半截。这是因为:ARM硬件的中断时并不自动压栈任何寄存器,所以免去了恢复堆栈指针的麻烦;另外,我们最好在进入ISR保存当前任务现场时一同保存好TCB中的堆栈指针,而不是在OSIntCtxSw()中保存。具体的解释也可以参考上面这里只是用的寄存器不同而已。IMPORT OSTaskSwHookOSIntCtxSw BL OSTaskSwHook /调用OSTaskSwHook函数 LDR r4, =OSTCBHighRdy /得到当前最高优先级就绪的任务 LDR r4, r4 LDR r5, =OSTCBCur STR r4, r5 / OSTCBCur = OSTCBHighRdy LDR r6, =OSPrioHighRdy LDRB r6, r6 LDR r5, =OSPrioCur STRB r6, r5 / OSPrioCur = OSPrioHighRdy LDR sp, r4 /得到新任务的堆栈指针 LDMFD sp!, r4 / pop new task cpsr MSR cpsr_cxsf, r4LDMFD sp!, r0-r12,lr,pc /切换到新的任务/这是 UCOS-II 抢占式调度ISR的一个标本。当一个优先级高的任务放弃CPU使用权,例如要休眠 10 个 Tick,系统调度一个低优先级的任务执行之。OSTickISR()为休眠的任务计时,每次执行,就把休眠任务剩余的睡觉时间减去一个Tick数。如果发现一个任务睡够了,就顺便恢复它为READY态。做完该做的一切,一个对OSIntExit()的调用,使调度发生了。EXPORT OSTickISR IMPORT OSIntEnter IMPORT OSTimeTick IMPORT tick_hook IMPORT OSIntExit/注意ARM的IRQ中断发生后的PC保存(处理器自动保存LR=PC+4),而不是前面的PCLR。另外,我们保存的是SVC模式下的现场,中断后处理器进入IRQ模式,访问不到SVC模式下的R13(sp),于是在IRQ模式下,只好先另存SPSR和LR,然后尽快退回到SVC模式,这时的R13才是任务的堆栈指针。在此模式下再将SPSR和LR保存到堆栈中,立即保存所有寄存器。任务是在SVC模式下运行。关于时钟节拍怎么实现的(如果不是很懂就看下一篇文章关于ARM中断处理的详细分析)。LINK_SAVE DCD 0 /申请一个字单元用0来初始化这个字PSR_SAVE DCD 0 /地址为LINK_SAVE+4OSTickISR STMFD sp!, r4 /这里的sp是IRQ 模式下的,将r4压入堆栈/另存IRQ模式下的SPSR和LR,以便在SVC模式下也能访问,相当于一个中介作用 LDR r4, =LINK_SAVE STR lr, r4 /LINK_SAVE = lr,保存lr,此lr为IRQ模式下 MRS lr, spsr /lr=spsr STR lr, r4, #4 / PSR_SAVE = spsr_irq,保存spsr/ LDMFD sp!, r4 /恢复r4中的内容 ORR lr, lr, #0x80 / Mask irq for context switching before MSR cpsr_cxsf , lr / 从IRQ模式恢复到SVC模式/ SUB sp, sp, #4 / Space for给PC保留位置 STMFD sp!, r0-r12, lr /保存寄存器和lr LDR r4, =LINK_SAVE /r4= lr_irq LDR lr, r4, #0 /lr=lr_irq SUB lr, lr, #4 / PC = LINK_SAVE - 4,这个一定要正确/ 将PC= LR4存回到堆栈中,刚才跳过了PC 4字节的空间 (R1到R12再加lr共占了14个字) STR lr, sp, #(14*4) /sp=sp+14*4, 因为堆栈是从高地址向低地址递减 PC=LR -4 LDR r4, r4, #4 / r4 = PSR_SAVE, STMFD sp!, r4 / save CPSR of the task LDR r4, =OSTCBCur /将sp保存到当前的任务中 LDR r4, r4 STR sp, r4 / OSTCBCur - stkptr = sp BL OSIntEnter /处理中断嵌套曾数的增加也可以直接 给OSIntNesting加一 BL OSTimeTick /调用ostimetick() BL tick_hook / 我们在Tick_hook()里清除S3C44B0x的Tick_Int_Pend位 函数在main.c里,是另加的 BL OSIntExit /决定是否进行任务调度/如果返回则继续运行此任务 LDMFD sp!, r4 /pop new task cpsr MSR cpsr_cxsf, r4 LDMFD sp!, r0-r12,lr,pc / pop new task r0-r12,lr & pc/定义关中断,主要是为了安全访问临界区的资源EXPORT ARMDisableIntARMDisableInt MRS r0, cpsr STMFD sp!, r0 / push current PSR ORR r0, r0, #0xC0 MSR cpsr_c, r0 /disable IRQ Int s MOV pc, lr /返回/定义开中断 EXPORT ARMEnableIntARMEnableInt LDMFD sp!, r0 / pop current PSR MSR cpsr_c, r0 /restore original cpsr MOV pc, lr /返回/三、(1)OS_CPU.C.C文件的移植 (针对S1C33209)/C/OS-II 的移植需要用户改写OS_CPU_C.C中的六个函数:OSTaskStkInit()OSTaskCreateHook()OSTaskDelHook()OSTaskSwHook()OSTaskStatHook()OSTimeTickHook()实际需要修改的只有OSTaskStkInit()函数,其他五个函数需要声明,但不一定有实际内容。这五个函数都是用户定义的,所以OS_CP
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年4月重庆市妇幼保健院部分岗位招聘模拟试卷附答案详解(模拟题)
- 2025江西吉安市吉水县吉瑞招商运营有限公司面向社会招聘1人模拟试卷含答案详解
- 2025贵州省文化和旅游厅所属事业单位第十三届人博会引进人才3人模拟试卷及完整答案详解1套
- 2025贵州惠水县公益性岗位招聘4人考前自测高频考点模拟试题有答案详解
- 2025标准车辆买卖合同模板
- 2025内蒙古鑫和资源投资集团有限责任公司招聘26名模拟试卷含答案详解
- 2025规范的劳动合同样本
- 2025江西九江市武宁县医疗卫生单位招聘劳务派遣人员3人考前自测高频考点模拟试题及1套参考答案详解
- 2025年河北石家庄海关技术中心公开招聘劳务派遣类工作人员2名模拟试卷及参考答案详解1套
- 2025年深圳房地产中介服务合同
- 机电安装安全措施方案
- 25年一建建筑实务真题及答案
- 烈士陵园介绍课件
- 通信行业安全生产责任清单制全员安全职责
- CGF生长因子在口腔医学中的应用
- 渣土运输日常管理制度
- 2025至2030年中国中试基地行业市场全景调查及发展趋向研判报告
- 【课件】列代数式表示数量关系(第3课时+反比例关系)+课件+2024-2025学年人教版七年级数学上册+-
- JG/T 225-2007预应力混凝土用金属波纹管
- 承兑汇票转让协议书
- 贴牌委托协议书
评论
0/150
提交评论