我正在使用gdb进行调试.我想知道gdb如何在内部通过JTAG在嵌入式处理器上设置brekpoint.
我正在Xilinx的Microblaze上运行带有完整MMU的Linux内核3.3.我正在做的任务要求我知道以下内容:我需要创建一个文本文件(缓冲区)并找到该缓冲区的物理地址,我不希望内核将此文件写入不连续的内存区域.
我需要这个的原因是因为我有一个DMA引擎从预设的物理内存地址流式传输数据,所以我需要强制Linux在那个确切的内存位置创建缓冲区文件,以便当我将数据写入此文件时立即传输由DMA引擎到另一个硬件核心
更多细节:
我的系统有一个512 MB DDR3 RAM通过"Xilinx"多端口内存控制器(MPMC)连接到系统.该内存控制器的基地址为0x90000000,系统中的所有单元通过该控制器访问内存,包括MicroBlaze,DMA我所使用的单元使用称为本机个性化接口(NPI)的特殊接口,以非常低的级别与存储器通信,从而产生非常高的速度性能.
这个NPI DMA单元最初设计用于一个名为"xilkernel"的非常基本的嵌入式内核,它不支持虚拟内存,MMU也不是MicroBlaze的一部分,因此程序员可以看到操作系统代码所在的位置并选择物理内存地址如0x91800000作为DMA将从中流出的源地址,然后程序员可以将文件放在该确切的地址中并运行系统
当我们需要迁移项目以使用Linux而不是xilkernel时我们遇到了这个问题,我在外部存储设备上有文件,我可以从Linux访问作为块设备,我需要将每个文件移动到主内存(DDR3 RAM)并使DMA流成为文件.目前来自固定地址的DMA流,但如果需要,我可以使它成为通用的.
我想编写我的代码来处理Microblaze上的TLB未命中,当然还有页面表等.这些都是在OVPsim上完成的.
在我学习的过程中,我编写了这个小程序集以引用未映射的位置(0x1000000) - 我将此作为特权代码运行,其中VM为:
ori r20, r0, 0
ori r12, r0, 0x1000000
/* next line should break it */
sw r20, r12, r0
Run Code Online (Sandbox Code Playgroud)
(即,将内容写入r20 == 0ORing形成的地址r12 == 0x1000000,r0 == 0 => 0x1000000显然.)
但是,GDB没有跳转到异常向量,而是报告"程序收到SIGSEV" - 我出错了什么?我没有在MSR中启用硬件异常位,但是手册说你无法在任何情况下掩盖这些异常,所以这不应该是问题.
进一步的信息我不能得到任何(例如,包括错位异常)要执行的异常处理代码,(除非我明确地调用它),无论我是否使用调试器.关闭调试器后,我从OVPsim得到这个输出(NB我只是改变了测试地址 - 上面的0xA000000和0x100000之间没有区别):
Processor Exception (PC_PRX) Processor 'platform/cpu0' 0x248: sw r20, r12, r0
Processor Exception (PC_WPX) No write access at 0xa000000
Run Code Online (Sandbox Code Playgroud)
这是所有代码都以特权模式运行,所以除非我没有正确配置Microblaze ,否则我没有看到它没有调用处理程序的明显原因.我打开了这些:
icmAddStringAttr(cpu1_attr, "endian", "big");
icmAddDoubleAttr(cpu1_attr, "mips", 100.000000);
icmAddStringAttr(cpu1_attr, "variant", "V8_20");
icmAddBoolAttr(cpu1_attr, "verbose", …Run Code Online (Sandbox Code Playgroud) 为什么xil_printf导致堆栈溢出而XUartLite_SendByte没有引起堆栈溢出?谁能解释一下?带注释的部分(XUartLite_SendByte)正常工作,但最终我想在i上调用一个函数并使用xil_printf返回结果。
代码如下所示。
使用xilinx sdk进行微火
#include <stdio.h>
/*#include "xparameters.h" */
#include "xil_cache.h"
/*#include "uartlite_header.h"
#include "xbasic_types.h"
#include "xgpio.h"
#include "gpio_header.h"
#include "xspi.h"
#include "spi_header.h"*/
#include "xparameters.h"
#include "xutil.h"
#include "xuartlite_i.h"
#define UART_ADDR 0x40600000
int main()
{
Xil_ICacheEnable();
Xil_DCacheEnable();
print("---Entering main---\n\r");
Xuint16 i;
while(1==1)
{
while(XUartLite_IsReceiveEmpty(UART_ADDR));
i = XUartLite_RecvByte(UART_ADDR);
xil_printf("%c ", i);
/*while(XUartLite_IsTransmitFull(UART_ADDR));*/
/*XUartLite_SendByte(UART_ADDR, i);*/
//}
}
print("---Exiting main---\n\r");
Xil_DCacheDisable();
Xil_ICacheDisable();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 这是我试图在嵌入式Linux系统上运行的一些示例测试代码:
#include <iostream>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
std::cout << "Hello World from C++" << std::endl;
std::cout << "c=" << c << std::endl;
std::cout << "i=" << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
嵌入式系统是Microblaze,它是在Xilinx FPGA上运行的32位RISC软核处理器.请不要因为你的许多标准Linux知识仍然适用而被推迟.处理器配置为带有MMU的LSB,而我正在使用的Linux版本(由Xilinx提供的PetaLinux)期望相同.我正在使用提供的GNU编译器; Microblaze似乎在GCC正式支持.
我遇到的问题是,当stdlib需要与整数进行交互时,会出现段错误.这是输出:
Hello World from C++
c=A
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
请注意,char处理得很好.这段代码的C等效也可以正常工作:
#include <stdio.h>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
printf("Hello World from C\n");
printf("c=%c\n", c);
printf("i=%i\n", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
... …
为了确保与我正在开发的产品的二进制兼容性,我需要强制我的一些枚举由单个字节表示。
由于 C90 允许编译器选择适当的类型(6.7.2.2 枚举说明符),因此我想强制编译器选择 8 位。
我确实希望 GCC 属性允许这样做,但我在这里找不到任何东西。还有其他方法可以处理这个问题吗?(或者我错过的属性)
我正在为 Microblaze 和 C90 使用 GCC 4.6.4(我在这里也没有看到相关选项)。
有没有人为MicroBlaze编写了多线程C ++应用程序?Xilinx文档指出:
EDK随附的标准C库不是为多线程环境构建的。诸如printf(),scanf()的STDIO函数以及诸如malloc()和free()的内存管理函数是非线程安全函数的常见示例。在多线程环境中使用C库时,必须使用适当的互斥技术来保护线程不安全的函数。
此外,MicroBlaze GCC报告线程模型为“单个”。
如果我使用的是C ++标准库容器,那肯定是不安全的,对吗?
甚至从Xilinx那里得到关于这个简单问题的答案的时间也很短,更不用说解决它的方法了。似乎这是Xilinx提供的构建系统的主要缺陷。
是否有可能在没有EDK的情况下在任何Xilinx FPGA器件上编程Microblaze?
我正在Linux下开发.
关于那个是否有可取的tutos /书籍?有一个稳定的开源克隆吗?
我现在正在为fpga上的microblaze编写交流程序,我现在想检查一下我是否收到了消息,但是strncmp和strcmp不工作的唯一方法就是这样:
char*as=malloc(sizeof(int));
as=p->payload;
if (*(as)=='o') {//first letter o
if (*(as+1)=='k') {//second letter
Run Code Online (Sandbox Code Playgroud)
但是,一旦我处理较长的文本,这将很难,所以任何好方法?我用这种格式试了strncmp:
if (strncmp(as,"ok",2)==0) //didnt work even changing 0 to 1 it just doesnt detectct it
Run Code Online (Sandbox Code Playgroud)