Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: RL-ARM USB Device
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
cinema_effect
Добрый день, коллеги!

Мучаю пример от Keil конфигурации ОСРВ RL-ARM для USB Device класса HID на отладочной плате MCB1700. Как только добавляю еще один процесс в ОСРВ, она сразу же перестает работать. А конкретнее, только разкомментирую строчки, где создается task KEYREAD и само описание KEYREAD, на дисплее даже надписи не высвечиваются, а также компьютер не видит USB устройство. Подскажите, с чем это может быть связано?

/*----------------------------------------------------------------------------
* RL-ARM - USB
*----------------------------------------------------------------------------
* Name: USBD_Demo.c
* Purpose: USB Device Demonstration
* Rev.: V4.20
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright © 2004-2011 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/

#include <RTL.h>
#include <rl_usb.h>
#include "GLCD.h"
#include <LPC17xx.h>
#include "KBD.h"
#include "stdio.h"


OS_TID t_keyread; /* assigned task id of task: keyread */



__task void keyread (void);



/*----------------------------------------------------------------------------
* Task 1 'init': Initialize
*---------------------------------------------------------------------------*/

__task void init (void) {
GLCD_Init ();
GLCD_Clear (Blue);
GLCD_SetBackColor (Blue);
GLCD_SetTextColor (White);
GLCD_DisplayString (4, 0, 1, " USB HID ");
GLCD_DisplayString (5, 0, 1, " DRM Manage ");
KBD_Init ();

os_tsk_prio_self(100);
usbd_init(); /* USB Device Initialization */
usbd_connect(__TRUE); /* USB Device Connect */
// t_keyread = os_tsk_create (keyread,0); /* start keyread task */

os_tsk_delete_self(); /* Terminate Task */
}

int main (void) {

os_sys_init(init); /* Init RTX and start 'init' */
}

///*----------------------------------------------------------------------------
// * Task 6 'keyread'
// *---------------------------------------------------------------------------*/
__task void keyread (void) {
uint32_t kbd_val;
short AD_value;
kbd_val = (LPC_GPIO1->FIOPIN >> 20) & KBD_MASK;
while (1) { /* endless loop */

if (KBD_Get () !=0x079) {
AD_value = kbd_val;
printf ("AD value = 0x%03x\n\r",AD_value);
}
// os_dly_wait (5); /* wait for timeout: 5 ticks */
}
}
cinema_effect
И еще один вопрос, знаете ли Вы программы-аналоги Bushound (требуется отслеживать прием трафика по USB и самое главное - отсылать команды)? это удачная программа, но запускается только в демо режиме.
toweroff
Цитата(cinema_effect @ May 30 2012, 10:03) *
И еще один вопрос, знаете ли Вы программы-аналоги Bushound (требуется отслеживать прием трафика по USB и самое главное - отсылать команды)? это удачная программа, но запускается только в демо режиме.

на торренте лежит с таблеткой
cinema_effect
Цитата(toweroff @ May 30 2012, 13:28) *
на торренте лежит с таблеткой


А не могли бы Вы подсказать на каком конкретно торренте? Ибо я искал Bushound и на торрентах тоже... Не нашел (
toweroff
Цитата(cinema_effect @ May 30 2012, 10:48) *
А не могли бы Вы подсказать на каком конкретно торренте? Ибо я искал Bushound и на торрентах тоже... Не нашел (

rutracker.org
cinema_effect
Цитата(toweroff @ May 30 2012, 14:15) *
rutracker.org

Спасибо! Действительно там лежала, родимая! И работает)


А вот проблема, озвученная/написанная в начале темы, так и не исчезла... Наверное я с операционной системой неправильно работаю? Если в режиме отладки смотреть, то запущен task os_idle_demon, остальные (USBD_RTX_Core и USBD_RTX_EndPoint1) находятся в состоянии wait_or. Если же строчки моего кода раскомментировать, то вообще все ломается... и даже в режиме отладки не работает
Shein
Какие приоритеты у остальных задач, созданных в системе?
А эта строчка
Цитата(cinema_effect @ May 30 2012, 07:15) *
// os_dly_wait (5); /* wait for timeout: 5 ticks */

была закомментирована, когда вставлялось создание keyread? Если все задачи с одинаковым приоритетом, то без os_dly_wait, keyread управление не отдаст.

Цитата(cinema_effect @ May 30 2012, 07:15) *
на дисплее даже надписи не высвечиваются, а также компьютер не видит USB устройство.

тут надо видеть код GLCD_DisplayString (4, 0, 1, " USB HID "); реализации чтоб делать выводы почему ничего не отображается. Возможно причина та же - почему-то не передается управление между задачами.
Цитата(cinema_effect)
Если же строчки моего кода раскомментировать, то вообще все ломается... и даже в режиме отладки не работает

Что значит ничего не работает? До какого места доходит отладчиком? Точки останова в начале main и init ставились? до них доходит?
cinema_effect
Цитата
Что значит ничего не работает? До какого места доходит отладчиком? Точки останова в начале main и init ставились? до них доходит?

В случае разкомментированного кода: отладчик в файле startup_LPC17xx.s проходит SystemInit, доходит до __main и после на строчку BX R0. После этого в окне "Disassembly" попадает на строчку BEAB BKPT 0xAB и там останавливается...
Код
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
Shein
Цитата(cinema_effect @ May 31 2012, 07:23) *
В случае разкомментированного кода: отладчик в файле startup_LPC17xx.s проходит SystemInit, доходит до __main и после на строчку BX R0. После этого в окне "Disassembly" попадает на строчку BEAB BKPT 0xAB и там останавливается...

хм... тут дело даже не в RTX... какая-то фигня на этапе линковки... Или с конфигурацией чего-то не то...
Может чего подсказал бы более конкретно, но для этого надо видеть проект. У себя в Keil'е я этого примера не нашел.

cinema_effect
Вроде разобрался тут с RTX, переписал task'и и заставил делать ОС различные задачки. Вроде все работало, однако потом решил все-таки что-нибудь вывести по COM. как только появляется функция printf - опять сразу ломается, на том же месте... Хм......
Код
/*----------------------------------------------------------------------------
*      RL-ARM - USB
*----------------------------------------------------------------------------
*      Name:    USBD_Demo.c
*      Purpose: USB Device Demonstration
*      Rev.:    V4.20
*----------------------------------------------------------------------------
*      This code is part of the RealView Run-Time Library.
*      Copyright (c) 2004-2011 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/

#include <RTL.h>
#include <rl_usb.h>
#include "GLCD.h"
#include <LPC17xx.h>
#include "KBD.h"
#include "stdio.h"

extern void getline (char *, int);    /* external function:  input line      */
extern int  getkey  (void);           /* external function:  input character */

OS_TID t_UART;                      /* assigned task id of task: lights    */
OS_TID t_keyread;                     /* assigned task id of task: keyread   */
OS_TID t_Command_to_GLSD_from_Joystick;                          /* Add by Me     */
OS_TID t_USB_Out_report;                      /* Add by Me     */

__task void keyread (void);
__task void Command_to_GLSD_from_Joystick (void);
__task void USB_Out_report (void);
__task void UART (void);

/*----------------------------------------------------------------------------
*        Task 1 'init': Initialize
*---------------------------------------------------------------------------*/

__task void init (void) {
  GLCD_Init          ();
  GLCD_Clear         (Blue);
  GLCD_SetBackColor  (Blue);
  GLCD_SetTextColor  (White);
  GLCD_DisplayString (4, 0, 1, "  USB HID      ");
  GLCD_DisplayString (5, 0, 1, "  DRM Manage   ");
  KBD_Init ();

  os_tsk_prio_self(100);
  usbd_init();                          /* USB Device Initialization          */
  usbd_connect(__TRUE);                 /* USB Device Connect                 */
  t_keyread = os_tsk_create (keyread,0); /* start keyread task               */
  t_Command_to_GLSD_from_Joystick = os_tsk_create (Command_to_GLSD_from_Joystick, 0);
  os_tsk_delete_self();                 /* Terminate Task                     */
}

int main (void) {

  os_sys_init(init);                    /* Init RTX and start 'init'          */
//  t_keyread = os_tsk_create (keyread,0);
//  t_Command_to_GLSD_from_Joystick = os_tsk_create (Command_to_GLSD_from_Joystick, 0);
}

///*----------------------------------------------------------------------------
// *        Task 2 'keyread'
// *---------------------------------------------------------------------------*/
__task void keyread (void) {

  while (1) {                                 /* endless loop                */
    if (INT0_Get() == 0) {                    /* if key pressed              */
      os_evt_set (0x0010, t_UART);          /* send signal to task UART  */
    }

    if (KBD_Get () !=0x079) {
      os_evt_set (0x0004, t_Command_to_GLSD_from_Joystick);

      }

  }
}

///*----------------------------------------------------------------------------
// *        Task 3 'Command_to_GLSD_from_Joystick'
// *---------------------------------------------------------------------------*/
__task void Command_to_GLSD_from_Joystick (void) {
    uint32_t kbd_val;

     while (1) {

     os_evt_wait_or (0x0004, 0xffff);

kbd_val = (LPC_GPIO1->FIOPIN >> 20) & KBD_MASK;

  
  if ((kbd_val & KBD_UP)     == 0) GLCD_DisplayString (4, 0, 1, "  USB UP      ");/* up     pressed means 0    */
  if ((kbd_val & KBD_LEFT)   == 0) GLCD_DisplayString (5, 0, 1, "  USB Left      "); /* left   pressed means 0    */
  if ((kbd_val & KBD_RIGHT)  == 0) GLCD_DisplayString (6, 0, 1, "  USB Right      "); /* right  pressed means 0    */
  if ((kbd_val & KBD_SELECT) == 0) GLCD_DisplayString (7, 0, 1, "  USB Select      "); /* select pressed means 0    */
  if ((kbd_val & KBD_DOWN)   == 0) GLCD_DisplayString (8, 0, 1, "  USB Down      "); /* down   pressed means 0    */


      }
    }

///*----------------------------------------------------------------------------
// *        Task 4 'UART'
// *---------------------------------------------------------------------------*/
__task void UART (void) {
  

   while (1) {
       os_evt_wait_or (0x0010, 0xffff);
//     printf ("\nCommand: ");
     os_dly_wait (50);
        }

}


Стоит разкомментировать строчку с printf в task UART и сразу же те же проблемы
toweroff
а fputc реализован для uart?
Shein
Как уже написали выше, для работы printf нужно определить функцию fputc.
Как это сделать можно взять из примеров, там, как правило, есть файл serial.c (бывает еще и retarget.c) Там определяется fputc. иногда и fgetc. Естественно, перед первым вызовом printf UART уже должен бть инициализирован.
cinema_effect
Цитата(Shein @ Jun 2 2012, 18:18) *
Как уже написали выше, для работы printf нужно определить функцию fputc.
Как это сделать можно взять из примеров, там, как правило, есть файл serial.c (бывает еще и retarget.c) Там определяется fputc. иногда и fgetc. Естественно, перед первым вызовом printf UART уже должен бть инициализирован.

Спасибо, точно именно этого и не хватало! Сейчас заработало и выводится то, что нужно. Конечно еще остались некоторые проблемы, видимо не правильно использую функцию os_evt_ХХХ.

Насколько я понял из документации, os_evt_set (флаг, task) - устанавливает флаг и соответствующую ему задачу.

os_evt_wait_or (флаг, время ожидания флага) - должна быть прописана в task и как раз и ждет флага. когда os_evt_set (флаг, task) устанавливает этот флаг, os_evt_wait_or (флаг, время ожидания флага) дождавшись его начинает выполнение соответствующего task

os_evt_clear (флаг, task) - когда нужно ее применять и где правильно необходимо применять?
toweroff
Цитата(cinema_effect @ Jun 4 2012, 11:12) *
os_evt_clear (флаг, task) - когда нужно ее применять и где правильно необходимо применять?

да как раз перед ожиданием флага, его, родимого, и сбрасываем для уверенности sm.gif
ViKo
Цитата(cinema_effect @ Jun 4 2012, 10:12) *
os_evt_clear (флаг, task) - когда нужно ее применять и где правильно необходимо применять?

никогда, нигде... IMHO.
cinema_effect
Разносторонние ответы... Ладно, спасибо, буду дальше разбираться
ViKo
Цитата(cinema_effect @ Jun 4 2012, 11:47) *
Разносторонние ответы... Ладно, спасибо, буду дальше разбираться

Флаги сама ОС сбрасывает после того, как задача их дождалась.
Поэтому сбрасывать их нужно в какой-то особой ситуации, если почему-то уже стали не нужны.
toweroff
Цитата(ViKo @ Jun 4 2012, 13:04) *
Флаги сама ОС сбрасывает после того, как задача их дождалась.
Поэтому сбрасывать их нужно в какой-то особой ситуации, если почему-то уже стали не нужны.

здесь может возникнуть ситуация, когда одна задача постоянно генерит эти флаги, а вторая ловит
но, наверное, проще в генерящей задаче проверять, ждет ли кто-то флаг, и если да, то выставлять его
ViKo
Цитата(toweroff @ Jun 4 2012, 12:08) *
здесь может возникнуть ситуация, когда одна задача постоянно генерит эти флаги, а вторая ловит

Так для этого они и предназначены. Одна задача устанавливает флаг, когда ей нужно, а другая ждет их. Если вторая задача не успевает реагировать на каждый флаг, значит, не судьба.
cinema_effect
Цитата(toweroff @ Jun 4 2012, 16:08) *
здесь может возникнуть ситуация, когда одна задача постоянно генерит эти флаги, а вторая ловит
но, наверное, проще в генерящей задаче проверять, ждет ли кто-то флаг, и если да, то выставлять его

А как проверить в генерящей задаче ждет ли кто то флаг?
toweroff
Цитата(cinema_effect @ Jun 4 2012, 13:31) *
А как проверить в генерящей задаче ждет ли кто то флаг?

можно завести глобальную переменную, в которую будет заноситься ID текущей задачи

Код
OS_TID  otask;


//
//
//

__task void task1 ()
{
otask = os_tsk_self ();
os_evt_wait_or(FLAG_MASK, TIMEOUT);
otask = 0xFFFFFFFF;
}

__task void task2 ()
{
//
//
//
if (otask != 0xFFFFFFFF) os_evt_set(FROM_TASK2_FLAG, otask);
}


примерно так
cinema_effect
Цитата(toweroff @ Jun 4 2012, 17:05) *
можно завести глобальную переменную, в которую будет заноситься ID текущей задачи


Интересно, буду пробовать, спасибо Вам
ViKo
Для синхронизации двух задач можно (нужно) использовать два флага. В каждой задаче по одному.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.