1.定义类型使用#typedef,使用#define u16 unsigned long这样的语句会带来错误与bug
2.对某一个内存(寄存器)读取它的值,使用如下操作:
#define READ_REG(x) *((volatile unsigned int *)(x + BASE_ADDR))
X表示偏移地址,BASE_ADDR表示基础地址
同理,对一个内存(寄存器)进行写操作,使用如下操作:
#define WRITE_REG(addr,value) (*(volatile unsigned char *)(addr+0xe000d000) = (value))
3.SATA的出现时为了取代PATA,DDR的出现时为了取代SDRAM
4.为什么SDK中找不到xparameters.h或者其他结构体以及宏定义
a) 导入库文件,将缺少的库添加进去,库下面有很多的版本,根据自己板子的实际情况添加对应版本的src,具体方法右键“properties”
b) 从Vivado导出配置文件之后,没有从vivado中启动SDK
c) SDK的workspace和vivado的workspace没有设定为一起,SDK在生成platform和bsp的时候,会用到vivado生成的.sdk后缀名的目录。
5.以串口输出的方式从当前运行的函数中得到函数名和行号,printf(“%s %d\n”,__FUNCTION__,__LINE__);
6.likely和unlikely在编码中的作用:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
这里的__built_expect()函数是gcc(version >= 2.96)的内建函数,提供给程序员使用的,目的是将"分支转移"的信息提供给编译器,这样编译器对代码进行优化,以减少指令跳转带来的性能下降。
__buildin_expect((x), 1)表示x的值为真的可能性更大.
__buildin_expect((x), 0)表示x的值为假的可能性更大.
也就是说,使用likely(),执行if后面的语句的机会更大,使用unlikely(),执行else后面的语句机会更大一些。通过这种方式,编译器在编译过程中,会将可能性更大的代码紧跟着后面的代码,从而减少指令跳转带来的性能上的下降。
7.DSP6678的MPAX解析
根据手册里面的信息,我们映射的话,需要配置以下信息:
要配置的segsz,利用哪一个seg进行配置,需要映射的36位起始地址,映射到的32位目标地址,最后是权限。
起始手册说的很明白,就是把要映射的物理地址的高24位放到XMPAXL的高24位,低8位是perm,然后把要映射的32位逻辑地址的高20位,放到MPAXH的高20位,中间7位应该写0,最后5位是写入SEGSZ的大小。假设我们利用seg4,那么
volitale unsigned int *xmpaxl=(volatile unsigned int *)(0x08000000+32);
volatile unsigned int *xmpaxh=(volatile unsigned int *)(0x08000000+32+4);
unsigned int r_addr=(unsigned int)(0x880000000>>4);//因为寄存器是32位的,我们需要进行一个转换
*xmpaxl=(r_addr&0xffffff00)|(perm&0xff);
*xmpaxh=(0x50000000&0xfffff000)|(size&0x1f)
这样其实就配置好了,我们的核访问0x50000000的时候,就访问到了高端2G内存的前面256M,根据这个方法,可以依次根据cpu_id,配置2G的空间,每个核256M,大小正好是2G。