S3C2440 SDRAM内存驱动
s3c2410s3c2440处理器介绍
鲁东大学 LUDONG UNIVERSITY
S3C2410A结构框图
S3c2440处理 器结构框图
❖ S3C2410A在片上,S3通C过24A1M0ABA简总介线集成了以下资源:
AHB总线-各类控制器
✓支持STN和TFT的LCD控制器 ✓ NAND Flash 控制器 ✓存储管理器(片选逻辑和SDRAM控制器) ✓时钟及电源管理器
APB总线-设备与接口 ✓ 3通道UART、 ✓ 4通道DMA、 ✓ 4通道PWM定时器、 ✓ I/O口、 ✓ RTC、
: 1M bps
CTS/RTS
Key
Debug
GPS
BT
Matrix
SRAM/ROM /NOR Flash /OneNAND/OneDRAM
1Gbit X 6banks (x8/x16/x32)
UART0 SMC
UART1
NAND
NAND Flash IF
SDRAM/mDDR
1Gbit X 2banks (x16/x32)
PMIC
Main Charger
Li-Ion
USB Charger
Control
Data
5V DC
5V USB
TV-out
TV
TFT/CSTN LCDC + SPI(GPIO) + TSADC RGB I/F
Main TFT LCD & TSP
1/2/4/8/16 bpp Up to QVGA
SD/SDIO IIS I/F
✓ I2C总线接口、 ✓ I2S总线接口、 ✓ USB主设备、USB从设备 ✓ SD主卡和MMC(Multi Media Card,多媒体卡)卡接口 ✓2通道的SPI接口)
SPI驱动程序(S3C2440)
2410_SPI接口与linux驱动以下先从下到上的进行分析:driver/spi下有两个底层相关的spi驱动程序:spi_s3c24xx.c和spi_s3c24xx_gpio.c其中spi_s3c24xx.c是基于s3c24xx下相应的spi接口的驱动程序,spi_s3c24xx_gpio.c允许用户指定3个gpio口接口,模拟标准的spi总线。
s3c2410自带了两个spi接口(spi0和spi1),在此我只研究基于s3c2410下spi接口的驱动程序spi_s3c24xx.c。
首先从spi驱动的检测函数进行分析:static int s3c24xx_spi_probe(struct platform_device *pdev){struct s3c24xx_spi *hw;struct spi_master *master;struct spi_board_info *bi;struct resource *res;int err = 0;int i;master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); if (master == NULL) {dev_err(&pdev->dev, "No memory for spi_master\n");err = -ENOMEM;goto err_nomem;}hw = spi_master_get_devdata(master);memset(hw, 0, sizeof(struct s3c24xx_spi));hw->master = spi_master_get(master);hw->pdata = pdev->dev.platform_data;hw->dev = &pdev->dev;if (hw->pdata == NULL) {dev_err(&pdev->dev, "No platform data supplied\n");err = -ENOENT;goto err_no_pdata;}platform_set_drvdata(pdev, hw);//dev_set_drvdata(&pdev->dev, hw) init_completion(&hw->done);hw->bitbang.master = hw->master;hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;hw->bitbang.chipselect = s3c24xx_spi_chipsel;hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;hw->bitbang.master->setup = s3c24xx_spi_setup;dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (res == NULL) {dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");err = -ENOENT;goto err_no_iores;}hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, pdev->name);if (hw->ioarea == NULL) {dev_err(&pdev->dev, "Cannot reserve region\n");err = -ENXIO;goto err_no_iores;}hw->regs = ioremap(res->start, (res->end - res->start)+1);if (hw->regs == NULL) {dev_err(&pdev->dev, "Cannot map IO\n");err = -ENXIO;goto err_no_iomap;}hw->irq = platform_get_irq(pdev, 0);if (hw->irq < 0) {dev_err(&pdev->dev, "No IRQ specified\n");err = -ENOENT;goto err_no_irq;}err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);if (err) {dev_err(&pdev->dev, "Cannot claim IRQ\n");goto err_no_irq;}hw->clk = clk_get(&pdev->dev, "spi");if (IS_ERR(hw->clk)) {dev_err(&pdev->dev, "No clock for device\n");err = PTR_ERR(hw->clk);goto err_no_clk;}clk_enable(hw->clk);writeb(0xff, hw->regs + S3C2410_SPPRE);writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);s3c2410_gpio_setpin(S3C2410_GPE13, 0);s3c2410_gpio_setpin(S3C2410_GPE12, 0);s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0); s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0); s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0);if (!hw->pdata->set_cs) {s3c2410_gpio_setpin(hw->pdata->pin_cs, 1);s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); }err = spi_bitbang_start(&hw->bitbang);if (err) {dev_err(&pdev->dev, "Failed to register SPI master\n");goto err_register;}dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown);bi = &hw->pdata->board_info[0];for (i = 0; i < hw->pdata->board_size; i++, bi++) {dev_info(hw->dev, "registering %s\n", bi->modalias);bi->controller_data = hw;spi_new_device(master, bi);}return 0;err_register:clk_disable(hw->clk);clk_put(hw->clk);err_no_clk:free_irq(hw->irq, hw);err_no_irq:iounmap(hw->regs);err_no_iomap:release_resource(hw->ioarea);kfree(hw->ioarea);err_no_iores:err_no_pdata:spi_master_put(hw->master);;err_nomem:return err;}struct spi_master * __init_or_modulespi_alloc_master(struct device *dev, unsigned size) {struct spi_master *master;if (!dev)return NULL;master = kzalloc(size + sizeof *master, SLAB_KERNEL); if (!master)return NULL;class_device_initialize(&master->cdev);master->cdev.class = &spi_master_class;master->cdev.dev = get_device(dev);spi_master_set_devdata(master, &master[1]);return master;}int spi_bitbang_start(struct spi_bitbang *bitbang){int status;if (!bitbang->master || !bitbang->chipselect)return -EINVAL;INIT_WORK(&bitbang->work, bitbang_work, bitbang);spin_lock_init(&bitbang->lock);spi_new_device INIT_LIST_HEAD(&bitbang->queue);if (!bitbang->master->transfer)bitbang->master->transfer = spi_bitbang_transfer;//spi数据的传输就是通过调用这个方法来实现的if (!bitbang->txrx_bufs) {bitbang->use_dma = 0;bitbang->txrx_bufs = spi_bitbang_bufs;if (!bitbang->master->setup) {if (!bitbang->setup_transfer)bitbang->setup_transfer =spi_bitbang_setup_transfer;bitbang->master->setup = spi_bitbang_setup;bitbang->master->cleanup = spi_bitbang_cleanup;}} else if (!bitbang->master->setup)return -EINVAL;bitbang->busy = 0;bitbang->workqueue = create_singlethread_workqueue(bitbang->master->cdev.dev->bus_id);if (bitbang->workqueue == NULL) {status = -EBUSY;goto err1;}status = spi_register_master(bitbang->master);if (status < 0)goto err2;return status;err2:destroy_workqueue(bitbang->workqueue);err1:return status;}int __init_or_modulespi_register_master(struct spi_master *master){static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);struct device *dev = master->cdev.dev;int status = -ENODEV;int dynamic = 0;if (!dev)return -ENODEV;if (master->bus_num < 0) {master->bus_num = atomic_dec_return(&dyn_bus_id); dynamic = 1;}snprintf(master->cdev.class_id, sizeof master->cdev.class_id, "spi%u", master->bus_num);status = class_device_add(&master->cdev);//注册设备if (status < 0)goto done;dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, dynamic ? " (dynamic)" : "");scan_boardinfo(master);status = 0;done:return status;}static void __init_or_modulescan_boardinfo(struct spi_master *master){struct boardinfo *bi;struct device *dev = master->cdev.dev;down(&board_lock);list_for_each_entry(bi, &board_list, list) {struct spi_board_info *chip = bi->board_info;unsigned n;for (n = bi->n_board_info; n > 0; n--, chip++) {if (chip->bus_num != master->bus_num)continue;if (chip->chip_select >= master->num_chipselect&& master->num_chipselect) {dev_dbg(dev, "cs%d > max %d\n",chip->chip_select,master->num_chipselect);continue;}(void) spi_new_device(master, chip);}}up(&board_lock);}int __initspi_register_board_info(struct spi_board_info const *info, unsigned n)struct boardinfo *bi;bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);if (!bi)return -ENOMEM;bi->n_board_info = n;memcpy(bi->board_info, info, n * sizeof *info);down(&board_lock);list_add_tail(&bi->list, &board_list);up(&board_lock);return 0;}struct spi_device *__init_or_modulespi_new_device(struct spi_master *master, struct spi_board_info *chip){struct spi_device *proxy;//这个结构很重要,以后就是通过这个结构来操作实际的spi设备的struct device *dev = master->cdev.dev;int status;if (!spi_master_get(master))return NULL;proxy = kzalloc(sizeof *proxy, GFP_KERNEL);if (!proxy) {dev_err(dev, "can't alloc dev for cs%d\n",chip->chip_select);goto fail;}proxy->master = master;proxy->chip_select = chip->chip_select;proxy->max_speed_hz = chip->max_speed_hz;proxy->mode = chip->mode;proxy->irq = chip->irq;proxy->modalias = chip->modalias;snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,"%s.%u", master->cdev.class_id,chip->chip_select);proxy->dev.parent = dev;proxy->dev.bus = &spi_bus_type;proxy->dev.platform_data = (void *) chip->platform_data; proxy->controller_data = chip->controller_data;proxy->controller_state = NULL;proxy->dev.release = spidev_release;status = master->setup(proxy);if (status < 0) {dev_dbg(dev, "can't %s %s, status %d\n","setup", proxy->dev.bus_id, status);goto fail;}status = device_register(&proxy->dev);//真正注册原始设备if (status < 0) {dev_dbg(dev, "can't %s %s, status %d\n","add", proxy->dev.bus_id, status);goto fail;}dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id); return proxy;fail:spi_master_put(master);kfree(proxy);return NULL;}static int s3c24xx_spi_setup(struct spi_device *spi){int ret;if (!spi->bits_per_word)spi->bits_per_word = 8;if ((spi->mode & SPI_LSB_FIRST) != 0)return -EINVAL;ret = s3c24xx_spi_setupxfer(spi, NULL);if (ret < 0) {dev_err(&spi->dev, "setupxfer returned %d\n", ret);return ret;}dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n",__FUNCTION__, spi->mode, spi->bits_per_word,spi->max_speed_hz);return 0;}static int s3c24xx_spi_setupxfer(struct spi_device *spi,struct spi_transfer *t){struct s3c24xx_spi *hw = to_hw(spi);unsigned int bpw;unsigned int hz;unsigned int div;bpw = t ? t->bits_per_word : spi->bits_per_word;hz = t ? t->speed_hz : spi->max_speed_hz;if (bpw != 8) {dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);return -EINVAL;}div = clk_get_rate(hw->clk) / hz;div = (div / 2) - 1;//求出预分频值if (div < 0)div = 1;if (div > 255)div = 255;dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz);writeb(div, hw->regs + S3C2410_SPPRE);//设置预分频值spin_lock(&hw->bitbang.lock);if (!hw->bitbang.busy) {hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);//修改时钟,先禁用spi}spin_unlock(&hw->bitbang.lock);return 0;}static void s3c24xx_spi_chipsel(struct spi_device *spi, int value){struct s3c24xx_spi *hw = to_hw(spi);unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;unsigned int spcon;switch (value) {case BITBANG_CS_INACTIVE:if (hw->pdata->set_cs)hw->pdata->set_cs(hw->pdata, value, cspol);elses3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1);break;case BITBANG_CS_ACTIVE:spcon = readb(hw->regs + S3C2410_SPCON);if (spi->mode & SPI_CPHA)spcon |= S3C2410_SPCON_CPHA_FMTB;elsespcon &= ~S3C2410_SPCON_CPHA_FMTB;if (spi->mode & SPI_CPOL)spcon |= S3C2410_SPCON_CPOL_HIGH;elsespcon &= ~S3C2410_SPCON_CPOL_HIGH;spcon |= S3C2410_SPCON_ENSCK;writeb(spcon, hw->regs + S3C2410_SPCON);if (hw->pdata->set_cs)hw->pdata->set_cs(hw->pdata, value, cspol);elses3c2410_gpio_setpin(hw->pdata->pin_cs, cspol);break;}}好了,至此spi主控制器(驱动)和板上spi设备注册完毕,以后要使用spi来传输数据的话,只要先获得spi设备交道了(就好像你要操作一个文件,先要获取文件句柄一样,明白吧^_^)原文地址/luofuchong/archive/2007/09/24/33942.html~~~~~~~~~~~~~~~~~~``任何SPI都有4种模式2008-11-06 22:17void McBSPObj::McBSP0Init(void)//McBSP从设备SPI硬件配置{//PCR设置过程(FSM=0,CLKM=0)McBSP0->SPSA = PCR;McBSP1->SPSD = (0 << PCR_XIOEN) //发送非通用I/O模式位| (0 << PCR_RIOEN) //接收非通用I/O模式位| (0 << PCR_FSXM) //外部发送帧同步脉冲(外部片选)| (0 << PCR_FSRM) //外部接收帧同步脉冲(外部片选)| (0 << PCR_CLKXM) //外部发送时钟(外部时钟源)| (0 << PCR_CLKRM) //外部接收时钟(外部时钟源)#if SPIMODE == 0//SPI设置过程00(0--FS高电平有效,0--CLK上升沿收发数据)| (0 << PCR_FSXP) //发送帧同步脉冲极性(高电平有效)| (0 << PCR_FSRP) //接收帧同步脉冲极性(高电平有效)| (0 << PCR_CLKXP) //发送时钟极性(上升沿发送数据)| (0 << PCR_CLKRP);//接收时钟极性(上升沿接收数据)#endif#if SPIMODE == 1//SPI设置过程01(0--FS高电平有效,1--CLK下降沿收发数据)| (0 << PCR_FSXP) //发送帧同步脉冲极性(高电平有效)| (0 << PCR_FSRP) //接收帧同步脉冲极性(高电平有效)| (1 << PCR_CLKXP) //发送时钟极性(下降沿发送数据)| (1 << PCR_CLKRP);//接收时钟极性(下降沿接收数据)#endif#if SPIMODE == 2//SPI设置过程10(1--FS低电平有效,0--CLK上升沿收发数据)| (1 << PCR_FSXP) //发送帧同步脉冲极性(低电平有效)| (1 << PCR_FSRP) //接收帧同步脉冲极性(低电平有效)| (0 << PCR_CLKXP) //发送时钟极性(上升沿发送数据)| (0 << PCR_CLKRP);//接收时钟极性(上升沿接收数据)#endif#if SPIMODE == 3//SPI设置过程11(1--FS低电平有效,1--CLK下降沿收发数据)| (1 << PCR_FSXP) //发送帧同步脉冲极性(低电平有效)| (1 << PCR_FSRP) //接收帧同步脉冲极性(低电平有效)| (1 << PCR_CLKXP) //发送时钟极性(下降沿发送数据)| (1 << PCR_CLKRP);//接收时钟极性(下降沿接收数据)#endif//MCR1设置过程(RMCM=0)McBSP0->SPSA = MCR1;//McBSP0->SPSD = (0 << MCR1_RMCM) //允许接收多通道选择(0)| (0x00 << MCR1_RPBBLK)| (0x00 << MCR1_RPABLK)| (0x00 << MCR1_RCBLK);//MCR2设置过程(XMCM=0)McBSP0->SPSA = MCR2;//McBSP0->SPSD = (0x00 << MCR2_XMCM) //允许发送多通道选择(00b) | (0x00 << MCR2_XPBBLK)| (0x00 << MCR2_XPABLK)| (0x00 << MCR2_XCBLK);//RCERA设置过程McBSP0->SPSA = RCERA;//McBSP0->SPSD = 0;//RCERB设置过程McBSP0->SPSA = RCERB;//McBSP0->SPSD = 0;//XCERA设置过程McBSP0->SPSA = XCERA;//McBSP0->SPSD = 0;//XCERB设置过程McBSP0->SPSA = XCERB;//McBSP0->SPSD = 0;//XCR1设置过程McBSP0->SPSA = XCR1;//McBSP0->SPSD = (0x00 << XCR1_XFRLEN1) //每帧1个字(每帧中断的次数1!!!) // | (0x02 << XCR1_XWDLEN1);//每字16位长(每次中断的字节数2!!!)| (0x00 << XCR1_XWDLEN1);//每字8位长(每次中断的字节数2!!!)//XCR2设置过程McBSP0->SPSA = XCR2;McBSP0->SPSD = (0 << XCR2_XPHASE) //单相帧(其他设置都为0)| (0x00 << XCR2_XCOMPAND)//发送数据从最高位(MSB)开始| (0x00 << XCR2_XDATDLY);//同步后延迟0位数据//RCR1设置过程McBSP0->SPSA = RCR1;McBSP0->SPSD = (0x00 << RCR1_RFRLEN1) //每帧1个字(每帧中断的次数1!!!) // | (0x02 << RCR1_RWDLEN1);//每字16位长(每次中断的字节数2!!!)| (0x00 << RCR1_RWDLEN1);//每字8位长(每次中断的字节数2!!!)//RCR2设置过程McBSP0->SPSA = RCR2;McBSP0->SPSD = (0 << RCR2_RPHASE) //单相帧(其他设置都为0)| (0x00 << RCR2_RCOMPAND)//接收数据从最高位(MSB)开始| (0x00 << RCR2_RDATDLY);//同步后延迟0位数据//SRGR1设置过程McBSP0->SPSA = SRGR1;McBSP0->SPSD = (0x00 << SRGR1_CLKGDV);//1//SRGR2设置过程McBSP0->SPSA = SRGR2;McBSP0->SPSD = (0 << SRGR2_FSGM)| (1 << SRGR2_CLKSM)//由CPU时钟产生的采样率时钟1| (0 << SRGR2_CLKSP)//0| (1 << SRGR2_GSYNC)//| (0x0f << SRGR2_FPER);//0x0f//SPCR1设置过程(CLKSTP=1Xb,RINTM=00b)McBSP0->SPSA = SPCR1;McBSP0->SPSD = (0x00 << SPCR1_RINTM) //接收中断模式00(每帧接收1次中? | (0 << SPCR1_DLB) //禁止回送| (1 << SPCR1_DXENA) //DX使能| (0x00 << SPCR1_RJUST) //接收符号不扩展| (0x02 << SPCR1_CLKSTP);//SPI模式时钟开始于上升沿(无延迟)//SPCR2设置过程(XINTM=02b)McBSP0->SPSA = SPCR2;McBSP0->SPSD = (0x02 << SPCR2_XINTM)//发送中断模式02| (1 << SPCR2_XEMPTY) //发送移位寄存器空| (1 << SPCR2_XRDY); //发送准备好//SPCR1复位过程McBSP0->SPSA = SPCR1;McBSP0->SPSD|= (1 << SPCR1_RRST);//接收器复位//SPCR2复位过程McBSP0->SPSA = SPCR2;McBSP0->SPSD|= (1 << SPCR2_XRST)//发送器复位| (1 << SPCR2_GRST)//采样率发生器复位| (1 << SPCR2_FRST);//帧同步发生器复位//清除允许BXINT0中断过程// SREG->IFR = (1 << IFR_BXINT0);//清除BXINT0中断标志// SREG->IMR |= (1 << IMR_BXINT0);//允许BXINT0中断//清除允许BRINT0中断过程SREG->IFR = (1 << IFR_BRINT0);//清除BRINT0中断标志SREG->IMR |= (1 << IMR_BRINT0);//允许BRINT0中断}void McBSPObj::McBSP1Init(void)//GPIO配置{McBSP1->SPSA = SPCR1;McBSP1->SPSD = 0;McBSP1->SPSA = SPCR2;McBSP1->SPSD = 0;McBSP1->SPSA = PCR;//设置收发。
使用JLink间接烧写S3C2410、S3C2440开发板Nor、Nand Flash的方法
nand write.jffs2 30000000 0 30000 // 把前面下载到 0x30000000 的程序烧写到 Nand 去
注意,上面用的 2ffff、30000 等数字是 192K,如果你的程序比较小,请自行设置。
本贴被 juedi 编辑过,最后修改时间:2009-03-04,14:30:34.
3. 下载特制的 uboot: h loadbin e:\u-boot.bin 0x33f80000 setpc 0x33f80000 g 上述操作命令可以参考图 5。
(原文件名:使用 jlink 下载运行 uboot.JPG) 现在,u-boot 已经启动了,在串口工具上可以看到如图 6 所示界面,以后就可以通过网络、串口下载文件,然后使用 u-boot 里 的命令进行烧写。
1. speed 12000
//设置 TCK 为 12M,下载程序时会很快
2. 下载并运行 init.bin,这是用来初始化 SDRAM 的 2.1 如果是 NAND 启动: loadbin e:\init.bin 0 setpc 0 g 2.2 如果是 Nor 启动: loadbin e:\init.bin 0x40000000 setpc 0x40000000 g
编辑 删除 编辑 删除
积分:287 派别: 等级:-----来自:广东佛山
__________________________ suffering from C library
2009-03-04,14:38: 19
资料 邮件
编辑 删除
【3 楼】 yangsen 积分:1199 派别: 等级:-----来自:
顶一个,好东东
2009-03-04,14:49: 02
星S3C2440微处理器
应用实例一:嵌入式系统开发
嵌入式系统开发
星S3C2440微处理器适用于嵌入 式系统开发,其强大的处理能力 和丰富的外设接口使其成为嵌入 式领域的理想选择。
实时操作系统
星S3C2440微处理器支持实时操 作系统(RTOS)的开发,RTOS 能够提供实时任务调度和多任务 处理能力,满足实时系统的需求。
3
APB和ASB总线
APB和ASB总线用于连接低速外设,如GPIO、 UART等。
03
星S3C244ห้องสมุดไป่ตู้微处理器的指令集 架构
指令集架构概述
ARM架构
01
S3C2440微处理器采用ARM架构,属于精简指令集(RISC)的
范畴。
指令集发展历程
02
ARM架构的指令集经过多年的发展,已成为移动设备和嵌入式
指令集功能
数据处理指令
用于执行算术、逻辑、移位等基本操 作。
控制流程指令
用于控制程序的执行流程,如条件判 断、跳转等。
内存访问指令
用于读写内存和访问外部存储器。
协处理器指令
用于执行特定功能,如浮点运算、加 密等。
指令集实现方式
汇编语言
使用汇编语言编写程序,通过汇编器将汇编代码转换 为机器码。
C/C语言
星S3C2440微处理器
• 星S3C2440微处理器概述 • 星S3C2440微处理器的体系结构 • 星S3C2440微处理器的指令集架构
• 星S3C2440微处理器的编程模型 • 星S3C2440微处理器的应用实例
01
星S3C2440微处理器概述
定义与特点
定义
S3C2440是一款由三星公司开发的 ARM920T核的微处理器。
嵌入式课后习题答案
第八章
一、填空题。
1、Makefile、配置文件、配置工具。
2、配置命令解释器、配置用户界面。
arch:arch目录包括了所有和体系结构相关的核心代码。include:include目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux子目录下;init:init目录包含核心的初始化代码(不是系统的引导代码),有main.c和Version.c两个文件;mm:mm目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下;drivers:drivers目录中是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound;ipc:ipc目录包含了核心进程间的通信代码;modules:modules目录存放了已建好的、可动态加载的模块;fs:fs目录存放Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext3文件系统对应的就是ext3子目录;Kernel:Kernel内核管理的核心代码放在这里。同时与处理器结构相关代码都放在arch/*/kernel目录下;net:net目录里是核心的网络部分代码,其每个子目录对应于网络的一个方面;lib:lib目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/*/lib/目录下;scripts:scripts目录包含用于配置核心的脚本文件;documentation:documentation目录下是一些文档,是对每个目录作用的具体说明。
S3C2440处理器资料
1
S3C2440处理器介绍
1.1三星ARM处理器介绍 1.2 S3C2440功能特点 1.3 S3C2440系统管理/体系结构 1.4 S3C2440存储器 1.5 S3C2440时钟和电源管理
2
1.1三星ARM处理器介绍
S3C44B0:ARM7TDMI、66MHz、集成LCD控制器 (支持STN,但不支持TFT)、无网络接口;适用产品: POS、PDA、E-BOOK、GPS、智能电话、电子书包、 机顶盒,手持游戏机等等。160LQFP,160FBGA。支 持LINUX、PSOS、uC/OSII等。 S3C2410:ARM920T、200MHz、支持TFT、USB HOST、USB DEVICE、 SD Card 以及MMC接口、 触摸屏接口, NAND FLASH直接引导。无网络接口。 适用产品: POS、PDA、E-BOOK、GPS、智能电话、 电子书包、机顶盒,手持游戏机、电子相册、多媒体产 品、视频监控、智能控制仪表等等。272BGA。支持 WINCE、LINUX、VxWorks等。
用于控制各模块是否有频率输入,一般保持默认即可
32
3、时钟控制寄存器(CLKCON续1)
33
3、时钟控制寄存器(CLKCON续2)
Bit3: 1:进入睡眠模式 Bit2:1 进入特别模式(保留模式,没有使用)
34
4、慢时钟控制寄存器(CLKSLOW)
慢时钟模式,用于设置与慢时钟模式相关的配置信息
大纲
s3c2440 时钟频率管理 S3c2440 电源管理模块 相关寄存器使用说明
15
时钟 频率 管理
16
晶振电路和外部时钟
17
时钟源选择
keil下的s3c2440启动代码分析
由于片面问题,所以可能会看起来不太美观,可以看附件中的内容。
ARM启动代码相当于我们电脑的BIOS,也就是ARM启动时对处理器的一些初始化及嵌入式系统硬件的一些初始化。
由于它直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。
一般包括:中断向量表,初始化存储器系统,初始化堆栈,初始化有特殊要求的断口,设备初始化,变量初始化等。
这几天对着RealView MDK-ARM中自带的启动代码研究了一下,遇到问题又对着数据手册和指令表看了一下,总算对S3C2440A的硬件有了一个大致的了解。
学习嵌入式系统重在系统,学习ARM只是为学习嵌入式系统铺路,懒猫比较笨可能在上系统之前要裸奔几天以强化以下对S3C2440A内部结构的了解。
把MDK自带的S3C2440A.S文件的注释发一下,这些是懒猫结合数据手册与ARM指令表理解了,可能会有错误,放在这里只是引导一下像我一样还没有入门的兄弟们,希望你们不要害怕ARM害怕嵌入式,老毛他老人家说的对,世上无难事,只怕有心人,ARM指令就那么多,看一遍不会就多看几遍,还有一定要学习看软件自带的帮助文件.;/*****************************************************************************/;/* S3C2440.S: Startup file for Samsung S3C440 */;/*****************************************************************************/;/* <<< Use Configuration Wizard in Context Menu >>> */ ;/*****************************************************************************/;/* This file is part of the uVision/ARM development tools. */ ;/* Copyright (c) 2005-2008 Keil Software. All rights reserved. */ ;/* This software may only be used under the terms of a valid, current, */;/* end user licence from KEIL for a compatible version of KEIL softwar e */;/* development tools. Nothing else gives you the right to use this softwa re. */;/*****************************************************************************/;下面这些参数是与CPSR状态寄存器有关;参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,;比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10。
S3C2440外部中断操作
1
20100831
编写:小龍
吧把 INTPND 中相应位置 1,所以同一时间只有一位是 1。也就是说前面的寄存 器置 1 是表示发生了,只有 INTPND 置 1,CPU 才会处理。 INTOFFSET :用来表示 INTPND 中哪一位置 1 了,好让你查询,普 通中断跳转时查询用。清除 INTPND、SRCPND 时自动清除。 4.各寄存器关系:
5
20100831 case 0x2000: if(rGPBDAT & 0x80) LED3_ON(); else LED3_OFF(); break; case 0x4000: if(rGPBDAT & 0x100) LED4_ON(); else LED4_OFF(); break; case 0x8000: LED_ON(); break; case 0x80000: LED_OFF(); break;
下面看图说明: 5.中断过程。 a 如果是不带子中断的内部中断:发生后 SRCPND 相应位置 1,如果没有被 INTMSK 屏蔽,那么等待进一步处理。 b 如果是带子中断的内部中断:发生后 SUBSRCPND 相应位置 1,如果没有被 INTSUBMSK 屏蔽,那么 SRCPND 相应位置 1,等待进一步处理,几个 SUBSRCPND 可能对应同一个 SRCPND,对应表如下: SRCPND SUBSRCPND INT_UART0 INT_RXD0,INT_TXD0,INT_ERR0 INT_UART1 INT_RXD1,INT_TXD1,INT_ERR1 INT_UART2 INT_RXD2,INT_TXD2,INT_ERR2 INT_ADC INT_ADC_S, INT_TC INT_CAM INT_CAM_C, INT_CAM_P INT_WDT_AC97 INT_WDT, INT_AC97
ATC培训试题(题库一)粤嵌
ARM-ATC认证考试题姓名: __________ 联系电话:_______________ 身份证号码:_________________________一、填空题(每空1分,共10分)1.ARM的英文全称为Advanced RISC Machines。
2. ARM的种跳转指令是: b 、 bl 、 bx 和 blx 。
3. ARM微处理器支持字数据类型来表示有符号数和无符号数,字需要 4 字节对齐。
4. 数据在存储器上的储存格式有两种,分别为大端格式和小端格式。
6. ARM 微处理器支持四种类型的堆栈工作方式,分别为满递增、空递增、满递减、和空递减。
7. ARM汇编伪操作,定义一个数字常量ADDR为0x48000004: ADDR EQU 0x48000004 。
8. ARM9的五级流水线取指--译码--执行--缓冲/数据--回写。
9. 在ARM9中与设置IRQ中断有关的寄存器有:中断模式寄存器、外部中断寄存器、外部屏蔽寄存器、内部屏蔽寄存器。
10.S3C2440拥有 60 个中断源,其中属于外部中断有 24 个。
二、选择题(不定项,错选扣分,漏-选按点计分,每题2分,共30分)1. ARM 属于(A )[A] RISC 架构[B] CISC架构2. ARM 指令集是( C )位宽,Thumb 指令集是( B )位宽的。
[A] 8位[B] 16 位 [C] 32位 [D] 64位3. 复位后,ARM处理器处于(B )模式,( D )状态[A] User [B] SVC [C] System [D] ARM [E] Thumb4. ARM处理器总共( E )个寄存器,System模式下使用( A )个寄存器,SVC模式下使用( B )个寄存器。
[A] 17个[B] 18个 [C] 32个 [D] 36个 [E] 37个5. ARM处理器中优先级别最高的异常为( E ),(AC )异常可以用来相应中断[A] FIQ [B] SWI [C] IRQ [D] SVC [E] RESET6. ARM数据处理指令中有效的立即数是(AC EGH )[A] 0X00AB0000 [B] 0X0000FFFF [C ] 0XF000000F [D ] 0X08000012[E] 0X00001F80 [F] 0XFFFFFFFF [G] 0 [H] 0XFF0000007. 在用ARM汇编编程是,其寄存器有多个别名,通常PC是指(D ),LR 是指( C ),SP是指(B )[A] R12[B] R13 [C ] R14 [D ] R158. CPSR寄存器中反映处理器状态的位是( D )[A] J位[B] I位[C ] F位[D ] T位9. ARM7属于(A )结构,ARM9属于(B )结构。
SDRAM内存驱动
SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存。
内存的工作原理、控制时序、及相关控制器的配置方法一直是嵌入式系统学习、开发过程中的一个难点。
我们从其硬件的角度来分析其原理,然后再引出SDRAM的驱动编写过程。
内存是代码的执行空间,以PC机为例,程序是以文件的形式保存在硬盘里面的,程序在运行之前先由操作系统装载入内存中,由于内存是RAM(随机访问存储器),可以通过地址去定位一个字节的数据,CPU在执行程序时将PC的值设置为程序在内存中的开始地址,CPU会依次的从内存里取址,译码,执行,在内存没有被初始化之前,内存好比是未建好的房子,是不能读取和存储数据的,因此我们要想让MTOS运行在内存里必须进行内存的初始化。
通用存储设备:在介绍内存工作原理之前有必要了解下存储设备的存储方式:ROM,RAMl ROM(Read-Only Memory):只读存储器,是一种只能读出事先所存数据的固态半导体存储器。
其特性是一旦储存资料就无法再将之改变或删除。
通常用在不需经常变更资料的电子或电脑系统中,资料并且不会因为电源关闭而消失。
如:PC里面的BIOS。
l RAM(Random Access Memory):随机访问存储器,存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。
可以理解为,当你给定一个随机有效的访问地址,RAM会返回其存储内容(随机寻址),它访问速度与地址的无关。
这种存储器在断电时将丢失其存储内容,故主要用于存储短时间内随机访问使用的程序。
计算机系统里内存地址是一个四字节对齐的地址(32位机),CPU的取指,执行,存储都是通过地址进行的,因此它可以用来做内存。
RAM按照硬件设计的不同,随机存储器又分为DRAM(Dynamic RAM)动态随机存储器和SRAM(Static RAM)静态随机存储器。
S3C2440启动代码经验总结
1、引言2、汇编基础2.1、伪操作GET 伪操作类似于C 语言里面的include,是将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。
IMPORT伪操作相当于C 语言中的extern 声明,它告诉编译器当前的符号不再本源文件中定义,而是在其他源文件中定义,在本源文件中可能引用该符号。
AERA 伪操作用于定义一个代码或者数据段。
ASSERT在汇编编译器对汇编程序的扫描中,如果ASSERT 中条件不成立,ASSERT 伪操作将报告错误信息。
2.2、汇编指令LDR伪指令将一个32 位的常数或者一个地址值读取到寄存器中。
BL跳转指令,L 决定是否保存返回地址。
MRS用于将状态寄存器的内容传送到通用寄存器中。
MSR用于将通用寄存器的内容或一个立即数传送到状态寄存器中。
LDM和STM分别为批量Load/Store内存访问指令。
FD为满递减数据栈。
3、启动代码功能模块分解启动代码主要是在主程序运行之前初始化系统硬件及软件的运行环境,它的主要功能包括以下的几个方面:* 建立中断向量表* 初始化系统堆栈* 应用程序执行环境初始化* 跳转至主函数3.1、系统堆栈初始化ARM有7种模式:* 用户模式* 快速中断模式* 中断模式* 管理模式* 中止模式* 未定义模式* 系统模式系统堆栈的初始化主要是给各个处理器模式分配堆栈空间。
堆栈是为中断或程序跳转服务的,当发生中断或程序跳转时,需要将当前处理器的状态及一些参数保持在堆栈中,当中断处理完毕以后或程序执行完后返回时,再将堆栈保存的现场数据进行恢复,以保证原来的程序正确运行。
USERMODE EQU 0x10 ;用户模式FIQMODE EQU 0x11 ;快速中断模式IRQMODE EQU 0x12 ;中断模式SVCMODE EQU 0x13 ;监管模式ABORTMODE EQU 0x17 ;异常中断模式UNDEFMODE EQU 0x1b ;未定义模式MODEMASK EQU 0x1f ;模式掩码NOINT EQU 0xc0 ;取消中断;设置工作模式的堆栈的起始地址;在option.inc 中定义了_STACK_BASEADDRESS EQU 0x33ff8000 UserStack EQU (_STACK_BASEADDRESS-0x3800) ;堆栈空间0x33ff4800 SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;堆栈空间0x33ff5800 UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;堆栈空间0x33ff5c00AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;堆栈空间0x33ff6000IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;堆栈空间0x33ff7000 FIQStack EQU (_STACK_BASEADDRESS-0x0) ;堆栈空间0x33ff8000堆栈初始化的顺序决定系统最后运行在哪种处理器模式,最后初始化哪种模式的堆栈,系统就运行在哪种模式。
s3c2440中文手册第6章-nandflash
s3c2440中⽂⼿册第6章-nandflash第六章Nand Flash控制器6.1概述⽬前,Nor Flash价格较⾼,⽽SDRAM和Nand Flash存储器相对经济,这样促使⼀些⽤户在NAND Flash上执⾏启动代码,在SDRAM上执⾏主程序。
s3c2440A的驱动代码可以在外部的NAND Flash存储器上被执⾏。
为了⽀持NAND Flash的boot loader,s3c2440A配备了⼀个内部的SRAM缓冲器名为“Steppingstone”。
启动时,NAND Flash上的前4KByte字节将被装载到Steppingstone上别且装载到Steppingstone上的启动代码会被执⾏。
⼀般情况下,启动代码会拷贝NAND Flash上的内容到SDRAM。
使⽤硬件的ECC,NAND Flash的数据被检查。
在完成拷贝的基础上,主程序将在SDRAM上被执⾏。
6.2特性(1)⾃动启动:启动代码在重启时被传输到4kbytes的Steppingstone上。
传输后代码会在Steppingstone上被执⾏(2)NAND Flash存储器接⼝:⽀持256字、512字节、1000字和2000Byte页(3)软件模式:⽤户可以直接访问NAND Flash,例如这个特性可以被⽤于对NADN Flash 存储器的读/擦除/编程。
(4)接⼝:8/16微的NADN Flash存储器接⼝总线(5)硬件ECC⽣成,检测和指⽰(软件纠错)(6)SFR接⼝:⽀持⼩端模式,对于数据和ECC数据寄存器的字节/半字/字访问,对于其他寄存器的字访问。
(7)Steppingstone接⼝:⽀持⼤⼩端,字节/半字/字访问(8)Steppingstone4kB内部SRAM缓冲器可以在NAND Flash启动后被⽤于其他⽬的。
6.2.1模块图6.2.2Boot loader功能在重启期间,NAND Flash控制器通过引脚状态得到连接NAND Flash的信息(NCON(Adv flash),GPG13(页⼤⼩),GPG14(地址周期),GPG15(总线宽度)–参考引脚配置)。
友善之臂Mini2440开发板的存储系统及IO空间总结
友善之臂Mini2440开发板的存储系统及I/O空间总结用友善之臂的板子已经有一段时间了.对于存储系统和I/O空间的认识也渐渐淡忘了,原因是在做其他开发时,一直用着自带的启动代码,从不关心板子的储存空间配置.最近在做网卡驱动,突然间就不知道网卡的地址是什么了,于是花点时间总结一下.废话少说.开始吧.1,板上的存储资源两个32M的SDRAM.一个2M的NOR FLASH一个128M(有些是64M)的NAND FLASH以上这些资源看原理图便知.2,板上的I/O资源这块板子上(准确的说是S3C2440)的I/O空间是用存储映射的方法映射到存储空间上的,也就说I/O空间是要占用存储空间的.3,各种存储器的区别与各自的用途为什么这块板子上有那么多存储设备呢?原因很简单.每种存储设备的用途都不一样,而且为了兼顾广大用户的需要,也必须有不同的存储设备.首先说SDRAM.(写到这突然想起忘了说SRAM了.SRAM是静态随机存储器,它具有掉电不丢失数据且不必频繁刷新的特点,存储速度快,相当于PC的内存,看来这块相当于内存的东西很重要,可是刚刚怎么没说有这块东西呢?原因很简单.因为本来就没有.其实,如果需要随机存储器,SDRAM就是随机存储器啊,只是它需要不断的刷新以保持里面的数据(电平)。
说到这,SDRAM的作用同学们也应该了解了.也就说我们这块板子就是有64M的内存,足够用了。
其次说说NOR FLASH.NOR FLASH是具有SRAM接口特性的ROM。
记住,是ROM,也就说,它相当于PC里的硬盘,可是NOR FLASH才2M未免太少了,没错,是很少,可是我们有NAND FLASH啊,它也是ROM啊,它也是”硬盘”啊,所以加起来我们可以说这块板子有130M(66M)的硬盘.这也足够用了,可以烧好几个Linux了.再说说NAND FLASH,NAND FLASH可以做的很大,但是速度却比不上NOR FLASH,NOR FLASH能做快却不能做的大,所以,速度和容量是一对矛盾.为了克服这对矛盾,这板子上两种FLASH都有了.各有用途.另外,初学者一定要知道NAND FLASH 与NOR FLASH启动的不同吧.这是跟他们的特性有关的,接下来谈谈.4,NOR FLASH 启动与NAND FLASH 启动开发板上有一个S2开关,当它打在NOR一端是就是NOR启动.相反,打在另一端就是NAND FLASH启动了.先说这两种启动的不同,再说说硬件上是如何启动的,空间又是如何分配的。
S3C2440启动流程
我想请问下。
主板上的DL1灯是在什么阶段点亮的?[2010-6-13 下午02:40:44] michael: 早上打电话给你,还怕打扰你休息了。
原来你们也需要上班。
呵呵[2010-6-13 下午02:40:58] Zhilong Wu: 应该在uboot 里.一开机的时候.[2010-6-13 下午02:42:00] michael: 我们现在有些板启动不了。
发现UART口没有U-BOOT输出信息。
DL1灯不亮[2010-6-13 下午02:44:03] Zhilong Wu: 每个flash 芯片,烧uboot的时候,有没有重新读出一遍,做检查. 确保uboot 是烧好的[2010-6-13 下午02:44:05] michael: DL1灯是UBOOT来控制的还是什么模块控制的?[2010-6-13 下午02:44:51] Zhilong Wu: uboot , 通过cpu的io[2010-6-13 下午02:47:44] michael: 烧写UBOOT的时候,应该是怎样的流程?我们现在是erase--->blank_check-->program---->verify[2010-6-13 下午02:48:07] Zhilong Wu: 这样也可以[2010-6-13 下午02:49:42] michael: DL1有几个阶段:[2010-6-13 下午02:50:12] michael: 不亮,常亮,慢闪,快速[2010-6-13 下午02:50:32] Zhilong Wu: 在uboot 就是一个状态.[2010-6-13 下午02:50:46] Zhilong Wu: 长亮.[2010-6-13 下午02:51:12] Zhilong Wu: 能闪的时候,表示uboot 没问题.起来wince 了[2010-6-13 下午02:51:21] michael: 噢。
S3C2440重要资料
S3C2440与SDRAM的地址连线分析S3C2440有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-ba nk7,当访问bankx的地址空间,ngcsx引脚为低电平,选中外设。
2^27=2^7 * 2^10 * 2^10 = 128Mbyte8*128Mbyte = 1Gbyte所以S3C2440总的寻址空间是1Gbyte。
市面上很少有32位宽度的单片SDRAM,一般选择2片16位SDRAM扩展得到32位SDRAM.选择的SDARM是HY57V561620F,4Mbit * 4bank *16,共32Mbyte。
首先了解下SDRAM的寻址原理。
SDRAM内部是一个存储阵列。
可以把它想象成一个表格。
和表格的检索原理一样,先指定行,再指定列,就可以准确找到所需要的存储单元。
这个表格称为逻辑B ANK。
目前的SDRAM基本都是4个BANK。
寻址的流程就是先指定BANK地址,再指定行地址,最后指定列地址。
这就是SDRAM的寻址原理。
存储阵列示意图如下:查看HY57V561620F的资料,这个SDRAM有13根行地址线 RA0-RA129根列地址线CA0-CA82根BANK选择线 BA0-BA1SDRAM的地址引脚是复用的,在读写SDRAM存储单元时,操作过程是将读写的地址分两次输入到芯片中,每一次都由同一组地址线输入。
两次送到芯片上去的地址分别称为行地址和列地址。
它们被锁存到芯片内部的行地址锁存器和列地址锁存器。
/RAS是行地址锁存信号,该信号将行地址锁存在芯片内部的行地址锁存器中;/CAS是列地址锁存信号,该信号将列地址锁存在芯片内部的列地址锁存器中。
地址连线如下图:SDRAM的A0接S3C2440的ADDR2,很多初学者都对这里又疑问。
A0为什么不接ADDR0?要理解这种接法,首先要清楚在CPU的寻址空间中,字节(8位)是表示存储容量的唯一单位。
用2片HY57V561620F扩展成32位SDRAM,可以认为每个存储单元是4个字节。
三款2440 开发板 各项比较
底板尺寸友善之臂mini2440开发板型64MB, 等长布线 LT22MB,掉电非易失256MB,掉电非易失,已经安装BIOS型2M,支持CFI接口型256MBS3C2440A,主频400MHz,最高533Mhz 1.在板64M SDRAM 2.32bit 数据总线 3.SDRAM 时钟频率高达100MHzS3C2440AL系统时钟源实时时钟扩展接口操作系统支持价格套餐配置基本性能CPU 处理器SDRAM 内存Nor Flash NandFlash 接口和资源一款3.5寸触摸屏USB转串口线一根 触摸100 x 100(mm)一条 交叉网线USB数据线(带磁环)一根一只 5V 稳压电源交叉网线一根一条 USB 电缆TFT显示屏驱动板一片一条 DB9 直连串口线5V/2A电源适配器一个一张 DVD数据光盘(内置丰富开发资料)DVD用户光盘一条 Jtag烧写线 + Jtag下载小板 4.3寸TFT触摸屏一片,1 个40 pin 2.0mm 系统总线 接口定时器接口,中断口等接一片 mini2440开发板LT2440核心板一片 LT Linux2.6.32.2 + QtE4.6.3 + Qtopia-2.2.0 6.0(R3)459 RMBLinux-2.6.3电源接口(5V),带电源开关和指示灯支持总线的扩展,如ID1 个34 pin 2.0mm GPIO 接口扩展出SPI接口,IIC接口 12M 无源晶振内部实时时钟(带后备锂电池)可接1 个2.0 mm 间距20pin 摄像头接口20Pin摄像头接口板载实时时钟电池可接C1220时钟后背电池1 个可调电阻,用于AD 模数转换测试板载高精度可调电阻,1 个I2C 总线AT24C08 芯片,用于I2C 总线测试IIC 板载AT24C026 USER buttons(带引出座)支持3.5寸 4.3寸 7寸 1 个PWM 控制蜂鸣器板载蜂鸣器测试PWM1 个2.0mm 间距10 针JTAG 接口板载 10Pin JTAG接口4 USER Leds 4个用户按键,驱动支持1 个SD 卡存储接口支持大容量SD卡,最大1 路立体声音频输出接口,一路麦克风接口一路音频输入,一路音1 个USB Host 一个USB host 接口,可1 个USB Slave B 型接口一个USB device A型口1 个100M以太网RJ-45接口(采用DM9000 网络芯片)100Mbs 网卡,10Mbs/13 个串行口2个RS232串口 三个内部实时钟,带有后备锂电池座,断电后系WinCE、Linux、Android568 RMBSamsung S3C6410处理器,ARM1176JZF-S533MHz/667MHz标配256M字节DDR内存(可选配1G 快速、稳定的企业级芯片开发板性能比较型号:K4S561632N 64MB, 等长布线 LT2440 S3C2440开发板飞凌嵌入式ARM11 S3C6410 OK6型号:AM29LV160DB 2M,支持CFI接口型号:K9F2G08U0B256MB440AL-40 最高533Mhz 稳定运行 触摸笔一根一个包装盒120 x 138(mm)105 x 144(mm)环)一根一条USB线一个5V 直流电源一片一条串口线(一头针一头孔)一个一条网线(交叉网线)一块4.3寸真彩触摸屏(包括触摸笔一根)一片,分辨率480*272OK6410-A用户光盘3张(详见开发板所提供的口等接口一个用来 扩展8×8矩阵键盘, 另一个可连片 LT2440-B底板一片一块已测试好的 OK6410-A开发板(包括核心350 RMB2.6.33.6内核, Wince 5.0软件特性,如IDE,双网口3个10×2插针扩展口IC接口,模拟接口一个 包括1路GND、1路DA、8路AD、10路IO、可接C1220时钟后背电池 12MHz、48MHz、27MHz、32.768KHz时四个LED 背电池一个蜂鸣器电阻,测试ADC输入1个单线数字式温度传感器接口(DS18B20)02一个红外模块 7寸 8寸等TFT液晶屏支持电阻式触摸屏触摸板接口支持4线电阻式触摸板;支持3.5WM一个无线网卡(WIFI)扩展接口G接口一个JTAG接口,使用10X2插针连接器动支持,使用外部中断1路CVBS输出接口,最大支持32GB一个高速SD卡座。
第1讲三星s3c2440微处理器
掉电模式:所有外设和内核的电源都切断了;
1. 可以通过EINT[15:0]或RTC报警中断来从掉电模式中唤醒处
理器
12
S3C2440A特性
中断控制器
60个中断源(1个看门狗定时器,5个定时器, 9个UARTs,24个外部中断,4个DMA,2个 RTC,2 个ADC,1 个IIC,2 个SPI,1个SDI, 2个USB,1 个LCD和1个电池故障,1个NAND 和2个Camera),1个AC97音频
电平/边沿触发模式的外部中断源 可编程的边沿/ 电平触发极性 1. 支持为紧急中断请求提供快速中断服务
13
S3C2440A特性
具有脉冲带宽调制功能的定时器(PWM) 4 通道16位具有PWM功能的定时器,1通道16
位内部定时器,可基于DMA或中断工作 可编程的占空比周期,频率和极性 能产生死区 1. 支持外部时钟源
Main TFT LCD & TSP
1/2/4/8/16 bpp Up to QVGA
SD/SDIO IIS I/F
Audio Codec
TDMB/WLAN
SD/MMC Stereo Speaker Head Set Mic
引言
三星公司推出的16/32位RISC微处理器 S3C2440A,为手持设备和一般类型应用 提供了低价格、低功耗、高性能小型微 控制器的解决方案。
–LCD 实际尺寸的典型值是:640 ×480,320 ×240, 160×160 及其他
–最大虚拟屏幕大小是4M字节
–256 色模式下支持的最大虚拟屏是:4096 ×1024,
2048 ×2048,1024×4096等
17
S3C2440A特性
TFT彩色显示屏 支持彩色TFT的1,2,4或8bbp(像素每位)调色显示 支持16,24bbp无调色真彩显示TFT 在24bbp 模式下支持最大16M色TFT lpc3600定时控制器,为嵌入式lts350Q1-PD1/2(SAMSUNG
嵌入式智能小车的设计与实现
嵌入式智能小车的设计与实现梁明亮;孙逸洁【摘要】@@%本文设计一种基于ARM和AVR单片机嵌入式控制技术的智能小车.介绍了智能小车的系统方案、硬件设计和软件设计.主控器以ARM9系列S3C2440A为处理器,电机驱动器以AVR单片机ATmega16L为处理器,实现小车的速度和转向控制;ARM9采用Linux操作系统,AVR单片机采用基于PID算法的C语言编程.整机调试和运行表明,智能小车实现了自动寻迹、智能避障、温度探测、图像采集、无线通信等功能,非常适用于工业厂矿相关数据采集和自动探测.【期刊名称】《制造业自动化》【年(卷),期】2012(034)022【总页数】4页(P87-89,94)【关键词】智能小车;自动探测;嵌入式;S3C2440A;PID【作者】梁明亮;孙逸洁【作者单位】郑州铁路职业技术学院,郑州450052;郑州铁路职业技术学院,郑州450052【正文语种】中文【中图分类】TP2730 引言智能机器人已经广泛用于工业、军事、交通运输、航天航空等领域。
智能小车是机器人研究领域的一项重要内容和基础,在移动方式上以轮式移动最为常见;在控制技术方面,嵌入式技术依靠其功能强、成本低、可裁减等优点,适应了工业自动化的发展要求,能很好地胜任系统的控制要求和工作任务。
1 总体方案设计如图1所示为智能小车系统设计框图,以嵌入式为主要控制技术,由S3C2440A主控制器、红外线寻迹模块、传感器探测模块、驱动电路、直流电机、行走机构和电源等部分组成。
图1 系统总体设计框图系统主处理器为S3C2440A,控制软件基于ARM9嵌入式环境设计,在移植Linux操作系统的基础上,基于C语言进行程序开发。
红外线寻迹模块使用反射式红外线采集路面信息,寻迹信号传送给S3C2440A主控制器,实现对黑线或白线的寻迹。
CMOS摄像头用于图像的采集,S3C2440A收到图像信息后,进行图像分析、处理,通过无线网卡完成图像的远程传送、标志物形状和颜色的识别。
jlink配置-S3C2440
jlink配置-S3C2440J-Flash ARM的配置。
一般说来file-->open project里面会找到一些*.jflash的配置文件,加载他们就行了,但是没找到适合S3C2440的。
所以自己建了一个MINI2440.jflash,手动进行配置:j-link设置1. 打开J-Flash ARM,并进入菜单:Options-->Project settings2.主要设置CPU选项和Flash选项CPU :Core --> ARM9, Little endianUse target RAM(faster)-->Addr:40000000 4KB(不选很慢;从Nor flash启动时内部Boot SRAM的地址和大小,参考S3C2440A的芯片手册)初始化序列(Init sequence)按下面的填,简单做了下注释。
##-------Action-----Value0------Value1HaltDisable MMUWrite 32bit 0x53000000 0x00000000 ; pWTCON , 看门狗定时器控制寄存器Write 32bit 0x4A000008 0xFFFFFFFF ; INTMSK , 中断屏蔽寄存器Write 32bit 0x4A00001C 0x000007FF ; INTSUBMSK , 针对INTMAK具体化的一个中断请求屏蔽寄存Write 32bit 0x56000050 0x000055AA ; rGPFCON , Port F controlWrite 32bit 0x4C000014 0x00000007 ; CLKDIVN , CPU时钟分频控制寄存器Write 32bit 0x4C000000 0x00FFFFFF ; LOCKTIME , 锁时计数寄存器Write 32bit 0x4C000004 0x00061012 ; MPLLCON , MPLL寄存器Write 32bit 0x4C000008 0x00040042 ; UPLLCON , UPLL寄存器Write 32bit 0x48000000 0x22111120 ; Bus width & wait statusWrite 32bit 0x48000004 0x00002F50 ; Boot ROM controlWrite 32bit 0x48000008 0x00000700 ; BANK1 controlWrite 32bit 0x4800000C 0x00000700 ; BANK2 controlWrite 32bit 0x48000010 0x00000700 ; BANK3 controlWrite 32bit 0x48000014 0x00000700 ; BANK4 controlWrite 32bit 0x48000018 0x0007FFFC ; BANK5 controlWrite 32bit 0x4800001C 0x00018005 ; BANK6 controlWrite 32bit 0x48000020 0x00018005 ; BANK7 controlWrite 32bit 0x48000024 0x008E0459 ; DRAM/SDRAM refresh Write 32bit 0x48000028 0x00000032 ; Flexible Bank SizeWrite 32bit 0x4800002C 0x00000030 ; Mode register set for SDRAMWrite 32bit 0x48000030 0x00000030 ; Mode register set for SDRAM3. Flash取消"Automatically detect flash memory",然后"Select Flash Device"。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
S3C2440 SDRAM内存驱动SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存.内存的工作原理,控制时序,及相关控制器的配置方法一直是嵌入式系统学习,开发过程中的一个难点.我们从其硬件的角度来分析其原理,然后再引出SDRAM的驱动编写过程.内存是代码的执行空间,以PC机为例,程序是以文件的形式保存在硬盘里面的,程序在运行之前先由操作系统装载入内存中,由于内存是RAM(随机访问存储器),可以通过地址去定位一个字节的数据,CPU在执行程序时将PC的值设置为程序在内存中的开始地址, CPU会依次的从内存里取址,译码,执行,在内存没有被初始化之前,内存好比是未建好的房子,是不能读取和存储数据的,因此我们要想让MTOS运行在内存里必须进行内存的初始化.通用存储设备:在介绍内存工作原理之前有必要了解下存储设备的存储方式:ROM,RAMl ROM(Read-Only Memory):只读存储器,是一种只能读出事先所存数据的固态半导体存储器.其特性是一旦储存资料就无法再将之改变或删除.通常用在不需经常变更资料的电子或电脑系统中,资料并且不会因为电源关闭而消失.如:PC里面的BIOS.l RAM(Random Access Memory) :随机访问存储器,存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器.可以理解为,当你给定一个随机有效的访问地址,RAM会返回其存储内容(随机寻址),它访问速度与地址的无关.这种存储器在断电时将丢失其存储内容,故主要用于存储短时间内随机访问使用的程序.计算机系统里内存地址是一个四字节对齐的地址(32位机),CPU的取指,执行,存储都是通过地址进行的,因此它可以用来做内存.RAM按照硬件设计的不同,随机存储器又分为DRAM(Dynamic RAM)动态随机存储器和SRAM(Static RAM) 静态随机存储器.l DRAM:它的基本原件是小电容,电容可以在两个极板上短时间内保留电荷,可以通过两极之间有无电压差代表计算机里的0和1,由于电容的物理特性,要定期的为其充电,否则数据会丢失.对电容的充电过程叫做刷新,但是制作工艺较简单,体积小,便于集成化,经常做为计算机里内存制作原件.比如:PC的内存,SDRAM,DDR,DDR2,DDR3等,缺点:由于要定期刷新存储介质,存取速度较慢.l SRAM:它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据.因此其存取速度快,但是体积较大,功耗大,成本高,常用作存储容量不高,但存取速度快的场合,比如CPU的L1cache,L2cache(一级,二级缓存) ,寄存器.为了满足开发的需要MINI2440在出厂时搭载了三种存储介质:1.NOR FLASH(2M):ROM存储器,通常用来保存BootLoader,引导系统启动2.NAND FLASH(256M,型号不一样,Nandflash大小不一样):保存操作系统映像文件和文件系统3.SDRAM(64M):内存,执行程序l NORFLASH:它的特点是支持XIP芯片内执行(eXecute In Place),这样应用程序可以直接在Flash闪存内运行,不必再把代码读到系统RAM中,也就是说可以随机寻址.NOR FLASH的成本较高.l NAND FLASH:它能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快.其成本较低,不支持XIP.可做嵌入式里的数据存储介质.如:手机存储卡,SD卡等.1. S3C2440存储器地址段(Bank)S3C2440对外引出了27根地址线ADDR0~ADDR26,它最多能够寻址128MB,而S3C2440的寻址空间可以达到1GB,这是由于S3C2440将1GB的地址空间分成了8个BANKS(Bank0~Bank7),其中每一个BANK对应一根片选信号线nGCS0~nGCS7,当访问BANKx的时候,nGCSx管脚电平拉低,用来选中外接设备, S3C2440通过8根选信号线和27根地址线,就可以访问1GB.如图2-48所示.图2-48 S3C2440存储器BANK如图所示,左侧图对应不使用Nandflash启动时(通过跳线设置),存储器Bank分布图,通常在这种启动方式里选择Norflash启动,将Norflash焊接在Bank0, 系统上电后,CPU从Bank0的开始地址0x00000000开始取指运行.上图右侧是选择从Nandflash引导启动(通过跳线设置),系统上电后,CPU会自动将Nandflash里前4K 的数据复制到S3C2440内部一个4K大小SRAM类型存储器里(叫做Steppingstone),然后从Steppingstone取指启动.其中Bank0~Bank5可以焊接ROM或SRAM类型存储器,Bank6~Bank7可以焊接ROM,SRAM,SDRAM类型存储器,也就是说,S3C2440的SDRAM内存应该焊接在Bank6~Bank7上,最大支持内存256M,Bank0~Bank5通常焊接一些用于引导系统启动小容量ROM,具体焊接什么样存储器,多大容量,根据每个开发板生产商不同而不同,比如MINI2440开发板将2M的Norflash焊接在了Bank0上,用于存放系统引导程序Bootloader,将两片32M,16Bit位宽SDRAM内存焊接在Bank6和Bank7上,并联形成64M,32位内存.由于S3C2440是32位芯片,理论上讲可以达到4GB的寻址范围,除去上述8个BANK用于连接外部设备,还有一部分的地址空间是用于设备特殊功能寄存器,其余地址没有被使用.外接设备起始地址结束地址存储控制器0x48000000 0x48000030USB Host控制器0x49000000 0x49000058中断控制器0x4A000000 0x4A00001CDMA 0x4B000000 0x4B0000E0时钟和电源管理0x4C000000 0x4C000014LCD控制器0x4D000000 0x4D000060NAND FLASH控制器0x4E000000 0x4E000014摄像头接口0x4F000000 0x4F0000A0UART 0x50000000 0x50008028脉宽调制计时器0x51000000 0x51000040USB设备0x52000140 0x5200026FWATCHDOG计时器0x53000000 0x53000008IIC控制器0x54000000 0x5400000CIIS控制器0x55000000 0x55000012I/O端口0x56000000 0x560000B0实时时钟RTC 0x57000040 0x5700008BA/D转换器0x58000000 0x58000010SPI 0x59000000 0x59000034SD接口0x5A000000 0x5A000040AC97音频编码接口0x5B000000 0x5B00001C表2-14 S3C2440设备寄存器地址空间2. SDRAM内存工作原理SDRAM的内部是一个存储阵列.阵列就如同表格一样,将数据"填"进去.在数据读写时和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理,如图2-49所示.图2-49 内存行,列地址寻址示意图这个单元格(存储阵列)就叫逻辑Bank(Logical Bank,下文简称L-Bank). 由于技术,成本等原因,不可能只做一个全容量的L-Bank,而且最重要的是,由于SDRAM的工作原理限制,单一的L-Ban k将会造成非常严重的寻址冲突,大幅降低内存效率.所以人们在SDRAM内部分割成多个L-Bank,目前基本都是4个(这也是SDRAM规范中的最高L-Bank数量),由此可见,在进行寻址时就要先确定是哪个L-Bank,然后在这个选定的L-Bank中选择相应的行与列进行寻址.因此对内存的访问,一次只能是一个L-Bank工作.如图2-50:图2-50 内存存储单元当对内存进行操作时(见下图),先要确定操作L-Bank,因此要对L-Bank进行选择.在内存芯片的外部管脚上多出了两个管脚BA0, BA1,用来片选4个L-Bank.如前所述, 32位的地址长度由于其存储结构特点,分成了行地址和列地址.通过下面的内存结构图可知,内存外接管脚地址线只有13根地址线A0~A12,它最多只能寻址8M内存空间,到底使用什么机制来实现对64M内存空间进行寻址的呢?SDRAM的行地址线和列地址线是分时复用的,即地址要分两次送出,先送出行地址(nSRAS行有效操作),再送出列地址(nSCAS 列有效操作).这样,可以大幅度减少地址线的数目,提高器件的性能和制作工艺复杂度.但寻址过程也会因此而变得复杂.实际上,现在的SDRAM一般都以L-Bank为基本寻址对象的.由L-Bank地址线BAn控制L-Bank间的选择,行地址线和列地址线贯穿连接所有的L-Bank,每个L-Bank的数据的宽度和整个存储器的宽度相同,这样,可以加快数据的存储速度.同时,BAn还可以使未被选中的L-Bank工作于低功耗的模式下,从而降低器件的功耗.图2-51 HY57561620内部结构图开发板内存控制器管脚接线(以MINI2440开发板为例):2.1 确定BA0,BA1的接线表2-15 BA0,BA1接线Bank Size:外接内存容量大小(HY57561620是4Mbit*16bit*4Bank*2Chips/8=64MB) Bus Width:总线宽度(两片16位HY57561620,并联成32位)Base Component:单个芯片容量(bit)(256Mb)Memory Configration:内存配置((4M*16*4banks)*2Chips)由硬件手册Bank Address管脚连接配置表可知,使用A[25:24]两根地址线作为Bank片选信号,正好两根接线可以片选每个存储单元的4个BANKS.2.2 确定其它接线SDRAM内存是焊接在BANK6~BANK7上的,其焊接管脚,如图2-52:图2-52 S3C2440 16位宽内存芯片上图是S3C2440提供的两片16位芯片并联连接示意图,An是CPU地址总线,其中A2~A14为内存芯片寻址总线,之所以地址寻址总线从A2开始是因为内存地址都是按字节对齐的.A24,A25为L-Bank片选信号,Dn为CPU数据总线,其它为对应控制信号线.外接管脚名内接管脚名全称描述A2~A14 A0~A12 Address 地址线D0~D31 DQ0~DQ31 Data Input/Output 数据线A24,A25 BA0,BA1 Bank Address L-BANK片选信号DQM0~DQ M3 LDQM, UDQMData Input/Output Mask高,低字节数据掩码信号SCKE SCKE Clock Enable 输入时钟有效信号SCLK SCLK Clock 输入时钟表2-16 内存芯片各管脚说明我们通过S3C2440 16位宽内存芯片接线图可以看出,两片内存芯片只有两个地方不一样,LDQM, UDQM 和数据总线DQn接线方式不一样.由于存储芯片位宽为16位,一次可以进行两个字节的读取.但是,通常操作系统里最小寻址单位是1字节,因此内存控制器必须要保证可以访问内存里每一个字节.UDQM ,LDQM分别代表16位数据的高,低字节读取信号,当读取数据时,LDQM /UDQM分别用来控制16位数据中高低字节能否被读取,当LDQM /UDQM 为低电平时,对应的高/低字节就可以被读取,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被读取.当向内存里写入数据时,LDQM /UDQM控制数据能否被写入,当LDQM /UDQM为低电平时,对应的高/低字节就可以被写入,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被写入.通过对LDQM/UDQM信号的控制可以控制对两个存储芯片存储数据,由于两个存储单元的地址线是通用的,他们都能接收到CPU发出的地址信号,但是,发给两个存储单元的LDQM /UDQM信号是不同的,以此来区分一个字的高低字节.S3C2440A为32位CPU,也就是说其数据总线和地址总线宽度都是32位(可以理解为32根线一端连接CPU内部,另外一端连接向内存控制器),那么内存数据的输入/输出端也要保证是32位总线,MINI2440上采用两片16位宽总线内存芯片并联构成32位总线.其中一个芯片连接到CPU数据总线的低16位,另外一个芯片连接到数据总线上的高16位,并联成32位总线,因此两个芯片的输入/输出总线连接到CPU总线上的不同管脚上.3. SDRAM的读操作SDRAM进行读操作时,先向地址线上送上要读取数据的地址,通过前面的知识了解到,地址被分成3部分,行地址,列地址,L-Bank片选信号.片选(L-Bank的定址)操作和行有效操作可以同时进行.在CS,L-Bank定址的同时,RAS(nSRAS行地址选通信号)也处于有效状态.此时An地址线则发送具体的行地址.A0~A12,共有13根地址线(可表示8192行),A0~A12的不同数值就确定了具体的行地址.由于行有效的同时也是相应L-Bank有效,所以行有效也可称为L-Bank有效.行地址确定之后,就要对列地址进行寻址了.但是,地址线仍然是行地址所用的A0~A12.没错,在SDRAM 中,行地址与列地址线是复用的.列地址复用了A0~A8,共9根(可表示512列).那么,读/写的命令是怎么发出的呢?其实没有一个信号是发送读或写的明确命令的,而是通过芯片的可写状态的控制来达到读/写的目的.显然WE信号(nWE)就是一个关键.WE无效时,当然就是读取命令.有效时,就是写命令.SDRAM基本操作命令, 通过各种控制/地址信号的组合来完成(H代表高电平,L代表低电平,X表示高,低电平均没有影响).此表中,除了自刷新命令外,所有命令都是默认CKE(SCKEl输入时钟频率有效)有效.列寻址信号与读写命令是同时发出的.虽然地址线与行寻址共用,但CAS(nSCAS列地址选通信号)信号则可以区分开行与列寻址的不同,配合A0~A8,A9~A11来确定具体的列地址.读取命令与列地址一块发出(当WE为低电平是即为写命令)然而,在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟),这个很好理解,在地址线上送完行地址之后,要等到行地址稳定定位后再送出列地址,tRCD是SDRAM的一个重要时序参数,相关数值参看对应芯片硬件手册.通常tRCD以时钟周期(tCK,Clock Time)数为单位,比如笔者MINI2440所用内存芯片里面写到tRCD为20nst,如果将来内存工作在100MHz,那么RCD至少要为2个时钟周期, RCD=2.图2-53 SDRAM读操作时序图在选定列地址后,就已经确定了具体的存储单元,剩下就是等待数据通过数据I/O通道(DQ)输出到内存数据总线上了.但是在列地址选通信号CAS 发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS潜伏期).由于CL只在读取时出现,所以CL又被称为读取潜伏期(RL,Read Latency).CL的单位与tRCD一样,也是时钟周期数,具体耗时由时钟频率决定(笔者官方手册CL=3).不过,CAS并不是在经过CL周期之后才送达存储单元.实际上CAS与RAS一样是瞬间到达的.由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责.但它要有一个准备时间才能保证信号的发送强度,这段时间我们称之为tAC(Access Time from CLK,时钟触发后的访问时间).4. SDRAM预充电操作从存储体的结构图上可以看出,原本逻辑状态为1的电容在读取操作后,会因放电而变为逻辑0.由于SDRAM的寻址具有独占性,所以在进行完读写操作后,如果要对同一L-Bank的另一行进行寻址,就要将原先操作行关闭,重新发送行/列地址.在对原先操作行进行关闭时,DRAM为了在关闭当前行时保持数据,要对存储体中原有的信息进行重写,这个充电重写和关闭操作行过程叫做预充电,发送预充电信号时,意味着先执行存储体充电,然后关闭当前L-Bank操作行.预充电中重写的操作与刷新操作(后面详细介绍)一样,只不过预充电不是定期的,而只是在读操作以后执行的.5. SDRAM突发操作突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)数量就是突发长度(Burst Length,简称BL).在目前,由于内存控制器一次读/写P-Bank位宽的数据,也就是8个字节,但是在现实中小于8个字节的数据很少见,所以一般都要经过多个周期进行数据的传输,上文写到的读/写操作,都是一次对一个存储单元进行寻址,如果要连续读/写,还要对当前存储单元的下一单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对地寻址).虽然由于读/写延迟相同可以让数据传输在I/O端是连续的,但是它占用了大量的内存控制资源,在数据进行连续传输时无法输入新的命令效率很低.为此,引入了突发传输机制,只要指定起始列地址与突发长度,内存就会依次自动对后面相应长度数据的数据存储单元进行读/写操作而不再需要控制器连续地提供列地址,这样,除了第一笔数据的传输需要若干个周期(主要是之间的延迟,一般的是tRCD + CL)外,其后每个数据只需一个周期即可.总结下:SDRAM的基本读操作需要控制线和地址线相配合地发出一系列命令来完成.先发出芯片有效命令(ACTIVE),并锁定相应的L-BANK地址(BA0,BA1给出)和行地址(A0~A12给出).芯片激活命令后必须等待大于tRCD(SDRAM的RAS到CAS的延迟指标)时间后,发出读命令.CL(CAS延迟值)个时钟周期后,读出数据依次出现在数据总线上.在读操作的最后,要向SDRAM发出预充电(PRECHARGE)命令,以关闭已经激活的L-BANK.等待tRP时间(PRECHAREG命令后,相隔tRP时间,才可再次访问该行)后,可以开始下一次的读,写操作.SDRAM的读操作支持突发模式(Burst Mode),突发长度为1,2,4,8可选.6. SDRAM写操作SDRAM的基本写操作也需要控制线和地址线相配合地发出一系列命令来完成.先发出芯片有效命令,并锁定相应的L-BANK地址(BA0,BA1给出)和行地址(A0~A12给出).芯片有效命令发出后必须等待大于tRCD的时间后,发出写命令数据,待写入数据依次送到DQ(数据线)上.在最后一个数据写入后,延迟tWR时间.发出预充电命令,关闭已经激活的页.等待tRP时间后,可以展开下一次操作.写操作可以有突发写和非突发写两种.突发长度同读操作.图2-54 SDRAM写操作时序图7. SDRAM的刷新SDRAM之所以成为DRAM就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是SDRAM最重要的操作.刷新操作与预充电中重写的操作一样,都是用S-AMP先读再写.但为什么有预充电操作还要进行刷新呢?因为预充电是对一个或所有L-Bank中的工作行操作,并且是不定期的,而刷新则是有固定的周期,依次对所有行进行操作,以保留那些很长时间没经历重写的存储体中的数据.但与所有L-Bank预充电不同的是,这里的行是指所有L-Bank中地址相同的行,而预充电中各L-Bank中的工作行地址并不是一定是相同的.那么要隔多长时间重复一次刷新呢?目前公认的标准是,存储体中电容的数据有效保存期上限是64ms(毫秒,1/1000秒),也就是说每一行刷新的循环周期是64ms.这样刷新时间间隔就是: 64m/行数s.我们在看内存规格时,经常会看到4096 Refresh Cycles/64ms或8192 Refresh Cycles/64ms的标识,这里的4096与8192就代表这个芯片中每个L-Bank的行数.刷新命令一次对一行有效,刷新间隔也是随总行数而变化,4096行时为15.625μs(微秒,1/1000毫秒),8192行时就为7.8125μs.刷新操作分为两种:Auto Refresh,简称AR与Self Refresh,简称SR.不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作.对于AR,SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址.由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说CAS在RAS之前有效.所以,AR又称CBR(CAS Before RAS,列提前于行定位)式刷新.由于刷新涉及到所有L-Bank,因此在刷新过程中,所有L-Bank都停止工作,而每次刷新所占用的时间为9个时钟周期(PC133标准),之后就可进入正常的工作状态,也就是说在这9个时钟期间内,所有工作指令只能等待而无法执行.64ms之后则再次对同一行进行刷新,如此周而复始进行循环刷新.显然,刷新操作肯定会对SDRAM的性能造成影响,但这是没办法的事情,也是DRAM相对于SRAM(静态内存,无需刷新仍能保留数据)取得成本优势的同时所付出的代价.SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR(Suspend to RAM,休眠挂起于内存).在发出AR命令时,将CKE置于无效状态,就进入了SR模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作.在SR期间除了CKE之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并进入正常操作状态.SDRAM相关寄存器:7.1 BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER)表2-17 SDRAM控制寄存器(BWSCON)根据开发板的存储器配置和芯片型号,设置每个BANK焊接芯片的位宽和等待状态BWSCON,每4位对应一个BANK,这4位分别表示:l STx:启动/禁止SDRAM的数据掩码引脚(UB/LB),SDRAM没有高低位掩码引脚,此位为0,SRAM连接有UB/LB管脚,设置为1l 注:UB/LB数据掩码引脚用来控制芯片读取/写入的高字节和低字节(对比硬件手册SDRAM和SRAM的接线图)l WSx:是否使用存储器的WAIT信号,通常设为0l DWx:设置焊接存储器芯片的位宽,笔者开发板使用两片容量为32M,位宽为16的SDRAM组成64M,32位存储器,因此DW7,DW6位设置为0b10,其它BANK不用设置采用默认值即可.l BANK0对应的是系统引导BANK,这4位比较特殊,它的设置是由硬件跳线决定的,因此不用设置l BWSCON设置结果:0x220000007.2 BANKCON0~BANKCON5 (BANK CONTROL REGISTER)表2-18 BANKCON[0~5]控制寄存器这6个寄存器用来设置对应BANK0~BANK5的访问时序,采用默认值0x700即可7.3 BANKCON6~BANKCON7 (BANK CONTROL REGISTER)表2-19 BANKCON[6~7]控制寄存器由于内存都焊接在这两个BANK上,因此内存驱动主要是对这两个寄存器进行设置l MT:设置BANK6~BANK7的存储器类型,00=ROM or SRAM 01=保留10=保留11=SDRAM内存为SDRAM,设置为0b11,对应的应该设置Trcd和SCAN位,其它位和SDRAM无关l Trcd:RAS to CAS Delay行地址选通到列地址选通延迟,这个参数请看后面的内存工作原理扩展部分解释,笔者内存芯片为HY57V561620,由其芯片手册可知其Trcd为最少20ns,如果内存工作在100MHz,则该值至少要为2个时钟周期,通常设置为3个时钟周期,因此设置为0b01l SCAN:SDRAM Column Address Number SDRAM的列地址数,笔者内存芯片为HY57V561620,列地址数为9,设置为0b01l BANK6,BANK7设置结果为:0x180057.4 REFRESH (REFRESH CONTROL REGISTER)表2-20刷新频率设置寄存器(REFRESH)SDRAM的刷新有效,刷新频率设置寄存器(刷新)l REFEN:开启/关闭刷新功能,设置为1,开启刷新l TREFMD:SDRAM刷新模式,0=CBR/AutoRefresh, 1=Self Refresh,设置为0,自动刷新l Trp:行地址选通预充电时间,一般设置为0b00即可l Tsrc:单行刷新时间,设置为0b11即可.l Refresh Counter:内存存储单元刷新数,它通过下面公式计算出:Refresh Counter = 2^11 + 1 – SDRAM时钟频率(MHz)* SDRAM刷新周期(uS)SDRAM的刷新周期,也就是内存存储单元间隔需要多久进行一次刷新,前面内存工作原理分析可知电容数据保存上限为64ms,笔者使用内存芯片每个L-Bank共有8192行,因此每次刷新最大间隔为:64ms/8192 = 7.8125uS,如果内存工作在外部晶振频率12MHz下,Refresh Counter = 1955,如果内存工作在100MHz下,那么Refresh Counter = 1269(取大整数)l REFRESH寄存器设置为:0x8e0000 + 1269 = 0x008e04f5(HCLK = 100MHz)0x8e0000 + 1955 = 0x008e07a3(HCLK = 12MHz)7.5 BANKSIZE寄存器(BANKSIZE REGISTER)表2-21 BANKSIZE寄存器(BANKSIZE)设置内存的突发传输模式,省电模式和内存容量.l BURST_EN:是否开启突发模式, 0 = ARM内核禁止突发传输1 = 开启突发传输,设置为1,开启突发传输l SCKE_EN:是否使用SCKE信号作为省电模式控制信号, 0 = 不使用SCKE信号作为省电模式控制信号1 = 使用SCKE信号作为省电模式控制信号,通常设置为1l SCLK_EN: 设置向存储器输入工作频率,0 = 一直输入SCLK频率,即使没有内存操作也会输入, 1 = 仅当进行内存数据操作时才输入SCLK频率,通常设置为1l BK76MAP:设置Bank6/7的内存容量,笔者使用开发板内存为两片32M内存芯片并联成64M,它们全部都外接到Bank6上,因此选择0b001l BANKSIZE寄存器设置为:0xb17.6 SDRAM模式设置寄存器MRSRx (SDRAM MODE REGISTER SET REGISTER)表2-22 SDRAM模式设置寄存器(MRSRx)该寄存器用于设置CAS潜伏周期,可以手动设置的位只有CL[6:4]位,通过前面内存工作原理可知,笔者使用开发板CL=3,即0b011l MRSR6,MRSR7设置为:0x000000308. 内存驱动实验设置该工程加载时运行时地址为0x30000000,如图2-55所示:图2-55设置加载时运行时地址init.s:本程序文件主要实现了,关闭看门狗,初始化内存,拷贝ROM数据到内存中,然后跳往内存中执行xmain函数,从xmain函数返回之后,将全部led点亮,进入死循环.1;2; 内存初始化实验3;4 AREA Init, CODE, READONLY5 ENTRY6 start7; close watchdog8 ldr r0, = 0x53000000 ; 将看门狗控制寄存器地址放入r09mov r1, #010str r1, [r0] ; 设置看门狗控制寄存器的值为011 bl initmem ; 跳转到initmem代码段,初始化内存据拷贝代码段,将ROM中数据拷贝到内存中13 IMPORT xmain ; 引入main.c中的xmain函数14 ldr sp, =0x34000000 ; 调用C程序之前先初始化栈指针15 ldr lr, =endxmain ; 设置xmain函数的返回地址16 ldr pc, =xmain ; 跳转到C程序中的xmain函数的入口处执行1718 endxmain19 ldr r0, =0x56000010 ; LED的GPIO接口配置寄存器20 ldr r1, =0x00015400 ; GPIO配置数据21str r1, [r0] ; 设置GPIO22 ldr r0, =0x56000014 ; LED控制寄存器地址23 ldr r1, =0x0 ; 全部LED亮24str r1,[r0]2526 loop27 b loop ; 死循环2829 copyall30 IMPORT |Image$$RO$$Base| ; 引入编译器Image$$RO$$Base符号变量31 IMPORT |Image$$RW$$Limit| ; 引入编译器Image$$RW$$Limit符号变量32 ldr r0, = |Image$$RO$Base| ; 取得Image$$RO$Base域基址的值33 ldr r1, = |Image$$RW$$Limit| ; 取得Image$$RW$Base域结束地址的值34 ldr r2, =0x0 ; 数据拷贝源地址35 copyallloop36 teq r0,r1 ; 测试是否拷贝完成37 beq quitcopyallloop ; 拷贝完成,跳往quitcopyallloop退出38 ldr r3, [r2], #4; 四字节加载39str r3, [r0], #4; 四字节存储回继续执行41 quitcopyallloop42mov pc, lr ; 调用返回4344 initmem ; 内存初始化45 ldr r0, =0x48000000 ; 加载内存相关寄存器首地址r046 ldr r1, =0x48000034 ; 加载内存相关寄存器尾地址到r147 adr r2, memdata ; 将寄存器配置数据地址段首地址加载到r248 initmemloop49 ldr r3, [r2], #4; 循环设置存寄存器50str r3, [r0], #451 teq r0, r152 bne initmemloop ; 循环到最后一个寄存器时退出函数53mov pc,lr 5455 memdata5657 DCD 0x22000000 ;BWSCON58 DCD 0x00000700 ;BANKCON059 DCD 0x00000700 ;BANKCON160 DCD 0x00000700 ;BANKCON261 DCD 0x00000700 ;BANKCON362 DCD 0x00000700 ;BANKCON463 DCD 0x00000700 ;BANKCON564 DCD 0x00018005 ;BANKCON665 DCD 0x00018005 ;BANKCON766 DCD 0x008e07a3 ;REFRESH67 DCD 0x000000b1 ;BANKSIZE68 DCD 0x00000030 ;MRSRB669 DCD 0x00000030 ;MRSRB77071 ENDmain.c:本程序文件主要实现led灯的初始化,然后四个led灯循环滚动亮5遍,xmain函数返回.。