Jump to content

    

hasuman_

Участник
  • Content Count

    11
  • Joined

  • Last visited

Community Reputation

0 Обычный
  1. Здесь стандартные драйвера для stm32f4 http://www.st.com/web/en/catalog/tools/PF257901. Там этот файл есть, нужно только его подключить. С кейлом не работал, поэтому не могу подсказать, как это сделать.
  2. У меня похожая проблема, описал ее здесь http://electronix.ru/forum/index.php?showtopic=118130. Из-за недостатка времени забросил это дело. Если найдете решение, выложите пожалуйста здесь.
  3. Добрый день. Помогите пожалуйста разобраться с проблемой. Есть код: uint8_t PTPService_Start(void) { if(isRunning) { return PTP_ERR; } serviceMode = ePTP_NoInit; PTPService_Init(); isTimeSet = 0; isRunning = 1; xTaskCreate(vPTPService_GnThread, (signed char *) "ptp", 2048, NULL, (tskIDLE_PRIORITY + 1UL), (xTaskHandle *) NULL); return PTP_OK; } static portTASK_FUNCTION(vPTPService_GnThread, pvParameters) { struct netconn *pxPTPEventConn; struct netconn *pxPTPGeneralConn; struct netbuf *generalBuf; struct netbuf *eventBuf; pxPTPGeneralConn = netconn_new(NETCONN_UDP); if(pxPTPGeneralConn == NULL) { while(1); } pxPTPEventConn = netconn_new(NETCONN_UDP); if(pxPTPEventConn == NULL) { while(1); } netconn_set_recvtimeout(pxPTPGeneralConn, 50); netconn_set_recvtimeout(pxPTPEventConn, 50); if(ERR_OK != netconn_join_leave_group(pxPTPGeneralConn, &ptpGroup, IP_ADDR_ANY, NETCONN_JOIN)) { while(1); } if(ERR_OK != netconn_join_leave_group(pxPTPEventConn, &ptpGroup, IP_ADDR_ANY, NETCONN_JOIN)) { while(1); } if(ERR_OK != netconn_bind(pxPTPEventConn, IP_ADDR_ANY, PTP_EVENT_PORT)) { while(1); } if(ERR_OK != netconn_bind(pxPTPGeneralConn, IP_ADDR_ANY, PTP_GENERAL_PORT)) { while(1); } while(isRunning) { if(netconn_recv(pxPTPGeneralConn, &generalBuf) == ERR_OK) { vLedCtl_Toggle(LED3); netbuf_delete(generalBuf); } if (netconn_recv(pxPTPEventConn, &eventBuf) == ERR_OK) { vLedCtl_Toggle(LED2); netbuf_delete(eventBuf); } } netconn_join_leave_group(pxPTPGeneralConn, &ptpGroup, IP_ADDR_ANY, NETCONN_LEAVE); netconn_join_leave_group(pxPTPEventConn, &ptpGroup, IP_ADDR_ANY, NETCONN_LEAVE); netconn_delete(pxPTPGeneralConn); netconn_delete(pxPTPEventConn); /* */ vLedCtl_On(LED3); vLedCtl_On(LED4); vTaskDelete(NULL); } На ПК запущен ptpd, который отправляет multicast запросы. На 319 и 320 порты(PTP_EVENT_PORT и PTP_GENERAL_PORT соответственно). В wireshark'e вижу, что на 319 порт идут Sync пакеты с периодичностью примерно раз в секунду. На 320 приходят Follow_up - раз в секунду, и Announce - раз в две секунды. Проблема в том, что на stm32 стабильно доходят только Sync, то есть на 319 порт. На 320 порт пакеты приходят случайно, то есть их нет, а потом чудесным образом прилетает какой-то шальной пакет и снова тишина. Если 319 порт не открывать, а оставить только 320, то ситуация меняется. Пакеты начинают приходить, но периодичность Follow_up не 1 секунда, а 2. Изначально написал для каждого соединения свой Task, но ситуация такая же. lwipopts.h /** * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain * critical regions during buffer allocation, deallocation and memory * allocation and deallocation. */ #define SYS_LIGHTWEIGHT_PROT 0 #define ETHARP_TRUST_IP_MAC 0 #define IP_REASSEMBLY 0 #define IP_FRAG 0 #define ARP_QUEUEING 0 #define TCP_LISTEN_BACKLOG 1 /** * NO_SYS==1: Provides VERY minimal functionality. Otherwise, * use lwIP facilities. */ #define NO_SYS 0 /* ---------- Memory options ---------- */ /* MEM_ALIGNMENT: should be set to the alignment of the CPU for which lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 byte alignment -> define MEM_ALIGNMENT to 2. */ #define MEM_ALIGNMENT 4 /* MEM_SIZE: the size of the heap memory. If the application will send a lot of data that needs to be copied, this should be set high. */ #define MEM_SIZE (20*1024) /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. */ #define MEMP_NUM_PBUF 100 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ #define MEMP_NUM_UDP_PCB 10 /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ #define MEMP_NUM_TCP_PCB 10 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ #define MEMP_NUM_TCP_PCB_LISTEN 5 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #define MEMP_NUM_TCP_SEG 20 /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ #define MEMP_NUM_SYS_TIMEOUT 10 /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ #define PBUF_POOL_SIZE 20 /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ #define PBUF_POOL_BUFSIZE 500 /* ---------- TCP options ---------- */ #define LWIP_TCP 1 #define TCP_TTL 255 /* Controls if TCP should queue segments that arrive out of order. Define to 0 if your device is low on memory. */ #define TCP_QUEUE_OOSEQ 0 /* TCP Maximum segment size. */ #define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ /* TCP sender buffer space (bytes). */ #define TCP_SND_BUF (2*TCP_MSS) /* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */ #define TCP_SND_QUEUELEN (4* TCP_SND_BUF/TCP_MSS) /* TCP receive window. */ #define TCP_WND (2*TCP_MSS) /* ---------------------------------- ---------- IGMP options ---------- ---------------------------------- */ /** * LWIP_IGMP==1: Turn on IGMP module. */ #define LWIP_IGMP 1 #define LWIP_RAND() vRndGen_GetValue() /* ---------- ICMP options ---------- */ #define LWIP_ICMP 1 /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. DHCP is not implemented in lwIP 0.5.1, however, so turning this on does currently not work. */ #define LWIP_DHCP 1 /* ---------- PTP options ---------- */ #define LWIP_PTP 1 /* ---------- UDP options ---------- */ #define LWIP_UDP 1 #define UDP_TTL 255 /* ---------- Statistics options ---------- */ #define LWIP_STATS 0 #define LWIP_PROVIDE_ERRNO 1 /* ---------- link callback options ---------- */ /* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface * whenever the link changes (i.e., link down) */ #define LWIP_NETIF_LINK_CALLBACK 1 /* -------------------------------------- ---------- Checksum options ---------- -------------------------------------- */ /* The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware: - To use this feature let the following define uncommented. - To disable it and process by CPU comment the the checksum. */ #define CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 0 /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 0 /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 0 /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 0 /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 0 /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 0 /* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/ #define CHECKSUM_GEN_ICMP 0 #else /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 1 /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 1 /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 1 /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 1 /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 1 /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 1 /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/ #define CHECKSUM_GEN_ICMP 1 #endif /* ---------------------------------------------- ---------- Sequential layer options ---------- ---------------------------------------------- */ /** * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) */ #define LWIP_NETCONN 1 /* ------------------------------------ ---------- Socket options ---------- ------------------------------------ */ /** * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) */ #define LWIP_SOCKET 0 /* ----------------------------------- ---------- DEBUG options ---------- ----------------------------------- */ #define LWIP_DEBUG 0 /* ------------------------------------ ---------- Socket options ---------- ------------------------------------ */ /** * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and * SO_RCVTIMEO processing. */ #ifndef LWIP_SO_RCVTIMEO #define LWIP_SO_RCVTIMEO 1 #endif /* --------------------------------- ---------- OS options ---------- --------------------------------- */ #define TCPIP_THREAD_NAME "TCP/IP" #define TCPIP_THREAD_STACKSIZE 1000 #define TCPIP_MBOX_SIZE 5 #define DEFAULT_UDP_RECVMBOX_SIZE 2000 #define DEFAULT_TCP_RECVMBOX_SIZE 2000 #define DEFAULT_ACCEPTMBOX_SIZE 2000 #define DEFAULT_THREAD_STACKSIZE 500 #define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 3UL) #define LWIP_COMPAT_MUTEX 1 FreeRTOSConfig.h #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( ( portTickType ) 250 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 40 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 10 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 8 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 0 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 #define configGENERATE_RUN_TIME_STATS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Software timer definitions. */ #define configUSE_TIMERS 0 #define configTIMER_TASK_PRIORITY ( 2 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskDelayUntil 0 #define INCLUDE_vTaskDelay 1 /* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Normal assert() semantics without relying on the provision of an assert.h header file. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler Драйвер ethernet с сайта stm - stm32f4x7_eth. Также заметил, что через некоторое время пакеты перестают доходить и на 319 порт, хотя на пинги устройство отвечает. До этого работал с этим же железом и lwIp, но без FreeRTOS. Использовал raw/native API и никаких проблем не заметил.
  4. Добрый день. Столкнулся с той же самой проблемой на stm32f417. Ваша тема на форуме st? Подскажите, как решили данную проблему. Если возможно, выложите исходный код.
  5. Я на все 100% уверен, что тема была. Просто никак не могу найти, вот и создал эту тему.
  6. Нужно сделать постраничное меню. Навигация осуществляется с помощью кнопок "вверх", "вниз", "ESC" - выход на предыдущую страницу, "ENTER" - на следующую страницу, в зависимости от того, на какой строке меню находился курсор. Второй день не могу найти никакой литературы по этой теме. Накидайте ссылок пожалуйста или помогите советом :)
  7. Вот, что у меня получилось. Дельные комментарии приветствуются :) #ifndef lcd_header #define lcd_header #include <msp430x16x.h> #include "symbols.h" #include "mytypes.h" uChar lcd_CurrColumn; // текущий столбец LCD-дисплея uChar lcd_CurrPage; // текущая страница LCD-дисплея //P4 #define lcd_Data P4OUT #define lcd_ImageOff 0xAE // выключить изображение #define lcd_ImageOn 0xAF // включить изображение #define lcd_StaticControlOn 0xA4 // включить статическое управление #define lcd_StaticControlOff 0xA5 // выключить ---//--- #define lcd_Reset 0xE2 // сброс #define lcd_SetStartString 0xC0 // установить начальную строку #define lcd_SetPage 0xB8 // установить страницу #define lcd_SetColumn 0x00 // установить столбец //P6 #define lcd_Control P6OUT #define lcd_A0 BIT4 #define lcd_RW BIT5 #define lcd_E1 BIT6 #define lcd_E2 BIT7 #define lcd_E12 0xC0 /// Функция посылки комманды на LCD-дисплей. /// cmd - комманда, посылаемая дисплею. /// param нужен только для установки начальной строки, страницы и столбца; /// в остальных случаях он не используется. /// Значения начальной строки могут быть 0-31, /// страницы 0-3, столбца 0-119. /// void LcdSendCommand(uChar cmd, uChar param) { lcd_Control &= ~(lcd_A0 + lcd_RW); // подаем на входы A0 и RW низкий уровень switch(cmd) // записываем комманду в ОЗУ дисплея { case lcd_SetStartString:/* начальная строка */ lcd_Data = (cmd | param); lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break; case lcd_SetPage:/* страница */ lcd_Data = (cmd | param); lcd_CurrPage = param; // устанавливаем новую текущую страницу lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break; case lcd_SetColumn:/* столбец */ if(param <= 59) // если столбец < 60, { lcd_Data = (cmd | param); lcd_Control |= lcd_E1; // то выполняем для левой части lcd_Control &= ~lcd_E1; } else // иначе { lcd_Data = (cmd | (param - 60)); lcd_Control |= lcd_E2; // выполняем для правой части lcd_Control &= ~lcd_E2; } lcd_CurrColumn = param; // устанавливаем новый текущий столбец break; default:/* остальные комманды */ lcd_Data = cmd; lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break; } }; /* LcdSendCommand() */ /// Функция посылки данных на LCD-дисплей. /// data - 8 бит данных. /// #pragma inline=forced void LcdSendData(uChar *data) { lcd_Control |= lcd_A0; // высокий уровень на A0 lcd_Control &= ~lcd_RW;// низкий уровень на RW lcd_Data = *data; // записываем данные в ОЗУ дисплея /* рисуем на нужной половине экрана */ if(lcd_CurrColumn <= 59) { lcd_Control |= lcd_E1; lcd_Control &= ~lcd_E1; } else { lcd_Control |= lcd_E2; lcd_Control &= ~lcd_E2; } }; /* LcdSendData() */ /// Функция рисования символа на дисплее. /// symb - символ, который нужно нарисовать. /// void LcdPutChar(uChar symb) { for(uChar i = 0; i < 6; i++) { LcdSendData(&symb_array[(symb * 6) + i]); lcd_CurrColumn++; // увеличиваем счетчик столбца if(lcd_CurrColumn == 60) // если кончилась левая половина экрана LcdSendCommand(lcd_SetColumn, lcd_CurrColumn); if(lcd_CurrColumn == 120) // если столбец выехал за правую половину экрана { lcd_CurrColumn = 0; // обнуляем столбец lcd_CurrPage++; // и переходим на след страницу if(lcd_CurrPage > 3) // если страница >3, то переходим на верхнюю lcd_CurrPage = 0; LcdSendCommand(lcd_SetPage, lcd_CurrPage); // устанавливаем новую LcdSendCommand(lcd_SetColumn, lcd_CurrColumn);// страницу и столбец } } }; /* LcdPutChar() */ /// Функция вывода строки текста на экран. /// str - указатель на строку, которую нужно вывести. /// #pragma inline=forced void LcdPutText(uChar *str) { while(*str) LcdPutChar(*str++); }; /* LcdPutText() */ /// Функция очистки LCD-дисплея. /// #pragma inline=forced void LcdClearScreen() { LcdSendCommand(lcd_SetColumn, 0); // устанавливаем столбец LcdSendCommand(lcd_SetPage, 0); // и страницу в 0 uChar tmp[] = " "; // 20 пробелов, чтобы for(uChar i = 0; i < 4; i++) // зарисвать 4 строки LcdPutText(tmp); // зарисовываем весь экран пробелами }; /* LcdClearScreen() */ /// Функция инициализации LCD-дисплея /// #pragma inline=forced void InitLcd() { LcdSendCommand(lcd_SetStartString, 0); LcdClearScreen(); LcdSendCommand(lcd_ImageOn, 0); }; /* InitLcd() */ #endif /* lcd_header */
  8. Спасибо за помощь, так и сделаю.
  9. Сам хотел сделать 8*8, но экрана не хватит для всей информации :( Размер экрана 120*32, разница в 5 символов получается. А что значит "расположить таблицу по адресу с 11 младшими нулевыми разрядами"? То есть положить в память, например по адресу 0x800? PS. пишу на Си под msp430
  10. "код символа" - имеется ввиду ascii-код? Если да, то для массива в котором хранятся цифры 0-9 и буквы А-Я(в порядке возрастания кодов) нужно будет сделать одну промежуточную операцию: если рисуем цифру, то из кода символа нужно вычесть код '0', а если букву, то вычесть код 'А'. Затем уже умножаем получившееся число на размер символа - это и есть индекс начала символа в массиве. Или я не прав?
  11. Никак не соображу как лучше рисовать символы. Сейчас работаю следующим образом: 1. Есть массив, в котором лежат все символы в виде {0x00, 0xFF, 0xFF, 0xAA, 0x84, 0xFF и т.д.}. Символ размером 8x6(высота, ширина). То есть для 10 символов получается массив из 60 байт. 2. Есть массив структур. В структуре лежит сам символ и индекс, с которого этот символ начинается в массиве описанном выше. При вызове функции вывода символа на экран (например printf('A')), ищу в массиве структур нужный мне символ, беру из этой структуры индекс, с которого начинается символ в массиве и последовательно вывожу 6 байт символа. Может кто-нибудь знает способ проще и быстрее? :)