EDN首页   博客首页 用户登陆  |  注册
aaa
发表于 2008/7/17 14:01:38

1

关于投票

分散加载的实现(scatter) zt

很多朋友对分散加载不是很理解,其实它的原来很简单,这些加载的原理都源自生活。

由于现在的嵌入式技术发展比较快,各类存储器也层出不穷,但是它们在容量、成本和速度上有所差异,嵌入式系统又对成
本比较敏感,那么合理的选择存储器和充分的利用存储器资源成为一个必要解决的问题。咋们工程师最喜欢的就是发掘问
题,然后解决问题,基于嵌入式系统对存储器的敏感,那么要合理的利用存储器资源,就必须找到一种合理的方式。工程师
们发现,可以把运行的程序放在不同成本的存储器中来寻找这个成本的支点,比如把没有运行的但是较为庞大的程序放在容
量大、成本低、速度也较低的FLASH存储器中,要用的时候再去拿。但是,这里面又有一个问题,嵌入式本身就对信号的处理
速度有较高的要求,这点在实时操作系统的定义上上有所体现。所以那些经常要用的程序段如果要保证其高速的运行那么就
得放在一个在高速的存储器中,不过这是有代价的:较高成本,小容量。但是,相信由于技术的发展这个问题终将被解决,
到时候寻找平衡点的问题也就不存在了。好了,说了多了点。切入正题。

         程序总有两种状态:运行态和静止态。当系统掉电的时候程序需要被保存在非易失性的存储器中,且这个时候程序
的排放是按照地址依次放的,换句话说:我才懒得管它怎么放,只要不掉就行。当系统上电后,CPU就要跑起来了,CPU属于
高速器件,存储器总是不怎么能跟得上,既然跟不上那么我们就尽量缩短它们之间的差距,那留下一条路,那就是尽量提高
存储器的读取速度,存储器类型决定其速度的水平,那么尽量放在速度高的存储器就成为首选解决方案。那么我们就把要执
行的程序暂时拿到速度较快的RAM中。那么拿的过程就牵涉到程序的加载了。这就是要解决的问题。

         一个映像文件由域(region)、输出段(output sections)和输入段(input sections)组成。不要想得太复杂,
其实他们之间就是包含与被包好的关系。具体关系是这样的:

        映像文件 >   域 >  输出段 >  输入段

输入段:

        输入段就是我们写的代码+初始化的数据+应该被初始化为0的数据+没有初始化的数据,用英文表示一下就是:RO
(ReadOnly),RW(ReadWrite),ZI(ZeroInitialized),NOINIT(Not Initialized)。ARM连接器根据各个输入段不同的
属性把相同的拿再一起组合一下就成为了输出段。

        请看看平时写的东东:

         AREA    RESET, CODE, READONLY

         AREA    DSEG1, DATA, READWRITE

         AREA    HEAP, NOINIT, READWRITE

看出其属性没?

输出段:

        为了简化编译过程和更容易取得各种段的地址,那么把多个同属性的输入段按照一定的规律组合在一起,当然这个
输出段的属性就和它包含的输入段的属性一样咯。输入段的排放规律就是:最先排放RO属性的输入段,然后是RW属性段,最
后是ZI或NOINIT段。

域:        

        为什么还要加一层域,我的理解是由于代码的功能不同,那么我们有必要把不同功能的代码分类放。我们可以把需
要高速执行的代码放在一起、把对速度要求不高的放在一起、把执行频率高的放在一起,把执行频率低的放在一起...那么按
照这种方式放的代码就可以根据其具体需要放在不同的存储器中了。这样可以提高程序执行速度。一个域中包含1~3个输出
段。

映像文件:

         我暂时把映像文件理解成烧到存储器中的文件,由N个域组成。这些域其实可以看做是独立的模块,只是他们按照
一定的顺序(这个顺序还是:RO+RW+ZI)被捆绑在一起,这样才方便烧写到非易失存储器中去。

        好了,了解了映像文件的组成,那么来看看映像文件是怎么跑起来的。

       映像文件就是有N节车厢的火车,车厢(域)里装着要送到不同站(不同类型的存储器)的货物。到相应的站了,那
么就把相应的车厢拿下来。指挥拿这个的就是scatter文件。拿下货物车厢后,我们就解开它,把里面的品牌为RO的货物提取
出来,按照scatter的指示发给某个地址,然后再先后把品牌为RW和ZI的货物发到scatter指定的地址。

       看看这个加深理解:

       LOAD_ROM1     0X00000000    ; 从火车上取出来时的地址(如:成都站)

{

            EXEC_ROM1       0x40000000     

            {

                   PROGRAM.O(+RO)  ;把品牌RO的货物发给0x40000000去

                    RAM1          0x80000000

                    {

                    PROGRAM.O(+RW,+ZI);把品牌RW,ZI的货物依次发给0x80000000

                     }                    

             }

             ......

}

其他的段也可以这样依葫芦画瓢。

        scatter的原理就介绍这样,其中的语法和规则要多写多把代码的地址拖出来看才能体会。不过都是很简单的,生活
中的小常识就能解决这些问题。为什么?因为设计这些规则的工程师的灵感就是源自生活。嘿嘿...享受把代码随处放的乐趣
吧,...enjoy...

系统分类: ARM  |  用户分类: arm开发  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(407) | 回复(0)

发表于 2008/5/13 12:00:18

0

关于投票

ulink原理图

点击下载

系统分类: 嵌入式  |  用户分类: arm开发  |  标签: 无标签  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(745) | 回复(1)

发表于 2007/12/5 8:33:35

0

关于投票

NXP的LPCxx系列写的测试程序

这是一个用NXPLPCxx系列写的测试程序,以前项目的一部分。应该是一个简单的测试版。其中包括了用I/O口模拟串行总线驱动ST792012864液晶。模拟I2C驱动RX8025时钟芯片,硬件I2C驱动ZLG7290数码管+按键。还有串口接收程序,比较简单。程序里面有的地方写得不好。只是希望给大家一个参考。有什么问题自己研究吧。变成自己的东西才是最终目的。

 

rar

系统分类: ARM  |  用户分类: arm开发  |  标签: ARM7  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(1193) | 回复(2)

发表于 2007/12/1 12:50:48

0

关于投票

SP3767,TEA5767调谐驱动,基于ARM,ADS1.2(转)

//SP3767和philips的TEA5767一样

/**
 * FL-120BC 收音模块 由TENSUN 深圳金图旭昂通讯科技有限公司
 * SP3767HN(the same as Philips' TEA5767HN) by SI-POWER 无锡,低功耗立体声收音电路
 * 2006 by Yan taosong<taosong.yan@gmail.com>
 */
#define  _SP3767_GLOBALS
#i nclude "fia.h"
#i nclude "sp3767.h"
#i nclude "i2c.h"
/*
苏    徐州市    徐州市    中央人民广播电台           
苏    徐州市    徐州市    江苏人民广播电台           
苏    徐州市    ??    徐州电台        94.2    
苏    徐州市    徐州市    徐州电台新闻综合频道    1269    93.0    
苏    徐州市    徐州市    徐州电台经济台    801    91.6    
苏    徐州市    徐州市    徐州电台交通台        103.3    
苏    徐州市    徐州市    徐州电台文艺之声    1143    89.6      —
苏    徐州市    贾旺区          —       
苏    徐州市    铜山县    铜山人民广播电台      —    94.2      —
苏    徐州市    沛县    沛县 徐州 221600       —         —
苏    徐州市    丰县    丰县 徐州 221700       —         —
苏    徐州市    邳州市    邳州市 徐州 221300       —         —
苏    徐州市    新沂市    新沂人民广播电台      —    99.9      —
苏    徐州市    睢宁县    睢宁县 徐州 221200       —         —
*/

/* main.c */
extern AT91PS_SYS AT91_SYS;

extern void mdelay(int ms);

int read_sp3767(char *info ,short len);
int write_sp3767(char *info ,short len);
void enable_search(void);
void disable_search(void);


char sp3767_tx[5];
char sp3767_rx[5] = { 0xff, 0xff, 0xff, 0xff, 0xff};

int write_sp3767(char *info ,short len)
{
 struct i2c_msg msgs[2];
 unsigned char rw_bit = 0;
 int ret; 
  
 msgs[0].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[0].flags = rw_bit;
 /* 无内部地址 */
 msgs[0].len = 0;
 msgs[0].buf = 0;
 
 msgs[1].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[1].flags = rw_bit;
 msgs[1].len = len;
 msgs[1].buf = info;

 ret =at91_i2c_transfer(msgs);
 
 return ret; 
}

int read_sp3767(char *info ,short len)
{
 struct i2c_msg msgs[2];
 unsigned char rw_bit = 1;//i2c read
 int ret; 
  
 msgs[0].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[0].flags = rw_bit;
 /* 无内部地址 */
 msgs[0].len = 0;
 msgs[0].buf = 0;
 
 msgs[1].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[1].flags = rw_bit;
 msgs[1].len = len;
 msgs[1].buf = info;

 ret = at91_i2c_transfer(msgs);
 
 return ret; 
}

/*
 * frq(频率)以62.5Hz为单位,如98.0MHz ,frq = 98000000/62.5=1568000
 * div与频率的关系:
 *    f="87".5MHz  ,div = (87500 * 4 + 700 + 225 + 25) / 50;
 */
void set_sp3767_freq(unsigned int frq)
{
    unsigned div;

    //printk("radio freq = %d.%03d MHz\r\n", frq/16000,(frq/16)%1000);

    sp3767_tx[2] = SP3767_PORT1_HIGH;
    sp3767_tx[3] = SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL;
    //sp3767_tx[4] = 0;

//    printk("SP3767 set to stereo\r\n");
//    printk("SP3767 radio HIGH LO inject xtal @ 32,768 MHz\r\n");
 
    sp3767_tx[2] |= SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] |= SP3767_XTAL_32768;
    /* const 700=4000*175 kHz - to adjust freq to right value */
    /* 锁相环的参考频率为32.768kHz,所以要>>15,即除以32768
     * frq*(4000/16)*/
    div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
    sp3767_tx[0] |= (div >> 8) & 0x3f;
    sp3767_tx[1] = div & 0xff;
 write_sp3767(sp3767_tx, 5);
}

void set_sp3767_freq_real(unsigned int frq)
{
    unsigned div;
    static unsigned char count="0";
 frq = frq/62.5;
    printk("radio freq = %d.%03d MHz , count:%d\r\n", frq/16000,(frq/16)%1000,count++);

    sp3767_tx[2] |= SP3767_PORT1_HIGH;
    sp3767_tx[3] |= SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL;
    sp3767_tx[4] = 0;

//    printk("SP3767 set to stereo\r\n");
//    printk("SP3767 radio HIGH LO inject xtal @ 32,768 MHz\r\n");
 
    sp3767_tx[2] |= SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] |= SP3767_XTAL_32768;
    /* const 700=4000*175 kHz - to adjust freq to right value */
    /* 锁相环的参考频率为32.768kHz,所以要>>15,即除以32768
     * frq*(4000/16)*/
    div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
    sp3767_tx[0] |= (div >> 8) & 0x3f;
    sp3767_tx[1] = div & 0xff;
 write_sp3767(sp3767_tx, 5);
}

void sp3767_auto_search(unsigned int from_frq ,unsigned int to_frq)
{
 //float step = 62.5;
 unsigned int diff;
 unsigned int frq = from_frq;//1400000;//87.5MHz
 unsigned div;
 unsigned char station = 0;
 unsigned char completed = 0;
 char buf[5];
 
 //set_sp3767_freq_real(100000000);
 
 for (diff = 0 ;diff < 2000 ;diff ++){
  set_sp3767_freq_real(87500000+diff*10000);
  enable_search();
  read_sp3767(buf ,5);
  while(!(buf[0]&0x80)&&!completed){
   read_sp3767(buf ,5);
   mdelay(20);
   //if((buf[0]&0x80))printk("locked   \r\n");
   if((buf[1]&0x7f)>0x31&&(buf[1]&0x7f)<0x3E){
    completed = TRUE;
    
    printk("Locked  buf[1]:%x \r\n",(buf[1]&0x7f));
    
   }
  }
  completed = FALSE;
  //mdelay(100);
  //disable_search();
  mdelay(50);
 }
 
 
 
#if 0 
 enable_search();
 
 
 from_frq = (unsigned int)((float)from_frq/62.5);
 to_frq   = (unsigned int)((float)to_frq/62.5);
   

 for (diff = 0 ;diff <= (to_frq - from_frq)/100 && !completed;diff++){
  //set_sp3767_freq(from_frq + diff*100);
  read_sp3767(buf ,5);  
  /* RF : 1 ,a band is locked
   *      0 ,no band is locked */
   //div = ((unsigned)(buf[0]&0x3f)<<8)+(unsigned)buf[1];
   //frq = ((((unsigned int)div << 15) - 700000 - 225000 - 16384)*16)/4000;
   
   //printk("%d.%03dMHz ,frq=%d\r\n",frq/16000 ,(frq/16)%1000,frq);
   mdelay(20);//400
 //  div = ((unsigned)(buf[0]&0x3f)<<8)+((unsigned)buf[1])&0x00ff;
 //  frq = (unsigned int)((((float)( ((unsigned int)div * 32768) - 700000 - 225000 - 16384)*16)/4000)*62.5);
 //  printk("locked! ,diff:%d,station:%d,frq=%d,[0]:%x,[1]:%x,[2]:%x\r\n",diff,station,frq,buf[0],buf[1],buf[2]);
#if 1
  if (buf[0] & SP3767_READY_FLAG_MASK){
   station++;
   enable_search();
   div = ((unsigned)(buf[0]&0x3f)<<8)+(((unsigned)buf[1])&0x00ff);
   frq = (unsigned int)((((float)( ((unsigned int)div * 32768) - 700000 - 225000 - 16384)*16)/4000)*62.5);
   //printk("%d.%03dMHz band is locked , station = %d\r\n",frq/16000 ,(frq/16)%1000 ,station);
   //printk("locked!");
   //buf[2]:IF
   //set_sp3767_freq_real(frq);
   printk("locked! ,diff:%d,station:%d,frq=%d,[0]:%x,[1]:%x,[2]:%x\r\n",diff,station,frq,buf[0],buf[1],buf[2]);
   mdelay(200);
   //station ++;
  }
#endif  
  /* 先自动搜索5个台试试看 */
  //if (station >= 5)
   //completed = 1;  
 }
 disable_search();
#endif
 
}


void turn_on_sp3767(void)
{
 sp3767_tx[3] &= (~SP3767_STDBY);
 sp3767_tx[0] &= (~SP3767_MUTE);
 write_sp3767(sp3767_tx, 5);
 printk("Turn on radio.\r\n");
}

/* 待机模式,STBY(standby) */
void turn_off_sp3767(void)
{
 sp3767_tx[3] |= SP3767_STDBY;
 write_sp3767(sp3767_tx, 5);
}

void enable_search(void)
{
 /* Enable search mode */
 sp3767_tx[0] |= SP3767_SEARCH;
 write_sp3767(sp3767_tx, 5);
}

void disable_search(void)
{
 /* Disable search mode */
 sp3767_tx[0] &= (~SP3767_SEARCH);
 write_sp3767(sp3767_tx, 5);
}

int sp3767_detect(void)
{
 read_sp3767(sp3767_rx ,5);

  printk("rx[0] = %x ,rx[1] = %x ,rx[2] = %x ,rx[3] = %x ,rx[4] = %x \r\n",sp3767_rx[0],sp3767_rx[1],sp3767_rx[2],sp3767_rx[3],sp3767_rx[4]);
    /*  Status bytes:
     *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
     *          bit 0   : internally set to 0
     *  Byte 5: bit 7:0 : == 0 */
    if (((sp3767_rx[3] & 0x0f) != 0x00) || (sp3767_rx[4] != 0x00)) {
     printk("Chip ID is not zero. It is not a SP3767\r\n");
        return -1;
    }
 
 printk("SP3767 detected.\r\n");
 return 0;
 
}

void AT91F_SP3767_CfgPIO(void)
{
 /* I2C configuration */
 //AT91_SYS->PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
 //AT91_SYS->PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK; 
}

int sp3767_init(void)
{
 /* 对SP3767所需要的PIO进行初始化 */
 AT91F_SP3767_CfgPIO();
 /* Detect SP3767 */
 if(sp3767_detect()){
  printk("Can't find SP3767\r\n");
  return -1;
 }

 /* 静音,非搜索模式 */
 sp3767_tx[0] = SP3767_MUTE;
 sp3767_tx[1] = 0;
 /* 搜索停止标准:搜索模式下禁止 , 立体声 ,左右声道正常 */
 //sp3767_tx[2] = 0;
    //sp3767_tx[2] = SP3767_PORT1_HIGH;
    /* 自动搜索时,由高频往低频搜索(搜索方向) */
    sp3767_tx[2] = SP3767_PORT1_HIGH/*|SP3767_SEARCH_UP*/|SP3767_SRCH_HIGH_LVL|SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] = SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL|SP3767_XTAL_32768|SP3767_STDBY;
 /* 初始化处于待机模式 ,XTAL为32.768KHz */
 //sp3767_tx[3] = SP3767_STDBY|SP3767_XTAL_32768;
 sp3767_tx[4] = 0;
 /* Write SP3767 initial status */
 //write_sp3767(sp3767_tx, 5);
 return 0;
}

 

连接:http://www.mcublog.com/blog/user1/11414/archives/2006/16753.html

系统分类: ARM  |  用户分类: arm开发  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(999) | 回复(1)

发表于 2007/11/28 21:53:39

0

关于投票

嵌入式系统 Boot Loader 技术内幕

很不错的一篇文章

http://www.ibm.com/developerworks/cn/linux/l-btloader/index.html

 

系统分类: 嵌入式  |  用户分类: arm开发  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(675) | 回复(0)

发表于 2007/11/20 9:05:50

1

关于投票

lcp21xx系列keil下的例程

仅供参考

rar

zip

系统分类: 汽车电子  |  用户分类: arm开发  |  标签: 无标签  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(664) | 回复(0)

发表于 2007/11/14 11:39:56

0

关于投票

嵌入式linux开发入门

华恒的一篇嵌入式linux入门文档。pdf

系统分类: 汽车电子  |  用户分类: arm开发  |  标签: arm9  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(576) | 回复(0)

发表于 2007/11/14 11:35:22

1

关于投票

AT91SAM7S64 深圳英贝德的开发板

深圳英贝德公开的资料,学习atmel的arm7的朋友可以参考一下,这块板子的重点是can总线。一般的开发板好像都没有can。我把资料传上来。另外pcb图是powerpcb画的。打开的时候注意一下

原理图:pdf

pcb图:rar

文档:rar

系统分类: 汽车电子  |  用户分类: arm开发  |  标签: arm7  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(790) | 回复(0)

Total , Page /