esp-rs / esp-wifi-sys Goto Github PK
View Code? Open in Web Editor NEWWi-Fi and BT drivers packaged for integration into bare-metal esp-wifi.
License: Apache License 2.0
Wi-Fi and BT drivers packaged for integration into bare-metal esp-wifi.
License: Apache License 2.0
cargo doc
returns the following error :
> cargo doc
Updating git repository `https://github.com/esp-rs/esp-pacs`
Updating crates.io index
Updating git repository `https://github.com/bjoernQ/bleps`
error: failed to select a version for the requirement `riscv = "^0.9"`
candidate versions found which didn't match: 0.10.1, 0.8.0, 0.7.0, ...
location searched: crates.io index
required by package `riscv-rt v0.10.0`
... which satisfies dependency `riscv-rt = "^0.10.0"` of package `esp-wifi v0.1.0 (/home/ash/Rust/esp-wifi)`
Is there another way to build the documentation ?
Make the custom linker script obsolete by moving the relevant things to esp-hal
The code manually corrects s_wifi_task_hdl
- ideally that shouldn't be needed. There is a comment in the code about that
esp-rs/esp-hal#207 breaks this crate.
I was adding esp32 support to my esp32c3 project and for some reason I'm getting linking issues when activating the esp-wifi feature I have.
I honestly dont understand much so maybe I can get some help in here:
This is the linking error and this is the project
Hi, I tried running the DHCP example (commit a0a6b5fbcf7
) on my esp32-c3-mini and it appears as though the code is racy. It fails to get an ip address, unless I do some random permutation of dump_packets
, wifi_logs
, and manually putting in for i in 1000 {}
style loops.
I'm working with @ImUrX and he also cannot get the example working on his PCB, although his is a lolin_c3_mini v1.0.0 (which may have hardware issues with wifi, so could be a red herring).
If I use --release
it works consistently.
I'm interested in using a esp32c3 to received UDP packets. I've been playing with the DHCP example and it looks like it is working quite well (kudos!) and I'm excited to use this more - is there any chance that UDP support is coming soon?
I observed some interesting behavior on ESP32
The ble_esp32
example works fine for me until I comment out this line in the toy-ble-stack: https://github.com/bjoernQ/ble-hci/blob/9c52ccf018756d90df9b90363e04e651589d74de/src/attribute_server.rs#L193
If that log statement is removed / commented-out the ble stack doesn't see the configured services or at least it doesn't find any matching one
I tried to look into that but it still puzzles me
Update: Even a nop
there makes things work
The examples do some extensive logging but the wifi log seems to interfere with the println
from main
We should remove the println
implementation here and favor using esp-println
. It's not even used in the crate itself but just in the examples.
WiFi connects (judging by the logs) regardless of LTO, but with lto = true
in Cargo.toml it hangs somewhere after connection.
I use this code:
wifi_interface.connect().unwrap();
println!("Wait to get connected");
loop {
let res = wifi_interface.is_connected();
match res {
Ok(connected) => {
if connected {
break;
}
}
Err(err) => {
println!("{:?}", err);
loop {}
// wifi_interface.connect().unwrap();
}
}
}
println!("Wait to get an ip address");
let network = Network::new(wifi_interface, current_millis);
loop {
network.poll_dhcp().unwrap();
network.work();
if network.is_iface_up() {
println!("got ip {:?}", network.get_ip_info());
break;
}
}
wifi_led.set_high().unwrap();
And with LTO led never turns on.
I've been playing around trying to get this work. Scanning works perfectly, I can see a table of networks near me, but If I try to connect to any (I've tried 4 in total, on two different esp32c3's), the WiFi state never transitions to STA_CONNECTED
. Judging by the logs below is transitions to STA_STOP
.
wifi_connect returned 0
D (405) wifi:scan end: arg=0x0, status=0, ss_state=0x03
V (405) wifi:hint scan, stop scan
V (405) wifi:back home chan=<1,0>, current chan=<10,0>
V (408) wifi:ht20 freq=2412, chan=1
D (412) wifi:filter: set rx policy=4
D (412) wifi:first chan=1
V (416) wifi:scan_done: arg=0x0, status=0, cur_time=647416, scan_id=128, scan state=00
V (423) wifi:call scan_done cb, arg=0x0
D (427) wifi:handoff_cb: status=0
D (431) wifi:clear rc list
D (431) wifi:clear blacklist
D (435) wifi:send disconnect event
D (438) wifi:connect status 1 -> 3
D (442) wifi:disable connect timer
D (443) wifi:clear scan ap list
wifi_init
I've sniffed the connect packed with my laptop in promiscuous mode and the packet seems normal.
I would like to keep this issue open to track progress towards fully working Bluetooth.
Personally I am interested in seeing support for Bluetooth hid devices from the ESP32-S3.
I tried to run the coex example on a Beetle esp32c3, when my usb suddenly disconnected, and the next time i tried to connect the esp32 to the desktop, it started giving me FailedEnumeration errors. I suspect strongly its related to something similar to this issue: espressif/arduino-esp32#6264. I reset the chip, by pulling down pin9, and uploading a blinky script, which solved the problem. My guess is that it will be possible to reproduce the same error by using the wifi example. I will try to reproduce later.
For the occational googler, to fix the chip after "bricking" the usb, try pulling gpio9 to ground, while connecting the usb, and upload a different script.
Looks like esp-wifi
includes a global allocator. It would be better to let the user choose their own global allocator.
I'll submit a PR to do this.
Calling esp_wifi_internal_set_log_level
or esp_wifi_internal_set_log_mod
crashes immediately or cause crashes later (depending on when those are called) - so Wifi logs are never enabled on ESP32 (i.e. it works fine on ESP32C3)
Additionally there is a problem with VaList on ESP32 (or Xtensa in general) - that's why it's conditionally compiled only for ESP32C3 in log_writev
On ESP32C3 there is init_intr11
- it seems to be unnecessary. Double check and remove it. The function is also there as a no-op on ESP32
Consider adding simple web server to examples.
e.g when some task is checking to get a lock on a mutex or semaphore it would be more efficient to yield to another task
When AP connection suceeds:
Call wifi_connect
wifi_connect returned Ok(())
Ok(EnumSet(Client))
Status(Starting, Stopped)
Status(Started(Connected(Waiting)), Stopped)
Start busy loop on main
When AP connection fails:
Call wifi_connect
wifi_connect returned Ok(())
Ok(EnumSet(Client))
Status(Starting, Stopped)
Status(Started(Disconnected), Stopped)
Start busy loop on main
What other info can we find out from the disconnection reason? Should we also put retry logic into esp-wifi itself, or should we update the examples to show how to handle retries?
Currently it's not possible to use WIFI and BTLE together - we need to explore how to get coex working
it seems they had a major change in the Wifi
trait and the code needs updating.
While most of these things are not in the PAC it might still be a good idea to have those things in the HAL. e.g. reading the MAC address and probably other things, too
Version: 69956d42d2ddf00dd7021e429ed815f982e35319
(latest main)
Feature flags: "esp32c3", "wifi"
I noticed that the crate patches esp32c3-hal
, but that I am using esp32c3-hal = 0.2. Perhaps that could be why?
Error:
error[E0433]: failed to resolve: could not find `wifi_interface` in the crate root
--> /Users/ryan.butler/.cargo/git/checkouts/esp-wifi-836f3b2af57fa847/69956d4/src/wifi/utils.rs:103:31
|
103 | interface: RefCell<crate::wifi_interface::Wifi<'a>>,
| ^^^^^^^^^^^^^^ could not find `wifi_interface` in the crate root
error[E0433]: failed to resolve: could not find `wifi_interface` in the crate root
--> /Users/ryan.butler/.cargo/git/checkouts/esp-wifi-836f3b2af57fa847/69956d4/src/wifi/utils.rs:110:27
|
110 | interface: crate::wifi_interface::Wifi<'a>,
| ^^^^^^^^^^^^^^ could not find `wifi_interface` in the crate root
error[E0433]: failed to resolve: could not find `wifi_interface` in the crate root
--> /Users/ryan.butler/.cargo/git/checkouts/esp-wifi-836f3b2af57fa847/69956d4/src/wifi/utils.rs:122:31
|
122 | F: FnOnce(&mut crate::wifi_interface::Wifi<'a>) -> R,
| ^^^^^^^^^^^^^^ could not find `wifi_interface` in the crate root
error[E0392]: parameter `'a` is never used
--> /Users/ryan.butler/.cargo/git/checkouts/esp-wifi-836f3b2af57fa847/69956d4/src/wifi/utils.rs:102:20
|
102 | pub struct Network<'a> {
| ^^ unused parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `'n` is never used
--> /Users/ryan.butler/.cargo/git/checkouts/esp-wifi-836f3b2af57fa847/69956d4/src/wifi/utils.rs:166:23
|
166 | pub struct Socket<'s, 'n: 's> {
| ^^ unused parameter
|
= help: consider removing `'n`, referring to it in a field, or using a marker such as `PhantomData`
Some errors have detailed explanations: E0392, E0433.
For more information about an error, try `rustc --explain E0392`.
error: could not compile `esp-wifi` due to 5 previous errors
log
and use it in the library crate instead of the custom logging macrosembedded-nal
embedded-svc
(mainly the Wifi trait) as the user facing APII am aware that this library contains some proprietary closed source code. Could a permissive license be provided that lets us us link to this compiled binary along with the rest of the rust source code in an open source project in a way that is compatible with MIT/Apache 2.0 and doesnt impose any restrictions on the final linked binary?
I assume that the closed source blob implicitly prohibits downstream source code from using GPL-style licenses, which is fine (I don't use viral licenses anyway :P)
Since 69956d4 it freezes in initialze
on ESP32-C3-DevKit-RUST-1 while it still works on other ESP32-C3 development boards (when running the DHCP example)
Would be very nice.
I haven't actually read a lot on how it should work. We would first need embedded-svc
to implement an async trait
which is nightly. But I see a lot of calls like scanning that could be async and it would be pretty nice to have that, I also see that smoltcp
implements Waker
s for their socket stuff, could we also have async sends and receives ๐ฒ?
By now if we need to look into what this library includes, we have to do reverse engineering works. By providing source code (or write a clean room one without reading its original source) we can get this library bottom-up in Rust compiler only without tampering with the toolchains.
In #30 we added BLE support for ESP32C3. We should be able to do the same for ESP32
The value used there doesn't seem to make sense. However, it works this way
Maybe related to the clocks_init
issue.
To support that we probably just need to fully implement phy_enable
and phy_disable
Currently all the additional tasks get the same stack size - that is inefficient.
Should be possible to configure the stack size per task
In function create_network_interface()
from src/wifi/utils.rs
for _ in 0..sockets_to_add {
let rx_tx_socket1 = {
static mut TCP_SERVER_RX_DATA: [u8; 1536] = [0; 1536];
static mut TCP_SERVER_TX_DATA: [u8; 1536] = [0; 1536];
let tcp_rx_buffer = unsafe { TcpSocketBuffer::new(&mut TCP_SERVER_RX_DATA[..]) };
let tcp_tx_buffer = unsafe { TcpSocketBuffer::new(&mut TCP_SERVER_TX_DATA[..]) };
TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer)
};
ethernet.add_socket(rx_tx_socket1);
}
When sockets_to_add
is more than one, the static mutable variables TCP_SERVER_RX_DATA
and TCP_SERVER_TX_DATA
are used multiple times to create multiple TcpSocket's.
This will result in multiple mutable references to the same buffer which is unsound.
And as a consequence data is corrupted when multiple sockets are used at the same time.
Having USB and Wi-Fi at the same time reduces Wi-Fi performance.
Currently we have it always on ESP32-C3 but don't have it yet on ESP32-S3
While smoltcp
itself has no alternative in the embedded world, I'm less than convinced that embedded-nal
is the no-brainer for embedded networking: it still relies on the nb
"async" approach, which is essentially just busylooping with constant polling of the networking layer. While this might have been the norm a few years ago, it is no more:
embedded-hal
is moving away from nb
in favor of the async-based traitssmoltcp
itself has an async support and an async
feature since quite some time, so it is very easy to bind it to an async executor of your choice, if you prefer soIn my opinion:
esp-wifi
all dependencies / reliance on embedded-nal
/ smoltcp-nal
. This stuff is anyway a thin wrapper on top of the heavy lifting done by smoltcp
itselfWifi
struct can instead take directly the smoltcp IP interface, i.e. the "ethernet" varcreate_network_stack
utility will construct and return directly the smoltcp interface instead of the embedded-nal
wrapper. Perhaps, we should rename the utility to create_network_interface
or suchlikenetwork_stack
method of the Wifi
struct should instead directly return the native smoltcp interfaceWith that little surgery, users would be free to either use smoltcp-nal on top of the smoltcp interface returned by Wifi
, or the smoltcp built-in async facilities, with an async executor of their choice.
There is a clocks_init
in the code but it's unused because
Probably the second issue causes the first
ble.cmd_set_le_advertising_data(create_advertising_data(&[
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]),
AdStructure::CompleteLocalName("BLE_TO_ISOTP"),
])).unwrap();
could you help explain AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]),
versus
gatt!([service {
uuid: "0000abf0-0000-1000-8000-00805f9b34fb", // SPP_SERVICE
characteristics: [
characteristic {
uuid: "0000abf2-0000-1000-8000-00805f9b34fb", // DATA_NOTIFY
read: rf,
},
characteristic {
uuid: "0000abf3-0000-1000-8000-00805f9b34fb", // COMMAND_WRITE
write: wf,
},
],
},]);
is the service UUID duplicated?
$ cargo "+esp" run --example ble --release --target xtensa-esp32-none-elf --features "esp32,ble"
Compiling esp-wifi v0.1.0 (/Users/brandonros/Desktop/esp-wifi)
Finished release [optimized] target(s) in 1.66s
Running `espflash --speed 921600 --monitor target/xtensa-esp32-none-elf/release/examples/ble`
Detected 2 serial ports. Ports which match a known common dev board are highlighted.
Serial port: /dev/tty.usbserial-02728E37
Connecting...
WARN setting baud rate higher than 115200 can cause issues.
Chip type: ESP32 (revision 3)
Crystal frequency: 40MHz
Flash size: 16MB
Features: WiFi, BT, Dual Core, 240MHz, Coding Scheme None
MAC address: 94:b9:7e:57:4b:18
App/part. size: 294688/16711680 bytes, 1.76%
[00:00:00] ######################################## 16/16 segment 0x1000 [00:00:00] ######################################## 1/1 segment 0x8000 [00:00:03] ######################################## 156/156 segment 0x10000
Flashing has completed!
Commands:
CTRL+R Reset chip
CTRL+C Exit
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0048,len:12
ho 0 tail 12 room 4
load:0x3fff0054,len:4800
load:0x40078000,len:17448
0x40078000 - r_rwip_reset
at ??:??
load:0x4007c428,len:4840
0x4007c428 - r_rwip_reset
at ??:??
entry 0x4007c6a0
0x4007c6a0 - r_rwip_reset
at ??:??
WARN - coex_register_bt_cb 0x40081698
0x40081698 - coex_bt_callback
at ??:??
WARN - coex_schm_register_btdm_callback 0x400df318
0x400df318 - coex_schm_btdm_callback
at ??:??
WARN - coex_wifi_channel_get
Ok(CommandComplete { num_packets: 5, opcode: 3075, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8198, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8200, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8202, data: [0] })
started advertising
ASSERT_PARAM(9 0), in lld_pdu.c at line 605
Exception occured Illegal Context { PC: 400816df, PS: 60c11, A0: 80081ac5, A1: 3ffff1e0, A2: 0, A3: 9, A4: 0, A5: 3f4110da, A6: 25d, A7: fffffffc, A8: 8000814b, A9: 3ffff150, A10: 0, A11: 3ffff173, A12: 3ffff11f, A13: 35, A14: 0, A15: 3ffff124, SAR: 4, EXCCAUSE: 0, EXCVADDR: 0, LBEG: 400819cd, LEND: 400819d5, LCOUNT: 0, THREADPTR: 0, SCOMPARE1: 0, BR: 0, ACCLO: 0, ACCHI: 0, M0: 0, M1: 0, M2: 0, M3: 0, F64R_LO: 0, F64R_HI: 0, F64S: 0, FCR: 0, FSR: 80, F0: 433b8000, F1: 426c0000, F2: 43800000, F3: 0, F4: 0, F5: 0, F6: 0, F7: 0, F8: 0, F9: 0, F10: 0, F11: 0, F12: 0, F13: 0, F14: 0, F15: 0 }
0x400816df
0x400816df - r_assert
at ??:??
0x40081ac5
0x40081ac5 - r_assert_param
at ??:??
0x40086364
0x40086364 - r_lld_pdu_rx_handler
at ??:??
0x40084be4
0x40084be4 - r_lld_evt_end
at ??:??
0x400848f5
0x400848f5 - r_lld_evt_end_isr
at ??:??
0x400870b1
0x400870b1 - r_rwble_isr
at ??:??
0x40088432
0x40088432 - r_rwbtdm_isr_wrapper
at ??:??
0x400d3521
0x400d3521 - RWBLE
at ??:??
0x4008ba44
0x4008ba44 - _ZN14esp_hal_common9interrupt8vectored16handle_interrupt17hd4ff79f68e7aaaf8E
at ??:??
0x4008b9fd
0x4008b9fd - _ZN14esp_hal_common9interrupt8vectored17handle_interrupts17h66a646a6760229b5E
at ??:??
0x4008af91
0x4008af91 - __level_3_interrupt
at ??:??
0x4008bc92
0x4008bc92 - .RestoreContext
at ??:??
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0048,len:12
ho 0 tail 12 room 4
load:0x3fff0054,len:4800
load:0x40078000,len:17448
0x40078000 - r_rwip_reset
at ??:??
load:0x4007c428,len:4840
0x4007c428 - r_rwip_reset
at ??:??
entry 0x4007c6a0
0x4007c6a0 - r_rwip_reset
at ??:??
WARN - coex_register_bt_cb 0x40081698
0x40081698 - coex_bt_callback
at ??:??
WARN - coex_schm_register_btdm_callback 0x400df318
0x400df318 - coex_schm_btdm_callback
at ??:??
WARN - coex_wifi_channel_get
Ok(CommandComplete { num_packets: 5, opcode: 3075, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8198, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8200, data: [0] })
Ok(CommandComplete { num_packets: 5, opcode: 8202, data: [0] })
started advertising
INFO - polled: Some(AsyncData(AclPacket { handle: 0, boundary_flag: FirstAutoFlushable, bc_flag: PointToPoint, data: [3, 0, 4, 0, 2, f, 2] }))
INFO - att: ExchangeMtu { mtu: 20f }
INFO - Requested MTU 527, returning 23
INFO - src_handle 0
INFO - data [3, 17, 0]
INFO - encoded_l2cap [3, 0, 4, 0, 3, 17, 0]
INFO - writing [2, 0, 20, 7, 0, 3, 0, 4, 0, 3, 17, 0]
INFO - polled: Some(Event(NumberOfCompletedPackets { number_of_connection_handles: 1, connection_handles: 0, completed_packets: 1 }))
INFO - polled: Some(AsyncData(AclPacket { handle: 0, boundary_flag: FirstAutoFlushable, bc_flag: PointToPoint, data: [3, 0, 4, 0, a, 3, 0] }))
INFO - att: ReadReq { handle: 3 }
INFO - src_handle 0
INFO - data [b, 48, 65, 6c, 6c, 6f, 20, 42, 61, 72, 65, 2d, 4d, 65, 74, 61, 6c, 20, 42, 4c, 45]
INFO - encoded_l2cap [15, 0, 4, 0, b, 48, 65, 6c, 6c, 6f, 20, 42, 61, 72, 65, 2d, 4d, 65, 74, 61, 6c, 20, 42, 4c, 45]
INFO - writing [2, 0, 20, 19, 0, 15, 0, 4, 0, b, 48, 65, 6c, 6c, 6f, 20, 42, 61, 72, 65, 2d, 4d, 65, 74, 61, 6c, 20, 42, 4c, 45]
INFO - polled: Some(Event(NumberOfCompletedPackets { number_of_connection_handles: 1, connection_handles: 0, completed_packets: 1 }))
ASSERT_PARAM(0 182), in lld_pdu.c at line 605
Exception occured Illegal Context { PC: 400816df, PS: 60811, A0: 80081ac5, A1: 3ffd8e80, A2: 0, A3: 0, A4: b6, A5: 3f4110da, A6: 25d, A7: fffffffc, A8: 8000814b, A9: 3ffd8df0, A10: 0, A11: 3ffd8e13, A12: 3ffd8dbf, A13: 35, A14: 0, A15: 3ffd8dc4, SAR: 4, EXCCAUSE: 0, EXCVADDR: 0, LBEG: 400819cd, LEND: 400819d5, LCOUNT: 0, THREADPTR: 0, SCOMPARE1: 0, BR: 0, ACCLO: 0, ACCHI: 0, M0: 0, M1: 0, M2: 0, M3: 0, F64R_LO: 0, F64R_HI: 0, F64S: 0, FCR: 0, FSR: 0, F0: 0, F1: 0, F2: 0, F3: 0, F4: 0, F5: 0, F6: 0, F7: 0, F8: 0, F9: 0, F10: 0, F11: 0, F12: 0, F13: 0, F14: 0, F15: 0 }
0x400816df
0x400816df - r_assert
at ??:??
0x40081ac5
0x40081ac5 - r_assert_param
at ??:??
0x40086364
0x40086364 - r_lld_pdu_rx_handler
at ??:??
0x40084be4
0x40084be4 - r_lld_evt_end
at ??:??
0x400848f5
0x400848f5 - r_lld_evt_end_isr
at ??:??
0x400870b1
0x400870b1 - r_rwble_isr
at ??:??
0x40088432
0x40088432 - r_rwbtdm_isr_wrapper
at ??:??
0x400d3521
0x400d3521 - RWBLE
at ??:??
0x4008ba44
0x4008ba44 - _ZN14esp_hal_common9interrupt8vectored16handle_interrupt17hd4ff79f68e7aaaf8E
at ??:??
0x4008b9fd
0x4008b9fd - _ZN14esp_hal_common9interrupt8vectored17handle_interrupts17h66a646a6760229b5E
at ??:??
0x4008af91
0x4008af91 - __level_3_interrupt
at ??:??
0x4008bc92
0x4008bc92 - .RestoreContext
at ??:??
After #51 is merged I can tackle this one.
Until now we depend on NuttX's wifi / bluetooth implementation. This will change that.
We need to generate headers and libraries our own from a recent commit of ESP-IDF and then use them here.
This not only updates the dependencies but also enables us to consider adding support for ESP32-S3 and ESP32-S2 (and others later).
When the dhcp_esp32c3
is ran in release it hangs at Start busy loop on main
and never continues. This same dhcp_esp32c3
example gets an IP address from DHCP as expected for me when it's ran in debug.
Related to #6?
In #52 I tried to use a queue for the TX packets but didn't got it to work.
The weirdest thing here is that it works when using my laptop's hotspot but not with any other access point - so when getting to this make sure to test with different access points
So far I've been really appreciating tools like defmt-rtt
, cargo embed
, probe-rs
etc. I believe these tools are only possible with the direct-boot mode of esp-hal
. Therefore it would be awesome to add support for using esp-wifi
in direct-boot
mode.
Does anyone have any guidance for someone looking to implement this? I assume its all to do with how the linker script works.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.