I am trying to run the sample code for tftp server. I get no complaints when synthesizing my hardware or compiling the code. However, when I add the lwip_init() statement, it seems to stop working (it doesn't output any of the print statements). This is very frustrating and I have no idea what is causing it. Any ideas? Thanks
#include <stdio.h>
#include "xenv_standalone.h"
#include "xparameters.h"
#include "platform.h"
#include "netif/xadapter.h"
#include "lwip/init.h"
#define EMAC_BASEADDR XPAR_LLTEMAC_0_BASEADDR
int main()
{
print("-- Starting main() -- \r\n");
struct netif *netif, server_netif;
struct ip_addr ipaddr, netmask, gw;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
netif = &server_netif;
microblaze_init_icache_range(0, XPAR_MICROBLAZE_0_CACHE_BYTE_SIZE);
microblaze_init_dcache_range(0, XPAR_MICROBLAZE_0_DCACHE_BYTE_SIZE);
/* enable caches */
XCACHE_ENABLE_ICACHE();
XCACHE_ENABLE_DCACHE();
platform_setup_interrupts();
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr, 192, 168, 1, 10);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 1, 1);
print_app_header();
print_ip_settings(&ipaddr, &netmask, &gw);
lwip_init();
...
}
EDIT in response to vicky:
maybe you can explain something cause you might be right. When i compile it without lwip_init(), i get:
text data bss dec hex
7214 356 1104 8674 21e2
and with lwip_init() i get:
text data bss dec hex
9726 356 559080 569162 8af4a
which is ALOT bigger. too bad it can't give a warning about this
Presumably (assuming you are doing a clean rebuild) it's linking in lots of new stuff when you start calling LWIP functions, so your image has changed. Has your image overflowed any of its constraints (program size, data size, stack size...)?
Related
I'm making a remote controlled machine using a pi pico to drive the motors and read some sensors, and a raspberry pi 4 to send commands to the pi pico via serial and host the web interface.
I'm working on sending and receiving commands from the raspberry and for now I'm stuck with this code:
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#define UART_ID uart0
#define BAUD_RATE 19200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
#define UART_TX_PIN 0
#define UART_RX_PIN 1
static int chars_rxed = 0;
char uCommand[32] = {0, 0};
void on_uart_rx() {
char tmp_string[] = {0, 0};
while (uart_is_readable(UART_ID)) {
uint8_t ch = uart_getc(UART_ID);
tmp_string[0] = ch;
strcat(uCommand, tmp_string);
if(uart_is_writable(UART_ID)){
uart_putc(UART_ID, '-');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '-');
}
chars_rxed++;
}
}
int main(){
uart_init(UART_ID, BAUD_RATE);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
uart_set_fifo_enabled(UART_ID, false);
int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
irq_set_enabled(UART_IRQ, true);
uart_set_irq_enables(UART_ID, true, false);
uart_puts(UART_ID, "\nOK\n");
while (1){
tight_loop_contents();
if(uCommand[0] != 0){
uart_putc(UART_ID, '/');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '/');
}
}
}
my idea was to take the command sent via serial during the interrupt and place it in a charset, then parse it and execute it externally.
Trying it, I notice that it never enters the if inside the while and it doesn't 'fill' the 'uCommand' charset completely but only a few characters compared to the ones sent.
I hope my question is not off topic.
You should declare uCommand (and any other shared objects) volatile.
The while-loop is waiting for uCommand[0] != 0 to become true, but the main thread does not modify uCommand[0] so the compiler is free to "optimise" away the entire block of code if it "knows" it can never be true.
Similarly chars_rxed may get optimised away because you write but never read it.
Declaring it volatile will also prevent that.
The optimisaton of apparently redundant accesses usually only occurs when -O1 or higher optimisation level is set. Though you should in any event use volatile in such circumstances regardless.
I was trying to write a basic program to print ā (a with overline) in C using curses and non-spacing characters. I have set the locale to en_US.UTF-8 and I am able to print international language characters using that. This code only prints a without overline. I am getting similar results with ncurses too. What else do I need to do to get ā on screen?
#include <curses.h>
#include <locale.h>
#include <wchar.h>
#include <assert.h>
int main() {
setlocale(LC_ALL, "");
initscr();
int s = 0x41; // represents 'a'
int ns = 0x0305; // represents COMBINING OVERLINE (a non-spacing character)
assert(wcwidth(ns) == 0);
wchar_t wstr[] = { s, ns, L'\0'};
cchar_t *cc;
int x = setcchar(cc, wstr, 0x00, 0, NULL);
assert(x == 0);
add_wch(cc);
refresh();
getch();
endwin();
return 0;
}
The curses calls need a pointer to data, not just a pointer.
It's okay to pass a null-terminated array for the wide-characters, but the pointer for the cchar_t data needs some repair.
Here's a fix for the program:
> diff -u foo.c.orig foo.c
--- foo.c.orig 2020-05-21 19:50:48.000000000 -0400
+++ foo.c 2020-05-21 19:51:46.799849136 -0400
## -3,7 +3,7 ##
#include <wchar.h>
#include <assert.h>
-int main() {
+int main(void) {
setlocale(LC_ALL, "");
initscr();
int s = 0x41; // represents 'a'
## -12,11 +12,11 ##
assert(wcwidth(ns) == 0);
wchar_t wstr[] = { s, ns, L'\0'};
- cchar_t *cc;
- int x = setcchar(cc, wstr, 0x00, 0, NULL);
+ cchar_t cc;
+ int x = setcchar(&cc, wstr, 0x00, 0, NULL);
assert(x == 0);
- add_wch(cc);
+ add_wch(&cc);
refresh();
getch();
That produces (on xterm) a "A" with an overbar:
(For what it's worth, 0x61 is "a", while 0x41 is "A").
Your code is basically correct aside from the declaration of cc. You'd be well-advised to hide the cursor, though; I think it is preventing you from seeing the overbar incorrectly rendered in the following character position.
I modified your code as follows:
#include <curses.h>
#include <locale.h>
#include <wchar.h>
#include <assert.h>
int main() {
setlocale(LC_ALL, "");
initscr();
int s = 0x41; // represents 'A'
int ns = 0x0305; // represents COMBINING OVERLINE (a non-spacing character)
assert(wcwidth(ns) == 0);
wchar_t wstr[] = { s, ns, L'\0'};
cchar_t cc; /* Changed *cc to cc */
int x = setcchar(&cc, wstr, 0x00, 0, NULL); /* Changed cc to &cc */
assert(x == 0);
set_curs(0); /* Added to hide the cursor */
add_wch(&cc); /* Changed cc to &cc */
refresh();
getch();
endwin();
return 0;
}
I tested on a kubuntu system, since that's what I have handy. The resulting program worked perfectly on xterm (which has ugly fonts) but not on konsole. On konsole, it rendered the overbar in the following character position, which is clearly a rendering bug since the overbar appears on top of the following character if there is one. After changing konsole's font to Liberation Mono, the test program worked perfectly.
The rendering bug is not going to be easy to track down because it is hard to reproduce, although from my experiments it seems to show up reliably when the font is DejaVu Sans Mono. Curiously, my system is set up to use non-spacing characters from DejaVu Sans Mono as substitutes in other fonts, such as Ubuntu Mono, and when these characters are used as substitutes, the spacing appears to be correct. However, Unicode rendering is sufficiently intricate that I cannot actually prove that the substitute characters really come from the configured font, and the rendering bug seems to come and go. It may depend on the font cache, although I can't prove that either.
If I had more to go on I'd file a bug report, and if I get motivated to look at this some more tomorrow, I might find something. Meanwhile, any information that other people can provide will undoubtedly be useful; at a minimum, that should include operating system and console emulator, with precise version numbers, and a list of fonts tried along with an indication whether they succeeded or not.
It's not necessary to use ncurses to see this bug, by the way. It's sufficient to test in your shell:
printf '\u0041\u0305\u000a'
will suffice. I found it interesting to test
printf '\u0041\u0305\u0321\u000a'
as well.
The system I tested it on:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic
$ konsole --version
konsole 17.12.3
$ # Fonts showing bug
$ otfinfo -v /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf
Version 2.37
$ # Fonts not showing bug
$ otfinfo -v /usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf
Version 1.07.4
There are multiple issues here. First, you're storing the result of setcchar to random memory at an uninitialized pointer, cc. Whenever a function takes a pointer for output, you need to pass the address of an object where the result will be stored, not an uninitialized pointer variable. The output must be an array of sufficient length to store the number of characters in the input. I'm not sure what the null termination convention is so to be safe I'd use:
cchar_t cc[3];
int x = setcchar(cc, wstr, 0x00, 0, NULL);
Then, the add_wch function takes only a single character to add, and replaces or appends based on whether it's a spacing or non-spacing character. So you need to call it once for each character.
I'm dealing with machine embedded C language software and struggling to understand how to use 'putimage' function to load 'qrcode'image in c. What I've tried to do is put some image on the LCD panel screen on the machine and coudn't figure out how to use putimage function properly.
I've learned that 'putimage' function shows image data array which have gotten from 'getimage' function and two functions I've mentioned are used as below.
void putimage(int left, int top, void *bitmap, int op);
void getimage(int left, int top, int right, int bottom, void *bitmap) ;
Since it is said that bitmap files can be converted to hex format starting '0x42, 0x4D...', I've tried to put array which I've defined like 'char QRbuff[] = {'0x42, 0x4D,...,}' into '*bitmap' parameter while using 'putimage'fuction. but no image have been appeared.
If I defined BMPbuff[] as below ingnoring bitmap format(eg. 0x42, 0x4D), some dotted image is shown.
char BMPbuff[] = {30, 0, 30, 0, 0x18, 0x24, 0x42, 0x99, 0x99, 0x42, 0x24, 0x18} ;
I have no idea how it works. I guess bitmap format that has to do with putimage is not the format which starts with 0x42, 0x4D. Instead, it seems that the format start with size of image {30, 0, 30, 0...} which I don't know where it came from.
I would be so appreciated with any help how to define bitmap array in this case...
I need a function which can calculate the length of an x86-64 instruction.
For example, it would be usable like so:
char ret[] = { 0xc3 };
size_t length = instructionLength(ret);
length would be set to 1 in this example.
I do not want to include an entire disassembly library, since the only information I require is the length of the instruction.
I am looking for a minimalist approach, written in C, and ideally as small as possible.
100% complete x86-64 instruction set is not strictly necessary (very obscure ones such as vector register set instructions can be omitted).
A similar answer to what I am looking for (but for the wrong architecture):
Get size of assembly instructions
There is XED library from Intel to work with x86/x86_64 instructions: https://github.com/intelxed/xed, and it is the only correct way to work with intel machine codes.
xed_decode function will provide you all information about instruction: https://intelxed.github.io/ref-manual/group__DEC.html
https://intelxed.github.io/ref-manual/group__DEC.html#ga9a27c2bb97caf98a6024567b261d0652
And xed_ild_decode is for instruction length decoding:
https://intelxed.github.io/ref-manual/group__DEC.html#ga4bef6152f61997a47c4e0fe4327a3254
XED_DLL_EXPORT xed_error_enum_t xed_ild_decode ( xed_decoded_inst_t * xedd,
const xed_uint8_t * itext,
const unsigned int bytes
)
This function just does instruction length decoding.
It does not return a fully decoded instruction.
Parameters
xedd the decoded instruction of type xed_decoded_inst_t . Mode/state sent in via xedd; See the xed_state_t .
itext the pointer to the array of instruction text bytes
bytes the length of the itext input array. 1 to 15 bytes, anything more is ignored.
Returns:
xed_error_enum_t indiciating success (XED_ERROR_NONE) or
failure. Only two failure codes are valid for this function:
XED_ERROR_BUFFER_TOO_SHORT and XED_ERROR_GENERAL_ERROR. In general
this function cannot tell if the instruction is valid or not. For
valid instructions, XED can figure out if enough bytes were provided
to decode the instruction. If not enough were provided, XED returns
XED_ERROR_BUFFER_TOO_SHORT. From this function, the
XED_ERROR_GENERAL_ERROR is an indication that XED could not decode the
instruction's length because the instruction was so invalid that even
its length may across implmentations.
To get length from xedd filled by xed_ild_decode, use xed_decoded_inst_get_length: https://intelxed.github.io/ref-manual/group__DEC.html#gad1051f7b86c94d5670f684a6ea79fcdf
static XED_INLINE xed_uint_t xed_decoded_inst_get_length ( const xed_decoded_inst_t * p )
Return the length of the decoded instruction in bytes.
Example code ("Apache License, Version 2.0", by Intel 2016): https://github.com/intelxed/xed/blob/master/examples/xed-ex-ild.c
#include "xed/xed-interface.h"
#include <stdio.h>
int main()
{
xed_bool_t long_mode = 1;
xed_decoded_inst_t xedd;
xed_state_t dstate;
unsigned char itext[15] = { 0xf2, 0x2e, 0x4f, 0x0F, 0x85, 0x99,
0x00, 0x00, 0x00 };
xed_tables_init(); // one time per process
if (long_mode)
dstate.mmode=XED_MACHINE_MODE_LONG_64;
else
dstate.mmode=XED_MACHINE_MODE_LEGACY_32;
xed_decoded_inst_zero_set_mode(&xedd, &dstate);
xed_ild_decode(&xedd, itext, XED_MAX_INSTRUCTION_BYTES);
printf("length = %u\n",xed_decoded_inst_get_length(&xedd));
return 0;
}
If you're on Windows, you can just use IDebugControl::Disassemble(..., &end_address) from dbgeng.dll. See this question for example usage.
I have an strace of my program that interacts with USB, and I am wondering what the following write command tells me. I understand the writev iovec structure consists of the data array pointer followed by the length, but what does the "#\10\335 \320\2w\4\240K\252\0\7" in the data array denote? I'm particularly wondering what the # symbol, 2w, and 240K means as those are not hex data values as I would expect them to be.
I'm running on Linux and here is the writev line:
writev(6, [{"#\10\335 \320\2w\4\240K\252\0\7", 13}, {"\0\0\0\4\0\0\0\4", 8}], 2) = 21
From the man page of writev:
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
That is, the second argument is an array of size the value of the third argument (2 in your case) elements of type struct iovec.
When strace prints those it octal escapes unprintable characters but displays all other exactly as they can be printed. Hence, # is just the byte corresponding to #, K is the byte corresponding to K and so on.
Answering your questions in the comment, another look at the man page shows
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes to transfer */
};
Which means that {"#\10\335 \320\2w\4\240K\252\0\7", 13} is to be read as iov_len = 13 and iov_base is a memory area containing the bytes printed as #\10\335 \320\2w\4\240K\252\0\7. Fire up gdb if you want to see the binary values:
[mihai#winterfell 1]$ gdb -q
(gdb) p/x "#\10\335 \320\2w\4\240K\252\0\7"
$1 = {0x40, 0x8, 0xdd, 0x20, 0xd0, 0x2, 0x77, 0x4, 0xa0, 0x4b, 0xaa, 0x0, 0x7, 0x0}
Where the last 0x0 is the null terminator of the string and should be ignored.