uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(68)

系统 1657 0

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

ADI bf561 DSP

优视 BF561EVB 开发板

uclinux-2008r1.5-rc3(smp patch)

Visual DSP++ 5.0(update 5)

欢迎转载,但请保留作者信息

本文讨论链接: http://www.bfin-tools.org/bbs/viewthread.php?tid=20&extra =

在之前的处理中,只是简单地给 B 核一条 idle 指令,并让它先于 A 核运行,现在要开始使用 B 核了,自然这种方式就不好使了。

还记得 ADI 那个经典的 Set_PLL 吗?呵呵,看看:

void Set_PLL( short CoreCLOCK_multiplier, short SCLK_divider)

{ short previous_PLL= *pPLL_CTL;

short previous_SICA_IWR = *pSICA_IWR0;

short previous_SICB_IWR = *pSICB_IWR0;

short new_PLL= (previous_PLL & 0x81ff) | ((CoreCLOCK_multiplier & 0x3f) <<9);

if (new_PLL != previous_PLL) { // skip if multiplier has not changed

if (( int )(*pSRAM_BASE_ADDRESS) == 0xFF800000 ) { // do things for Core A

*pSICB_SYSCR |= 0x0080; // Raise Core B Supplemental-Int0

ssync();

while ((*pSICB_SYSCR & 0x080)) { // Wait: Core B Acknowledge SUP-B0

asm volatile ( "nop;nop;nop;nop;" );

}

*pSICA_IWR0 = (previous_SICA_IWR | 0x1); // enable PLL Wakeup Interrupt

*pPLL_CTL = new_PLL;

ssync();

idle(); // put in idle

*pSICA_IWR0 = previous_SICA_IWR; // continue here after idle, restore previous IWR content

ssync();

}

else { // do things for Core B

while (!(*pSICB_SYSCR & 0x0080)) { // Wait: For Core A to raise SUP-B0

asm volatile ( "nop;nop;nop;nop;" );

}

*pSICB_SYSCR = 0x0800; // Acknowledge Supplemental Interrupt

ssync();

*pSICB_IWR0 = (previous_SICB_IWR | 0x1); // enable PLL Wakeup Interrupt

ssync();

idle(); // put in idle

*pSICB_IWR0 = previous_SICB_IWR; // continue here after idle, restore previous IWR content

ssync();

} // if (&_CORE == 0)

} // if (new_PLL != previous_PLL)

*pPLL_DIV = (*pPLL_DIV & 0xFFF0) | SCLK_divider;

ssync();

}

这段代码无非就是撇开 SICA_SYSCR 中的 CoreB_SRAM_INIT 这一位,改用 SICB_SYSCR 进行核间通信。因为在 VDSP CoreB_SRAM_INIT 这一位总是为 0 的,也就是说 B 核总是运行的。既然如此,我们干脆大方点,一开始就把这一位清 0

看看 SICB_SYSCR

SICB_SYSCR

再看看它的使用:

Core A can write “1” to Bit 6 of SICB_SYSCR to interrupt itself or to Bit 7 to interrupt Core B. Similarly, Core B can write “1” to Bit 8 of SICB_SYSCR to interrupt Core A or to Bit 9 to interrupt itself. Writing “1” to Bits 10, 11, 12, 13, respectively, would clear these interrupts.

现在我们学习它的这种方式,在 B 核启动的时候调用这个函数:

void wait_pll_setup()

{

/* 等待 A 核进行 PLL 配置 */

short previous_SICB_IWR = *pSICB_IWR0;

while (!(*pSICB_SYSCR & 0x0080))

{

// Wait: For Core A to raise SUP-B0

asm volatile ( "nop;nop;nop;nop;" );

}

*pSICB_SYSCR = 0x0800; // Acknowledge Supplemental Interrupt

ssync();

*pSICB_IWR0 = (previous_SICB_IWR | 0x1); // enable PLL Wakeup Interrupt

ssync();

idle(); // put in idle

*pSICB_IWR0 = previous_SICB_IWR; // continue here after idle, restore previous IWR content

ssync();

// 等待真正的启动信号

while (!(*pSICB_SYSCR & 0x0080))

{

asm volatile ( "nop;nop;nop;nop;" );

}

}

这段代码将首先等待 A 核的一个中断,然后进入 IDLE 状态,这样 A 核进行的 PLL 设置就可以生效了。然后进入第二次等待,等待真正的启动信号,这样 B 核才真正开始执行,这个启动信号将在 A 核启动完成后给出,也就是原来要将 SICA_SYSCR 中的 CoreB_SRAM_INIT 这一位清 0 的位置。

A 核中,原来进行 PLL 配置是由这几行代码实现的:

//p0.h = hi(PLL_CTL);

//p0.l = lo(PLL_CTL); /* Load the address */

//cli r2; /* Disable interrupts */

//ssync;

//w[p0] = r0.l; /* Set the value */

//idle; /* Wait for the PLL to stablize */

//sti r2; /* Enable interrupts */

我们现在改用这个函数来完成:

void notify_pll_setup( unsigned int pll_value)

{

short previous_SICA_IWR = *pSICA_IWR0;

unsigned int mask;

/* The default startup code does not include any functionality to allow core

A to enable core B. A convenient way to enable core B is to use the

'adi_core_b_enable()' function. */

adi_core_b_enable();

*pSICB_SYSCR |= 0x0080; // Raise Core B Supplemental-Int0

ssync();

while ((*pSICB_SYSCR & 0x080))

{

// Wait: Core B Acknowledge SUP-B0

asm volatile ( "nop;nop;nop;nop;" );

}

*pSICA_IWR0 = (previous_SICA_IWR | 0x1); // enable PLL Wakeup Interrupt

ssync();

*pPLL_CTL = pll_value;

ssync();

idle(); // put in idle

*pSICA_IWR0 = previous_SICA_IWR; // continue here after idle, restore previous IWR content

ssync();

}

这段代码将启用 B 核,然后给它一个中断,再等待 B 核的确认,最后再写入 PLL_CTL

这样在 VDSP 下调试的时候,只要先运行 B 核就可以了。

搞定!

PS:突然想起某君的一篇论文,其实通篇就一句话:“用SICB_SYSCR进行核间通信”,居然也可以包装出一篇论文来,不得不让人感叹包装的力量,哈哈!!

1 参考资料

uclinux-2008R1.5-RC3(bf561) VDSP5 的移植 (63) _NSIG_WORDS_is_unsupported_size (2009-2-11)

uclinux-2008R1.5-RC3(bf561) VDSP5 的移植 (64) __ebss_b_l1 (2009-02-12)

uclinux-2008R1.5-RC3(bf561) VDSP5 的移植 (65) B 核启动 (2009-2-13)

uclinux-2008R1.5-RC3(bf561) VDSP5 的移植 (66) _ebss_l1 (2009-02-13)

uclinux-2008R1.5-RC3(bf561) VDSP5 的移植 (67) li1240 (2009-2-14)

uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(68):PLL配置


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论