Learn ZYNC (2)
AXI HP接口的DMA+GIC编程(参照博客)
参考设计代码文件:ug873源码
Vivado 接线图:
地址分配:
AXI-CDMA IP核,是由PL完成的将数据从内存的一个位置搬移到另一个位置,无需CPU来插手。
AXI CDMA 从机接口连接到PS 通用主机接口M_AXI_GP1.用于PS 来配置AXI 寄存器用于数据传输和状态检测。
AXI CDMA 主机接口连接到PS 高性能从机接口S_AXI_HP0.用于CDMA 模块读取DDR 系统内存源缓冲区数据。
AXI CDMA 主机接口连接到PS 高性能从机接口S_AXI_HP2.用于CDMA 模块将数据写回DDR 系统内存目的缓冲区。
AXI CDMA 中断从PL 连接到PS 全局中断控制器(GIC)。当数据传输完成或传输时有错误发生,则产生中断。
standalone代码:
#include <stdio.h>
//#include "platform.h"
#include "xaxicdma.h"
#include "xdebug.h"
#include "xil_exception.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xscugic.h"
//包含头文件,不必多言
#define NUMBER_OF_TRANSFERS 2 /* 做两次传输 */
#define DMA_CTRL_DEVICE_ID XPAR_AXICDMA_0_DEVICE_ID //DMA控制设备ID号=
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //GIC控制设备ID号=
#define DMA_CTRL_IRPT_INTR XPAR_FABRIC_AXI_CDMA_0_CDMA_INTROUT_INTR //中断号
volatile static int Done = 0; /* Dma transfer is done */
volatile static int Error = 0; /* Dma Bus Error occurs */
static u32 SourceAddr = 0x10000000; // XPAR_PS7_DDR_0_S_AXI_HP0_BASEADDR static u32 DestAddr = 0x18000000; // XPAR_PS7_DDR_0_S_AXI_HP2_BASEADDR static XAxiCdma AxiCdmaInstance; /* XAxiCdma 控制对象*/
static XScuGic IntcController; /* Interrupt Controller 控制对象*/ static int Array_3[32][16]; //阵列
static int Array_4[32][16];
static int Array_1[32][16];
static int Array_2[32][16];
int const input[16] = {0xb504f33, 0xabeb4a0, 0xa267994, 0x987fbfc, 0x8e39d9c, 0x839c3cc, 0x78ad74c, 0x6d743f4, 0x61f78a8, 0x563e6a8, 0x4a5018c, 0x3e33f2c, 0x31f1704, 0x259020c, 0x1917a64, 0xc8fb2c};
/* Length of the buffers for DMA transfer */
static u32 BUFFER_BYTESIZE = (XPAR_AXI_CDMA_0_M_AXI_DATA_WIDTH * XPAR_AXI_CDMA_0_M_AXI_MAX_BURST_LEN); //大小为64*256/8=2KB,起始就是我们在XPS中设置好的
static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries);//执行传输
static void DisableIntrSystem(XScuGic *IntcInstancePtr , u32 IntrId)//禁止中断
{
XScuGic_Disable(IntcInstancePtr ,IntrId );
XScuGic_Disconnect(IntcInstancePtr ,IntrId );
}
//Multiply and Shift
int MUL_SHIFT_30(int x, int y)//实现x*y,但又怕溢出,所以右移30位,除以2^30~1e9
{
return ((int) (((long long) (x) * (y)) >> 30));
}
void MULT_SHIFT_LOOP(int Value )//生成源数据的函数
{
int i, j;
for (i = 0; i < 32; i++) {
for (j = 0; j < 16; j++) {
Array_3[i][j] = (int)((MUL_SHIFT_30(input[j],Array_1[j][i])) + Value);
Array_4[i][j] = (int)((MUL_SHIFT_30(input[j],Array_2[j][i])) + Value);
}
}
} void TestPattern_Initialization(void)//生成原始数据
{
int i, j;
for (i = 0; i < 32; i++)
{
for (j = 0; j < 16; j++)
{
Array_1[i][j] = (int ) ((0xA5A5A5A5 >> 1) * i );
Array_2[i][j] = (int ) ((0xA5A5A5A5 << 1) * i );
}
}
}
//下面是中断服务函数
static void Cdma_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr)
{
if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {
Error = TRUE;
printf("\r\n--- Transfer Error --- \r\n");//传输出错
} if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {
printf("\r\n--- Transfer Done --- \r\n");
Done = TRUE;//传输成功
} }
//设置中断系统,初始化中断控制器
static int SetupIntrSystem(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,
u32 IntrId) {
int Status; /*
* Initialize the interrupt controller driver
*/
XScuGic_Config *IntcConfig; /*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
} Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
} XScuGic_SetPriorityTriggerType(IntcInstancePtr, IntrId, 0xA0, 0x3); /*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
Status = XScuGic_Connect(IntcInstancePtr, IntrId,
(Xil_InterruptHandler)XAxiCdma_IntrHandler,
InstancePtr);
if (Status != XST_SUCCESS) {
return Status;
} /*
* Enable the interrupt for the DMA device.
*/
XScuGic_Enable(IntcInstancePtr, IntrId); Xil_ExceptionInit(); /*
* Connect the interrupt controller interrupt handler to the hardware
* interrupt handling logic in the processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
IntcInstancePtr); /*
* Enable interrupts in the Processor.
*/
Xil_ExceptionEnable(); return XST_SUCCESS;
} int XAxiCdma_Interrupt(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,
u16 DeviceId, u32 IntrId)
{
{
XAxiCdma_Config *CfgPtr;
int Status;
int SubmitTries = 1; /* Retry to submit */
int Tries = NUMBER_OF_TRANSFERS;
int Index; /* Initialize the XAxiCdma device.
*/
CfgPtr = XAxiCdma_LookupConfig(DeviceId);
if (!CfgPtr) {
return XST_FAILURE;
} Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
} /* Setup the interrupt system
*/
Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
} /* Enable all (completion/error/delay) interrupts
*/
XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK); for (Index = 0; Index < Tries; Index++) {
Status = CDMATransfer(InstancePtr,
BUFFER_BYTESIZE, SubmitTries); if(Status != XST_SUCCESS) {
DisableIntrSystem(IntcInstancePtr, IntrId);
return XST_FAILURE;
}
} /* Test finishes successfully, clean up and return
*/
DisableIntrSystem(IntcInstancePtr, IntrId); return XST_SUCCESS;
}
}
/*****************************************************************************/
/*
*
* This function does CDMA transfer
*
* @param InstancePtr is a pointer to the XAxiCdma instance
* @param Length is the transfer length
* @param Retries is how many times to retry on submission
*
* @return
* - XST_SUCCESS if transfer is successful
* - XST_FAILURE if either the transfer fails or the data has
* error
*
* @note None
*
******************************************************************************/
static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{ int Status; Done = 0;
Error = 0; printf("Start Transfer \n\r");
/* Try to start the DMA transfer
*/
Done = 0;
Error = 0; /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)SourceAddr, Length); Status = XAxiCdma_SimpleTransfer(InstancePtr,
(u32)(u8 *) (SourceAddr ),
(u32)(DestAddr),
Length,
Cdma_CallBack,
(void *)InstancePtr); if (Status == XST_FAILURE) {
printf("Error in Transfer \n\r");
return 1;
} /* Wait until the DMA transfer is done
*/
while (!Done && !Error) {
/* Wait */
} if (Error) {
return XST_FAILURE;
return 1;
}
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((u32)DestAddr, Length); return XST_SUCCESS;
}
int main()
{
int Status;
u32 *SrcPtr;
u32 *DestPtr;
u32 Index;
int i, j; printf("\r\n--- Entering main() --- \r\n"); /*********************************************************************************
Step : 1 : Intialization of the SOurce Memory with the Specified test pattern
Clear Destination memory
**********************************************************************************/
TestPattern_Initialization(); /* Initialize the source buffer bytes with a pattern and the
* the destination buffer bytes to zero
*/
SrcPtr = (u32*)SourceAddr;
DestPtr = (u32 *)DestAddr;
for (Index = 0; Index < (BUFFER_BYTESIZE/1024); Index++)
{
MULT_SHIFT_LOOP((Index*100));
for (i = 0; i < 32; i++)
{
for (j = 0; j < 16; j++)
{
SrcPtr[((i+j))*(Index+1)] = Array_3[i][j];
SrcPtr[((i+j)*(Index+1)) + 1] = Array_4[i][j];
DestPtr[(i+j)*(Index+1)] = 0;
DestPtr[((i+j)*(Index+1)) + 1] = 0;
} } }
/*********************************************************************************
Step : 2 : AXI CDMA Intialization
Association of the CDMA ISR with the Interrupt
Enable the CDMA Interrupt
Provide Source and destination location to CDMA
Specified Number of byte to be transfer to CDMA register
Start the CDMA
Wait for the Interrupt and return the status
**********************************************************************************/ Status = XAxiCdma_Interrupt( &IntcController,
&AxiCdmaInstance,
DMA_CTRL_DEVICE_ID,
DMA_CTRL_IRPT_INTR
); if (Status != XST_SUCCESS) { printf("XAxiCdma_Interrupt: Failed\r\n");
return XST_FAILURE;
} xil_printf("XAxiCdma_Interrupt: Passed\r\n"); /*********************************************************************************
Step : 3 : Compare Source memory with Destination memory
Return the Status
**********************************************************************************/
for (Index = 0; Index < (BUFFER_BYTESIZE/4); Index++)
{
if ( DestPtr[Index] != SrcPtr[Index])
{
printf("Error in Comparison : Index : %x \n\r", Index);
return XST_FAILURE;
}
} printf("DMA Transfer is Successful \n\r");
return XST_SUCCESS; return 0;
}
Linux 驱动程序代码参考:xilinx_axicdma.c
Linux DeviceTree参考:axi-cdma.txt
Linux app程序代码(已完成,2014.6.5更新):
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#define CDMA_BASE_ADDRESS 0x80200000
#define GPIO_DATA_OFFSET 0
#define GPIO_DIRECTION_OFFSET 4 //此处要修改为我们的总线地址****************************
#define DDR_BASE_ADDRESS 0x10000000 #define DDR_BASE_WRITE_ADDRESS 0x18000000
#define XGPIO_CHAN_OFFSET 8 #define XAXICDMA_CR_OFFSET 0x00000000 /**< Control register */
#define XAXICDMA_SR_OFFSET 0x00000004 /**< Status register */
#define XAXICDMA_CDESC_OFFSET 0x00000008 /**< Current descriptor pointer */
#define XAXICDMA_TDESC_OFFSET 0x00000010 /**< Tail descriptor pointer */
#define XAXICDMA_SRCADDR_OFFSET 0x00000018 /**< Source address register */
#define XAXICDMA_DSTADDR_OFFSET 0x00000020 /**< Destination address register */
#define XAXICDMA_BTT_OFFSET 0x00000028 /**< Bytes to transfer */ /** @name Bitmasks of XAXICDMA_CR_OFFSET register
* @{
*/
#define XAXICDMA_CR_RESET_MASK 0x00000004 /**< Reset DMA engine */
#define XAXICDMA_CR_SGMODE_MASK 0x00000008 /**< Scatter gather mode */ /** @name Bitmask for interrupts
* These masks are shared by XAXICDMA_CR_OFFSET register and
* XAXICDMA_SR_OFFSET register
* @{
*/
#define XAXICDMA_XR_IRQ_IOC_MASK 0x00001000 /**< Completion interrupt */
#define XAXICDMA_XR_IRQ_DELAY_MASK 0x00002000 /**< Delay interrupt */
#define XAXICDMA_XR_IRQ_ERROR_MASK 0x00004000 /**< Error interrupt */
#define XAXICDMA_XR_IRQ_ALL_MASK 0x00007000 /**< All interrupts */
#define XAXICDMA_XR_IRQ_SIMPLE_ALL_MASK 0x00005000 /**< All interrupts for
simple only mode */
/*@}*/ /** @name Bitmasks of XAXICDMA_SR_OFFSET register
* This register reports status of a DMA channel, including
* idle state, errors, and interrupts
* @{
*/
#define XAXICDMA_SR_IDLE_MASK 0x00000002 /**< DMA channel idle */
#define XAXICDMA_SR_SGINCLD_MASK 0x00000008 /**< Hybrid build */
#define XAXICDMA_SR_ERR_INTERNAL_MASK 0x00000010 /**< Datamover internal err */
#define XAXICDMA_SR_ERR_SLAVE_MASK 0x00000020 /**< Datamover slave err */
#define XAXICDMA_SR_ERR_DECODE_MASK 0x00000040 /**< Datamover decode err */
#define XAXICDMA_SR_ERR_SG_INT_MASK 0x00000100 /**< SG internal err */
#define XAXICDMA_SR_ERR_SG_SLV_MASK 0x00000200 /**< SG slave err */
#define XAXICDMA_SR_ERR_SG_DEC_MASK 0x00000400 /**< SG decode err */
#define XAXICDMA_SR_ERR_ALL_MASK 0x00000770 /**< All errors */
/*@}*/ #define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1) #define DDR_MAP_SIZE 0x10000000
#define DDR_MAP_MASK (DDR_MAP_SIZE - 1) #define DDR_WRITE_OFFSET 0x10000000 #define BUFFER_BYTESIZE 262144 // Length of the buffers for DMA transfer int main()
{
int memfd;
void *mapped_base, *mapped_dev_base;
off_t dev_base = CDMA_BASE_ADDRESS; int memfd_1;
void *mapped_base_1, *mapped_dev_base_1;
off_t dev_base_1 = DDR_BASE_ADDRESS; int memfd_2;
void *mapped_base_2, *mapped_dev_base_2;
off_t dev_base_2 = DDR_BASE_WRITE_ADDRESS; unsigned int TimeOut =5;
unsigned int ResetMask;
unsigned int RegValue;
unsigned int SrcArray[BUFFER_BYTESIZE ];
unsigned int DestArray[BUFFER_BYTESIZE ];
unsigned int Index; /*STEP 1 : Initialize the source buffer bytes with a pattern and clear the Destination
location
=====================================*/
for (Index = 0; Index < (BUFFER_BYTESIZE/2); Index++)
{
SrcArray[Index] = 0x5A5A5A5A/*Index & 0xFF*/;
DestArray[Index] = 0;
} /*STEP 2 : Map the kernel memory location starting from 0x10000000 to the User layer
=======================================*/
memfd_1 = open("/dev/mem", O_RDWR | O_SYNC);
if (memfd_1 == -1)
{
printf("Can't open /dev/mem.\n");
exit(0);
}
printf("/dev/mem opened.\n");
// Map one page of memory into user space such that the device is in that page, but it may not
// be at the start of the page. mapped_base_1 = mmap(0, DDR_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd_1, dev_base_1 & ~DDR_MAP_MASK);
if (mapped_base_1 == (void *) -1)
{
printf("Can't map the memory to user space.\n");
exit(0);
}
printf("Memory mapped at address %p.\n", mapped_base_1);
// get the address of the device in user space which will be an offset from the base
// that was mapped as memory is mapped at the start of a page
mapped_dev_base_1 = mapped_base_1 + (dev_base_1 & DDR_MAP_MASK); /*STEP 3 : Copy the Data to the DDR Memory at location 0x10000000
========================================*/
memcpy(mapped_dev_base_1, SrcArray, (BUFFER_BYTESIZE)); /* STEP 4 : Un-map the kernel memory from the User layer.
===========================================*/
if (munmap(mapped_base_1, DDR_MAP_SIZE) == -1)
{
printf("Can't unmap memory from user space.\n");
exit(0);
}
close(memfd_1); /*==STEP 5 : Map the AXI CDMA Register memory to the User layer
Do the Register Setting for DMA transfer
=================================================*/
memfd = open("/dev/mem", O_RDWR | O_SYNC);
if (memfd == -1)
{
printf("Can't open /dev/mem.\n");
exit(0);
}
printf("/dev/mem opened.\n"); // Map one page of memory into user space such that the device is in that page, but it may not
// be at the start of the page.
mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, dev_base & ~MAP_MASK);
if (mapped_base == (void *) -1)
{
printf("Can't map the memory to user space.\n");
exit(0);
}
// get the address of the device in user space which will be an offset from the base
// that was mapped as memory is mapped at the start of a page
mapped_dev_base = mapped_base + (dev_base & MAP_MASK);
//Reset CDMA
do{
ResetMask = (unsigned long )XAXICDMA_CR_RESET_MASK;
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET)) = (unsigned long)ResetMask;
/* If the reset bit is still high, then reset is not done */
ResetMask = *((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET));
if(!(ResetMask & XAXICDMA_CR_RESET_MASK))
{
break;
}
TimeOut -= 1;
}while (TimeOut);
//enable Interrupt
RegValue = *((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET));
RegValue = (unsigned long)(RegValue | XAXICDMA_XR_IRQ_ALL_MASK );
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET)) = (unsigned long)RegValue;
// Checking for the Bus Idle
RegValue = *((volatile unsigned long *) (mapped_dev_base + XAXICDMA_SR_OFFSET));
if(!(RegValue & XAXICDMA_SR_IDLE_MASK))
{
printf("BUS IS BUSY Error Condition \n\r");
return 1;
}
// Check the DMA Mode and switch it to simple mode
RegValue = *((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET));
if((RegValue & XAXICDMA_CR_SGMODE_MASK))
{
RegValue = (unsigned long)(RegValue & (~XAXICDMA_CR_SGMODE_MASK));
printf("Reading \n \r");
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_CR_OFFSET)) = (unsigned long)RegValue ; }
//Set the Source Address
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_SRCADDR_OFFSET)) = (unsigned long)DDR_BASE_ADDRESS;
//Set the Destination Address
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_DSTADDR_OFFSET)) = (unsigned long)DDR_BASE_WRITE_ADDRESS;
RegValue = (unsigned long)(BUFFER_BYTESIZE);
// write Byte to Transfer
*((volatile unsigned long *) (mapped_dev_base + XAXICDMA_BTT_OFFSET)) = (unsigned long)RegValue; /*STEP 6 : Wait for the DMA transfer Status
=====================================*/
do
{
RegValue = *((volatile unsigned long *) (mapped_dev_base + XAXICDMA_SR_OFFSET));
}while(!(RegValue & XAXICDMA_XR_IRQ_ALL_MASK)); if((RegValue & XAXICDMA_XR_IRQ_IOC_MASK))
{
printf("Transfer Completed \n\r ");
}
if((RegValue & XAXICDMA_XR_IRQ_DELAY_MASK))
{
printf("IRQ Delay Interrupt\n\r ");
}
if((RegValue & XAXICDMA_XR_IRQ_ERROR_MASK))
{
printf(" Transfer Error Interrupt\n\r ");
} /* STEP 7 : Un-map the AXI CDMA memory from the User layer.
=======================================*/
if (munmap(mapped_base, MAP_SIZE) == -1)
{
printf("Can't unmap memory from user space.\n");
exit(0);
} close(memfd); /*STEP 8 : Map the kernel memory location starting from 0x18000000 to the User layer
=======================================================*/
memfd_2 = open("/dev/mem", O_RDWR | O_SYNC);
if (memfd_2 == -1)
{
printf("Can't open /dev/mem.\n");
exit(0);
}
printf("/dev/mem opened.\n");
// Map one page of memory into user space such that the device is in that page, but it may not
// be at the start of the page.
mapped_base_2 = mmap(0, DDR_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd_2, dev_base_2 & ~DDR_MAP_MASK);
if (mapped_base_2 == (void *) -1)
{
printf("Can't map the memory to user space.\n");
exit(0);
}
printf("Memory mapped at address %p.\n", mapped_base_2);
// get the address of the device in user space which will be an offset from the base
// that was mapped as memory is mapped at the start of a page
mapped_dev_base_2 = mapped_base_2 + (dev_base_2 & DDR_MAP_MASK); /*STEP 9 : Copy the Data from DDR Memory location 0x10000000 to Destination Buffer
==========================================================*/
memcpy(DestArray, mapped_dev_base_2, (BUFFER_BYTESIZE ));
/*==STEP 10 : Un-map the Kernel memory from the User layer.=*/
if (munmap(mapped_base_2, DDR_MAP_SIZE) == -1)
{
printf("Can't unmap memory from user space.\n");
exit(0);
} close(memfd_2); /*STEP 11 : Compare Source Buffer with Destination Buffer.
==================================================*/
for (Index = 0; Index < (BUFFER_BYTESIZE/4); Index++)
{
if (SrcArray[Index] != DestArray[Index])
{
printf("Error in the Data comparison \n \r");
return 1;
}
}
printf("DATA Transfer is Successfull \n\r"); return 0;
}
linux下运行成功图:
Learn ZYNC (2)的更多相关文章
- Learn ZYNC (6)
最近在关注的问题是怎么样从ps端丢数据到ram, 然后用ip核进行处理后再输送到ram,ps端可以读取. 参考文献:[OpenHW参赛手记]AXI-Stream接口开发详细流程 首先按照作者的探索思路 ...
- Learn ZYNC (5)
今天为了熟悉axiLite的自定义ip核设计, 把LED和SW的往AXI总线输入输出定义在一个ip核中, BD设计如下: ip核顶层文件(增加了LED_Out和SW_In的定义)mygpio_v1.0 ...
- Learn ZYNC (4)
最近整理出一些适合学习zed的实例(所有的例程都基于Vivado2013.4开发环境) (1)关于zed双核的测试案例: 官方链接:地址1.11.standalone,地址1.12.linux 修改源 ...
- Atitit learn by need 需要的时候学与预先学习知识图谱路线图
Atitit learn by need 需要的时候学与预先学习知识图谱路线图 1. 体系化是什么 架构 知识图谱路线图思维导图的重要性11.1. 体系就是架构21.2. 只见树木不见森林21.3. ...
- Python 爬取所有51VOA网站的Learn a words文本及mp3音频
Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...
- [转载]VIM 教程:Learn Vim Progressively
文章来源:http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/ Learn Vim Progressively TL ...
- some tips learn from work experience
1.you can't avoid office politics 2.you'll never have a job which you "can't quit" - if yo ...
- Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL
没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...
- Learn RxJava
Learn RxJava http://reactivex.io/documentation/operators.html https://github.com/ReactiveX/RxJava/wi ...
随机推荐
- [Python] 学习笔记之MySQL数据库操作
1 Python标准数据库接口DB-API介绍 Python标准数据库接口为 Python DB-API,它为开发人员提供了数据库应用编程接口.Python DB-API支持很多种的数据库,你可以选择 ...
- linux磁盘分区模式
linux磁盘分区模式 模式一:MBR 1)主分区不超过四个 2)单个分区容量最大2TB 模式二:GPT 1)主分区个数"几乎"没有限制(原因:在GPT的分区表中最多可以支持128 ...
- Linux/CentOS优化配置 汇总
[强烈要求做的]CentOS启用sudo,禁用root远程登录 Linux命令行修改IP.网关.DNS.主机名 的方法 Linux开机直接进入“命令行”模式 更改CentOS 6.x yum源为国内1 ...
- 限制帐号同时两处以上登录-ASP.NET
///登录页面 Hashtable haol = (Hashtable)Application["olTable"]; if (haol == null) { haol = new ...
- CentOS 安装tomcat 7
安装环境:CentOS-6.3 安装方式:源码安装 软件:apache-tomcat-7.0.29.tar.gz 下载地址:http://tomcat.apache.org/download-70.c ...
- linux常用命令-帮助命令man,whatis,apropos,info,help
man 命令 man 配置文件,注意这里只需要写文件名称就可以了,不能写文件的绝对路径 man既可以查看命令的帮助信息也可以查看配置文件的帮助信息,如果内容太多,可以输入"/内容" ...
- js 连续赋值。。理解不了,先占坑
http://www.cnblogs.com/xxcanghai/p/4998076.html
- Shell判断字符串包含关系的几种方法
现在每次分析网站日志的时候都需要判断百度蜘蛛是不是真实的蜘蛛,nslookup之后需要判断结果中是否包含“baidu”字符串 以下给出一些shell中判断字符串包含的方法,来源程序员问答网站 stac ...
- poj 3280 Cheapest Palindrome
链接:http://poj.org/problem?id=3280 思路:题目给出n种m个字符,每个字符都有对应的添加和删除的代价,求出构成最小回文串的代价 dp[i][j]代表区间i到区间j成为回文 ...
- hashmap实现原理浅析
看了下JAVA里面有HashMap.Hashtable.HashSet三种hash集合的实现源码,这里总结下,理解错误的地方还望指正 HashMap和Hashtable的区别 HashSet和Hash ...