状況と質問
Cで書かれたあるソースコード(念のため一番下に載せておきます)をコピペして動かしたいのですが、セグフォのエラーが出てしまいました。そこで最低限のものを書いて実験したところ、ループの途中でセグフォが出ていることがわかりました。
どうしてループの途中で、しかも決まった回数のときにsegmentation faultになるのでしょうか? またそれを解決する方法はありますか?
初歩的な質問かもしれないことは承知ですが、調べるとっかかりになるワードだけでも構いませんので、ご回答いただければ助かります。
コード
C
1// test2.h 2 3#include <stdio.h> 4 5struct udmabuf{ 6 char name[128]; 7 unsigned char * buf; 8};
C
1// test1.c 2 3#include <stdio.h> 4#include "test2.h" 5 6int main(){ 7 struct udmabuf intake_buf; 8 float a[32 * 32]; 9 int i, j; // 行列の添字 10 int m, n; // 行列のサイズ 11 m = n = 32; 12 for (i = 0; i < m*n; i++){ // 行列を初期化 13 a[i] = i / 2.0; 14 } 15 16 int count = 0; 17 for (i = 0; i < m; i++){ 18 for (j = 0; j < n; j++){ 19 ((float *)(intake_buf.buf))[i * n + j] = a[i * n + j]; 20 printf("%d\n", count); // 420までで止まる。なぜ?? 21 count = count + 1; 22 } 23 } 24 25 return 0; 26} 27
bash
1# 実行結果 2$ gcc test1.c && ./a.out 31 42 53 6... 7418 8419 9420 10Segmentation fault: 11
元にしている実際に動かしたいコード
c
1// dma_simple.h 2 3#include <stdio.h> 4#include <stdint.h> 5#include <stdlib.h> 6#include <unistd.h> 7#include <fcntl.h> 8#include <string.h> 9#include <sys/types.h> 10#include <sys/mman.h> 11 12#define DMA_INTAKE_DMACR (0x0000) 13#define DMA_INTAKE_DMASR (0x0004) 14#define DMA_INTAKE_SA (0x0018) 15#define DMA_INTAKE_LENGTH (0x0028) 16 17#define DMA_OUTLET_DMACR (0x0030) 18#define DMA_OUTLET_DMASR (0x0034) 19#define DMA_OUTLET_DA (0x0048) 20#define DMA_OUTLET_LENGTH (0x0058) 21 22#define DMA_CR_RS (1u<<0) 23#define DMA_CR_RESET (1u<<2) 24 25#define DMA_SR_HALTED (1u<<0) 26#define DMA_SR_IDLE (1u<<1) 27#define DMA_SR_IOC_Irq (1u<<12) 28#define DMA_SR_ERR_Irq (1u<<14) 29 30 31static inline uint32_t regs_read32 (void* addr){ 32 volatile uint32_t* regs_addr = (uint32_t*)(addr); 33 return *regs_addr; 34} 35 36static inline void regs_write32 (void* addr, uint32_t data){ 37 volatile uint32_t* regs_addr = (uint32_t*)(addr); 38 * regs_addr = data; 39} 40 41static inline void dma_reset (void* regs){ 42 regs_write32(regs+DMA_INTAKE_DMACR, DMA_CR_RESET); 43 while(regs_read32(regs+DMA_INTAKE_DMACR) & DMA_CR_RESET); // この構文謎い 44 regs_write32(regs+DMA_OUTLET_DMACR, DMA_CR_RESET); 45 while(regs_read32(regs+DMA_OUTLET_DMACR) & DMA_CR_RESET); 46} 47 48static inline void dma_setup ( 49 void* regs, 50 unsigned long src_addr, 51 unsigned long dst_addr 52 ){ 53 regs_write32(regs + DMA_OUTLET_DMACR, DMA_CR_RS); 54 regs_write32(regs + DMA_OUTLET_DA , dst_addr); 55 regs_write32(regs + DMA_INTAKE_DMACR, DMA_CR_RS); 56 regs_write32(regs + DMA_INTAKE_SA , src_addr); 57} 58 59static inline void dma_intake_start (void* regs, unsigned int xfer_size){ 60 regs_write32(regs + DMA_INTAKE_LENGTH, xfer_size); 61} 62 63static inline void dma_outlet_start (void* regs, unsigned int xfer_size){ 64 regs_write32(regs + DMA_OUTLET_LENGTH, xfer_size); 65} 66 67static inline void dma_wait_irq (void* regs){ 68 while (~regs_read32(regs + DMA_INTAKE_DMASR) & DMA_SR_IOC_Irq); 69 while (~regs_read32(regs + DMA_OUTLET_DMASR) & DMA_SR_IOC_Irq); 70} 71 72static inline void dma_clear_status (void* regs){ 73 regs_write32(regs + DMA_INTAKE_DMASR, DMA_SR_IOC_Irq | DMA_SR_ERR_Irq); 74 regs_write32(regs + DMA_OUTLET_DMASR, DMA_SR_IOC_Irq | DMA_SR_ERR_Irq); 75} 76 77struct udmabuf { 78 char name[128]; 79 int file; 80 unsigned char* buf; 81 unsigned int buf_size; 82 unsigned long phys_addr; 83 unsigned long debug_vma; 84 unsigned long sync_mode; 85}; 86 87int udmabuf_open (struct udmabuf* udmabuf, const char* name); 88int udmabuf_close (struct udmabuf* udmabuf);
c
1// dma_simple.c 2 3#include "dma_simple.h" 4 5int udmabuf_open (struct udmabuf* udmabuf, const char* name){ 6 char file_name[1024]; 7 int fd; 8 unsigned char attr[1024]; 9 10 strcpy(udmabuf -> name, name); 11 udmabuf -> file = -1; 12 13 // phys_addr 14 sprintf(file_name, "/sys/class/u-dma-buf/%s/phys_addr", name); 15 if ( 16 (fd = open(file_name, O_RDONLY)) == -1 17 ){ 18 printf("Can not open %s\n", file_name); 19 return (-1); 20 } 21 read(fd, (void*)attr, 1024); 22 sscanf(attr, "%x", &udmabuf->phys_addr); 23 close(fd); 24 25 // size 26 sprintf(file_name, "/sys/class/u-dma-buf/%s/size", name); 27 if ( 28 (fd = open(file_name, O_RDONLY)) == -1 29 ){ 30 printf("Can not open %s\n", file_name); 31 return (-1); 32 } 33 read(fd, (void *)attr, 1024); 34 sscanf(attr, "%x", &udmabuf -> buf_size); 35 close(fd); 36 37 sprintf(file_name, "/dev/%s", name); 38 if ( 39 (udmabuf -> file = open(file_name, O_RDWR | O_SYNC)) == -1 40 ){ 41 printf("Can not open %s\n", file_name); 42 return (-1); 43 } 44 45 udmabuf -> buf = mmap(NULL, udmabuf -> buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, udmabuf -> file, 0); 46 udmabuf -> debug_vma = 0; 47 udmabuf -> sync_mode = 1; 48 49 return 0; 50} 51 52int udmabuf_close(struct udmabuf* udmabuf){ 53 if (udmabuf -> file < 0) return -1; 54 55 close(udmabuf -> file); 56 udmabuf -> file = -1; 57 return 0; 58}
c
1// matrix.c 2 3#include "dma_simple.h" 4 5void main(){ 6 int uio1_fd = open("/dev/uio4", O_RDWR); 7 void *hls_regs = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, uio1_fd, 0); 8 9 int uio2_fd = open("/dev/uio5", O_RDWR); 10 void *dma_regs = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, uio2_fd, 0); 11 12 struct udmabuf intake_buf; 13 struct udmabuf outlet_buf; 14 if (udmabuf_open(&intake_buf, "udmabuf0") == -1) exit (1); 15 if (udmabuf_open(&outlet_buf, "udmabuf1") == -1) exit (1); 16 17 dma_reset(dma_regs); 18 regs_write32(hls_regs, 0x81); 19 20 float a[32*32]; 21 float b[32*32]; 22 float c[32*32]; 23 float cref[32*32]; 24 int i, j, t; 25 int m, n, k; 26 m = n = k = 32; 27 28 for (i = 0; i < m*n; i++){ 29 a[i] = (float) i/2.0; 30 b[i] = (float) i/3.0; 31 c[i] = (float) 0; 32 } 33 34 for (i = 0; i < m; i++){ 35 for (j = 0; j < n; j++){ 36 ((float *)(intake_buf.buf))[i*n + j] = a[i*n + j]; 37 } 38 } 39 for (i = 0; i < m; i++){ 40 for (j = 0; j < n; j++){ 41 ((float *)(intake_buf.buf))[i*n + j + m*m] = b[i*n + j]; 42 } 43 } 44 45 dma_setup(dma_regs, intake_buf.phys_addr, outlet_buf.phys_addr); 46 47 dma_outlet_start(dma_regs, m*m*4); 48 dma_intake_start(dma_regs, m*m*2*4); 49 50 dma_wait_irq(dma_regs); 51 dma_clear_status(dma_regs); 52 53 for (i = 0; i < m; i++){ 54 for (j = 0; j < n; j++){ 55 c[i*n + j] = ((float*)(outlet_buf.buf))[i*n + j]; 56 } 57 } 58 59 for (i = 0; i < m; i++){ 60 for (j = 0; j < n; j++){ 61 float sum = 0; 62 for (t = 0; t < k; t++){ 63 sum += a[i*k + t] * b[t*n + j]; 64 } 65 cref[i*n + j] = sum; 66 } 67 } 68 69 int cnt_ok = 0; 70 int cnt_ng = 0; 71 for (i = 0; i < m*m; i++){ 72 if (c[i] == cref[i]){ 73 cnt_ok++; 74 } else { 75 printf("NG: hw %f, sw %f\n", c[i], cref[i]); 76 cnt_ng++; 77 } 78 } 79 printf("OK: %d, NG: %d, Total: %d\n", cnt_ok, cnt_ng, m*m); 80 udmabuf_close(&outlet_buf); 81 udmabuf_close(&intake_buf); 82 close(uio2_fd); 83 close(uio1_fd); 84}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/24 08:57