Using VxWorks 653 2.5.0.2 for P2020RDB-PC target, using BSP1.0/4
I have a very simple test application
void usrAppInit (void)
{
RETURN_CODE_TYPE errCode;
printf("\n I am alive!");
PROCESS_ATTRIBUTE_TYPE processAttributes;
PROCESS_ID_TYPE thandle;
processAttributes.BASE_PRIORITY = 10;
processAttributes.DEADLINE = SOFT;
processAttributes.ENTRY_POINT = (SYSTEM_ADDRESS_TYPE)task;
strncpy(processAttributes.NAME, "TASK", MAX_NAME_LENGTH);
processAttributes.PERIOD = INFINITE_TIME_VALUE;
processAttributes.STACK_SIZE = 1024;
processAttributes.TIME_CAPACITY = INFINITE_TIME_VALUE;
CREATE_PROCESS(&processAttributes, &thandle, &errCode);
if(errCode != NO_ERROR)
{
printf("Just had an error creating the task: %d", errCode);
}
else
{
START(thandle, &errCode);
if(errCode != NO_ERROR)
{
printf("Just had an error starting the task: %d", errCode);
}
}
SET_PARTITION_MODE (NORMAL, &errCode);
if (errCode != NO_ERROR){
printf("\nError changing partition mode: %d", errCode);
}
while(1);
}
void task()
{
printf("\nI am a process.");
while(1);
}
When the program gets to the START line, it reboots. If I comment out the START line, it executes till the end of the main and obviously does nothing. I have tried to increase partition memory and I am adding the APEX components to the makefile.
What could be causing this?
PS: system output
VxWorks 653 System Boot
Copyright (c) 1984-2016 Wind River Systems, Inc.
CPU: Freescale P2020E - Security Engine
Version: 2.5.0.2
BSP version: 1.0/4
Creation date: Apr 29 2020, 15:00:10
Press any key to stop auto-boot...
0
auto-booting...
boot device : mottsec
unit number : 0
processor number : 0
host name : felipe
file name : D:\Projects\WindRiver\helloWorld\boot.txt
inet on ethernet (e) : 192.168.1.172
host inet (h) : 192.168.1.75
gateway inet (g) : 192.168.1.1
user (u) : felipe
ftp password (pw) : pass
flags (f) : 0x0
target name (tn) : board
Attached TCP/IP interface to mottsec0.
Warning: netmask value is 0.
Attaching interface lo0...done
Loading D:\Projects\WindRiver\helloWorld\boot.txt
sm0=D:\Projects\WindRiver\helloWorld\configRecord.reloc
0x00001a00 + (0x000fe600)
sm1=D:\Projects\WindRiver\helloWorld\coreOS.sm
0x00050e08 + 0x00007130 + 0x00006084 + 0x00015cac
sm2=D:\Projects\WindRiver\helloWorld\vxSysLib.sm
0x00031078 + 0x00004b20 + 0x00000918 + 0x00001d90
sm3=D:\Projects\WindRiver\helloWorld\fsl_p2020_rdb_part1.sm
0x000027c8 + 0x000000d0 + 0x00000010 + 0x00000008
Starting at 0x100000...
After this, it returns to the beggining and repeats the process forever
So, in case anyone else drops here with similar issue, in my case there were two main things affecting the functionality.
First, in the usrAppInit() function, one cannot define the while(1) loop in the end of the function. On opposite to other ARINC-653 systems, where the partition main is the same as the user main, for VxWorks it does not seems to be the case. This way, after SET_PARTITION_MODE, nothing else can be defined.
Second, the stack size for the process was too small. That fit perfectly for different targets and ARINC RTOS (in-house OS, executing on ARMv7 target), but for VxWorks on the P2020 target it requires a bigger stack. In this case, I've used 4096.
Here is the complete example code, now functional, in case anyone needs this.
void usrAppInit (void)
{
RETURN_CODE_TYPE errCode;
printf("\n I am alive!");
PROCESS_ATTRIBUTE_TYPE processAttributes;
PROCESS_ID_TYPE thandle;
processAttributes.BASE_PRIORITY = 10;
processAttributes.DEADLINE = SOFT;
processAttributes.ENTRY_POINT = (SYSTEM_ADDRESS_TYPE)task;
strncpy(processAttributes.NAME, "TASK", MAX_NAME_LENGTH);
processAttributes.PERIOD = INFINITE_TIME_VALUE;
processAttributes.STACK_SIZE = 4096;
processAttributes.TIME_CAPACITY = INFINITE_TIME_VALUE;
CREATE_PROCESS(&processAttributes, &thandle, &errCode);
if(errCode != NO_ERROR)
{
printf("Just had an error creating the task: %d", errCode);
}
else
{
START(thandle, &errCode);
if(errCode != NO_ERROR)
{
printf("Just had an error starting the task: %d", errCode);
}
}
SET_PARTITION_MODE (NORMAL, &errCode);
if (errCode != NO_ERROR){
printf("\nError changing partition mode: %d", errCode);
}
}
void task()
{
printf("\nI am a process.");
while(1);
}
Related
I'm having a problem using both TCP and UDP in the same sketch. What appears to happen is that if the same socket is reused for UDP after it was in use for TCP, UPD fails to receive data. I was able to reproduce this with the WebServer example. I've added to it a DNS query once in every 10 seconds to query yahoo.com IP address. The DSN queries succeed if I'm not creating any client traffic from the browser. After I query the server over HTTP over TCP, the DSN queries start to fail. DNS queries are implemented in UDP. This is the code that I'm using:
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 02 Sept 2015
by Arturo Guadalupi
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Dns.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
unsigned long t0;
void setup() {
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
//Ethernet.init(5); // MKR ETH shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Ethernet WebServer Example");
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start the server
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
t0 = millis();
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
if (millis() - t0 > 10000)
{
DNSClient dns;
dns.begin(IPAddress(8,8,8,8));
IPAddress yahoo;
if (dns.getHostByName("yahoo.com", yahoo) == 1)
{
Serial.print("Yahoo: ");
Serial.print(yahoo[0]);
Serial.print(".");
Serial.print(yahoo[1]);
Serial.print(".");
Serial.print(yahoo[2]);
Serial.print(".");
Serial.println(yahoo[3]);
}
else
{
Serial.println("Failed to query yahoo.com IP address");
}
t0 = millis();
}
}
Is this a known issue? Can someone please help in identifying the problem in my code, or if there is a workaround for this issue? Can it be a hardware issue? I'm using SunFounder boards, not the original Arduino boards.
Thanks a lot,
Boaz,
We are using libmodbus library to read register values from energy meter EM6400 which supports Modbus over RTU. We are facing the following two issues.
1) We are facing an issue with modbus_read_registers API, this API returns -1 and the error message is:
ERROR Connection timed out: select.
After debugging the library, we found this issue is due to the echo of request bytes in the response message.
read() API call in _modbus_rtu_recv returns request bytes first followed by response bytes. As a result, length_to_read is calculated in compute_data_length_after_meta() based on the request bytes instead of response bytes (which contains the number of bytes read) and connection timed out issue occurs.
We tried to use both 3.0.6 and 3.1.2 libmodbus versions but same issue occurs in both the versions.
2) modbus_rtu_set_serial_mode (ctx, MODBUS_RTU_RS485) returns "BAD file descriptor".
Please confirm if there is any API call missing or any parameter is not set correctly.
Our sample code to read register value is as follows.
int main()
{
modbus_t *ctx;
uint16_t tab_reg[2] = {0,0};
float avgVLL = -1;;
int res = 0;
int rc;
int i;
struct timeval response_timeout;
uint32_t tv_sec = 0;
uint32_t tv_usec = 0;
response_timeout.tv_sec = 5;
response_timeout.tv_usec = 0;
ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'E', 8, 1);
if (NULL == ctx)
{
printf("Unable to create libmodbus context\n");
res = 1;
}
else
{
printf("created libmodbus context\n");
modbus_set_debug(ctx, TRUE);
//modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK |MODBUS_ERROR_RECOVERY_PROTOCOL);
rc = modbus_set_slave(ctx, 1);
printf("modbus_set_slave return: %d\n",rc);
if (rc != 0)
{
printf("modbus_set_slave: %s \n",modbus_strerror(errno));
}
/* Commented - Giving 'Bad File Descriptor' issue
rc = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
printf("modbus_rtu_set_serial_mode: %d \n",rc);
if (rc != 0)
{
printf("modbus_rtu_set_serial_mode: %s \n",modbus_strerror(errno));
}
*/
// This code is for version 3.0.6
modbus_get_response_timeout(ctx, &response_timeout);
printf("Default response timeout:%ld sec %ld usec \n", response_timeout.tv_sec, response_timeout.tv_usec );
response_timeout.tv_sec = 60;
response_timeout.tv_usec = 0;
modbus_set_response_timeout(ctx, &response_timeout);
modbus_get_response_timeout(ctx, &response_timeout);
printf("Set response timeout:%ld sec %ld usec \n", response_timeout.tv_sec, response_timeout.tv_usec );
/* This code is for version 3.1.2
modbus_get_response_timeout(ctx, &tv_sec, &tv_usec);
printf("Default response timeout:%d sec %d usec \n",tv_sec,tv_usec );
tv_sec = 60;
tv_usec = 0;
modbus_set_response_timeout(ctx, tv_sec,tv_usec);
modbus_get_response_timeout(ctx, &tv_sec, &tv_usec);
printf("Set response timeout:%d sec %d usec \n",tv_sec,tv_usec );
*/
rc = modbus_connect(ctx);
printf("modbus_connect: %d \n",rc);
if (rc == -1) {
printf("Connection failed: %s\n", modbus_strerror(errno));
res = 1;
}
rc = modbus_read_registers(ctx, 3908, 2, tab_reg);
printf("modbus_read_registers: %d \n",rc);
if (rc == -1) {
printf("Read registers failed: %s\n", modbus_strerror(errno));
res = 1;
}
for (i=0; i < 2; i++) {
printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
}
avgVLL = modbus_get_float(tab_reg);
printf("Average Line to Line Voltage = %f\n", avgVLL);
modbus_close(ctx);
modbus_free(ctx);
}
}
Output of this sample is as follows:
created libmodbus context
modbus_set_slave return: 0
modbus_rtu_set_serial_mode: -1
modbus_rtu_set_serial_mode: Bad file descriptor
Default response timeout:0 sec 500000 usec
Set response timeout:60 sec 0 usec
Opening /dev/ttyUSB0 at 19200 bauds (E, 8, 1)
modbus_connect: 0
[01][03][0F][44][00][02][87][0A]
Waiting for a confirmation...
ERROR Connection timed out: select
<01><03><0F><44><00><02><87><0A><01><03><04><C4><5F><43><D4><C6><7E>modbus_read_registers: -1
Read registers failed: Connection timed out
reg[0]=0 (0x0)
reg[1]=0 (0x0)
Average Line to Line Voltage = 0.000000
Issue 1) is probably a hardware issue, with "local echo" enabled in your RS-485 adapter. Local echo is sometimes used to confirm sending of data bytes on the bus. You need to disable it, or find another RS-485 adapter.
I have written about this in the documentation of my MinimalModbus Python library: Local Echo
It lists a few common ways to disable local echo in RS-485 adapters.
The netmap/virtio_net driver didn't work (Linux 3.10 kernel). There were two problems.
On the 3.10.60 kernel from kernel.org, the patch to virtio_net.c didn't
work, one part of the patch was rejected. This is easily fixed.
More serious, was that the virtio initialization code didn't work, nor
did the packet receive code. The basic problem was failure to initialize
the indices properly and failure to maintain a 1 slot separation between
head/tail indices. (Same problem 2 locations in the code.)
This problem is easily seen by creating a KVM guest with a
netmap/virtio_net driver, and simply pinging the guest from the host.
The receive traffic can easily be monitored using the pkt-gen tool on
the guest.
The first 255 pings will work fine, when the index hits 255, then the
packet receive will fail, and will continue to fail every time on slot 255.
I've included patches for both problems in the hopes that the source code
will be updated and others won't have to find these problems.
First virtio_netmap_3.10.60.patch:
# patch is the whole netmap virtio driver patch for 3.10.60 (from
# kernel.org), and it applies correctly.
#
Index: linux-3.10.60/drivers/net/virtio_net.c
===================================================================
--- linux-3.10.60.orig/drivers/net/virtio_net.c 2014-11-14 11:48:23.000000000 -0500
+++ linux-3.10.60/drivers/net/virtio_net.c 2014-11-21 12:54:29.751760095 -0500
## -131,6 +131,10 ##
struct notifier_block nb;
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
## -210,6 +214,10 ##
/* Suppress further interrupts. */
virtqueue_disable_cb(vq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, vq2txq(vq)))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_subqueue(vi->dev, vq2txq(vq));
}
## -646,7 +654,16 ##
struct virtnet_info *vi = rq->vq->vdev->priv;
void *buf;
unsigned int r, len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+
+ if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
## -679,6 +696,16 ##
{
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ virtnet_napi_enable(&vi->rq[i]);
+ return 0;
+ }
+#endif
for (i = 0; i < vi->max_queue_pairs; i++) {
if (i < vi->curr_queue_pairs)
## -972,6 +999,9 ##
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
## -1644,6 +1674,10 ##
goto free_recv_bufs;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
## -1690,6 +1724,9 ##
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
unregister_hotcpu_notifier(&vi->nb);
/* Prevent config work handler from accessing the device. */
Next is the virtio_netmap.patch
# There is a problem with the initialization, and during read packet with
# control of the indices .
#
# This problem is easily seen by building a KVM netmap/virtio_net driver, and
# simply pinging it (host pings KVM guest). All goes well, until ring buffer
# reaches index 255, and no packet is actually received. This will fix that
# problem and resulted in a working driver.
#
Index: b/LINUX/virtio_netmap.h
===================================================================
--- a/LINUX/virtio_netmap.h 2014-11-21 16:26:03.951278021 -0500
+++ b/LINUX/virtio_netmap.h 2014-11-21 16:26:25.451386665 -0500
## -398,8 +398,8 ##
* Second part: skip past packets that userspace has released.
*/
nm_i = kring->nr_hwcur; /* netmap ring index */
- if (nm_i != head) {
- for (n = 0; nm_i != head; n++) {
+ if (nm_next(nm_i, lim) != head) {
+ for (n = 0; nm_next(nm_i, lim) != head; n++) {
struct netmap_slot *slot = &ring->slot[nm_i];
void *addr = NMB(slot);
int err;
## -421,7 +421,7 ##
virtqueue_kick(vq);
nm_i = nm_next(nm_i, lim);
}
- kring->nr_hwcur = head;
+ kring->nr_hwcur = nm_i;
}
/* We have finished processing used RX buffers, so we have to tell
## -454,6 +454,7 ##
for (r = 0; r < na->num_rx_rings; r++) {
COMPAT_DECL_SG
struct netmap_ring *ring = na->rx_rings[r].ring;
+ struct netmap_kring *kring = &na->rx_rings[r];
struct virtqueue *vq = GET_RX_VQ(vi, r);
struct scatterlist *sg = GET_RX_SG(vi, r);
struct netmap_slot* slot;
## -485,6 +486,7 ##
if (VQ_FULL(vq, err))
break;
}
+ kring->nr_hwcur = i;
D("added %d inbufs on queue %d", i, r);
virtqueue_kick(vq);
}
With the following code, I get this error when I run the executable file:
...
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{
printf("%s\n",errbuf);
exit(1);
}
printf("DEV: %s\n",dev);
descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
if(descr == NULL)
{
printf("pcap_open_live(): %s\n",errbuf);
exit(1);
}
packet = pcap_next(descr,&hdr);
if(packet == NULL)
{
printf("Didn't grab packet\n");
exit(1);
}
...
And the error:
pcap_open_live(): gbeth0: BIOCSRTIMEOUT: Invalid argument
When I change
descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
to
descr = pcap_open_live(dev,BUFSIZ,0,1,errbuf);
sniffer does not grab anything and the program exit with this error: Didn't grab packet
and when I change 1 to 0 it does not grab anything but with errors.
What should I do?
-1 is NOT a valid timeout argument to pcap_open_live() on any platform.
0, as a timeout argument, may behave differently on different platforms, and is not recommended.
And pcap_next() is not guaranteed to wait forever for a packet to arrive; it might return NULL if the timeout expires. If you want to capture at least one packet, try looping until pcap_null() doesn't return NULL.
Is there an easy way to check if a given memcached_st* is successfully connected to a memcached server?
I'm connecting via memcached_server_add_with_weight, and it's returning MEMCACHED_SUCCESS when I give it spurious hostnames. Similarly, calling memcached_last_error_errno immediately after the call to memcached_server_add_with_weight gives me MEMCACHED_SUCCESS.
One interesting way to do this is checking the actual socket descriptor.
If libmemcached successfully connected to the server then the socket descriptor is positive, otherwise it is -1.
std::shared_ptr<memcached_st> es (memcached_create (NULL), [](memcached_st* msp) {memcached_free (msp);});
memcached_server_add_with_weight (es.get(), "server1", 9201, 100);
memcached_server_add (es.get(), "server2", 9201);
memcached_server_add (es.get(), "server3", 9201);
memcached_server_fn serverVisitor = [](const memcached_st *ptr, memcached_server_instance_st server, void *context) {
if (server->fd < 0) throw std::runtime_error (std::string ("libmemcached connection to ") + server->hostname + " failed!");
return MEMCACHED_SUCCESS;
};
memcached_server_cursor (es.get(), &serverVisitor, NULL, 1);