|
|
用户名:swkyer 笔名:swkyer 地区: 湖北-武汉 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
JTAG(IEEE1149)测试系统构成(2)
话说上回A,B,C三点,描述了一下A点中芯片测试的描述文件的分析方法,目的就是能够将测试芯片抽象出来,把基本的测试对象给呈现出来,至于如何表现给用户,就要看第二点中描述的IDE环境了。
对于B点,比较传统的是用c++,vb来写出这样的IDE环境,但是这样工作量太大,跨平台运作比较麻烦。这里可以推荐采用eclipse的rcp方式制作这个软件,用图形模型框架来可视化我们的测试对象,什么报表,web应用什么的,可以给这个JtagATE增色不少,况且这样的环境采用java编写,可以跨平台运行。
另外一种简单的方式可以采用tcl/tk来实现这样一个JtagATE,这样的界面虽然效果一般,但是是和tcl无缝的结合在一起的,如果采用扩展tcl的方式实现芯片的测试,那么这样的一个环境,gui和实际的测试过程的接口是非常容易的,便于开发。
实际上如果采用eclipse和tcl结合的方式是更好的选择:eclipse通过bsdl文件抽象化测试对象,利用图形模型来实现可视化的测试对象之间的连接编辑,然后结合测试的设置项生成tcl的测试脚本,由eclipse来启动测试流程,也就是执行测试脚本,最后将测试结果呈现出来,图形也好,报表也好,提供各用户,实现过程自动化。
结构如下:
有时间在出最后一部分。。。
我看《不能说的秘密》
老早就听说周杰伦在拍他的第一部电影,还是比较期待的。从之前他演的几部电影来看,当演员的功力还是可以的;又从他专辑中自导演的MV来看,叙事方式、表现手法,取景,剪辑都是很不错的。再听电影的介绍,说会有不一样的感觉,所以电影上映后,还是很期待看到这部电影的。
看完了这部电影,真是不得不感叹周杰伦的才气。抛开一些细节不说,电影还是很好看的,来说说其中的一些亮点吧。
电影中发挥了jay原本的优势,---音乐,整部电影中的配乐非常好听,与电影情节搭配起来更能让人心动。斗琴那段实在是太精彩了,音乐通过这样的方式表现出来,让人有想亲自上去谈唱的冲动。复古的钢琴曲被他们演绎得如此动听,从中不仅看到了jay的音乐功力,更是让人觉得钢琴曲的美妙,复古音乐深藏的魅力。
记得上初中的时候,音乐课上老师用磁带机放着贝多芬、肖邦的钢琴曲,告诉我们闭着眼睛体会音乐美妙,从中感觉音乐所讲的故事,所表达的内容,看着老师沉浸在其中的神情,我们却感觉茫然,并没有体会到个中的奥妙,现在想来除了没有音乐的天赋外,还是缺乏人生的阅历,现在回过头来,从这部电影中,配乐中感觉到的意境与电影情节的匹配度上第一次让我感觉到是如此的关联,是以往电影中所体会到的。初次相遇,脚踏车,早操,淡水海边,不同的场景,不同的音乐。期待与思恋,音乐轻慢,淡淡的纯净,早操中,淡水海边,一吻定情;完美与激情,全方位技术性的操作,斗琴;幽默与搞笑,阿郎与阿;热恋中,音乐明朗快乐,四手联弹;优雅,父子跳舞中;心情低落,忧伤,失恋中;紧张,激动,希望,重生,secret曲;音乐是他的强项,在电影中表现得充分而高效。
电影的叙事采用倒叙的方式,前1个小时看来,和普通的青涩爱情片没有什么大的不同,看到这里的时候,如果依据一般的电影模式,大部分的观众恐怕已能够猜测出电影的结局,八九不离十。高明的地方就是在转折点,这个转折点有太大的特色,刚看到这个转折点,恐怕观众会觉得有些恐怖,难道是一个人鬼恋的故事?后面的倒叙解释才让观众明白,这是一个跨越时空的爱恋故事,让这个电影又具有了些奇幻色彩,走向未来,回到过去有带有科幻的意味,让人在观看的过程中,产生爱情片--〉悬疑片--〉奇幻片--〉爱情片的这样一个感受过程,我想这就是周杰伦所说的不一样的感觉吧?
故事叙事,铺成有序,前面的叙事为后面做了很多的铺垫,这些铺垫在初次看来有些怪异,但是在后来才能体会其中的意思,让人回味。转折点的铺成快速闪过,让人有豁然开朗的感觉。前面的一段是个完整的故事,抛弃其中的一些疑点,故事是连续而自成一体的,转折点处才继续把这个故事升华,让观众感觉新鲜与奇特,回味无穷。
演员的表演就不说了,两位美女的表现可圈可点,亮点是晴依角色被塑造得这样可爱而令人怜惜。
总之,故事,音乐是这个片子的亮点,对于自编自导自演的第一部电影来说,已经非常不错了,还是很值得一看的,jay真是太有才了。
AMV解码器
采用炬力芯片的视频MP3所播放的文件为AMV格式,本程序不采用任何外部的音视频解码库实现AMV文件的解码。
AMV文件由文件头和数据两部分组成,文件头与一般的AVI文件类似,即RIFF文件格式,其中包含有视频和音频的重要信息,比如视频的大小、帧数等,音频的采样率、分辨率、声道数等。
以下是AMV文件RIFF文件头信息:
// AMV Data Structure - Start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
typedef struct _amv_main_header
{
FOURCC fcc; // 必须为‘amvh’
DWORD size; // 本数据结构的大小,不包括最初的8 个字节
DWORD dwMicroSecPerFrame; // 视频帧间隔时间(以微秒为单位)
BYTE reserved[28]; // 初步分析,这28 个字节作为备用,全部为零。
/* DWORD dwMaxBytesPerSec; // 这个AVI 文件的最大数据率
DWORD dwPaddingGranularity; // 数据填充的粒度
DWORD dwFlags; // AVI文件的全局标记,比如是否含有索引块等
DWORD dwTotalFrames; // 总帧数
DWORD dwInitialFrames; // 为交互格式指定初始帧数(非交互格式应该指定为0)
DWORD dwStreams; // 本文件包含的流的个数
DWORD dwSuggestedBufferSize; // 建议读取本文件的缓存大小(应能容纳最大的块)
*/ DWORD dwWidth; // 视频图像的宽(以像素为单位)
DWORD dwHeight; // 视频图像的高(以像素为单位)
DWORD dwSpeed; // 帧速度 /(帧/秒)
DWORD reserve0; // 值等于1,用途还不清楚
DWORD reserve1; // 值等于0,用途还不清楚
BYTE dwTimeSec; // 总时间(秒)
BYTE dwTimeMin; // 总时间(分)
WORD dwTimeHour; // 总时间 (小时)
} AMVMainHeader;
typedef struct _amv_stream_header
{
FOURCC fcc; // 必须为‘strh’
DWORD size;
BYTE reserved[56];
/* FOURCC fccType; // 流的类型:‘auds’(音频流)、‘vids’(视频流)、
//‘mids’(MIDI流)、‘txts’(文字流)
FOURCC fccHandler; // 指定流的处理者,对于音视频来说就是解码器
DWORD dwFlags; // 标记:是否允许这个流输出?调色板是否变化?
WORD wPriority; // 流的优先级(当有多个相同类型的流时优先级最高的为默认流)
WORD wLanguage;
DWORD dwInitialFrames; // 为交互格式指定初始帧数
DWORD dwScale; // 这个流使用的时间尺度
DWORD dwRate;
DWORD dwStart; // 流的开始时间
DWORD dwLength; // 流的长度(单位与dwScale和dwRate 的定义有关)
DWORD dwSuggestedBufferSize; // 读取这个流数据建议使用的缓存大小
DWORD dwQuality; // 流数据的质量指标(0 ~ 10,000)
DWORD dwSampleSize; // Sample 的大小
struct {
short int left;
short int top;
short int right;
short int bottom;
} rcFrame; // 指定这个流(视频流或文字流)在视频主窗口中的显示位置
// 视频主窗口由AMVMAINHEADER结构中的dwWidth 和dwHeight 决定
*/
} AMVVideoStreamHeader;
typedef struct _amv_bitmap_info_header
{
FOURCC fcc; // 必须为‘strf’
DWORD size;
BYTE reserved[36];
/* DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
*/
} AMVBitmapInfoHeader;
typedef struct _amv_audio_stream_header
{
FOURCC fcc; // 必须为‘strh’
DWORD size;
BYTE reserved[48];
} AMVAudioStreamHeader;
typedef struct _amv_wave_format_ex
{
FOURCC fcc; // 必须为‘strf’
DWORD size;
WORD wFormatTag;
WORD nChannels; // 声道数
DWORD nSamplesPerSec; // 采样率
DWORD nAvgBytesPerSec; // 每秒平均字节数
WORD nBlockAlign;
WORD wBitsPerSample; // 采样位数
WORD cbSize;
WORD wSamplesPerBlock;
} AMVWaveFormatEx;
typedef struct _amv_info_struct
{
FOURCC ccRIFF;
DWORD riffSize;
FOURCC riffName;
FOURCC ccLIST; // "LIST"
DWORD listSize;
FOURCC listType; // "hdrl"
AMVMainHeader main_header; // listData
//////////////// video header <start> ///////////////
FOURCC ccLISTV; // "LIST"
DWORD listSizeV;
FOURCC listTypeVStrl; // "strl"
AMVVideoStreamHeader vstream_header; // listData
AMVBitmapInfoHeader vinfo_header; // listData
//////////////// video header <end> /////////////////
//////////////// audio header <start> ///////////////
FOURCC ccLISTA; // "LIST"
DWORD listSizeA;
FOURCC listTypeAStrl; // "strl"
AMVAudioStreamHeader astream_header; // listData
AMVWaveFormatEx ainfo_header; // listData
//////////////// audio header <end> /////////////////
} AMVHeader;
对于打开的AMV文件,采用如下方法即可读取AMV文件的信息:
amvhead = (AMVHeader *)malloc(sizeof(AMVHeader));
if(amvhead == NULL)
{
fclose(fp);
free(amv);
return NULL;
}
memset(amvhead, 0, sizeof(AMVHeader));
rtnlen = fread(amvhead, sizeof(char), sizeof(AMVHeader), fp);
amv->fileseekpos += rtnlen;
我们将其中重要的信息,放入到一个AMVInfo数据结构中以备用户调用:
typedef struct _amv_important_header_data
{
unsigned int dwMicroSecPerFrame; // 帧间时间间隔,微妙单位
unsigned int dwWidth; // 视频图像的宽(以像素为单位)
unsigned int dwHeight; // 视频图像的高(以像素为单位)
unsigned int dwSpeed; // 帧速度 /(帧/秒)
unsigned int dwTimeSec; // 总时间(秒)
unsigned int dwTimeMin; // 总时间(分)
unsigned int dwTimeHour; // 总时间 (小时)
unsigned short wFormatTag;
unsigned short nChannels; // 音频通道数
unsigned int nSamplesPerSec; // 音频采样率
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample; // 数据位数
unsigned short cbSize;
unsigned short wSamplesPerBlock;
} AMVInfo;
AMV文件视频采用单帧JPEG方式压缩,AMV中JPEG数据与普通的JPEG文件相比少了一些信息,比如图片大小,量化表,Huffman编码表,这些参数应该使用的是默认的数据,因此给AMV文件中的JPEG压缩数据添加相应的文件头,即可以在PC上以JPEG图片方式显示出来。同样,对压缩数据进行解码即可以还原为位图形式的数据,用作显示。
关于量化表,AMV如果采用JPEG标准默认的量化表,解码出来的图像效果很差,如下既是默认的量化表数据,数据从ffmpeg源代码中的mjpeg.c中获取。
/* These are the sample quantization tables given in JPEG spec section K.1.
* The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality.
*/
static const unsigned char std_luminance_quant_tbl[64] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const unsigned char std_chrominance_quant_tbl[64] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
为此我直接用windows的画图软件生成一幅简单的JPEG图片,然后直接把其中的量化表数据取出来,则解码出来的效果与AMV精灵软件解码出来的图像没有差别,新量化表如下:
static const unsigned char amv_luminance_quant_tbl[64] = {
0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07,
0x07, 0x07, 0x09, 0x09, 0x08, 0x0A, 0x0C, 0x14,
0x0D, 0x0C, 0x0B, 0x0B, 0x0C, 0x19, 0x12, 0x13,
0x0F, 0x14, 0x1D, 0x1A, 0x1F, 0x1E, 0x1D, 0x1A,
0x1C, 0x1C, 0x20, 0x24, 0x2E, 0x27, 0x20, 0x22,
0x2C, 0x27, 0x1C, 0x1C, 0x28, 0x37, 0x29, 0x2C,
0x30, 0x31, 0x34, 0x34, 0x34, 0x1F, 0x27, 0x39,
0x3D, 0x38, 0x32, 0x3C, 0x2E, 0x33, 0x34, 0x32
};
static const unsigned char amv_chrominance_quant_tbl[64] = {
0x09, 0x09, 0x09, 0x0C, 0x0B, 0x0C, 0x18, 0x0D,
0x0D, 0x18, 0x32, 0x21, 0x1C, 0x21, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, x32, 0x32, 0x32, 0x32
};
Huffman解码表则是一样的,Cb与Cr采用同一套量化表。具体请查看ffmpeg的mjpeg.c文件,在此就不列出了。
AMV音频采用IMA-ADPCM的方式压缩,压缩率为1/4,可能为了减少解码负担,也可能为了减小文件大小,AMV只采用了单声道的方式,如果采用双声道,则音频数据的大小将增大一倍。
ADPCM编解码均较简单,同样在ffmpeg中的adpcm.c文件中找到,index_table和step_table均一样,如下:
/* step_table[] and index_table[] are from the ADPCM reference source */
/* This is the index table: */
const int index_table[] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
/**
* This is the step table. Note that many programs use slight deviations from
* this table, but such deviations are negligible:
*/
static const int step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
需要注意的是解码过程中,初始值和step_index值在音频压缩数据中的位置如下:
audio.status[0].predictor = fbuff->audiobuff[0] + (fbuff->audiobuff[1]<<8);
audio.status[0].step_index = fbuff->audiobuff[2];
step_index的值比较重要,否则解码出的数据是完全杂乱的。
把解码库封装为DLL提供给感兴趣者,如需要代码,请e-mail联系。头文件如下:
/*
* CopyRight (C) 2007, SangWei(swkyer@gmail.com), Wuhan, Hubei, China.
* All Rights Reserved.
*
* FileName:
* Description:
*
*/
#ifndef __AMVDEC_H__
#define __AMVDEC_H__
//#include "AMVHeader.h"
#ifdef WIN32
#ifdef AMVLIB_EXPORTS
#define AMVLIB_API __declspec(dllexport)
#else
#define AMVLIB_API __declspec(dllimport)
#endif
#else /* Linux */
#define AMVLIB_API
#endif
//for C linkage
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _amv_important_header_data
{
unsigned int dwMicroSecPerFrame; // 帧间时间间隔,微妙单位
unsigned int dwWidth; // 视频图像的宽(以像素为单位)
unsigned int dwHeight; // 视频图像的高(以像素为单位)
unsigned int dwSpeed; // 帧速度 /(帧/秒)
unsigned int dwTimeSec; // 总时间(秒)
unsigned int dwTimeMin; // 总时间(分)
unsigned int dwTimeHour; // 总时间 (小时)
unsigned short wFormatTag;
unsigned short nChannels; // 音频通道数
unsigned int nSamplesPerSec; // 音频采样率
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample; // 数据位数
unsigned short cbSize;
unsigned short wSamplesPerBlock;
} AMVInfo;
typedef struct _frame_buffer_struct
{
unsigned char *videobuff;
unsigned char *audiobuff;
unsigned int videobufflen;
unsigned int audiobufflen;
int framenum;
} FRAMEBUFF;
typedef struct _video_buffer_struct
{
unsigned char *fbmpdat;
unsigned int len;
} VIDEOBUFF;
#define AUDIO_FILE_TYPE_PCM 0
#define AUDIO_FILE_TYPE_ADPCM_IMA 1
typedef struct _audio_buffer_struct
{
short *audiodata;
unsigned int len;
} AUDIOBUFF;
typedef struct _amv_decode_struct
{
char *amvfilename;
int opened;
long dataseekpos;
long fileseekpos;
AMVInfo amvinfo;
unsigned int currentframe;
unsigned int totalframe;
FRAMEBUFF framebuf;
VIDEOBUFF videobuf;
AUDIOBUFF audiobuf;
} AMVDecoder;
AMVLIB_API AMVDecoder *AmvOpen(const char *amvname);
AMVLIB_API void AmvClose(AMVDecoder *amv);
AMVLIB_API int AmvReadNextFrame(AMVDecoder *amv);
AMVLIB_API int AmvRewindFrameStart(AMVDecoder *amv);
AMVLIB_API int AmvVideoDecode(AMVDecoder *amv);
AMVLIB_API int AmvAudioDecode(AMVDecoder *amv);
AMVLIB_API int AmvCreateJpegFileFromFrameBuffer(AMVDecoder *amv, const char *dirname);
AMVLIB_API int AmvCreateJpegFileFromBuffer(AMVInfo *amvinfo,
FRAMEBUFF *framebuf,
const char *filename);
AMVLIB_API int AmvConvertJpegFileToBmpFile(const char *jpgname, const char *bmpname);
AMVLIB_API int AmvCreateWavFileFromAmvFile(AMVDecoder *amv, int type, const char *wavfile);
//for C linkage
#ifdef __cplusplus
}
#endif
#endif /* __AMVDEC_H__ */
DLL引入库,DLL文件,把扩展名改为RAR后解压缩。测试代码如下:
// AmvLibTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "conio.h"
#include "../AmvLib/AMVDec.h"
#include "../AmvLib/AMVHeader.h"
int main(int argc, char* argv[])
{
int retval;
AMVDecoder *amvdec;
AMVInfo *amvinfo;
FRAMEBUFF *fbuff;
short prev_sample;
unsigned char step_index;
unsigned int pcmlen;
AUDIOBUFF *abuff;
/*
if(argc == 1 && argv[1] == NULL)
{
printf("Usage: amvlibtest ***.amv\r\n");
return -1;
}
if(AMVOpen(argv[1]))
return -1;
*/
amvdec = AmvOpen("AMV1.amv");
if(amvdec == NULL)
return -1;
amvinfo = &(amvdec->amvinfo);
AmvCreateWavFileFromAmvFile(amvdec, AUDIO_FILE_TYPE_ADPCM_IMA, "AMV1.wav");
printf("视频帧间隔时间: %d uS\r\n", amvinfo->dwMicroSecPerFrame);
printf("视频图像宽: %d 像素\r\n", amvinfo->dwWidth);
printf("视频图像高: %d 像素\r\n", amvinfo->dwHeight);
printf("视频帧速度: %d 帧/秒\r\n", amvinfo->dwSpeed);
printf("视频播放时间: %d 时 %d 分 %d 秒\r\n", amvinfo->dwTimeHour,
amvinfo->dwTimeMin, amvinfo->dwTimeSec);
&bsp; printf("视频总帧数: %d\r\n", amvdec->totalframe);
printf("\r\n");
printf("音频通道数: %d \r\n", amvinfo->nChannels);
printf("音频采样率: %d \r\n", amvinfo->nSamplesPerSec);
printf("音频采样位数: %d \r\n", amvinfo->wBitsPerSample);
printf("音频平均每秒数据: %d \r\n", amvinfo->nAvgBytesPerSec);
printf("\r\n");
while(1)
{
retval = AmvReadNextFrame(amvdec);
if(retval)
break;
fbuff = &(amvdec->framebuf);
if(fbuff->framenum == -1)
break;
printf("帧 %d :\r\n", fbuff->framenum);
printf("\t视频数据长度: %d\r\n", fbuff->videobufflen);
printf("\t音频数据长度: %d\r\n", fbuff->audiobufflen);
// AmvCreateJpegFileFromFrameBuffer(amvdec, "d:\\");
// AmvVideoDecode(amvdec);
// AmvAudioDecode(amvdec);
abuff = &(amvdec->audiobuf);
prev_sample = fbuff->audiobuff[0] + (fbuff->audiobuff[1]<<8);
step_index = fbuff->audiobuff[2];
pcmlen = fbuff->audiobuff[4] + (fbuff->audiobuff[5]<<8) +
(fbuff->audiobuff[6]<<16) + (fbuff->audiobuff[7]<<24);
printf("初始值: %d, 索引值: %d, PCM 数据长度: %d, 剩余数据长度: %d\r\n",
prev_sample, step_index, pcmlen, fbuff->audiobufflen-8);
}
AmvClose(amvdec);
return 0;
}
JTAG(IEEE1149)测试系统构成(1)
JTAG(IEEE1149)测试系统构成
介绍我就不多说了,通过JTAG方式可以测试芯片,电路板,甚至可以错误定位,测试接线非常简单,关键是要有好的测试环境,好的测试工具,咱搞这个算是预研一下吧。
每个能够通过JTAG测试的芯片都能提供一个BSDL的描述文件,这个文件中记录着芯片的信息,测试方法等。每个BSDL芯片可以单独测试,也可以以BSDL器件为中心,在加上外围的器件构成电路板级的测试。
因此可以描述这样的一套测试环境,PC上运行一套测试软件,咱称之为JtagATE(Jtag Automatic Test Environment),这个软件具有一般的IDE环境一样的人机交互界面,改项目工程为测试方案。如VC中一个工程(project)由很多的源文件组成,测试方案则是通过读取待测试的目标上芯片的BSDL文件,通过实际目标电路的连接方式组成一个完整可观测的测试系统,测试方案中必须能够完整地描述实际待测试电路,同时还要包括脚本或者文本描述的测试输入向量,输出则为测试方案最后得到的可观测结果。
这个JtagATE环境通过连接与PC的各种不同的产生JTAG信号的工具与实际待测试的电路连接,JtagATE上的操作则通过这个工具驱动电路板。由此分析得来,这个JtagATE应该包括以下几个方面的内容:
A. 分析BSDL文件,以及从BSDL文件来描述芯片,在此基础上描述出多个芯片之间的不同的连接方式,从而得到测试系统中的完整地JTAG扫描链。进而对于一些不支持JTAG,但是和JTAG芯片由物理连接的芯片,也需要描述出来,这样的芯片输入向量仅为外部引脚的电平状态变化。
B. JtagATE这个IDE环境,将上述的描述方式以友好界面表现出来,利于操作。
C. JTAG控制器。这是产生JTAG信号的关键设备,可以有多种方式,最简单的可以采用并口直接模拟JTAG时序信号,也可以专门设计一种设备实现USB,PCI到JTAG的转换。
A是重点,但不是难点,设计中最好能够开放出接口,从而实现除测试以外的其它一些功能,比如调试、FLASH烧写等。
如何解析BSDL?干脆写一个BSDL分析软件吧。
/*
* CopyRight (C) 2007, SangWei(swkyer@gmail.com), Wuhan, Hubei, China.
* All Rights Reserved.
*
* FileName:
* Description:
*
*/
#ifndef __BSDLDB_H__
#define __BSDLDB_H__
#ifdef WIN32 /* WIN32 platform */
#ifdef BSDLLEX_EXPORTS
#define BSDLLEX_API __declspec(dllexport)
#else
#define BSDLLEX_API __declspec(dllimport)
#endif
#else /* Linux */
#define BSDLLEX_API
#endif
//for C linkage
#ifdef __cplusplus
extern "C" {
#endif
// port type
#define PORT_PIN_TYPE_IN 0
#define PORT_PIN_TYPE_OUT 1
#define PORT_PIN_TYPE_BUFFER 2
#define PORT_PIN_TYPE_INOUT 3
#define PORT_PIN_TYPE_LINKAGE 4
#define PORT_PIN_TYPE_UNKNOW -1
//cell name
#define CELL_BC_0 0 // Special cell, defenerate form
#define CELL_BC_1 1 // Design usable for many function
#define CELL_BC_2 2 // INTEST unsupported on Output2
#define CELL_BC_3 3 // Input or Internal only
#define CELL_BC_4 4 // Inpuy,Observe-Only,Clock or Internal only
#define CELL_BC_5 5 // Combined Input/Control
#define CELL_BC_6 6 // Bidirectional, deprecated
#define CELL_BC_7 7 // Bidirectional
#define CELL_BC_8 8 // Simpler bidrectional, lacking INTEST support
#define CELL_BC_9 9 // Output that observes the signal...
#define CELL_BC_10 10 // Simpler output, lacking INTEST support
//cell function
#define CELL_INPUT 0
#define CELL_CLOCK 1
#define CELL_OUTPUT2 2
#define CELL_OUTPUT3 3
#define CELL_CONTROL 4
#define CELL_CONTROLR 5
#define CELL_INTERNAL 6
#define CELL_BIDIR 7
#define CELL_OBSERVE_ONLY 8
#define CELL_Z 0
#defie CELL_PULL0 1
#define CELL_PULL1 2
#define CELL_WEAK0 3
#define CELL_WEAK1 4
#define CELL_KEEPER 5
#define CELL_INVALID -1
// BSDL jtag tap controller pin map
typedef struct _bsdl_tap_scan_pin
{
char *in_pin_name;
char *in_pin_state;
char *out_pin_name;
char *out_pin_state;
char *mod_pin_name;
char *mod_pin_state;
char *tck_pin_name;
char *tck_pin_state;
char *rst_pin_name;
char *rst_pin_state;
char *tck_freq;
} BSDL_TAPSCAN_PIN;
typedef struct _bsdl_compliance_patterns
{
char *name;
int bitnumber;
struct _bsdl_compliance_patterns *next;
} BSDL_COMPATN, BSDL_BDYCELL;
// BSDL instruction
typedef struct _bsdl_instr_str
{
char *name; // example "IDCODE"
char *code; // example "110010"
unsigned long instr_code;
unsigned long instr_mask;
unsigned char isprivate; // 0:false or 1:true
struct _bsdl_instr_str *next;
} BSDL_INSTR;
typedef struct _bsdl_char_cascade
{
char *chvalue;
struct _bsdl_char_cascade *next;
} CHAR_CASCADE;
// BSDL boundary register access map
typedef struct _bsdl_boundary_access
{
char *regname;
int accessdep;
CHAR_CASCADE *access;
struct _bsdl_boundary_access *next;
} BSDL_ACCESS;
// BSDL port map
typedef struct _bsdl_portmap_str
{
char *pin_name;
char *pin_type;
int pintype;
char *port_dimension;
struct _bsdl_portmap_str *next;
} BSDL_PORTMAP;
//pin function
typedef enum
{
PIN_NC, // NO CONNECT (in accessible)
PIN_VCC, //
PIN_GND, //
PIN_JTAG, //
PIN_INPUT, //
PIN_OUTPUT,//
PIN_BIDIR, //
PIN_OTHER //
} PIN_TYPE;
//whether pin is accessible or not
typedef enum
{
PIN_ACCESSIBLE, // accessible
PIN_INACCESSIBLE, // inaccessible (power or JTAG pin itself)
} PIN_ACCESS;
//pin state
typedef enum
{
PIN_OUT0,
PIN_OUT1,
PIN_HIZ,
PIN_IN0,
PIN_IN1,
PIN_UNKNOWN
} PIN_STATE;
//disval偺忬懺
typedef enum
{
PIN_DISVAL_0,
PIN_DISVAL_1,
PIN_DISVAL_X
} PIN_DISVAL;
// BSDL pin map
typedef struct _bsdl_pinmap_str
{
char *pin_name;
char *pin_number;
// char disval;
PIN_STATE state;
PIN_TYPE type;
PIN_ACCESS accessible;
PIN_DISVAL disval;
int out_cell_number;
int in_cell_number;
int cont_cell_number;
struct _bsdl_pinmap_str *next;
} BSDL_PINMAP;
// BSDL boundary cell
typedef struct _bsdl_cell_str
{
char *port_name;
int num;
int ccell;
int function;
unsigned char cell_type;
char safe;
char disval;
char rslt;
struct _bsdl_cell_str *next;
} BSDL_CELL;
// BSDL warning message
typedef struct _bsdl_warning_msg
{
char *msg;
struct _bsdl_warning_msg *next;
} BSDL_WARNING;
// BSDL
typedef struct _bsdldb_str
{
char *name; // BSDL器件描述名
char *package_name; // BSDL器件封装名
int bsdlid; // 除了描述名以外的一个区分不同BSDL器件的变量
char *chidcode; // BSDL器件ID码字符串
unsigned long idcode; // BSDL器件ID码
char *chusercode; // BSDL器件用户ID码字符串
unsigned long usercode; // BSDL器件用户ID码
unsigned int boundary_length; // BSDL器件扫描链总长
unsigned int instreg_length; // BSDL器件指令长度
char *instr_capture; // BSDL器件"CAPTURE"指令
unsigned long instr_cap_code;
unsigned long instr_cap_mask;
char *component_conformance; // IEEE规范
unsigned int max_comptn;
char *chcomptn;
BSDL_COMPATN *comptn;
unsigned int max_bdycell;
BSDL_BDYCELL *bdycell;
BSDL_TAPSCAN_PIN tapscan; // BSDL器件TAP状态机引脚配置
unsigned int max_port; // BSDL器件端口个数
BSDL_PORTMAP *port; // BSDL器件端口列表
unsigned int max_instr; // BSDL器件指令个数
BSDL_INSTR *instr; // BSDL器件指令列表
unsigned int max_regaccess; // BSDL器件寄存器访问方法个数
BSDL_ACCESS *regaccess; // BSDL器件寄存器访问方法列表
unsigned int max_pin; // BSDL器件引脚个数
BSDL_PINMAP *pin; // BSDL器件引脚列表
unsigned int max_cell; // BSDL器件扫描链个数
BSDL_CELL *cell; // BSDL器件扫描链列表
unsigned int max_warning; // BSDL器件警告信息个数
BSDL_WARNING *warning; // BSDL器件警告信息列表
struct _bsdldb_str *next;
} BSDLDB;
BSDLLEX_API BSDLDB *BsdlDbAllc(void);
BSDLLEX_API void BsdlDbRelease(BSDLDB *bsdl);
BSDLLEX_API int BsdlLoad(BSDLDB *bsdl, const char *filename);
BSDLLEX_API void BsdlShow(BSDLDB *bsdldb);
//for C linkage
#ifdef __cplusplus
}
#endif
#endif /* __BSDLDB_H__ */
以下为测试程序,上面的软件封装为DLL,最后会给出引入库和DLL下载链接。
#include
#include
#include
#include
#include "bsdldb.h"
int main(int argc, char *argv[])
{
BSDLDB *bsdl;
// if(argc == 1)
// {
// printf("Usage: bsdldb xxxx.bsd[xxxx.bsdl]\r\n");
// return 0;
// }
bsdl = BsdlDbAlloc();
// BsdlLoad(bsdl, argv[1]);
BsdlLoad(bsdl, "S3C2410_mod.bsd");
BsdlShow(bsdl);
BsdlDbRelease(bsdl);
return 0;
}
黑马要变成白马,07年中国MP3芯片市场竞争加剧 (zz)
黑马要变成白马,07年中国MP3芯片市场竞争加剧 | ||
| 上网时间 : 2006年12月15日 | ||
作者:潘九堂 “今年大家都叫我们黑马,是后闯进来的。争取明年不叫黑马,叫白马。”在荣获“2006年度‘中国芯’最佳市场表现奖”后发表获奖宣言时,瑞芯微电子CEO励民幽默地表示。随着瑞芯、吉芯/Spansion等黑马在2006年纷纷杀入MP3芯片市场,扬智(Ali)等低价杀手的存在,以及还有新厂商可能加入,2007年中国MP3芯片市场竞争将更加激烈。 瑞芯面向2.0英寸以上视频MP3市场 “它是2006年中国IC设计产业的一匹黑马,是本年度MP3播放器芯片领域最亮的‘芯’,它就是福州瑞芯微电子有限公司的数字音视频处理 芯片RK2606A。”2006年度“中国芯”评选活动主办方信息产业部软件与集成电路促进中心(CSIP)副主任邱善勤博士如此评价瑞芯。 瑞芯微电子董事助理吴伟暾介绍说,RK26XX系列芯片自从2006年初量产出货以来,已经被华旗、纽曼、漫音和蓝魔等200多家整机制 造商采用,预计今年可以实现销售400万片,实现销售额1.5亿元。另外,三星和Iriver等海外品牌制造商也开发出了样机,估计在07年春节以后可以 量产出货,不过,这要取决07年1月CES上的情况。 RK26XX系列芯片采用0.18微米工艺,面向带MPEG-4视频播放功能的中高端MP3播放器,最高可以支持QVGA格式(分辨率 320*240,帧数>24fps)。吴伟暾对《国际电子商情》记者表示:“它能够实现真正的MPEG-4 AVI电影播放,可以支持2.0-2.5英寸屏。”他指出,2006年1.8英寸屏还是主流,但2.0英寸以上屏的MP3播放器量已经开始起来了。他特别 指出,与同类方案采用MCU+DSP相比,RK26XX系列采用单个DSP,成本更低。基于RK26XX系列的1G容量MP3播放器,零售价为400元左 右。另外,RK26XX系列也可以用于数码相框和学习机。 除了RK26XX系列外,2007年瑞芯还将推出一片基础型MP3解码芯片,以面向MP3播放器的基础市场。但吴伟暾表示,由于中低端 MP3播放机市场已经很激烈了,它主要面向电子辞典。事实上,教育电子产品是瑞芯的起家产品,从2002年起,瑞芯持续保持复读机芯片市场占有率第一的地 位。另外,瑞芯的产品还有DTS收音机控制芯片。吴伟暾表示:“以前是学习机占大头,现在肯定是MP3占大头,因为MP3芯片的价格是学习机芯片的10倍。” 07年MP3芯片市场恶战在所难免 由于瑞芯微电子面向2.0英寸以上的视频MP3市场,因此目前和珠海炬力竞争不大,但随着炬力未来进入2.0英寸以上市场,再加上吉芯电子/Spansion、深圳安凯、Ali以及还可能加入的新厂商,07年MP3芯片市场恶战在所难免。 励民对《国际电子商情》记者透露说:“目前瑞芯每个月的出货量约为150万片。”而珠海炬力副总经理邓禹在十大“中国芯”厂商颁奖典礼上介绍说,预计206年珠海炬力MP3芯片出货量超过7,000万片,占据MP3播放器((iPod除外))芯片市场的50%以上,销售额超过14亿元人民币。 RK26XX系列瞄准的是MP3和MP4/PMP之间的市场,目前这个市场的说法非常乱,有称之为视频MP3市场,有的甚至称为MP3.5市场。吴伟暾表示:“目前这个市场还没有竞争对手,但明年肯定大家都要进来,估计炬力明年也会发布基于MIPS的芯片。我们先进去了,占有先机。后来人肯定要性能高一些,价格还低一些,才有机会。” 不过,对于炬力,吴伟暾却表现得尊敬有加。吴伟暾对《国际电子商情》记者笑道:“今天早晨我还和炬力的朋友聊天,我们大家一起把这个市场做 起来,不要象炬力和Sigmatel那样,其实这个市场太大了,一家也吃不完,大家都吃一些。”他表示,2006年全球MP3播放器(iPod除外)出货 量超过1.4亿,预计2007年超过2亿个。事实上,正是因为看好这个市场,微软和SanDisk等国外著名厂商都进入了MP3播放器市场。 在和吴伟暾现场交流的过程中,一位炬力的人士也加入进来了。他们相互之间似乎很熟,丝毫没有传说中双方打得很历害的感觉。但这位炬力的人士坦承:“他们和我们很象,成长历程和炬力很象。” 对于瑞芯这匹黑马,珠海炬力全球销售总监吴章良在电话中接受《国际电子商情》记者时表示:“瑞芯目前对于我们没有太大的挑战,因为瑞芯目前 面向2.0英寸以上市场,炬力主要是面向2.0英寸以下市场,双方的直接冲突很少。”不过,随着未来炬力进入2.0英寸以上市场,双方的竞争在所难免。对 此,吴章良笑道:“那是以后的事情。” 对于瑞芯来说,目前的主要竞争对手可能是2006年出现的另一匹黑马——吉芯电子/Spansion,它也是定位于视频MP3市场。吉芯电子CEO杨心怀对《国际电子商情》表示:“07年简单音频MP3销量将急剧下降,视频MP3销量将超过音频MP3,因为互联网上视频内容非常丰富,而且闪存和LCD屏的成本下降很快。” 除了炬力、Simgatel、瑞芯和吉芯电子/Spansion外,中国MP3芯片市 场还有深圳安凯和Ali,以及另外一些目前已经涉及足数码相框未来可能进入MP3芯片市场的新厂商——MP3和数码相框方案可以共用。其中,特别需要关注 的是目前专注于中低端市场的Ali。一位业界人士表示,Ali很喜欢杀价,常常杀到所有人都吐血而亡后,自己也死掉了,以前在传呼机市场它就这样做过。 随着MP3芯片越 来越没有技术含量,而下一代PMP产品迟迟不能够上量,预计未来的MP3芯片市场竞争会更加激烈,因此现有厂商也在寻求业务多元化。Sigmatel亚洲 区高级副总裁刘家声对《国际电子商情》记者指出:“我一直认为,PMP的出货量不会太大。目前国内PMP的概念是MP3+Video,这种产品市场不会很 大。PMP要看附加值,这将是一个细分化的市场,如PMP+DAB、PMP+移动电视、PMP+导航等。”除了力推视频MP3方案外,该公司目前开始在移动电视、多媒体手机、PMP+DAB和数码相框等市场寻找机会。吉芯电子也在PMP+GPS和多媒体手机市场寻找机会。 炬力的王者地位近期难以撼动 尽管如此,珠海炬力在MP3芯片市场的王者地位还是很难撼动。现有市场上绝对领先地位,十分稳健的经营,以及强大的资金后盾,为炬力未来的发展提供基础。关键在于炬力能够在MP3芯片市场衰落前,开拓出新的市场。根据炬力的发展路线图,未来将开拓PMP、VoIP、移动电视和游戏机等新市场。
过去一年来珠海炬力的股价走势图 和瑞芯一样,珠海炬力的MP3芯片ATJ2097 也获得了“2006年度‘中国芯’最佳市场表现奖”。ATJ2097采用0.25微米工艺,支持USB2.0高速传输,支持 MP3/WMA/WAV/WMV/ASF等格式媒体播放,今年出货量已经超过了几百万颗,预计明年会成为炬力的主力产品。在颁奖典礼,邓禹没有过多的介绍 产品,而是强调炬力对整个国内MP3产业链的推动和贡献。 2005年珠海炬力销售额为12.5亿元,比2004年增长174%,按照2006年销售额为14亿元计算,仅比2005年增长了 12%,增速明显减缓。这也体现了MP3市场成熟和竞争激烈。不过,虽然市场竞争激烈,珠海炬力仍保持了很高的利润率,这为炬力积累了大量的现金,为投资 PMP等新市场提供了资金支持。例如珠海炬力2006年第三季度运营利润率为45.2%,毛利率为56.7%;而2005年运营利润率为47%,毛利率为 59.8%。截至2006年9月30日,珠海炬力持有的现金和现金等价物总值为1.885亿美元。邓禹也指出:“ATJ2097虽然采用0.25微米工 艺,但在尺寸和性能上优于竞争对手0.18微米工艺的产品,这也是为什么我们利润率非常高的原因之一。” | ||
周立功--我的25年嵌入式生涯【收藏】
PCB布板闲谈(zz from 21IC)
毕业4年以来,虽然其中有段时间在做嵌入式实时软件系统的驱动部分,可一直都挂着“硬件工程师”的头衔。其实有点惭愧,谈不上对硬件的有多深的造诣,除了有相当一部分时间设计硬件电路以外,更重要的也就是PCB布板。仔细想想,其中亲手布过的电路板,从简单的数字电视机顶盒前面板的单层板,到复杂一点的AT89C51为核心的工业控制类的双层板,无线扩频电台的基带双层板,高速FPGA的应用板,再到比较复杂的含有DDR MEMERY总线的四层板等不下20块,所幸的还有接触过的手机电路的8层板,所以,终归对PCB的布板有些想法。想法也罢,经验也罢,只要能够对读者的布板有所帮助的话,也就达到了我写这篇文章的目的。
一块优秀的电路板,除了在实现电路原理功能之外,还要考虑EMI,EMC,ESD,信号完整性等电气特性,也要考虑机械结构,大功耗芯片的散热问题,在这基础上再考虑电路板美观问题。所以,PCB板布线是门艺术,具体而言是门折衷的艺术。在开始学习摸索PCB布线之前,或许您会在各式各样的参考书中看见各式各样的PCB板布线的规则,即使许多规则在一定程度上会是有相同的内涵,可是在不同的实际布板实践中会有不同的侧重点,甚至规则之间会产生冲突。举个例子:规则一信号传输的路径越短越好,规则二是在高频布线要求阻抗匹配。在考虑布DDR MEMORY的总线时,SOP封装的MEMERY芯片不可能对所有的TRACK实现规则一,正确的做法是整体考虑阻抗匹配的条件下实现所有的TRACK相对最短。因此,实际布线中规则之间的不可兼得就会让读者布线过程中自觉的有效利用这些规则时产生种种疑惑,甚至就陷入这样或者是那样的一般性的规则中不知所措。在这就需要强调一点――各种布线规则只是指导性的,要结合实际的布线过程去不断折衷以取得最大的效用。我想只要在实际布线中自觉注意这些规则,或多或少会对布线的效果有所帮助。
1. 模块化,结构化的思想不仅体现在硬件原理设计中,也要反映在布局布线效果中
如今的硬件平台的集成度越来越高,系统越来越复杂,自然而然也就要求无论是硬件原理图的设计中还是PCB布线中使用模块化,结构化设计的方法。如果接触过大规模的FPGA或是CPLD就知道,复杂IC的设计必然要求采用自上至下的模块化的设计方法。所以作为硬件工程师,在了解系统整体架构的前提下,首先应该在原理图和PCB布线设计中自觉融合模块化的设计思想。举个例子,数字电视机顶盒的硬件平台的主IC-QAMI5516中就有如下的几种模块:
ST20:主频180MHZ的32位RISC CPU
PTI:TRANSPORT STREAM的处理单元
DISPLAY:MPEG-2解码,显示处理单元
DEMODULATOR:QAM解调器
MEMORY INTERFACE:不同应用系统所需要不同的MEMORY的接口
STBUS:各个模块的数据通讯总线
PERIPHERALS:UART,SMARTCARD,IIC,GPIO,PWM等常用外设
AUDIO:音频输出接口
VEDIO:视频输出接口
QAMI5516模块化的设计过程,虽然不一定要求硬件工程师了解系统的方方面面,可是必然要求在设计硬件平台时,把在实际运用中使用到的IC不同模块的接口部分当作一个子系统来处理:例如音频部分电路和视频部分电路在布局布线的时候就应该在一个整体区域内进行。这样做,不仅延续了IC模块化设计的思路,而且可以方便在需要进行PCB板的物理分隔,减少不同模块之间的电气耦合,可以方便整个系统的调试。我们知道,硬件调试中最容易检查,处理电路原理设计中的错误的方法就是“头痛医头,脚痛医脚”,即上述的QAMI5516平台中,如果音频部分电路有问题,首先要做的就是检查校验音频模块。
模块化的思想还体现在系统总线的布线上,通常总线都区分为CONCROL BUS,DATA BUS,ADDR BUS,这三类。例如上面QAMI5516中SMI上使用的是一片16M的SDRAM,工作频率在100MHZ,这就要求这一组总线在布线过程中需要统一成一个整体来考虑阻抗匹配。在实际的布线过程中,不可能要把这些线布得七零八落吧。
模块化的思想也有利于PCB板的布局。
模块化的思想也有利于硬件系统的功能的扩展或是更改。
2. 站在整个系统的角度上,分析各个模块信号的性质,确定其在整个系统中占据的地位,从而确定模块在布局布线的优先级
布局对于整个系统具有重要的意义,这要求在实际的布线过程中,对于各个模块的具体处理有轻重缓急之分。一般的布局规则,都要求区分模块是模拟电路,还是数字电路,是高频电路还是低频电路,是主要的干扰源还是敏感的关键信号等等。因此,在布局之前必须仔细分析各个模块信号的性质包括模块的属性,功能,供电电源,具体信号的频率,电流的流向,电流强度等,以确定模块在PCB板上布局。通常,在机械结构确定的情况下,复杂的系统还会有N种不同的布局方式,这需要站在系统的角度上依照一些规则的折中来找出最优化的布局布线。
在数字模块中,都会有时钟,例如SDRAM的CLOCK,而时钟电路是影响EMC的主要因素。集成电路的大部分噪声都与时钟频率及其多次谐波有关。如果CLOCK信号是一个正弦波形式,如果处理不当,对系统会“贡献”一个该频率或是该频率的倍频的干扰源,如果是CLOCK信号是方波形式,则对系统“贡献”一个杂散频率的干扰源。同时,CLOCK还是一个容易受干扰的信号,如果CLOCK受到干扰,对数字系统的影响可想而知。因此,时钟电路模块是属于关键模块,在布局布线过程中优先各种规则考虑其布局布线。
类似的还有在现在许多的嵌入式硬件系统中的各种各样的中断模块。中断的触发有电平触发和边沿触发。曾经碰到过一个设置为上升沿触发的中断因外界的干扰而不断的被触发,最终导致了RTOS由于处理不过来而堵死的现象。
按照这一原则来分析二个简单的电路布局。在一个我接触到的手机硬件平台中,显示屏的亮度电路是通过一个PWM产生的不同脉宽信号,经过一个RC积分电路建立不同的背光灯电压来实现的。PWM信号和CLOCK相比,在对整个系统EMI的影响上在某种意义上是相同的。但是如果仔细分析一些,就应该知道,如果在布线时,IC的PWM信号在尽可能短的路径上建立模拟的电平后才在PCB板上传输,也就是说电阻和电容尽可能的靠近PWM管脚放置,这样可以使PWM对系统的干扰减小到最小。在手机硬件平台的设计中,RF部分和音频部分是系统的核心,这两部分的布线占据绝对核心的地位,在布线时置于优先考虑的地位。所以在实际布局布线中,这两个模块的信号线单独布在一中间层,并且在其邻层使用电源层和地层,把它屏蔽起来,同时其他模块尽量远离这两个模块,以免引入干扰。另外尝试着考虑这样一个细节:MIC输入很小的音频信号需要经过放大到一定的程度后再输入到AUDIO ADC中。我们知道抽象意义上的信道传输信噪比是衡量噪声对系统的影响。可以相互参照,一个小的噪声在音频信号放大之前就串扰就信道和在音频信号在放大之后才进信道对音频指标的影响。如果这信道的路径不得以经过一些强干扰源的区域,建议音频信号进行放大后再进行传输。
再比如在复杂系统的总线上通常会挂接类型的设备,如I2C总线可以挂127个从设备,在某些机顶盒硬件平台中通常会挂上DEMODULATOR,TUNER,E2PROM。这也要求对不同的设备对于分享总线的频率上加以区分,对于使用频率高的设备放在相对比较重要的位置上。例如在上述QAMI5516平台上的EMI接口同时使用了SDRAM,FLASH两种设备。基于对系统的理解,SDRAM放置的是实时操作系统的运行代码,FLASH是作为一种存储介质,在软件系统运行过程中SDRAM相对于FLASH有更多的读写操作,因此在布线过程中应该先考虑SDRAM的位置。
3. 注重电源完整性,布局布线中优先考虑电源和地线的处理
在任何电子系统中,干扰源对系统的干扰不外乎通过两种途径:一是通过导体的传递,二是通过电磁辐射经过空间的耦合。在频率较低的系统中主要是第一种路径,在高频系统中也有相当部分的干扰原因是通过导体的传递,其中比较明显的就是IC产生的噪声通过电源和地干扰整个系统。因此,电源的完整性或者说是电源质量对整个系统的抗干扰能力具有至关重要的意义。电源完整性实际上是信号完整性的一部分,然而考虑到电源对于所有系统的重要性,在此单独列出。要声明的是,在实际系统中,要做到这一点并不容易,系统中总会有各种不同频率的噪声。在电路设计和PCB布局布线中只是极力的减小各种频率的噪声,从而提高系统的抗噪声的整体性能。同时,在复杂系统中,减少系统的噪声不是更改一两电容的值就能够做到,而是需要注意电源滤波效果的累积。在手机硬件设计中,有专门的PMU来对管理对各个模块供电,然而PMU都是来自VBAT。无法想象,如果是敏感的音频运放的供电没有经过滤波的处理,直接取自VBAT,又或者,像给SDRAM供电的电路没有做滤波处理,任由这部分数字电路的开关噪声污染整个VBAT,会是有什么样的后果?
如果对电源完整性有了足够的重视,结合起前面说过的模块化和各个模块仔细分析后,这部分还是相对比较好处理。对于IC电源VCC通常的规则一般都会用旁路电容和去耦电容进行处理,并且在布板的时候尽量让这类电容靠近IC的电源输入处。如果在要求苛刻的系统中,还可以对不同的敏感频率采用LCCL电路(串接一个电感或是磁珠,并一个电解电容,并一个瓷片电容,再串一个小的电感,具体值需要依照相应频率确定)滤波。曾经做一个复杂的系统,由于在系统的DEMODULATOR上的一路核心电源上没有使用旁路电容,从而使DEMODULATOR的解调后的误码率高的无法忍受。对于系统中各种GND的处理,一般要求分析电流的回流路径。电流具有总是选择阻抗最小回流路径的性质。这是一个核心原则,可以通过这样一个事实来理解:在PCB布线中有“铺铜”这样的模式。“铺铜”经常会在网络GND上使用,所有的数字信号都可以抽象成一个最基本的门级电路,GND也就是信号回流路径的一部分。GND就是通过“铺铜”的方式,使信号的路径上的总阻抗变小。“就近接地”,“最小化接地阻抗”也正是基于这样的考虑。
上面只是抛砖引玉的讲述了这几年来鄙人在PCB板中的一些感触颇深的几点,有了这三个指导性原则,并结合具体的许多布线规则,剩下就是您的态度问题了。当然,毕竟能力和见识有限,其中难免有所偏颇,不足之处恳请指正。
我的探索之路(zz from 21IC)
(与电子爱好者共勉)
序
问几个问题,大家自己心里是怎么想的:
1 了解自己的特长吗?知道自己将来要做什么吗?
2 人生道路上的选择经常犹豫吗?
3 做过令自己激动人心的事没有?
我的探索之路写给哪些与我相同兴趣,正在学习、准备走上职业生涯或正在工作的朋友们,追求自己的梦想,创造自己的价值,与人相同兴趣的朋友共同探索世界、探索人生,在人生的道路上共勉!(可联系我:liu40231@126.com, 文章写后不久突发奇想:做真正的MP3-DIY,域名已申请:WWW.TASO123.COM, 有兴趣者敬请关注)
一 孩提时代
我是一个天生的电子爱好者,我梦想我能发明一点有用的东西,我梦想我的产品全世界都有,我梦想我会在社会留下值得纪念的东西。我出生在比较偏僻的农村,70代家里也非常穷,虽然小山村,但学习一直很优秀,动手能力很强,也是那种爱玩的那种,做什么事都 要玩出点花样。在小学时就会到泥塘里收集沼气,然后点火看看书里写的是不是真的,自己做箱子去验证植物生长的向光性,书本上的东西都很好奇,能动手做的就会去探索。有一件我记得很清楚的事:小时候,我们都玩一种竹子做的枪,用樟树籽做子弹,用空气压缩的原理,能把樟树籽打出很远,而且还有“嘭”的一声的响声,若今天有人用这个思路开发玩具,肯定是个很好的思路。做法是这样的:
砍一根直径大约是樟树籽大小的竹子,选取长约20公分的竹节,做成长竹筒,然后用一根筷子用刀削好,一头加上一个用手握把子,用作推进器,枪就做好了,从樟树上摘来的樟树籽用推进器推进长竹筒,当你推进另外一粒进,竹筒的空气就被压缩,压缩到一定的程度,前面的一粒就会“嘭”的一声射出,可以打到很远,这就是我们做打仗游戏的道具,小孩乐此不疲。枪一直延续下来就是这么做的,但是,在我手就改进了,我在竹筒大约1/4的地方开了一个洞,洞上再接上一个装樟树籽的的竹筒,枪就变成可以连射的了,就是机关枪了。我现在回想小时候,我想现在的小孩有几个有创造力呢,每天被许多的功课和作业压得喘不过气来,思维却被僵化了,哦,这是题外话。那小还小,也不知什么理想,什么上大学,只是玩得高兴而已。
二、初中时代
到了初中,接触电的知识了,对电产生了强烈的兴趣,有二件事我记得非常清楚。第一件事,做发电机。具体不记得哪一年了,在初中物理上教完发电机的原理时,自己就琢磨着试试发电。可想而之,我家里在农村,哪时住的还土屋,可以说是要什么没什么,但经过长期的努力,还是把最重要的材料:磁铁和漆包线弄到了,又经过很多的努力,手摇发电机终于可以发电了,可以把一个小灯泡点亮了,这样的高兴的事情是其它的东西无法比拟的。现在每天忙忙碌碌,要不是现在静下心来想一想,我的这些创举都快尘封记忆了。那些磁铁和漆包线一直都是我的宝贝,保存了很多年,不过今天是找不到了,唉可惜啊,不然可以教育教育孩子。
第二件事,收音机的事。在80年代,若是家里有一个收音机也是不错的了,我的姨父就有,是比较小的那种。我对姨父的收音机垂涎三尺,恨不得他送给我,但这是不可能的,我很好奇,很想打开看个究竟,终于有一次,我准备好了工具到他家作客,找个机会打开了,里面全是哪种竖起的电阻、电容、三极管之类,密密麻麻,我这个动动,哪个动动,结果可遭了,装上之后,没有声音了,后来就一直没有修好,姨父也知道是我干的,也没说什么,上了高中之后才送给我。
三、高中时代
初中就这样无忧无虑的过去了,在农村就是农活累了一点,其它的没什么,其实有很多好玩的事情,虽然没有钱,童年应该是比较快乐的,上了重点高中,那就是进城了,开始了人生的新生活,乡里人进城,好象什么都低人一等,城里人看上去好象都很厉害,这是我刚上高中的感觉。第一学期考下来,居然排进前几名,一下子有了信心了,环境好熟悉了,又开始鼓掏电子之类的东西了。有一次市里举行一个电子竞赛(居然还有这个!),报名参加了,那时实际上都不懂,但是兴趣所至,也没钱买书,真的是没有钱,我寄宿在学校,吃的米都要每个月回去拿,那时候想吃一个面包都是奢侈品,学校有一个面包店,吃过几次,那种面包的香味现在永远也体会不到了。没有钱只有经常往书店跑,也不买书,省钱买元器件。第一个做的实验就是全波整流电路,变压器、二极管、灯泡等一应俱齐,电路搭好了,电源一开,哈,灯泡亮了!可惜很快就灭了。你说是怎么回事,我用的是检波二极管,马上就被烧了!当然我当时并不知道是这回事,通过不断的学习和不断的解决问题,水平在不断上涨。要参加竞赛,经常冥思苦想,有时蹲在厕所都在想,毕竟知识有限,最终做了个跳动的闪光灯,获得一等奖,毕竟对于高中生来说已经非常不易了。很可惜当时的电路图不记得是什么样了,证书保存了很久,现在也不见了,有的话,还可以教育教育后代呢。
这样浓厚的兴趣使我自学了很多的电子知识,到了高三容不得有多少时间去搞了,我们的学校是省重点高中,我的成绩也一直排在前几位,考上大学好象是板上钉钉的事,所以恨不得高考赶快结束。在高考前,有国防科技大学的老师来招生,是招推荐生,人高高大大的,是自动控制专业的,自动控制专业名字很好听,也是搞电子的,而且上学不用钱,所以从来没有考虑过第二个学校,第二志愿只是粗略考虑了一下,也全是电子专业的。后来自己也考了高分,就顺利的录取了。这是人生的一个重大选择,穿上军装不得已,我不象别人因为军校才报的,在我自己心里就没有其它的专业,上国防科大是因为读书不用钱。就那样18岁那年穿上了军装,上了大学,来到了大都市长沙。我说,这些所有的事情,没有任何人的建议或咨询之类,我父母不懂,山沟里也就我一个人先出来,外面的世界没有人指点,一切都得自己选择。
四、大学生活
美好的大学生活开始了,入伍、宣誓、军训,既是军人,又是大学生,回家都好神气,只是没有钱花,我89年入校,当时的津贴是20几块,吃的、住的穿的全包了,上学后就没有用过家里的钱。大学的第一个元旦,为了显示自己的本事,在我们的宿舍做了一个大大的灯笼,专门设计一个闪光的灯放在里面,灯光一闪一闪的,显示了自己的不同,就这样,大家都知道了我的动手能力,什么修理电器之类的事情全包了。
当然,我是不会放过大学里广阔的资源的,业余时间就花了大量的时间学习电子方面的知识,电子基础书籍早就提前学完了,要知道那些课程是要到大三、大四才学的。大学二年级,举行全国第二届大学生挑战杯竞赛,我们学校以前没有参加过这项比赛,这次就当行政任务下达了,我就顺理成章的入选了,并且还有经费支持,真是天大的好事呀。哪一年暑假这一届全体学生都要下部队训练,而我却在实验室里搭硬件,写程序,这种机会绝不是等待而来的,机会都是留给有准备的人,包括工作。暑假完成作品,作品是可以记录弹琴的节奏和音符,是用单片机做的,由于经验上的不足,遗憾未能获奖,但是有这样的机会也大大的煅练自己。我对这些东西着了迷,也影响了其它东西的学习,主要是英语,英语是要花大量时间的,我对英语不感兴趣,到考试进尽量去应付,搞突击,这为后来埋下了隐患,在毕业考研英语没有过关,这对我的影响也是重大的。我没有什么门路,分不到城市里,被分到了一个遥远的军事基地。
五、第一个工作
第一次去那么遥远的地方,真是举目无亲啊。好在还有一个我们系里一个老师的女儿也在那个单位工作,是她接待了我一下,那个看都不愿意多看我一眼的人现在已经是我的妻子了。不在城市里,我想做的一切都没法实现,真是痛苦啊,也想过逃离,到深圳打工,这种想法很开始时很强烈,过久了只好随遇而安,努力工作,做好自己的岗位工作,得到了领导的赏识,在第三年就获得了考研究生的机会,要知道要求报考的人很多的,每年只有几个。第四年终于重返国防科技大学的校园,四年的青春为祖国作了贡献,四年几乎与我的专业和兴趣无关。考研的日子是辛苦而又紧张的,人就是这样,有目标的话,它总会达到。我认为自己又浮出水面了,深深的换了一口气,以前四年的我不是我,在基地四年,不长也不短,对于农村孩子来说,环境适应是没有问题的,现在想起那段时光,还真是值得记忆的,不象现在,每天忙忙碌碌,踢球、打扑克、抓知了、春游、谈恋爱,日子也过得很开心,在什么环境下就有什么样的生活。有一件事不得不提起:为了讨得女朋友的芳心,我用了上百个发光二极管做一个心形的发光二极管阵列,作为生日礼物,这可是花上大量功夫的哦。老婆还竟然没有给我保存。
六、读研究生
为了获得足够的学分,读研的第一年不敢多想,老老实实学习,第二年女儿出生,同时也用微薄工资积攒的钱买一台电脑(98年,一台MMX电脑值八千多呀),开始了创业生涯。第一份工作是单片机系统设计,是兼职,跟一个老师做,每月1500的工资,这是自己开始挣钱的开始。这份工作有了做硬件的一切条件,工作对我还是不难,多余的时间琢磨做出点什么产品,由于视野的限制,在现有的技术基础由也想不出很多点子。但功夫不负有心人,第一点子就是失之桑榆,收之东隅。我岳父家时有很多遥控器,经常找不着遥控器用,就冒出做一个万能遥控器的念头,能够自学习其它遥控器的指令。然后找资料、想办法,还。买了一个遥控器进行改装,经过不断的调试、测试,终于做到识别率很高了,而且还去申请了专利,什么都做下来了,就是没有变为经济效益,好象没什么用。但机会总是留给有准备的人,一个偶然的机会,我拿着遥控器给一个很大的做电教行业公司的研发部经理演示,当时经理如获至宝,他们正在找这种技术用于一种中央控制系统,所谓的中央控制系统就是用电脑控制很多的VCD、DVD、音响、投影机之类的设备,原来的技术是要改装这些设备使之变得可控,生产工艺非常复杂,有了红外学习技术之后,就不需要改装设备了。我为他们设计了一个红外学习卡,提供软件按数量卖给公司,这个公司的实力雄厚,销售很多,我的收入也可观,我觉得这是一次非常成功的经历。
七 工作
因为这一次经历,使自己进了电教设备研发、销售这个行业,一做就是好几年。同时我也在学校帮老师做项目,那时学校做磁悬浮项目正是红火的时候,我做了很多的事情,由于能力突出,争取了留校的名额。也有很大部分时间一个人在外面闯,也做了很多项目,主要都是电教行业,多媒体中央控制系统、双向多媒体控制系统这些热门的电教设备全部系统设计都是自己完成,然后和别人合作,不过第一次合作就钻进了别人的圈套,合同谈好是拿提成的,被老板左一个理由右一个理由把钱扣下来了,搞了一年几乎什么也没得到,被第一个老板骗了,接着又被第二个骗了,第二次是股份合作,当时只是一股劲头而已,谈不上创业之类,辛苦了大半年被别人控制着,也得不到什么好处,这样一直搞到2003年去了,可以说比较失败,只有经验教训:一是口头的承诺或自己不懂的规则总是会别人利用,然后牵着鼻子走,最终一无所获。二是要放弃自己一些不切实际的想法,想一下子就成功是很难的。当然,一无所有闯荡社会,总要付出一点代价的。2003年初,断了继续做下去的念头,牺牲了就牺牲了,我放弃了一切。我在网络上漫无目的搜索,想到深圳找个职位来打工(因为身份问题,出来不是那么容易的),最终还是静下心来研究学习DSP、研究网络通信技术,第一个(可能是吧)在DSP上把TCP/IP协议跑起来,那时还租了房子搞研究,为挣一点零花钱,把技术拿到网上去卖,也还有点收入。TI的DSP有强大的串口通信,可以配置I2S,自己家里的VCD我拆过,它的解码板查过资料也是I2S,在好奇心的驱使下,就开始了DSP驱动VCD解码板的研究,一个一个的难关攻破之后,DSP板终于可以播放VCD格式的文件了,而且还是通过网络播放的,就是说,文件是存放于电脑的。后来加以改进,写了一个服务器程序,可以支持100M以太网播放40个终端同时播放,很是了不起哦。因为我做过电教行业,知道电教行业的一些需求,这项技术肯定是有价值的,果然第一次谈成的转让费就很高,我走出了困境,后来又开发了好几个系统产品,做得忙不过来,自己也开了一家公司,通过多年的努力,短短的一两年总算有了小小的成功。
八 做MP3方案公司
在小有成就感时,心里有了变化,在学校自己的身份不允许,也有科研任务要做,总是觉得放不开手脚做,一直就有完全脱出来做的想法。
2004年,一个在深圳的朋友一直鼓动我来深圳做MP3,那年也正是MP3最红火的时候。当时他的一个朋友因为做矩力而一年成为千万富翁,成为做MP3的传奇。而当时我确实用Telechips的芯片做网络MP3的项目,技术上有一点积累,对这一行很是向往,也是我心中一直存在的梦想,心理是很想做一做,在全然不知行业的运转规律的情况,下了巨大的决心从学校跑出来,在深圳成立一家MP3方案公司。MP3是一个庞大的产业链,在深圳一个月有几KK的量,运行是这样一条轨迹:芯片厂商-方案商-生产厂家-经销商-用户
芯片有两大阵营:炬力和Sigmatel,应该说占了MP3的绝大部分市场,而两家也差不多平分秋色,国内市场和第三世界国家用炬力的多,发达国家中用Sigmatel的多。其它还有凌阳SPACA7550和现在的SPDA1000系列。TELECHIPS公司的TCC730系列,飞利浦公司的SAA7750系列,MP3门槛低,介入容易,。国外厂商因为本身所具有的实力,基本上都是自己研发制造。而国内的厂商因为实力欠缺,一般都采用代工生产,或者为别人生产。在我看来,很有绝大多数厂商没有真正做研发,几乎全由所谓的方案公司包了,我们公司一个月都可以做十几款的,而且研发都是不收取费用的,只是捆绑一些价值比较大(如芯片、显示屏)的销售给大家。
方案公司获得芯片厂商的软件源代码,做做UI界面设计,改一下显示屏的驱动,根据不同的时尚款式由LAYOUT工程师画出PCB,很快就可做出很多新产品。方案公司整个设计的方案:PCB板、原理图、BOM单、贴片图、软件(加了密),说明书的电子文档都做好了全部交给生产厂家,方案靠供应芯片、显示屏等来获取利润,由于进入门槛低,竞争非常激烈,方案商的毛利润很低(3%可能都不到),需要的资金很多,风险很大,去年有很多MP3厂倒闭,有的甚至一夜间消失,有一个我们的客户卷走几千万,很多供应商损失很惨重,我们也一样。
作为生产厂家这一环节,上马MP3项目相当容易,我刚才说过技术问题方案公司包了,既不需太多资金,也没有太高的技术要求。深圳周边中小规模的MP3工厂有上千家,基本流程如下:确定方案(方案公司的方案太多了,厂家可以有很多选择)→采购套件做样机并测试→OK则转入批量生产→出货给经销商,所谓的生产,很多的生产厂家也仅仅是组装一下而已,现在有很多的叫半成品公司,已经把MP3的主板都贴片好了,只剩下一下FLASH芯片未贴而已,也叫行业分工细致吧,找几个工人一焊,把外壳装好,装上包装盒可出厂了,生产厂家只有不断的做新款才能保证他的利润,旧的款式一台的利润10元都不到,新款有几十元的利润,生产厂家批发给经销商,经销商的利润略微高一点。
就这样,忙忙碌碌忙了一年半,公司规模做得也不小,费用高,利润低,还有其它很多的风险,钱还是很赚到的,忙来忙去,也就是帮工程师和业务员打工去了,我感到心灰意冷,MP3实在没什么好做的,也发挥不了自己的优势。痛定思痛,决计一刀两断,什么也不做,忙碌了这么多年,终于有时间静下心来写一点东西,免得日后全忘了以前做过的事。
一个月后,闲得无聊,MP3行业做了这么久,也留下了不少东西啊,我能不能为广大工程师作点贡献,做一个真正的MP3-DIY,我为这个想法而兴奋。
6月20日,MP3-DIY已开始实施,网站取名为探索电子在线,域名是WWW.TASO123.COM,整理了我以前的一些成果免费送给大家分享。
片言断语:
我因爱好电子,所以生活就是工作,工作就是生活,我工作,我快乐。
以我自己的经历:在电子行业,我应聘人的标准:有没有参加过什么竞赛,自己动手设计过什么东西没有,这是衡量一个人动力的标准。
要做自己感兴趣的事,钱再多,而没有自己了,我也是不会干的。