Код, который получает команды из консоли, к которой обращается компьютер через COM-порт. Команды передаются в символьном виде, типа YXXXX\n\r,
где Y — символ, означающий команду, далее любое количество символов цифр XXX и в конце, команды завершения строки \r\n. Код принимает их, переводит в цифровой вид, и передает в регистр на FPGA.
При создании проекта в Quartus`е мы создаем память, двунаправленную, которая с одной стороны подключается к процессору через мост h2p_lw по определенному адресу этой шины, а с другой стороны к FPGA. Чтобы обратиться к этой памяти, нам сначала надо определить её виртуальный адрес. Для этого, мы открываем файл /dev/mem (33) , и с помощью функции mmap() (38), получаем интересующий нас адрес. Далее в нем прибавляем адрес моста h2p_lw и адрес памяти в нем с маскировкой нужных битов (46).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
#define soc_cv_av #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <sys/mman.h> #include "hwlib.h" #include "soc_cv_av/socal/socal.h" #include "soc_cv_av/socal/hps.h" #include "soc_cv_av/socal/alt_gpio.h" #include "hps_0.h" //#include "led.h" #include <stdbool.h> #define HW_REGS_BASE ( ALT_STM_OFST ) #define HW_REGS_SPAN ( 0x04000000 ) #define HW_REGS_MASK ( HW_REGS_SPAN - 1 ) volatile unsigned long *h2p_lw_reg_addr=NULL; int main(int argc, char **argv) { void *virtual_base; int fd; int value; int adress; // map the address space for the LED registers into user space so we can interact with them. // we'll actually map in the entire CSR span of the HPS since we want to access various registers within that span if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) { printf( "ERROR: could not open \"/dev/mem\"...\n" ); return( 1 ); } virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE ); if( virtual_base == MAP_FAILED ) { printf( "ERROR: mmap() failed...\n" ); close( fd ); return(1); } h2p_lw_reg_addr = virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + LED_PIO_BASE ) & ( unsigned long)( HW_REGS_MASK ) ); while (1){ unsigned int ch = getchar(); if (ch > 64 && ch < 123 ) { value =0; adress = ch; while(1){ ch = getchar(); if (ch == 10 || ch ==13){ adress <<= 16; adress = adress + value; printf("final"); usleep(100*1000); printf("%d\n", adress); alt_write_word(h2p_lw_reg_addr, adress); break; } if (ch > 47 && ch < 58 ) value = (value * 10) + (ch - 48); } } if (ch == 46) break; } if( munmap( virtual_base, HW_REGS_SPAN ) != 0 ) { printf( "ERROR: munmap() failed...\n" ); close( fd ); return( 1 ); } close( fd ); return 0; } |
Со строки (48) начинается опрос ввода через консоль, которая открыта через COM-порт. Если приходит буквенный символ, подразумивающий собой команду (50), этот символ запоминается, и начинается преобразование всех последующих пришедших символов цифр ASCII в в десятичные числа (65), пока не придет конец строки. Если приходит что-то другое, то оно игнорируется (64). Когда приходит конец строки, полученная команда записывается в память (61). И цикл начинает ждать новую команду.

