Перейти к содержанию

    

jenya7

Участник
  • Публикаций

    1 931
  • Зарегистрирован

  • Посещение

Весь контент jenya7


  1. Размышления на тему TCP/IP.

    За два часа создал TCP сервер на Wiznet. Цена вопроса 3.5 долара – готовый демо борд – с одной стороны подключил контролер с другой воткнул кабель и готово. Возникает вопрос – зачем нужны навороченные камни с фаями и маками когда есть такое простое решение?
  2. На чем писать

    Есть какая нибудь среда разработки типа Visual Studio для малины? Поигрался с питоновскими скриптами, все хорошо, все весело но нужно где то писать GUI.
  3. Размышления на тему TCP/IP.

    ну пожалуй это самый сильный аргумент. остается подождать от визнетовских разработчиков новой версии с поддержкой фрагментации. Во - W5300 - вроде поддерживает фрагментацию. Нет, все таки IP Fragmentation is not supported. наверно это непросто реализовать.
  4. Размышления на тему TCP/IP.

    The W5500 SPI supports 80 MHz speed and the new efficient SPI protocol, so users can implement high speed network communication. А зачем открытый TCP стек? Я в LWIP никогда ничего не правил. Зачем IP Fragmentation нужна? для передачи web страниц? а что для вас поток? какие чудеса вы от него ждете?
  5. Размышления на тему TCP/IP.

    ок. это уже аргумент. осталось понять где тут жесткий однопоточный вариант int32_t WIZNET_Run(uint8_t sn, uint8_t* buf, uint16_t port) { int32_t ret; uint16_t size = 0, sentsize=0; #if _TCP_DEBUG_ uint8_t destip[4]; uint16_t destport; #endif uint8_t status = getSn_SR(sn); switch(status) { case SOCK_ESTABLISHED : //if(getSn_IR(sn) & Sn_IR_CON) if (status & Sn_IR_CON) { #if _TCP_DEBUG_ getSn_DIPR(sn, destip); destport = getSn_DPORT(sn); printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); #endif setSn_IR(sn, Sn_IR_CON); } if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. { if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; ret = recv(sn, buf, size); if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY. sentsize = 0; while(size != sentsize) { ret = send(sn, buf+sentsize, size-sentsize); if(ret < 0) { close(sn); return ret; } sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. } } break; case SOCK_CLOSE_WAIT : #if _TCP_DEBUG_ printf("%d:CloseWait\r\n",sn); #endif if((ret = disconnect(sn)) != SOCK_OK) return ret; #if _TCP_DEBUG_ printf("%d:Socket Closed\r\n", sn); #endif break; case SOCK_INIT : #if _TCP_DEBUG_ printf("%d:Listen, TCP server , port [%d]\r\n", sn, port); #endif if( (ret = listen(sn)) != SOCK_OK) return ret; break; case SOCK_CLOSED: #if _TCP_DEBUG_ printf("%d:TCP server start\r\n",sn); #endif if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; #if _TCP_DEBUG_ printf("%d:Socket opened\r\n",sn); #endif break; default: break; } return 1; } код бежит в своем потоке. а как иначе должно быть?
  6. Размышления на тему TCP/IP.

    то что я привел выше это для W5500. Не знаю с чем у него совместимость, проект я писал в IAR под STM32F3. нормальная отладка, я могу спуститься на любой уровень. Зачем грузить сторонний стек? чем родной плох?
  7. Размышления на тему TCP/IP.

    у них есть примеры DHCP, DNS, FTPClient, FTPServer, httpServer, MQTT, SNMP, SNTP, TFTP. По моему все потребности покрыли. 8 сокетов RX и 8 сокетов TX. зачем писать с нуля? у них прекрасная библиотека и прекрасные отлаженные примеры. нужно написать только апликативный лэер. Вы транс и обвязку все равно будете ставить. Это не стоит денег? И камень вы можете взять дешевле без Eth . я понимаю это to good to be true вот пытаюсь понять где подвох.
  8. Размышления на тему TCP/IP.

    Wiznet поддерживает скорость до 80 мега.
  9. На чем писать

    спасибо.
  10. На чем писать

    а С функцию нужно скомпилировать в dll?
  11. На чем писать

    а как вы вызываете С функции в питоне?
  12. На чем писать

    так GUI хочется. с контролами, с ивентами. как в Visual Studio.
  13. На чем писать

    я так понимаю wiringPi легко портируется на Qt.
  14. На чем писать

    нет. не хочу. хочу попрактиковаться в Linux Embedded. сколько можно винду топтать. :)
  15. На чем писать

    Наверное все таки Qt наше все. Почитал про инсталяцию Qt на малину - чуть сума не сошел. Можно как то скачать на SD и оттуда запустить?
  16. На чем писать

    Windows не хочу. Хочу и рыбку съесть и в Линуксе потренироваться. Вот думаю PyQT или QT.
  17. На чем писать

    я хотел чтоб пользователь мог посылать команды по TCP. как в Hercules. На малине есть апаратные UART и SPI. Если работать с ними через питоновскую библиотеку или скажем в С - будет чувствительная разница? спецы говорят что скриптовый язык работает раз в 300 медленее чем компилируемый.
  18. На чем писать

    Ну скажем если я на внешние пины повешу UART, SPI? Или если сделать TCP сервер?
  19. На чем писать

    а что там в опциях билд можно указать таргет - малину? выглядит неплохо. Вы пользовались? Как оно поддерживает риал тайм?
  20. Отладка по SWD

    Я в STM32 подключаюсь отладчиком (J-LINK, ST-LINK) к пинам SWDIO, SWCLK. Я их не трогал в програме и все было хорошо. Но на них сидит другой функционал и я их определил в GPIO_Init() как входы. И все - не могу подключиться. Прожег три платы пока понял в чем дело. Закрыл код определяющий эти пины как вход. Но теперь при подъеме отладчик выдает сообщение что не может подключиться. По идее при подъеме пины должны вернуться в первичное состояние. Перепаивать чипы?
  21. Отладка по SWD

    Пробовал. Почему то не получилось. а. понял. попробую с их утилитой. Это идея. Я бутовые пины наружу вывел.
  22. Таймер в режиме энкодера.

    Уменя в STM32F303CB я настраиваю таймер TIM2 в режим энкодера. Есть моторы с обычным AB incremental encoder а есть которые считают по одному проводу. В соответствии с этим я делаю void ENC_SetEncoderMode(uint32_t enc_mode) { TIM_TypeDef * TIMx; TIMx = TIM2; TIMx->CR1 &= 0xFFFE; switch (enc_mode) { case ENC_MODE_A: //ENCA - falling edge TIMx->CCER = 0; //rising edge TIMx->CCMR1 = 0x0001; // Ch. 1 as TI1 TIMx->SMCR |= 0x0007; // Ext. clk mode 1 TIMx->SMCR |= 0x0050; // TI1FP1 is the trigger TIMx->CCER = 0x0002; //falling edge break; case ENC_MODE_AX2: //ENCA - both edges TIMx->CCER = 0; //rising edge TIMx->CCMR1 = 0x0001; // Ch. 1 as TI1 TIMx->SMCR |= 0x0007; // Ext. clk mode 1 TIMx->SMCR |= 0x0050; // TI1FP1 is the trigger TIMx->CCER = 0x000A; //both edges break; case ENC_MODE_B: //ENCB - falling edge TIMx->CCMR1 = 0x0100; // Ch. 2 as TI2 CC2S TIMx->SMCR |= 0x0007; // Ext. clk mode 1 TIMx->SMCR |= 0x0060; // TI2FP2 is the trigger TIMx->CCER = 0x0020; //falling edge break; case ENC_MODE_BX2: //ENCB - both edges TIMx->CCMR1 = 0x0100; // Ch. 2 as TI2 CC2S TIMx->SMCR |= 0x0007; // Ext. clk mode 1 TIMx->SMCR |= 0x0060; // TI2FP2 is the trigger TIMx->CCER = 0x00A0; //both edges break; case ENC_MODE_AB: //AB Encoder TIM_EncoderInterfaceConfig(ENC1_TIMER, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); break; } TIMx->CR1 |= 0x0001; // enable counting } Если я настраиваю считать по одному проводу то при смене направления движения я должен поменять направление счета UP\DOWN в контрольном регистре. void MOT_SetDir(uint32_t dir) { if (dir == MOT_DIR_FWD) { if (motor_sys_params.enc_type != ENC_MODE_AB) //set encoder counter up TIM2->CR1 &= ~(1<<4); } else if (dir == MOT_DIR_REV) { if (motor_sys_params.enc_type != ENC_MODE_AB) //set encoder counter down TIM2->CR1 |= (1<<4); } } И потом я отслеживаю позицию int32_t MOT_GetPosition(void) { static int32_t position; static uint16_t prev_enc_count; uint16_t enc_count = TIM2->CNT; int16_t offset; offset = (int16_t)(enc_count - prev_enc_count); position += offset; prev_enc_count = enc_count; return position; } void MOT_PositionLoop(void) { motor_rt_params.position = MOT_GetPosition(); if (motor_rt_params.direction == MOT_DIR_FWD) { if (motor_rt_params.position >= motor_sys_params.max_pos_fwd) motor_rt_params.state = MOT_ST_STOP; } if (motor_rt_params.state == MOT_ST_STOP) { MOT_InstantStop(); sys_status |= MOT_POS_LIM; } } В нижнем положении мотор останавливается по концевику и позиция обнуляется (motor_rt_params.position = 0). В верхнем положении мотор останавливается по верхней позиции которую я задал (motor_sys_params.max_pos_fwd). Теперь проблема. Если мотор движется вверх-вниз без остановок то он четко приходит в верхнюю позицию. Но если я начинаю играться – мотор пошел вверх – остановился – пошел вниз – пошел вверх – после всех этих игр мотор приходит в верхнюю позицию с большой погрешностью. Я останавливаюсь на строчке sys_status |= MOT_POS_LIM; сразу после остановки мотора – и что я вижу - motor_rt_params.position = motor_sys_params.max_pos_fwd и более того в TIM2->CNT я вижу значение которое я задал в motor_sys_params.max_pos_fwd. А мотор убежал на пару сантиметров. Это происходит и с AB энкодером и с энкодером с одним проводом. Проблемы с мотором исключаются – тот же мотор с тем же энкодером прекрасно работает со старым драйвером - погрешность миллиметер.
  23. Таймер в режиме энкодера.

    ох. точно. нужно обнулять SMCR перед записью новых данных. спасибо. я этого не видел потому что всегда игрался с одним B проводом. фильтрация вроде как помогла, влепил по максимуму TIMx->CCMR1 |= (0x0F << 4); погоняли немного, выглядит неплохо.
  24. Таймер в режиме энкодера.

    Я тут подумал, может на старте-стопе возникает дребезг. конечно это можно проверить скопом, но там скопа нет. если я правильно понимаю из документации. и я делал так TIMx->CCMR1 |= 0x10; //TIMx->CCMR1 |= 0x20; //TIMx->CCMR1 |= 0x30; но это не помогло.
  25. Запись во FLASH.

    Я сохраняю системные параметры во внутреннюю память микроконтролера. (STM32F303CB) Собственно функции для записи. FLASH_Status WriteFlash(void* src, void* dst, int len) { uint32_t timeout = 0; uint16_t* srcw = (uint16_t*)src; volatile uint16_t* dstw = (uint16_t*)dst; FLASH_Status status = FLASH_COMPLETE; FLASH->CR |= FLASH_CR_PG; /* Programm the flash */ while (len) { *dstw = *srcw; while ((FLASH->SR & FLASH_SR_BSY) != 0 ) { timeout++; if (timeout > 100000) { status = FLASH_ERROR_PROGRAM; break; } } if (*dstw != *srcw ) { status = FLASH_ERROR_PROGRAM; break; } dstw++; srcw++; len = len - sizeof(uint16_t); } FLASH->CR &= ~FLASH_CR_PG; /* Reset the flag back !!!! */ return status; } FLASH_Status WriteToFlash(uint32_t flash_page) { uint32_t *addr; uint32_t size; uint32_t offset; //uint32_t space_left; FLASH_Status status = FLASH_COMPLETE; //flash unlock if((FLASH->CR & FLASH_CR_LOCK) != RESET) { /* Authorize the FLASH Registers access */ FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; } status = FLASH_ErasePage(flash_page); if (status == FLASH_COMPLETE) { size = sizeof(MOTOR_SYS_PARAMS); offset = 0; addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&motor_sys_params, addr, size); size = sizeof(GLOB_MOTOR_DATA); offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&glob_mot_data, addr, size); size = sizeof(IR_DATA); offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&ir_data, addr, size); size = sizeof(MOTOR_TASK) * MAX_TASKS; offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&mot_task, addr, size); } //flash lock FLASH->CR |= FLASH_CR_LOCK; return status; } И потом вызываю команду uint32_t COM_Save(uint32_t argc, char** args) { FLASH_Status status; __disable_interrupt(); status = WriteToFlash(FLASH_PAGE_62); __enable_interrupt(); if (status == FLASH_COMPLETE) Parser_SendString(COM_USART, "Save OK\r", 0); else Parser_SendString(COM_USART, "Save failed\r", 0); return MSG_OK; } Первая проблема – вызвал команду save – получил свой Save OK – рисет – вижу все прописалось. Но если я хочу прописать повторно я падаю на status = FLASH_ErasePage(flash_page); Не удается стереть страницу. Если сделать рисет – все нормально – страница перезаписалась. Первая проблема геморойна, неудобна, но можно жить. Вторая проблема – когда я сказал все прописалось я покривил душой – все кроме WriteFlash(&ir_data, addr, size); Падает на валидации данных if (*dstw != *srcw ) { status = FLASH_ERROR_PROGRAM; break; } ir_data ничем не страшнее других прописываемых структур typedef struct { uint8_t show; uint8_t bits; uint8_t protocol; uint8_t res; uint8_t action[4]; uint32_t code [4]; uint32_t debounce_time; }IR_DATA; IR_DATA ir_data; Думал битая страница (62). Поменял (63) – то же самое, обе проблемы присутствуют.