版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、threadx学习笔记(一)tx_ill.s文件用来处理初始化过程中的汇编语言,它是面向处理器和开发工具的。Void_tx_initialize_low_level1、CPSCR|= FIQ_ MODE,SET SP_fiq;2、CPSCR|=IRQ_MODE,SET SP_irp;3、CPSCR|=SVC_MODE,SET SP_svc;4、设置中断向量表IRQ_TABLE;5、设置内部TIMER线程的堆栈起始地址,堆栈大小和优先级:tx_timer_stack_start,_tx_timer_stack_size,_tx_timer_priorit;6、设置初始化后未使用内存地址的初始值_
2、tx_initialize_unused_memory;Tx_tcs.s负责在中断发生时对上次的运行现场进行保存,它保存中断上下文,为了不覆盖R14_irq离得中断返回地址,TCS的返回是通过跳到_tx_irq_processing_return地址做到的。Tx_TCR.S负责中断处理程序执行完后的处理。Void _tx_thread_context_save1、把表示中断嵌套个数的变量_tx_thread_system_state+;2、if _tx_thread_system_state1,PUSH R0-R3,CPSR,R14 in IRQ stack,B _tx_irq_process
3、ing_return;3、else if _tx_thread_current_ptr=0判断是否有线程正在运行,if not ,B _tx_irq_processing_return;4、else,PUSH Context_irq in threads stack,SP_thread=new SP,B _tx_irq_processing_return;由于R13和R14在不同的CPU模式下对应的是不同的物理寄存器,所以若要得到中断前的线程堆栈指针,需要先返回到该线程的运行模式,同时禁止中断,取值后再返回到终端模式。R14_irq保存的是终端发生时PC值+8,R14_svc保存得失中断前线程
4、自己的返回地址。所以在中段上下文中,(R14_irq-4)应该存在中断地址,而R14_svc存在R14的位置。Void _tx_thread_context_restore1、_tx_thread_system_state-,if _tx_thread_system_state0,POP R0-R3,CPSR,R14 from IRQ stack,BX R14;2、else if _tx_thread_current_ptr=0?if =0 CPSR|=VC_MODE,CPSR|=TX_INT_ENABLE,跳到线程调度程序B _tx_thread_schedule;3、if!=0,则判断线程
5、抢占是否禁止 if _tx_thread_preempt_disable=0?if!=0,POP Context_irq from threads stack,BX R14;4、if=0,_tx_timer_time_slice=new value,_tx_thread_current_ptr=0,CPSR|=SVC_MODE,设置堆栈指针为系统指针SP=SP_svc,CPSR|=TX_INT_ENABLE;5、B _tx_thread_schedule;Tx_tsr.s用于从线程退回到系统态,负责保存线程的最小语境并退回到Threadx的调度循环状态。它保存的上下文是请求上下文。Void _
6、tx_thread_system_return1、 PUSH Context_request:in threads stack,CPSR|=TX_INT_DISABLE;2、 _tx_thread_current_ptr-SP=SP,CPSR|=SVC_MODE;3、 设置堆栈指针为系统指针SP=SP_svc,_tx_thread_current_ptr=0,CPSR|=TX_INT_ENABLE;4、 B _tx_thread_schedule;由于用户模式不能直接更改CPSR来关断的,所以要通过SWI指令进入特权模式,而且特权模式和用户模式的SP对应不同的物理寄存器,所以要在转入系统模式取
7、得用户模式下SP,最后再回到特权模式。TX_TS.S负责调度和恢复就绪的优先级最高的线程的最后语境。Void _tx_thread_schedule1、 while(_tx_thread_execute_ptr=0);2、 CPSR|=TX_INT_DISABLE,_tx_threadx_current_ptr=_tx_thread_execute_ptr;3、 _tx_thread_current_ptr-TX_run_count+,_tx_timer_time_slice=_tx_thread_current_ptr-tx_time_slice;4、 If线程堆栈的中断类型=1,resto
8、re Context_irq,else restore Context_request;Tx_tic.s用于开中断和关中断。Unint _tx_thread_interrupt_control(unint new _posture)1、 R1=CPSR;2、 SWI;3、 CPSR|=RO=new posture;4、 R0=R1,R0为返回值;移植该函数时,针对不同的处理器,应盖根据准热爱寄存器CPSR的中断禁止未来设置开关中断向量,主要修改TX_PORT.H中的TX_INT_ENABLE和TX_INT_DISABLE.R0用来传递的参数和结果。Tx_tsb.s负责创建每个线程的初始堆栈结构
9、,这个初始的结构在线程创建时会引起中断上下文返回到_tx_thread_shell_entry函数的开头。然后这个函数调用指定线程入口函数。其中断类型设置为1,表示中断上下文。Void _tx_thread_stack_build(TXTHREAD *thread_ptr,void (*function)(void)1、 保证堆栈起始地址八字节对齐;2、 中断地址存入线程调用的入口地址PUSH function_ptr;3、 R0-R12,R14的初始值都设置为0,PUSH初始值;4、 要存入堆栈的CPSR值设置为用户模式,开中断,标志位清零,R1=USER_MODE,PUSH R1;5、 T
10、hread_ptr-sp=new SP;当处理一个低级的中断时,tx_tpc.s决定是否发生抢占,它是可选的,大多数端口都用不到。TX_TIMIN.S负责处理定时中断。这两个函数只要将它们翻译成相应ARM汇编语言就可以了。threadx学习笔记(二)-1tx_kernel_enter();进入threadx核tx_kernel_enter()void tx_kernel_enter(void)所属文件调用者开关量demo.C启动代码无操作系统首先从从量表直接进入该函数,在函数以前没有进行任何的硬件及软件的初始化!该函数主要包含_tx_initialize_low_level(),_tx_ini
11、tialize_high_level(),tx_application_define(_tx_initialize_unused_memory),_tx_thread_schedule()。VOID _tx_initialize_kernel_enter(VOID)/*确定编译器是否已经初始化过 */if (_tx_thread_system_state != TX_INITIALIZE_ALMOST_DONE)/* 没有初始化的话执行下面程序 */* 设置系统状态变量来表示现正在处理过程中 注意该变量在后边的中断嵌套中会使用*/_tx_thread_system_state = TX_INI
12、TIALIZE_IN_PROGRESS;/* 进行一些基本硬件设置,启动程序等 */_tx_initialize_low_level();/*进行一些高级的初始化*/_tx_initialize_high_level();/*设置系统状态变量来表示现正在处理过程中 注意该变量在后边的中断嵌套中会使用*/_tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;/* 调用初始化中提供的应用程序 把第一个未使用的变量地址传送给它 */tx_application_define(_tx_initialize_unused_memory);/*设置系统壮伟
13、进入线程调度做准备*/_tx_thread_system_state = TX_INITIALIZE_IS_FINISHED;/* 进入线程循环开始执行线程 */_tx_thread_schedule();_tx_initialize_low_level()void tx_kernel_enter(void)所属文件调用者开关量tx_till.s启动代码无该函数实现对FIQ、IRQ和SVC模式下的sp寄存器的初始化,并对定时堆栈的基地址、大小和定时优先级变量进行初始化。/* 进行一些基本硬件设置,启动程序等 */*该函数在文件tx_ill.s文件中*/_tx_initialize_low_le
14、vel();/* VOID _tx_initialize_low_level(VOID);EXPORT _tx_initialize_low_level_tx_initialize_low_level; /* 保存系统堆栈指针. */; /* _tx_thread_system_stack_ptr = (VOID_PTR) A7 (SP); */;/*设置各个模式下的sp(堆栈指针)*/; /* We must be in SVC mode at this point! */;LDR a2, =|Image$ZI$Limit| ; Get end of non-initialized RAM
15、areaLDR a3, pc, #FIQ_STACK_SIZE-.-8 ; 获得FIO堆栈地址(这里没有弄明白,有待?)MOV a1, #FIQ_MODE ; 设置FIQ_MODEMSR CPSR_c, a1 ; 进入FIQ模式ADD a2, a2, a3 ;计算FIQ堆栈的开始BIC a2, a2, #3 ; 将a2的低两位清零确保堆栈的的开始为long对齐SUB a2, a2, #4 ; 往回退一个字MOV sp, a2 ; 建立FIQ 堆栈指针(即FIQ模式的sp)MOV sl, #0 ; Clear sl(R10)MOV fp, #0 ; Clear fp(R11)LDR a3, pc
16、, #SYS_STACK_SIZE-.-8 ;获得 IRQ (system stack size)MOV a1, #IRQ_MODE ; 建立IRQ模式的 CPSRMSR CPSR_c, a1 ; 进入IRQ模式ADD a2, a2, a3 ; 计算IRQ stack的开始BIC a2, a2, #3 ; 将a2的低两位清零确保堆栈的的开始为long对齐SUB a2, a2, #4 ; 往回退一个字MOV sp, a2 ; 建立 IRQ 堆栈指针MOV a1, #SVC_MODE ; 建立SVC模式的CPSRMSR CPSR_c, a1 ; 进入 SVC模式LDR a4, pc, #SYS_S
17、TACK_PTR-.-8 ; 获得stack 指针STR a2, a4, #0 ; 保存系统堆栈; /* Save the system stack pointer. */; _tx_thread_system_stack_ptr = (VOID_PTR) (sp);LDR a2, pc, #SYS_STACK_PTR-.-8 ; 获得系统堆栈指针的地址LDR a1, a2, #0 ; 获得系统堆栈指针 ADD a1, a1, #4 ; 增加一个long长度; /* Pickup the first available memory address. */; /* Allocate space
18、 for the timer threads stack. */; _tx_timer_stack_start = first_available_memory; _tx_timer_stack_size = stack_size; _tx_timer_priority = 0;LDR a2, pc, #TIMER_STACK-.-8 ; 获得定时堆栈指针地址LDR a4, pc, #TIMER_STACK_SIZE-.-8 ; 获得定时堆栈大小地址LDR a3, pc, #TIM_STACK_SIZE-.-8 ; 获得实际定时堆栈大小STR a1, a2, #0 ;将定时堆栈的基地址放在堆栈
19、指针地址所对应的内存中STR a3, a4, #0 ; 存储定时器堆栈大小ADD a1, a1, a3 ; 新的空内存地址LDR a2, pc, #TIMER_PRIORITY-.-8 ; 获得定时器优先级地址MOV a3, #0 ; 获得定时器线程优先级STR a3, a2, #0 ; 存储定时器线程优先级; /*保存第一个变量内存地址. */; _tx_initialize_unused_memory = (VOID_PTR) System Stack + Timer Stack;LDR a3, pc, #UNUSED_MEMORY-.-8 ;获得没有使用的内存指针地址STR a1, a3
20、, #0 ; 保存第一个空内存地址; /* 建立周期性的定时中断. */STMDB LR/让lr入栈,保护lrBLTargetInit/TargetInit()为C语言编写的中断定时函数LDMIA lr/让lr出栈在这里加上ARM定时器已实现周期性的中断; /* Done, return to caller. */;MOV pc, lr ; Return to caller;_tx_irq_handler所属文件调用者开关量tx_till.s IRQ中断无该函数是在定时中断后调用,该函数调用了_tx_thread_context_save函数(包含在tx_tcs.s中),该函数又调用到_tx_
21、irq_processing_return函数处(包含在tx_till.s)EXPORT _tx_irq_handlerEXPORT _tx_irq_processing_return _tx_irq_handler; /* 调用函数保存线程上下文环境. */B _tx_thread_context_save_tx_irq_processing_return; /* At this point execution is still in the IRQ mode. The CPSR, point of; interrupt, and all C scratch registers are av
22、ailable for use. In ; addition, IRQ interrupts may be re-enabled - with certain restrictions -; if nested IRQ interrupts are desired. Interrupts may be re-enabled over; small code sequences where lr is saved before enabling interrupts and ; restored after interrupts are again disabled. */; /* For de
23、bug purpose, execute the timer interrupt processing here. In; a real system, some kind of status indication would have to be checked; before the timer interrupt handler could be called. */;BL clearflag;清除中断标志位很重要(自己移植时加的,位置是否恰当?)BL _tx_timer_interrupt ; 定时中断处理函数; /* 系统线程上下文环境恢复函数 */B _tx_thread_cont
24、ext_restore_tx_timer_interrupt所属文件调用者开关量tx_timin.s启动代码无该函数主要是中断后将系统时钟加1,时间切片减1。定时部分比较多,没有完全看明白。IMPORT _tx_timer_time_sliceIMPORT _tx_timer_system_clockIMPORT _tx_timer_current_ptrIMPORT _tx_timer_list_startIMPORT _tx_timer_list_endIMPORT _tx_timer_expired_time_sliceIMPORT _tx_timer_expiredIMPORT _tx
25、_timer_threadIMPORT _tx_thread_current_ptrIMPORT _tx_thread_time_sliceIMPORT _tx_thread_resumeIMPORT _tx_thread_preempt_disable;PRESERVE8AREA |C$code|, CODE, READONLY|x$codeseg| DATA;VOID _tx_timer_interrupt(VOID);EXPORT _tx_timer_interrupt_tx_timer_interrupt; /* Upon entry to this routine, it is as
26、sumed that context save has already; been called, and therefore the compiler scratch registers are available; for use. */; /* Increment the system clock. */; _tx_timer_system_clock+;LDR a2, pc, #SYSTEM_CLOCK-.-8 ; 获得系统时钟地址LDR a1, a2, #0 ; 获得系统时钟ADD a1, a1, #1 ; 将系统时钟加1STR a1, a2, #0 ; 存储新的系统时钟时间; /*
27、 Test for time-slice expiration. */; if (_tx_timer_time_slice); ;LDR a4, pc, #TIME_SLICE-.-8 ; 获得链表中的定时切片数地址LDR a3, a4, #0 ; 获得定时切片数的值CMP a3, #0 ; 定时切片是否有效,0有效,=0无效BEQ _tx_timer_no_time_slice ; =0时,跳到_tx_timer_no_time_slice处; /* 时间切片减1. */; _tx_timer_time_slice-;SUB a3, a3, #1 ; 时间切片值减1STR a3, a4, #
28、0 ; 存储新的时间切片值; /* 检查是否到期. */; if (_tx_timer_time_slice = 0);CMP a3, #0 ; 0还是=0?BNE _tx_timer_no_time_slice ; 如果0,;当没有定时切片时,将定时切片数标志位置1,表示链表中没有切片了。; /* Set the time-slice expired flag. */; _tx_timer_expired_time_slice = TX_TRUE;LDR a4, pc, #EXPIRED_TIME_SLICE-.-8 ; 获得定时切片数是否为0标志地址MOV a1, #1 ; 将标志设为1S
29、TR a1, a4, #0 ; 设立到时标志; ;_tx_timer_no_time_slice; /* Test for timer expiration. */; if (*_tx_timer_current_ptr); ;LDR a2, pc, #TIMER_CURRENT_PTR-.-8 ; 获得的是_tx_timer_current_ptr的地址;而TIMER_DECLARE TX_INTERNAL_TIMER *_tx_timer_current_ptr;LDR a1, a2, #0 ; 获得当前的_tx_timer_current_ptrLDR a3, a1, #0 ; 获得定时
30、列表的入口定时切片指针CMP a3, #0 ;链表中是否有定时切片存在BEQ _tx_timer_no_timer ; 不存在, 调用_tx_timer_no_time将;_tx_timer_current_ptr+; /* Set expiration flag. */; _tx_timer_expired = TX_TRUE;LDR a4, pc, #EXPIRED-.-8 ; Pickup expriation flag addressMOV a3, #1 ; Build expired valueSTR a3, a4, #0 ; Set expired flagB _tx_timer_
31、done ; Finished timer processing; ; else; _tx_timer_no_timer; /* No timer expired, increment the timer pointer. */; _tx_timer_current_ptr+;ADD a1, a1, #4 ; Move to next timer; /* Check for wrap-around. */; if (_tx_timer_current_ptr = _tx_timer_list_end);LDR a4, pc, #LIST_END-.-8 ; Pickup addr of tim
32、er list endLDR a3, a4, #0 ; Pickup list endCMP a1, a3 ; Are we at list end?BNE _tx_timer_skip_wrap ; No, skip wrap-around logic; /* Wrap to beginning of list. */; _tx_timer_current_ptr = _tx_timer_list_start;LDR a4, pc, #LIST_START-.-8 ; Pickup addr of timer list startLDR a1, a4, #0 ; Set current po
33、inter to list start;_tx_timer_skip_wrap;STR a1, a2, #0 ; Store new current timer pointer; ;_tx_timer_done; /* See if anything has expired. */; if (_tx_timer_expired_time_slice) | (_tx_timer_expired); ;LDR a4, pc, #EXPIRED_TIME_SLICE-.-8 ; Pickup addr of expired flagLDR a3, a4, #0 ; Pickup time-slice
34、 expired flagCMP a3, #0 ; Did a time-slice expire?BNE _tx_something_expired ; If non-zero, time-slice expiredLDR a2, pc, #EXPIRED-.-8 ; Pickup addr of other expired flagLDR a1, a2, #0 ; Pickup timer expired flagCMP a1, #0 ; Did a timer expire?BEQ _tx_timer_nothing_expired ; No, nothing expired;_tx_s
35、omething_expired;STR lr, sp, #-4! ; Save the lr register on the stack; /* Did a timer expire? */; if (_tx_timer_expired); ;LDR a2, pc, #EXPIRED-.-8 ; Pickup addr of expired flagLDR a1, a2, #0 ; Pickup timer expired flagCMP a1, #0 ; Check for timer expirationBEQ _tx_timer_dont_activate ; If not set,
36、skip timer activation; /* Increment the preempt disable counter in preparation for ; thread resumption. */; _tx_thread_preempt_disable+;LDR a4, pc, #PREEMPT_DISABLE-.-8 ; Pickup addr of preempt disable LDR a3, a4, #0 ; Pickup actual flagADD a3, a3, #1 ; Incrment the preempt disable countSTR a3, a4,
37、#0 ; Store it back; /* Activate the system timer thread. */; _tx_thread_resume(&_tx_timer_thread);LDR a1, pc, #TIMER_THREAD-.-8 ; Get timer thread control block addrBL _tx_thread_resume ; Call thread resume to wake up the; timer thread; _tx_timer_dont_activate; /* Did time slice expire? */; if (_tx_
38、timer_expired_time_slice); ;LDR a4, pc, #EXPIRED_TIME_SLICE-.-8 ; Pickup addr of time-slice expired LDR a3, a4, #0 ; Pickup the actual flagCMP a3, #0 ; See if the flag is setBEQ _tx_timer_not_ts_expiration ; No, skip time-slice processing; /* Time slice interrupted thread. */; if (!_tx_thread_time_s
39、lice(); _tx_timer_time_slice = _tx_thread_current_ptr - tx_time_slice;BL _tx_thread_time_slice ; Call time-slice processingCMP a1, #0 ; Check return statusBNE _tx_timer_not_ts_expiration ; If time-sliced, skip reset processingLDR a2, pc, #CURRENT_PTR-.-8 ; Pickup addr of current thread pointerLDR a1
40、, a2, #0 ; Pickup thread pointerLDR a3, a1, #24 ; Pickup fresh time-slice for thread; (a fresh time slice was setup in ; the _tx_thread_time_slice function)LDR a4, pc, #TIME_SLICE-.-8 ; Pickup addr of time-slice variableSTR a3, a4, #0 ; Setup new time-slice; ;_tx_timer_not_ts_expiration;LDR a4, pc,
41、#EXPIRED_TIME_SLICE-.-8 ; Pickup address of expired time-slice flagMOV a1, #0 ; Clear valueSTR a1, a4, #0 ; Clear time-slice expired flag;LDR lr, sp, #4 ; Recover lr register; ;_tx_timer_nothing_expired;MOV pc, lr ; Return to caller;TIME_SLICEDCD _tx_timer_time_sliceSYSTEM_CLOCKDCD _tx_timer_system_
42、clockTIMER_CURRENT_PTRDCD _tx_timer_current_ptrLIST_STARTDCD _tx_timer_list_startLIST_ENDDCD _tx_timer_list_endEXPIRED_TIME_SLICEDCD _tx_timer_expired_time_sliceEXPIREDDCD _tx_timer_expiredTIMER_THREADDCD _tx_timer_threadCURRENT_PTRDCD _tx_thread_current_ptrTHREAD_TIME_SLICEDCD _tx_thread_time_slice
43、RESUMEDCD _tx_thread_resumePREEMPT_DISABLEDCD _tx_thread_preempt_disableEND_tx_initialize_high_level()VOID _tx_initialize_high_level(VOID)所属文件调用者开关量tx_ihl.c启动代码无主要时对一些与硬件无关的变量进行初始化,其中主要实现了线程的初始化;定时的初始化,这里定时也是一个线程,且优先级为最高0;还有对信号量、队列、时间标志、块池、和字节池的初始化。/*进行一些高级的初始化*/_tx_initialize_high_level();VOID _tx_
44、initialize_high_level(VOID)/* Initialize the event log, if enabled. */TX_EL_INITIALIZE/* 调用线程初始化函数. */_tx_thread_initialize();/* 调用定时初始化函数 */_tx_timer_initialize();/* 调用信号量初始化函数 */_tx_semaphore_initialize();/* 调用队列初始化函数 */_tx_queue_initialize();/* 调用事件标志初始化函数. */_tx_event_flags_initialize();/* 调用blo
45、ck pool 初始化函数. */_tx_block_pool_initialize();/* 调用byte pool初始化函数. */_tx_byte_pool_initialize();/* 调用线程初始化函数. */_tx_thread_initialize();VOID _tx_thread_initialize(VOID)所属文件调用者开关量tx_ti.c启动代码无此函数主要实现对与线程有关的一些变量进行初始化。VOID _tx_thread_initialize(VOID)REG_1 UINT i; /* Working index variable */ REG_2 UCHAR
46、set_bit; /* Lowest set bit */ HREG_3 UINT temp; /* Working shift variable */ REG_4 UCHAR *lowest_set_ptr; /* Pointer in set bit array */REG_5 TX_THREAD_PTR*priority_list_ptr; /* Pointer in priority list */* Note: the system stack pointer and the system state variables are initialized by the low and
47、high-level initialization functions,respectively. */* 初始化当前线程指针为空 */_tx_thread_current_ptr = TX_NULL;/* 初始化要执行线程指针为空. */_tx_thread_execute_ptr = TX_NULL;/* 初始化优先级信息 */_tx_thread_priority_map = 0;_tx_thread_preempted_map = 0;_tx_thread_highest_priority = TX_MAX_PRIORITIES;/* 初始化the lowest-set bit 表.
48、这被用来当线程被挂起和从新启动时寻找下一个准备执行的线程 */_tx_thread_lowest_bit0 = 0;lowest_set_ptr = &_tx_thread_lowest_bit1;for (i = 1; i 1;set_bit+;/* 预先求出对应的线程优先级byte值所对应的优先级最高的的bit位*/ *(lowest_set_ptr+) = set_bit;/*例如priorityb_byte的值为5即0x101那么所对应的优先级最高为0,则lowest_set_ptrpriorityb_byte=0*/*当优先级字节的值为i时,我们很快可以知道该字节的高优先级为第_tx
49、_thread_lowest_bitibit位。*/* 初始化优先级头指针队列. 即将线程块对应的空间都初始化为空 */priority_list_ptr = &_tx_thread_priority_list0;for (i = 0; i TX_MAX_PRIORITIES; i+)*(priority_list_ptr+) = TX_NULL;/* I初始化以创建线程列表的头指针和以创建线程的个数*/_tx_thread_created_ptr = TX_NULL;_tx_thread_created_count = 0;/* Clear the global preempt disable variable. ?*/_tx_thread_preempt_disable = 0;VOID _tx_timer_initialize(VOID)所属文件调用者开关量tx_timi.c启动代码无主要实现有定时器有关的一些变量的初始化,并建立
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025土地流转合同范文
- 养猪产业链一体化2025年度合作协议模板3篇
- 2025城市综合体物业租赁合同
- 2025服务合同香港及境外股市投资咨询服务协议
- 2025年度农村房屋产权转让及配套设施移交合同2篇
- 二零二五年度企业培训与发展公司管理服务协议3篇
- 二零二五年度农副产品电商平台入驻合作协议3篇
- 2025年度智能化公厕建设与运营管理承包施工合同书模板3篇
- 二零二五农村宅基地买卖与农村土地整治与生态保护合同
- 二零二五年度农民工工资支付委托及劳务合同管理协议
- 穴位贴敷护理培训
- 腰椎间盘突出症护理查房课件
- DB45T 2866-2024 灵芝菌种制备技术规程
- 2024年度区块链软件产品知识产权共享协议3篇
- 人教版九年级上学期物理期末复习(压轴60题28大考点)
- 人教版(2024版)七年级上册英语期末模拟测试卷(含答案)
- 2024年度企业环境、社会及治理(ESG)咨询合同6篇
- 幼儿园中班美术活动《美丽的线条》课件
- 2024年01月22474旅游工作者素质修养期末试题答案
- 计量经济学知到智慧树章节测试课后答案2024年秋云南财经大学
- 乡镇卫生院院长工作职责
评论
0/150
提交评论