visitor83
visitor83
这家伙很懒,什么也没写!

注册于 14年前

回答
16
文章
0
关注者
0

发布于11年前

确实在vector.S中hal_default_exception_vsr 有去call hal_deliver_exception, 初始化将2~15中断向量都指向了hal_default_exception_vsr, 压入R1=exception state type, R2= vector number, R3=basepri, hal_default_exception_vsr参数为数据寄存器r0~r10, r11~r15, cpsr, vector, svc_lr, svc_sp,应该跟压入的参数顺序一致

_hal_registers = regs // _hal_registers 在packages/hal/common/current/src/hal_stub.c中定义 ,接下来执行__handle_exception(void)中要处理真正的stub

发布于11年前

在packages/hal/cortexm/arch/current/src/hal_misc.c中hal_reset_vsr(void)—>

  1. #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
  2. // Enable DebugMonitor exceptions. This is needed to enable single
  3. // step. This only has an effect if no exteranl JTAG device is attach
  4. {
  5. CYG_ADDRESS base = CYGARC_REG_DEBUG_BASE;
  6. cyg_uint32 demcr;
  7. HAL_READ_UINT32(base + CYGARC_REG_DEBUG_DEMCR, demcr);
  8. demcr |= CYGARC_REG_DEBUG_DEMCR_MON_EN;
  9. HAL_WRITE_UINT32(base + CYGARC_REG_DEBUG_DEMCR, demcr);
  10. }

看代码里_DEMCR这个宏是另一套stub实现,具体在看。

initialize_stub() : package/hal/common/current/src/generic-stub.c 初始化
1) install the standard set of trap handlers for the stub
在pakcages/hal/cortexm/stm32/var/current/include/plf_stub.h中指定
HAL_STUB_PLATFROM_INTERRUPTIBLE = 0不允许中断发生,其他中断与非stub使能状态一样。

2) 安装stub的设备例如串口 packages/hal/cortexm/stm32/var/current/src/hal_diag.c—>cyg_hal_plf_comms_int(void),然后发出去个’+’ 回应。

粗略读了下ecos代码,下来在读hal_deliver_exception

发布于12年前

都有助手了,不错

发布于13年前

感谢回复,
(4)while (1)
{
if (rt_mb_recv(ð_tx_thread_mb, (rt_uint32_t)&msg, RT_WAITING_FOREVER) == RT_EOK)
{
struct eth_device
enetif;

  1. RT_ASSERT(msg->netif != RT_NULL);
  2. RT_ASSERT(msg->buf != RT_NULL);
  3. enetif = (struct eth_device*)msg->netif->state;
  4. if (enetif != RT_NULL)
  5. {
  6. /* call driver's interface */
  7. if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
  8. {
  9. rt_kprintf("transmit eth packet failed\n");
  10. }
  11. }
  12. /* send ack */
  13. rt_sem_release(&(enetif->tx_ack));
  14. }
  15. }

这个没有 break ?

发布于14年前

忘了,感谢bernard的指教。上述有什么不对,还请各位指点!

发布于14年前

明白了!
线程第一次运行,它的默认上下文环境就是开启中断的,那么当这个线程被恢复时,那么系统中断不就立刻被打开了么
<<问题的关键是:
1。每一个进程都有自己的空间互不干扰。 进程被os恢复时,等于从进程的第一条指令开始执行,与其他什么乱七八糟的没什么关系。
2。 ARM Mode 的切换, rtthread 启动后一直是处于svc mode下,CPSR的F, I bit一直都是1,所以arm920t core的irq, fiq全部都是disable的。即使Interrupt register打开也没有用。
3。 第一次切换进程时的恢复上下文的设置。

  1. stk = (rt_uint32_t*)stack_addr;
  2. *(stk) = (rt_uint32_t)tentry; /* entry point */
  3. *(--stk) = (rt_uint32_t)texit; /* lr */
  4. *(--stk) = 0; /* r12 */
  5. *(--stk) = 0; /* r11 */
  6. *(--stk) = 0; /* r10 */
  7. *(--stk) = 0; /* r9 */
  8. *(--stk) = 0; /* r8 */
  9. *(--stk) = 0; /* r7 */
  10. *(--stk) = 0; /* r6 */
  11. *(--stk) = 0; /* r5 */
  12. *(--stk) = 0; /* r4 */
  13. *(--stk) = 0; /* r3 */
  14. *(--stk) = 0; /* r2 */
  15. *(--stk) = 0; /* r1 */
  16. *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
  17. *(--stk) = SVCMODE; /* cpsr */
  18. *(--stk) = SVCMODE; /* spsr */

下面的SVCMODE = 0x13,那么其实CPSR register中F, I bit 已经被打开了,所以说进程一进去就可以执行。

发布于14年前

楼主正解,代码里也是这样的,打开IRQ_DEBUG,一直到rt_system_scheduler_start();
才有中断的debug输出,所以很困惑。

发布于14年前

第一个进程是idle

  1. void rt_thread_idle_init()
  2. {
  3. /* init thread */
  4. rt_thread_init(&idle,
  5. "tidle",
  6. rt_thread_idle_entry, RT_NULL,
  7. &rt_thread_stack[0], sizeof(rt_thread_stack),
  8. RT_THREAD_PRIORITY_MAX - 1, 32);
  9. /* startup */
  10. rt_thread_startup(&idle);
  11. }

然后进入到
rt_system_scheduler_start();先查找优先级最高的进程,idle,在进入上下文切换的汇编代码。

  1. /*
  2. * void rt_hw_context_switch_to(rt_uint32 to);
  3. * r0 --> to
  4. */
  5. .globl rt_hw_context_switch_to
  6. rt_hw_context_switch_to:
  7. ldr sp, [r0] @ get new task stack pointer
  8. ldmfd sp!, {r4} @ pop new task spsr
  9. msr spsr_cxsf, r4
  10. ldmfd sp!, {r4} @ pop new task cpsr
  11. msr cpsr_cxsf, r4
  12. ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc

将保存的新进程的stack pop出去,并将pc指针定位到新的进程开始执行,你知道在那里开启中断,
不胜感谢,计划rtthread移植到新的平台下,所以拿2440先study下整个流程,谢谢。

发布于14年前

当然知道,第一个线程不起来要tick没什么必要,但是,没有找到开启中断的代码
在rtthread-0.4.0,所以才困惑!你知道那段代码开启?

发布于14年前

我没说清楚,问题是,PWM Timer4中断开启,并启动了,但直到rt_system_scheduler_start()
中断才可以进到中断vector_irq中,这是为什么。请高手指点,谢谢。

发布于14年前

OK , debug也是如此
(gdb) x/60x 0x00000000
0x0: 0x3000f9c0 0xe59ff014 0xe59ff014 0xe59ff014
0x10: 0xe59ff014 0xe59ff014 0xe59ff014 0xe59ff014
0x20: 0x30000120 0x30000160 0x30000180 0x300001a0
0x30: 0x300001e0 0x300001e4 0x30000220 0xdeadbeef
0x40: 0x30000000 0x30000000 0x00000b00 0x30200000
0x50: 0x302040bc 0x30202748 0x30201f48 0x30202148
0x60: 0x30202348 0x30077804 0xe10f0000 0xe3c0001f
0x70: 0xe3800013 0xe129f000 0xe3a00453 0xe3a01000
0x80: 0xe5801000 0xe59f1270 0xe3e00000 0xe5810000
0x90: 0xe59f1268 0xe59f0268 0xe5810000 0xe59f0060
0xa0: 0xe3a01000 0xe2802020 0xe8b007f8 0xe8a107f8
0xb0: 0xe1500002 0xdafffffb 0xeb00007c 0xe3a00000
0xc0: 0xe59f1240 0xe59f2240 0xe1510002 0x34810004
0xd0: 0x3afffffc 0xe59f0234 0xe59f1234 0xe1500001
0xe0: 0x0a000005 0xe4902004 0xe92d0003 0xe1a0e00f
(gdb) x/60x 0x30000120
0x30000120 : 0xe24dd048 0xe88d1fff 0xe28d803c 0xe9486000
0x30000130 : 0xe588e000 0xe14f6000 0xe5886004 0xe5880008
0x30000140 : 0xe1a0000d 0xeb003981 0xe1a00000 0xe1a00000
0x30000150 : 0xe1a00000 0xe1a00000 0xe1a00000 0xe1a00000
0x30000160 : 0xeb00398f 0xe1a00000 0xe1a00000 0xe1a00000
0x30000170 : 0xe1a00000 0xe1a00000 0xe1a00000 0xe1a00000
0x30000180 : 0xeb003994 0xe1a00000 0xe1a00000 0xe1a00000
0x30000190 : 0xe1a00000 0xe1a00000 0xe1a00000 0xe1a00000
0x300001a0 : 0xe24dd048 0xe88d1fff 0xe28d803c 0xe9486000
0x300001b0 : 0xe588e000 0xe14f6000 0xe5886004 0xe5880008
0x300001c0 : 0xe1a0000d 0xeb003998 0xe1a00000 0xe1a00000
0x300001d0 : 0xe1a00000 0xe1a00000 0xe1a00000 0xe1a00000
0x300001e0 : 0xeb0039a6 0xe92d5fff 0xeb001dc8 0xeb0039b0
0x300001f0 : 0xeb001dd8 0xe59f011c 0xe5901000 0xe3510001
0x30000200 : 0x0a00000a 0xe8bd5fff 0xe25ef004 0xe1a00000
那么实际上可以说start_gcc.S是没有用到了

发布于14年前

以上问题还是困扰着阿,首先start_gcc.S
/ set interrupt vector /
ldr r0, _load_address
mov r1, #0x0 / target address /
add r2, r0, #0x20 / size, 32bytes /

copy_loop:
ldmia r0!, {r3-r10} / copy from source address [r0] /
stmia r1!, {r3-r10} / copy to target address [r1] /
cmp r0, r2 / until source end addreee [r2] /
ble copy_loop
中是将0x3000000~ 0x30000000+0x20的内容copy到0x00000000,但是我调试发现0x0000000的地址上全是0x00000000.
版主有说通过MMU去重新定向,意思是说在mmu_init 之后将0x00000000的虚拟地址访问时通过MMU的重新定向到0x3000000
mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0
那么实际上start_gcc.S中的copy是作工作了马?
很糊涂。谁能清晰的解释下马,非常感谢。

发布于14年前

自问自答,根据arm920t techinical ref manual
上述代码是使用的Section Descriptor:
A section descriptor provides the base addresss of a 1MB block of memory,
所以rt-thread在arm920t下应该是没有开启page功能。
但为什么是两个bank 0还是不知道哦

发布于14年前

void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
{
volatile rt_uint32_t pTT;
volatile int i,nSec;
pTT=(rt_uint32_t
)_MMUTT_STARTADDRESS+(vaddrStart>>20);
nSec=(vaddrEnd>>20)-(vaddrStart>>20);
for(i=0;i<=nSec;i++)
{
*pTT = attr |(((paddrStart>>20)+i)<<20);
pTT++;
}
}
应该是建立Address Translation Table,建立的内容如下:
//mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0
mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0
怎么会有两个bank0, 另外为什么没有页的大小之类的定义?RT-Thread是如何实现内存管理的呢?

发布于14年前

意思是说内存访问事控制器通过MMU 将0x0000,0000 (virtual Memory)<-> 0x3000,0000(physical Memory)那里?

回到
顶部

发布
问题

投诉
建议