Troubles testing UART3 on Exynos5

Matthias Lange matthias.lange at kernkonzept.com
Fri Feb 27 09:37:23 CET 2015


Hi,

it is hard to see any obvious errors in your code and without the
hardware to test it is hard to give any hints beyond educated guesses.

You should start instrumenting your code (vcon_read) and see what's
going on there. You can also check in jdb whether the hardware interrupt
gets triggered for UART3.

Matthias.

On 02/23/2015 01:31 AM, Reinier Millo Sánchez wrote:
> Hi
> I'm testing Fiasco.OC+L4re on YSE5250 (Exynos 5250) Board. I have
> compiled and tested some examples. I'm testing a GPS Driver for the
> board. The GPS is conected over UART3 at 9600 baudrate, first I'm
> testing UART3 port comunicating the UART1 serial output with UART3. I'm
> following as example the serial-drv package on L4re.
> I have adapted the source code to my uart driver
>>>> gps_drv.cc
> 
>     #include <l4/drivers/uart_s3c2410.h>
>     #include <l4/io/io.h>
>     #include <l4/re/env>
>     #include <l4/re/error_helper>
>     #include <l4/re/namespace>
>     #include <l4/re/util/cap_alloc>
>     #include <l4/re/util/object_registry>
>     #include <l4/re/util/icu_svr>
>     #include <l4/re/util/vcon_svr>
>     #include <l4/sys/irq>
>     #include <l4/util/util.h>
> 
>     #include <cstdlib>
>     #include <cstdio>
> 
>     #define IRQ_NUM 86
>     #define UART_BASE 0x12C30000
> 
>     static L4::Cap<void> srv_rcv_cap;
> 
>     class Loop_hooks :
>       public L4::Ipc_svr::Ignore_errors,
>       public L4::Ipc_svr::Default_timeout,
>       public L4::Ipc_svr::Compound_reply
>     {
>     public:
>       void setup_wait(L4::Ipc::Istream &istr, bool)
>       {
>         istr.reset();
>         istr << L4::Ipc::Small_buf(srv_rcv_cap.cap(), L4_RCV_ITEM_LOCAL_ID);
>         l4_utcb_br_u(istr.utcb())->bdr = 0;
>       }
>     };
> 
>     using L4Re::Env;
>     using L4Re::Util::Registry_server;
>     static Registry_server<Loop_hooks> server(l4_utcb(),
>                                       Env::env()->main_thread(),
>                                       Env::env()->factory());
> 
>     using L4Re::Util::Vcon_svr;
>     using L4Re::Util::Icu_cap_array_svr;
> 
>     class GPS_server :
>       public Vcon_svr<GPS_server>,
>       public Icu_cap_array_svr<GPS_server>,
>       public L4::Server_object
>     {
>     public:
>       GPS_server();
>       virtual ~GPS_server() throw() {}
> 
>       bool running() const { return _running; }
> 
>       int vcon_write(const char *buffer, unsigned size);
>       unsigned vcon_read(char *buffer, unsigned size);
> 
>       L4::Cap<void> rcv_cap() { return srv_rcv_cap; }
> 
>       int handle_irq();
>      
>       bool init();
>       int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
> 
>     private:
>       bool _running;
>       L4::Uart *_uart;
>       L4::Cap<L4::Irq> _uart_irq;
>       Icu_cap_array_svr<GPS_server>::Irq _irq;
>     };
> 
>     GPS_server::GPS_server()
>       : Icu_cap_array_svr<GPS_server>(1, &_irq),
>         _running(false), _uart(0), _uart_irq(L4_INVALID_CAP),
>         _irq()
>     {
>       if (init())
>         _running = true;
>     }
> 
>     int GPS_server::vcon_write(const char *buffer, unsigned size)
>     {
>       _uart->write(buffer, size);
>       return -L4_EOK;
>     }
> 
>     unsigned GPS_server::vcon_read(char *buffer, unsigned size)
>     {
>       unsigned i = 0;
>       while (_uart->char_avail() && size)
>         {
>           int c = _uart->get_char(false);
>           if (c >= 0)
>         {
>           buffer[i++] = (char)c;
>           size--;
>         }
>           else
>         break;
>         }
>       // if there still some data available send this info to the client
>       if (_uart->char_avail())
>         i++;
>       else
>         _uart_irq->unmask();
>       return i;
>     }
> 
>     int GPS_server::handle_irq()
>     {
>       if (_irq.cap().is_valid())
>         _irq.cap()->trigger();
> 
>       return L4_EOK;
>     }
> 
>     bool GPS_server::init()
>     {
>       l4_addr_t virt_base = 0;
> 
>       // Mapeando memoria de registros del UART
>       if (l4io_request_iomem((l4_addr_t)UART_BASE, 0x1000,
>     L4IO_MEM_NONCACHED, &virt_base))
>         {
>           printf("gps-drv: request io-memory from l4io failed.\n");
>           return false;
>         }
>       printf("gps-drv: virtual base at:%lx\n", virt_base);
> 
>       // Inicializando memoria de los registros del UART
>       L4::Io_register_block_mmio *regs = new
>     L4::Io_register_block_mmio(virt_base);
> 
>       // Inicializando UART
>       _uart = new (malloc(sizeof(L4::Uart_s5pv210))) L4::Uart_s5pv210;
>       _uart->startup(regs);
>      
>       /**
>        * FIX - Ajustando el BaudRate del UART
>        * Valores calculados experimentalmente a través del UART1
>        *   SCLK_UART = 100 MHz
>        * TODO - Hacer el ajuste del BaudRate en el propio UART
>        */
>        regs->write<unsigned int>(0x28,0x28a);
>        regs->write<unsigned int>(0x2C,0x0);
> 
> 
>       _uart_irq = L4Re::Util::cap_alloc.alloc<L4::Irq>();
>       if (!_uart_irq.is_valid())
>         {
>           printf("gps-drv: Alloc capability for uart-irq failed.\n");
>           return false;
>         }
> 
>       if (l4io_request_irq(IRQ_NUM, _uart_irq.cap()))
>         {
>           printf("gps-drv: request uart-irq from l4io failed\n");
>           return false;
>         }
> 
>      /* setting IRQ type to L4_IRQ_F_POS_EDGE seems to be wrong place */
>       if
>     (l4_error(_uart_irq->attach((l4_umword_t)static_cast<L4::Server_object
>     *>(this),
>         L4Re::Env::env()->main_thread())))
>         {
>           printf("gps-drv: attach to uart-irq failed.\n");
>           return false;
>         }
> 
>       if ((l4_ipc_error(_uart_irq->unmask(), l4_utcb())))
>         {
>           printf("gps-drv: unmask uart-irq failed.\n");
>           return false;
>         }
>       _uart->enable_rx_irq(true);
> 
>        srv_rcv_cap = L4Re::Util::cap_alloc.alloc<void>();
>       if (!srv_rcv_cap.is_valid())
>         {
>           printf("serial-drv: Alloc capability for rcv-cap failed.\\n");
>           return false;
>         }
>      
>       return true;
>     }
> 
>     int
>     GPS_server::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
>     {
>       l4_msgtag_t tag;
>       ios >> tag;
>       switch (tag.label())
>         {
>         case L4_PROTO_IRQ:
>           if (!L4Re::Util::Icu_svr<GPS_server>::dispatch(obj, ios))
>         return handle_irq();
>         case L4_PROTO_LOG:
>           return L4Re::Util::Vcon_svr<GPS_server>::dispatch(obj, ios);
>         default:
>           return -L4_EBADPROTO;
>         }
>     }
> 
>     int main()
>     {
>       char buffer[100];
>       int tmp;
>       static GPS_server gps_srv;
> 
>       // Register calculation server
>       if (!server.registry()->register_obj(&gps_srv, "gps_srv").is_valid())
>       {
>         printf("Could not register GPS service, is there a 'gps_srv' in
>     the caps table?\n");
>         return 1;
>       }
> 
>       if (!gps_srv.running())
>       {
>           printf("Failed to initialize serial driver; Aborting.\n");
>           return 1;
>       }
> 
>       gps_srv.vcon_write("Hola Mundo\n",11);
>     while(1){
>       tmp = gps_srv.vcon_read(buffer,11);
>       if(tmp>0)
>           printf("Readed data: %s\n",buffer);
>     }
>       // Wait for client requests
>       server.loop();
>       return 0;
>     }
> 
> I have created my run config file
>>>> gps-drv.cfg
> 
>     require("L4");
>     -- Shortcuts
>     local ld = L4.default_loader;
>     local vbus_uart03 = ld:new_channel();
>     local platform_ctl = ld:new_channel();
>     local gps_srv = ld:new_channel();
>     -- Start the IO Server
>     ld:start(
>     {
>         caps = {
>             sigma0       = L4.cast(L4.Proto.Factory,
>     L4.Env.sigma0):create(L4.Proto.Sigma0);
>             icu          = L4.Env.icu;
>             platform_ctl = platform_ctl:svr();
>             uart03        = vbus_uart03:svr();
>         },
>         log = { "IO Server", "green" },
>         l4re_dbg = L4.Dbg.Warn,
>     }, "rom/io rom/yse5250.devs rom/yse5250.io");
> 
>     -- Start the GPS Driver Server conected to UART3
>     ld:start(
>     {
>         caps = {
>             gps_srv = gps_srv:svr();
>             vbus =  vbus_uart03;
>         },
>         log = {"GPS Driver","blue"}
>     }, "rom/gps_drv");
> 
> And have created the yse5250.devs and yse5250.io to put the UART3 on a
> virtual BUS
>>>> yse5250.devs
> 
>     local Hw = Io.Hw
>     local Res = Io.Res
>     Io.hw_add_devices
>     {
>         UART3 = Hw.Device
>         {
>             hid = "UART3";
>             Res.irq(86);
>             Res.mmio(0x12C30000, 0x12C3ffff);
>         }
>     }
> 
>>>> yse5250.io
> 
>     Io.add_vbusses
>     {
>         -- Create a virtual bus for a client and give access to UART3
>         uart03 = Io.Vi.System_bus(function ()
>             dev = wrap(Io.system_bus():match("UART3"));
>         end);
>     }
> 
> On modules.list have added an entry for my example
> 
>     entry GPS-Driver
>     kernel fiasco -serial_esc
>     roottask moe rom/gps-drv.cfg
>     module l4re
>     module ned
>     module gps-drv.cfg
>     module gps_drv
>     module io
>     module yse5250.devs
>     module yse5250.io
> 
> After that i have compiled and uploaded the example to the board. At
> runtime, i got the "Hola Mundo" over UART3 but when I write in the UART3
> I never read the written information.
> Something is wrong with my code?
> 
> -- 
> Lic. Reinier Millo Sánchez
> Centro de Estudios de Informática
> Universidad Central "Marta Abreu" de Las Villas
> 
> "antes de discutir ... respira;
>   antes de hablar ... escucha;
>  antes de escribir ... piensa;
>   antes de herir ... siente;
>  antes de rendirte ... intenta;
>   antes de morir ... vive"
> 
> 
> 
> _______________________________________________
> l4-hackers mailing list
> l4-hackers at os.inf.tu-dresden.de
> http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers
> 


-- 
Matthias Lange, matthias.lange at kernkonzept.com, +49 - 351 - 41 88 86 14

Kernkonzept GmbH.  Sitz: Dresden.  Amtsgericht Dresden, HRB 31129.
Geschäftsführer: Dr.-Ing. Michael Hohmuth




More information about the l4-hackers mailing list