网站公告列表

  没有公告

加入收藏
设为首页
联系本站
您现在的位置: AnalogCN安诺电子 >> 文章 >> 技术交流 >> 文章正文
  uclinux-2008R1-RC8(bf561)到VDSP5的移植(29):spinlock           ★★★ 【字体:
uclinux-2008R1-RC8(bf561)到VDSP5的移植(29):spinlock
作者:快乐虾    文章来源:http://blog.csdn.net/lights_joy    点击数:    更新时间:2008-5-12    
spinlock是用于线程间同步的自旋锁,由于我们希望使用BF561的两个核,因此它就显得极为重要。
1             定义
在内核中声明一个spinlock可以使用DEFINE_SPINLOCK这个宏定义,它的定义在include/linux/spinlock_types.h中:
#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
其中spinlock_t是在include/linux/spinlock_types.h中定义的一个结构体:
 
typedef struct {
     raw_spinlock_t raw_lock;
#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
     unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
     unsigned int magic, owner_cpu;
     void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
     struct lockdep_map dep_map;
#endif
} spinlock_t;
因为我们只定义了CONFIG_SMP,因此这个结构体实际就是:
 
typedef struct {
     raw_spinlock_t raw_lock;
} spinlock_t;
raw_spinlock_t的定义在include/asm/spinlock_types.h中:
 
typedef struct {
     volatile unsigned int lock;
} raw_spinlock_t;
在此之前,我们只是简单地将其设置为volatile unsigned int的类型,而现在,我们则希望借助于VDSP的库进行核间同步,因此将其定义改为:
 
typedef struct {
     testset_t lock;
} raw_spinlock_t;
因为testset_t自动就是volatile类型的,在此就不用声明了。
2             VDSP对核间同步的支持
以下内容来自VDSP的帮助:
Synchronization Functions

VisualDSP++ 5.0 provides functionality for synchronization. There are two compiler intrinsics (built-in functions) and three locking routines.
The compiler intrinsics are:
   #include <ccblkfn.h>
   int testset(char *);
   void untestset(char *);
The testset() intrinsic generates a native TESTSET instruction, which can perform atomic updates on a memory location. The intrinsic returns the result of the CC flag produced by the TESTSET instruction. Refer to the instruction set reference for details.
The untestset() intrinsic clears the memory location set by the
testset() intrinsic. This intrinsic is recommended in place of a normal memory write because the untestset() intrinsic acts as a stronger barrier to code movement during optimization.
The three locking routines are:
   #include <ccblkfn.h>
   void adi_acquire_lock(testset_t *);
   int adi_try_lock(testset_t *);
   void adi_release_lock(testset_t *);
The adi_acquire_lock() routine repeatedly attempts to claim the lock by issuing testset() until successful, whereupon it returns to the caller. In contrast, the adi_try_lock() routine makes a single attempt—if it successfully claims the lock, it returns nonzero, otherwise it returns zero.
The adi_release_lock() routine releases the lock obtained by either adi_acquire_lock() or adi_try_lock(). It assumes that the lock was already claimed and makes no attempt to verify that its caller is in fact the current owner of the lock. None of these intrinsics or functions disable interrupts—that is left to the caller’s discretion.
3             spin_lock
spin_lock的定义在include/linux/spinlock.h中:
#define spin_lock(lock)          _spin_lock(lock)
_spin_lock的定义在include/linux/spinlock_api_smp.h中:
void __lockfunc _spin_lock(spinlock_t *lock)       __acquires(lock);
而其实现则在kernel/spinlock.c中:
 
void __lockfunc _spin_lock(spinlock_t *lock)
{
     preempt_disable();
     spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
     _raw_spin_lock(lock);
}
_raw_spin_lock的实现则是不同的体系结构有不同的方法,但是其实现一般都放在asm/spinlock.h中,我们也这样做:
 
 
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
     adi_acquire_lock(&lock->lock);
}
 
4             .spinlock.text
uclinux为spinlock相关的函数定义了一个段:
#define __lockfunc fastcall __attribute__((section(".spinlock.text")))
因此我们需要在LDF文件中加上它:
 
        .text
        {
         INPUT_SECTION_ALIGN(4)
         . = (. + 3) / 4 * 4;
               __text = .;
               _text = .;
               __stext = .;
               
         INPUT_SECTIONS($OBJECTS_CORE_A(sdram_bank0) $LIBRARIES_CORE_A(sdram_bank0))
         INPUT_SECTIONS($OBJECTS_CORE_A(VDK_ISR_code) $LIBRARIES_CORE_A(VDK_ISR_code))
         INPUT_SECTIONS($OBJECTS_CORE_A(program) $LIBRARIES_CORE_A(program))
         INPUT_SECTIONS($OBJECTS_CORE_A(noncache_code) $LIBRARIES_CORE_A(noncache_code))
        
               INPUT_SECTIONS($LIBRARIES_CORE_A(.text.*))
               INPUT_SECTIONS($LIBRARIES_CORE_A(.fixup))
               INPUT_SECTIONS($LIBRARIES_CORE_A(.spinlock.text))
 
         INPUT_SECTION_ALIGN(16)
         . = (. + 15) / 16 * 16;
               ___start___ex_table = .;
               INPUT_SECTIONS($LIBRARIES_CORE_A(__ex_table))
              ___stop___ex_table = .;
 
         INPUT_SECTION_ALIGN(4)
         . = (. + 3) / 4 * 4;
               __etext = .;
        } > MEM_SDRAM
文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    ucos-ii在嵌入式智能视觉监控
    14bit 40 MSamples/s ADC应用
    打造windows下的嵌入式开发工
    DSP和FPGA在汽车电子中的广泛
    [连载]ADSP-TSl01S系列之一 
    ADI ADIS1625x低功耗陀螺仪方
    基于DSP的实时图像跟踪系统的
    wxWidgets和MFC动态类型信息
    用dll方式编译wxWidgets-2.8
    Blackfin时钟控制
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    版权所有:AnalogCN安诺电子 湘ICP备06016315号