vxWorks系统中多核cpu的使能
来源:互联网 发布:conor maynard知乎 编辑:程序博客网 时间:2024/06/07 21:59
平台介绍:
vxWorks6.7,CPU为loongson3A1000(4核)
基本过程就是首先0号cpu初始化(这段代码还没分析),之后就是0号cpu对1,2,3号CPU进行初始化。这里主要记录下对0号之外的cpu的初始化。
函数调用:
usrRootusrSmpInitkernelCpuEnableInternalvxCpuStateInitsysCpuEnablesysCpuStartgodson3_cpu_start
#define CPUSET_SET(cpuset, n) (cpuset |= (1 << n)) //某位置1#define CPUSET_ISSET(cpuset, n) (cpuset & (1 << n)) //判断某位是否为1#define CPUSET_CLR(cpuset, n) (cpuset &= ~(1 << n))//把某位置0#define CPUSET_ZERO(cpuset) (cpuset = 0) //清0LOCAL void usrEnableCpu (void) { int cpu; int numCpus = vxCpuConfiguredGet (); cpuset_t enabledCpus; ULONG timeoutTicks, timeoutStart, currentTickCount; CPUSET_ZERO (enabledCpus); CPUSET_SET (enabledCpus, 0); vxCpuEnableTimeout = VX_ENABLE_CPU_TIMEOUT; timeoutTicks = vxCpuEnableTimeout * sysClkRateGet (); //对0号之外cpu进行使能操作 for (cpu = 1; cpu < numCpus; cpu++) { //kernelCpuEnableInternal是做使能操作的函数,如果使能失败打印信息,没有失败则记录下该cpu已使能 if (kernelCpuEnableInternal (cpu) == ERROR) { logMsg ("usrEnableCpu: error when enabling additional CPU: %x\n" "userEnableCpu: kernelCpuEnableInternal failed\n" ,cpu, 0, 0, 0, 0, 0); } else CPUSET_SET (enabledCpus, cpu);}//在指定延迟的时间下还没有使能就打印,并循环执行等待使能 timeoutStart = vxAbsTicksGet (); do {currentTickCount = vxAbsTicksGet (); if ((currentTickCount - timeoutStart) > timeoutTicks) { for ( cpu = 1 ; cpu < numCpus ; cpu ++) {if (!CPUSET_ISSET (_WRS_CPU_ENABLED (),cpu)) logMsg ("usrEnableCpu: Timeout (%d secs) wating to enable " "additional CPU: %x\n", vxCpuEnableTimeout, cpu, 0, 0, 0, 0); } break; } } while (_WRS_CPU_ENABLED () != enabledCpus);//执行钩子函数 for ( cpu = 1 ; cpu < numCpus ; cpu ++) { if (CPUSET_ISSET (_WRS_CPU_ENABLED(), cpu)) { usrSmpCpuEnableHook (cpu); } } }
本函数调用kernelCpuEnableInternal对每个cpu进行使能。
STATUS kernelCpuEnableInternal ( unsigned int cpuToEnable ) { char *pStackBase;#ifdef _WRS_ARCH_SUPPORTS_VX_CPU_STATE_INIT WIND_CPU_STATE cpuState;#endif /* _WRS_ARCH_SUPPORTS_VX_CPU_STATE_INIT */ /* * cpu can be enabled in any sequence. * * return ERROR if input parameter is out of range * or CPU is already enabled */ if ((cpuToEnable >= _WRS_CPU_CONFIGURED ()) ||(CPUSET_ISSET (_WRS_CPU_ENABLED (), cpuToEnable))) return (ERROR); /* * idle task's exception stack will be used to * bring up the specified CPU */ pStackBase = (_WRS_KERNEL_CPU_GLOBAL_GET (cpuToEnable, idleTaskId))->pExcStackBase;#ifdef _WRS_ARCH_SUPPORTS_VX_CPU_STATE_INIT /* Init arch-specific WIND_CPU_STATE struct */ vxCpuStateInit (cpuToEnable, &cpuState, pStackBase, kernelCpuEntry); return sysCpuEnable (cpuToEnable, &cpuState);#else /* _WRS_ARCH_SUPPORTS_VX_CPU_STATE_INIT */ return sysCpuEnable (cpuToEnable, kernelCpuEntry, pStackBase); #endif /* _WRS_ARCH_SUPPORTS_VX_CPU_STATE_INIT */}
kernelCpuEnableInternal调用vxCpuStateInit设置要填写到cpu寄存器的值(也就是把cpu设置为一个可用的状态),sysCpuEnable使能cpu。
STATUS vxCpuStateInit ( unsigned int cpu, WIND_CPU_STATE *pCpuState, char *pStackBase, void (*entry) (void) ) { /* * return ERROR if input parameter is out of range * or CPU is already enabled */ if ((cpu >= vxCpuConfiguredGet()) ||(CPUSET_ISSET (_WRS_CPU_ENABLED (), cpu)))return (ERROR); if ((pCpuState == NULL) || (entry== NULL) || (pStackBase == NULL))return (ERROR); bzero ((char *)pCpuState, sizeof(WIND_CPU_STATE)); vxKernelVars[cpu].vars.cpu_archVars.cpu__mipsSrImask = SR_IMASK; pCpuState->regs.sr = taskSrDefault & ~SR_IE;#if defined(MIPSXX_xlr) pCpuState->regs.regEIMR = taskEimrDefault;#endif /* * initialize gp (small data area pointer). We use an assembler function * since _gp must be referenced as far data. */ vxSdaSet (&pCpuState->regs); //设置_gp pCpuState->regs.spReg = (_RType)pStackBase; pCpuState->regs.pc = (INSTR *)entry; }
这里主要是对pCpuState结构体进行设置,这是要写进cpu寄存器的值。其中entry是一个函数,作用为设置cpu已经使能标志(全局变量vxCpuEnabled),并加载idle程序。
entry:
_WRS_FUNC_NORETURN void kernelCpuEntry (void) { unsigned int currentCpu = _WRS_CPU_INDEX_GET (); //得到tcb指针(没看太明白) WIND_TCB *pTcb = _WRS_KERNEL_CPU_GLOBAL_GET (currentCpu, idleTaskId); pTcb->windSmpInfo.cpuIndex = currentCpu; //设置栈(也不是很明白) windIntStackSet (_WRS_KERNEL_CPU_GLOBAL_GET (currentCpu, vxIntStackBase)); //设置cpu使能的全局变量,标志该cpu初始化完成. /*vxCpuEnabled=1表示:0号cpu使能 * 3表示:0号1号cpu使能 * 7表示:0号1号2号cpu使能 * F表示:0号1号2号3号cpu使能 */ CPUSET_ATOMICSET (_WRS_CPU_ENABLED (), currentCpu); //加载idle windLoadContext ();}
sysCpuEnable:
STATUS sysCpuEnable(unsigned int cpuNum, WIND_CPU_STATE *cpuState) { if ((cpuNum < 1) || (cpuNum > (sysCpuAvailableGet ()-1))) {return -1; } sysCpuInitTable[cpuNum] = (FUNCPTR) cpuState->regs.pc; return sysCpuStart(cpuNum, cpuState); }STATUS sysCpuStart(int cpu, WIND_CPU_STATE *cpuState) {godson3_cpu_start(cpu, (void (*)(void))SYS_CPU_INIT, (long)cpuState->regs.spReg, (long)cpuState->regs.gpReg, (long)cpuState->regs.a1Reg);return OK; }
其中godson3_cpu_start函数为:
#define MAILBOX_BUF1 0x900000003ff01120 //核间寄存器,放置启动参数#define MAILBOX_BUF2 0x900000003ff01220 //#define MAILBOX_BUF3 0x900000003ff01320 //.globl godson3_cpu_start.ent godson3_cpu_startgodson3_cpu_start: //a0 a1 a2 a3 a4都是参数lit0,0x1 //t0=1bne a0,t0,1f //如果a0!=t0,就跳转到下面紧接着的标号1处nop //dlit0,MAILBOX_BUF1 //相等就加载MAILBOX_BUF1到t0中,并跳转到标号2处b2f //1: //lit0,0x2 //bnea0,t0,1f //nop //dlit0,MAILBOX_BUF2 //b2f //1: //lit0,0x3 //bnea0,t0,1f //nop //dlit0,MAILBOX_BUF3 //b2f //2: //sd a1,0(t0) //把a1的值放在t0存储的地址的偏移地址0处sda2,8(t0) //把a2的值放在t0存储的地址的偏移地址8处sda3,0x10(t0) //把a3的值放在t0存储的地址的偏移地址0x10处sda4,0x18(t0) //把a4的值放在t0存储的地址的偏移地址0x18处1: //jrra //.end godson3_cpu_start //#endif //
阅读全文
0 0
- vxWorks系统中多核cpu的使能
- python 多线程编程并不能真正利用多核的CPU
- Tilera的多核CPU
- LINUX系统 多核CPU小记
- vxWorks中的多核间的通信
- vxWorks中对于系统内存的分配
- .NET 中对多核心 CPU 的编程优化
- 多核CPU并不能让进程的多条线程同时执行
- 多核处理器中,使线程运行在指定CPU核心
- 如何获取多核、多cpu系统中指定cpu的序列号
- 如何获取多核、多cpu系统中指定cpu的序列号
- 如何获取多核、多cpu系统中指定cpu的序列号
- 如何获取多核、多cpu系统中指定cpu的序列号
- CPU多核的线程控制
- GCD的多核心性能
- 多颗CPU和多核CPU的衡量
- VxWorks的系统任务
- 多核CPU
- C语言实现顺序栈的基本操作
- 关于STEM教育
- 学习Vue的资源汇总
- Python Windows下环境安装
- opencv(一):Directory(遍历目录下的文件(夹))
- vxWorks系统中多核cpu的使能
- mysql半同步复制
- 分布式项目运用-Dubbo配置
- 利用反射实现mysql数据库sql查询 返回List<E>泛型(持久化)对象
- # 融云 集成会话列表加头布局
- spring jsp table 获取单个input字段值并传到后台 成功简例
- 【设计模式】Java设计模式之模板方法模式
- Python 包
- RxJava2 / RxAndroid2操作符take