threadx学习笔记(一)tx_ill.s文件用来处理初始化过程中的汇编语言,它是面向处理器和开发工具的。Void_tx_initialize_low_level{1、CPSCR|=FIQ_MODE,SETSP_fiq;2、CPSCR|=IRQ_MODE,SETSP_irp;3、CPSCR|=SVC_MODE,SETSP_svc;4、设置中断向量表IRQ_TABLE;5、设置内部TIMER线程的堆栈起始地址,堆栈大小和优先级::tx_timer_stack_start,_tx_timer_stack_size,_tx_timer_priorit;6、设置初始化后未使用内存地址的初始值_tx_initialize_unused_memory;}Tx_tcs.s负责在中断发生时对上次的运行现场进行保存,它保存中断上下文,为了不覆盖R14_irq离得中断返回地址,TCS的返回是通过跳到__tx_irq_processing_return地址做到的。Tx_TCR.S负责中断处理程序执行完后的处理。Void_tx_thread_context_save{1、把表示中断嵌套个数的变量_tx_thread_system_state++;2、if_tx_thread_system_state1,PUSHR0-R3,CPSR,R14inIRQstack,B__tx_irq_processing_return;3、elseif_tx_thread_current_ptr=0判断是否有线程正在运行,ifnot,B_tx_irq_processing_return;4、else,PUSHContext_irqinthread’sstack,SP_thread=newSP,B_tx_irq_processing_return;}由于R13和R14在不同的CPU模式下对应的是不同的物理寄存器,所以若要得到中断前的线程堆栈指针,需要先返回到该线程的运行模式,同时禁止中断,取值后再返回到终端模式。R14_irq保存的是终端发生时PC值+8,R14_svc保存得失中断前线程自己的返回地址。所以在中段上下文中,(R14_irq-4)应该存在中断地址,而R14_svc存在R14的位置。Void_tx_thread_context_restore{1、_tx_thread_system_state--,if_tx_thread_system_state0,POPR0-R3,CPSR,R14fromIRQstack,BXR14;2、elseif_tx_thread_current_ptr=0?if=0CPSR|=VC_MODE,CPSR|=TX_INT_ENABLE,跳到线程调度程序B_tx_thread_schedule;3、if!=0,则判断线程抢占是否禁止if_tx_thread_preempt_disable=0?if!=0,POPContext_irqfromthread’sstack,BXR14;4、if=0,_tx_timer_time_slice=newvalue,_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_tx_thread_system_return{1、????????????PUSHContext_request:inthread’sstack,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对应不同的物理寄存器,所以要在转入系统模式取得用户模式下SP,最后再回到特权模式。TX_TS.S负责调度和恢复就绪的优先级最高的线程的最后语境。Void_tx_thread_schedule{1、????????????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,restoreContext_irq,elserestoreContext_request;}Tx_tic.s用于开中断和关中断。Unint_tx_thread_interrupt_control(unintnew_posture){1、????????????R1=CPSR;2、????????????SWI;3、????????????CPSR|=RO=newposture;4、????????????R0=R1,R0为返回值;}移植该函数时,针对不同的处理器,应盖根据准热爱寄存器CPSR的中断禁止未来设置开关中断向量,主要修改TX_PORT.H中的TX_INT_ENABLE和TX_INT_DISABLE.R0用来传递的参数和结果。Tx_tsb.s负责创建每个线程的初始堆栈结构,这个初始的结构在线程创建时会引起中断上下文返回到_tx_thread_shell_entry函数的开头。然后这个函数调用指定线程入口函数。其中断类型设置为1,表示中断上下文。Void_tx_thread_stack_build(TXTHREAD*thread_ptr,void(*function)(void)){1、????????????保证堆栈起始地址八字节对齐;2、????????????中断地址存入线程调用的入口地址PUSHfunction_ptr;3、????????????R0-R12,R14的初始值都设置为0,PUSH初始值;4、????????????要存入堆栈的CPSR值设置为用户模式,开中断,标志位清零,R1=USER_MODE,PUSHR1;5、????????????Thread_ptr-sp=newSP;}当处理一个低级的中断时,tx_tpc.s决定是否发生抢占,它是可选的,大多数端口都用不到。TX_TIMIN.S负责处理定时中断。这两个函数只要将它们翻译成相应ARM汇编语言就可以了。threadx学习笔记(二)-1tx_kernel_enter();进入threadx核tx_kernel_enter()voidtx_kernel_enter(void)所属文件????调用者????开关量demo.C????启动代码????无操作系统首先从从量表直接进入该函数,在函数以前没有进行任何的硬件及软件的初始化!该函数主要包含_tx_initialize_low_level(),_tx_initialize_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_INITIALIZE_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);????/*设置系统壮伟进入线程调度做准备*/????_tx_thread_system_state=TX_INITIALIZE_IS_FINISHED;????/*进入线程循环开始执行线程*/????_tx_thread_schedule();}_tx_initialize_low_level()voidtx_kernel_enter(void)所属文件????调用者????开关量tx_till.s????启动代码????无该函数实现对FIQ、IRQ和SVC模式下的sp寄存器的初始化,并对定时堆栈的基地址、大小和定时优先级变量进行初始化。/*进行一些基本硬件设置,启动程序等*//*该函数在文件tx_ill.s文件中*/???_tx_initialize_low_level();;/*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(堆栈指针)*/;/*WemustbeinSVCmodeatthispoint!*/;????LDRa2,=|Image$$ZI$$Limit|;Getendofnon-initializedRAMarea????LDRa3,[pc,#FIQ_STACK_SIZE-.-8];获得FIO堆栈地址(这里没有弄明白,有待?)????MOVa1,#FIQ_MODE;设置FIQ_MODE????MSRCPSR_c,a1;进入FIQ模式????ADDa2,a2,a3;计算FIQ堆栈的开始????BICa2,a2,#3;将a2的低两位清零确保堆栈的的开始为long对齐????SUBa2,a2,#4;往回退一个字????MOVsp,a2;建立FIQ堆栈指针(即FIQ模式的sp)????MOVsl,#0;Clearsl(R10)????MOVfp,#0;Clearfp(R11)????LDRa3,[pc,#SYS_STACK_SIZE-.-8]????;获得IRQ(systemstacksize)????MOVa1,#IRQ_MODE;建立IRQ模式的CPSR????MSRCPSR_c,a1;进入IRQ模式????ADDa2,a2,a3;计算IRQstack的开始?????BICa2,a2,#3;将a2的低两位清零确保堆栈的的开始为long对齐????SUBa2,a2,#4;往回退一个字????MOVsp,a2;建立IRQ堆栈指针????MOVa1,#SVC_MODE;建立SVC模式的CPSR