Hacker Newsnew | past | comments | ask | show | jobs | submit | randomint64's commentslogin

Espressif is on fire! And the CPU even has SIMD instructions!

RISC-V cores is a big deal for embedded systems because now compiling for SoCs is only a matter of `rustup target add riscv32imac-unknown-none-elf` instead of downloading half-broken proprietary toolchains and SDKs.

Take a look at https://kerkour.com/introduction-to-embedded-development-wit... and https://kerkour.com/rust-esp32-pentest to get started with modern (Rust ;) embedded development.


>> And the CPU even has SIMD instructions!

Yes, but it looks like there is no hardware floating point. The description of the CORDIC module indicates fixed-point calculations, which is consistent with the lack of any reference to floating point.

I am happy the have CAN-FD and Motor PWM module, but nowhere did I see conversion times listed for the ADC. For motor control I demand 1uS conversion time or less, and in the last year I've switched from fixed point to floating point after holding off on that switch for ~15 years.


From the ESP32-S31 datasheet: "Single-precision floating-point unit (FPU) per core"

The datasheet apparently doesn't say, but judging by their other products' listed 12 bit SAR ADC sampling rates (and assuming this one is similar to what appears to be their standard ADC ) the conversion time will be on the order of 10uS.

Also why do you need 1uS for motor control? 1uS is 0.1 degrees of rotation at 16,666 RPM if I did the math right.

I don't know much about motor control, is it normal to need that fast of feedback?


>> Also why do you need 1uS for motor control?

It's not that important if you use current sensors on the motor phases. But then you're looking at HALL sensors or a shunt with a very high gain amplifier with good common mode rejection - looking for mV signals on top of a +12V or +48V square wave at PWM frequency.

By using low-side shunts under each half-bridge you don't need the common mode rejection, but you can only measure phase current while the low side FET for that phase is on. That means limiting the PWM duty cycle to ensure that FET is on long enough to measure current, so we trade available voltage range for sample time.

I've also written code to measure all phase voltages with a single low-side current shunt under the whole 3-phase bridge. That requires careful phase shifting of the PWM signals and very fast conversion time, but you don't have to compromise available voltage range 0-100 percent duty cycle is possible.

Typically we run the control loop at PWM frequency, but the measurements need to be faster than that.


You can also have two shunts per phase, one low side and one high side. The "hall" "shunts" are pretty good though.

That's wild. Would never have guessed.

Field-oriented Control schemes modulate phase currents at high frequency; the feedback loop must be much faster than the motor phases. Until fairly recently, this stuff was the exclusive province of dedicated ICs (Trinamic et al.) and FPGA. Today, FoC can be done in (mostly) software with MCUs.

Fast feedback loops are also necessary in SMPS, another area where precision, low latency MCU peripherals and software are actively displacing traditional approaches.


But even if you update your PWM signal on every PWM cycle, you won't go much beyond 30kHz. At some point you're running into high switching losses on your MOSFETs.


I didn’t know that. Thanks for letting me… meet the FOCers

I’ll see myself out of the Internet now.


The closed loop experiences a phase margin loss that is exponential with the frequency. At lower frecuencies it is negligible, but if you get close to the frequency of the delay the phase margin reduction becomes dramatic and the control goes from stable to unstable very fast.

If the sensor has a limited bandwidth, you add the conversion delay and then the computation delay on top of that you end up with a max workable loop bandwidth in the low tens of kHz and anything higher will have overshoots, oscillations, etc.


You see this in low cost products like MKS SERVO42x, where they're doing FoC with a GD32 MCU. It works; the motor runs cool, smooth and quiet, but the system is limited to 3000 RPM, and struggles with rapid acceleration because the control loop is too slow.

I have tried one. It has no torque. For what looks like an awesome product, it does not have the power to drive a peristaltic pump. I used the same motor on a TMC stepper controller and it's completely silent and works. It's open loop, so comparing apples to oranges but I am not sure what the MKS servo driver on a motor could actually do, aside from spin unloaded.

These can deliver 2.5-3A/phase, which should ample for a pump. Respectfully, I wonder what motor was involved and whether the current was configured: they come out of the box with conservative configuration so people don't burn up motors.

Nema 17

This is exactly correct. Low 10s of kHz is quite functional for machines moving in human space / speed.

If one is trying to do some assembly line (max # of operations per second), the power requirements alone get hard to manage. And then you're managing back EMF, eddy currents, heck, air resistance!

My rule: have dedicated low-level hw provide smooth PID response, mostly on the P term; and have a higher-level control produce the setpoint. Faster response means less need to rely on I or D terms as much (just because delta-T is so relatively small).


I similarly don't know much about motor control or hardware in general, but would this maybe open up multiplexing options?

People will always find a reason to complain or pretend they are controlling rocket motor servos with their ESP32

[flagged]


Have you never heard something that is surprising to you, and then asked for more information?

Well no. Probably not...


Both HP cores have single-precision FPU. But only HP core 1 has SIMD, unlike S3 and P4.

where did you find cordic mention?

Yeah but the moment you need IP blocks like for wifi or ethernet or usb, it's back to square one.

I suppose ESP32-based modules usually carry networking and USB hardware which is immediately usable, without esoteric IP licenses, don't they?

The wifi bits are closed-source blobs. The rust embedded community has reverse-engineered some of it for some chips, but not sure how complete that work is.

It's worth noting that the support for ESP32 in Rust is official [0], and there are multiple full time engineers at Espressif working on developing and maintaining it.

[0]: https://github.com/esp-rs/esp-hal/


Curious: What does the "imac" stand for in the architecture target name ?

IMAC are the RISC-V extensions supported:

I = Base integer instruction set, 32-bit

M = Standard extension for integer multiplication and division

A = Standard extension for atomic instructions

C = Standard extension for compressed instructions

https://en.wikipedia.org/wiki/RISC-V#ISA_base_and_extensions


Thanks.I can't believe they chose non-arcane, memory-friendly letters. Kind of rare in naming hardware I feel (unless it's not ?)

I see you are unfamiliar with `rv64mafdcbvh_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccrse_ziccamoa_zicclsm_za64rs_zihintpause_zic64b_zicbom_zicbop_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb_zfa_zawrs_supm_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt_svinval_svnapot_sstc_sscofpmf_ssnpm_ssu64xl_sstateen_shcounterenw_shvstvala_shtvala_shvstvecd_shvsatpa_shgatpa` also known as `RVA23`

rva23 is pretty friendly.

Needn't use the long thing.


Yea, but remove any one of the extensions and you have a distinct arch with a name that is basically just as confusing.

The point I wanted to make is that nowadays a lot of the extensions do not have such a nice (semi) easy to remember name.


RISC-V went wild with the extension naming in the past few years with the recently ratified extensions. The original extensions are all clubbed to be labelled as G.

The core set of extensions has pretty friendly single letters, but the flip side is you run out of letters pretty quickly.

The non-single-letter extensions should make you feel more at home. Like the supervisor instructions. You have Smcntrpmf which helps with benchmarking by pausing perf counters during traps. I think Smcntrpmf just rolls off the tongue nicely.

Then there's a lot of extensions that start with Z followed by a sprinkling of random letters which is secretly an abbreviation you couldn't have guessed. For instance you have your SHA-2 instructions in Zvknha and Zvknhb, since that's the Vector Krypto NIST Hashes.


There are a few lettered extensions to the base RV32I instruction set. e.g.:

* https://docs.riscv.org/reference/isa/unpriv/m-st-ext.html


where did you find it?

I need the equivalent of Claude Code, but for hardware projects, so I can actually do all the projects I envision with the EPS32s.

Something that combines: 3d printing; auto procurement of parts; custom software writing; maybe a robot arms or something, all in a nice box on my desk that I feed parts into like a mail slot. PROFIT.


Tbh, we're pretty close to that. This would essentially be the following set of work cells:

- PCB etching/engraving

- Solder placement

- component placement

- solder oven

This gets you one layer populated PCBs out the other side. Commercial systems like this exist in various forms, and open source projects for all of these also exist. It would be up to you to integrate them together.

As it stands, the frontier models are actually pretty ok at firmware dev at a high level. If you need max performance, they won't be any good at all (learning from the dregs of the internet isn't exactly helpful here). You'll also need to bring at least a willingness to learn about what is involved so you can debug the machine's mistakes.


For firmware dev, Claude is amazing. Just plug the dev board and tell him what you need. Great learning tool too!

At least part of what you describe is already being built: https://www.schematik.io/

Nice. Been meaning to try rust on these sort of devices but the riscv I saw thus far seemed to be mixed arm and riscv which seemed weird

ESP32-S3 already had SIMD, but Xtensa wasn't quite friendly about it.

https://bitbanksoftware.blogspot.com/2024/01/surprise-esp32-...


Its good you can do that but the command doesn't exactly roll off the tongue.

The sooner ARM and its closed ecosystem dies, the better. The era of shitty half working blobs has gone on for quite long enough.

Almost everything we hate about ARM based systems is the result of everyone in the SoC ecosystem, not just ARM. It's just unfortunate for them from an optics perspective that they've been basically the only CPU core on the block so they get the brunt of the hate.

I place far, far more blame on companies like Qualcomm, Broadcom, Imagination Technologies (PowerVR), etc.

Go look at any of the non-microcontroller RISC-V based SoCs. It's not any better on any metric. Upstream software support is little to non-existent. Basically every RISC-V board needs a vendor kernel and they all have device tree and u-boot hell.

The SoC providers that make powerful chips are in the market of selling more chips - bad external support is a feature for them. Means that when they stop supporting the product you have to come buy a new chip. And if everyone does that, there's no better company to switch to because they all treat you the same.

About the only SoC vendor I have any respect for is Texas Instruments because they actually upstream a bunch of their code. Honestly I think this is because most of their parts are aimed industrial products and have support cycles >10 years.

I intentionally didn't say Rockchip because while they're in a bunch of hobby boards they don't really help with open source hardware work. They just take the position of "we won't stop you, but we're not going to help you".


very interesting, do you have a pointer with more info on what kind of SIMD support it has?

Hopefully comparable or better than ESP32S3.

But with the weird alignment thing fixed


The same as P4 rev 3.x, which is still undocumented. Assembler source and esp-nn/esp-dsp are your friend. Some people have also tried some stuff. And HP core 0 is scalar-only now.

Why on earth SIMD instead of the risc-v vector extensions that are supposed to be better?

For compatibility and simplicity. Most SIMD instructions in P4 and S31 (compatible with P4 rev 3.x) are an direct evolution from S3. Espressif just doesn't want to rewrite their optimized assembly libraries.

While it's true that API keys are basically prefix + base32Encode(ID + secret), you will want a few more things to make secure API keys: at least versioning and hashing metadata to avoid confused deputy attacks.

Here is a detailed write-up on how to implement production API keys: https://kerkour.com/api-keys


Interesting read, I do have some questions though and hope you could answer them:

1. Why do you use the API key ID AND the organization ID, and not just one of them, to prevent the confused deputy problem?

2. Why is not necessary to use something like Argon2id for hashing? You say "our secret is already cryptograhically-secure", but what does this mean exactly? Is it due to the fact that the secret is already very high entropy and cracking it, even if we use much faster hash functions like the ones mentioned in your article, it would practically not be possible even PQ with highly parallelized hardware?

Anyways, very interesting read, thank you!


I don’t understand your explanation on mitigating the confused deputy. If the attacker has access to the database, can’t they just read the IDs for the target row they are overriding first so they can generate the correct hash?


The attack would be like: attacker has read/write access to the database but not to the code of the backend service. Attacker swaps the hash of a targeted API key with the hash of their own API key. Attacker has now access to the resources of the targeted organization when using their own API key.


Thank you! I will definitely look into it!


Sherlock Holmes liked to say "When you have eliminated the impossible whatever remains, however improbable, must be the truth".

The same is true for programming languages. When you have eliminated all the others for their fatal flaws, only Rust remains, so it's not "just a tool", it's the best tool (or less worse, depending on how you like the syntax).

You can read more about the technical reasons here: https://kerkour.com/rust-software-engineering-reliability


This is why I get turned off hearing about Rust (and I use it from time to time). You can say Rust is good without saying other languages are bad.


Luckily software development is not a static crime to be solved.

It's an evergreen field to be researched forever. With languages coming and going. ;)


hah hah hah!


That's right, Signal (https://kerkour.com/signal-app-rust), Proton (https://kerkour.com/proton-apps-rust), Matrix, Wire and many more are using a share, cross-platform Rust core and a platform-dependent UI layer.

But it's not only the security-critical paths, but also most of the business logic (see the 2 posts above).


For those who want to get started with SIMD programming in Rust, here is a great resource: https://kerkour.com/introduction-rust-simd


Indeed, Rust's supply chains story is an absolute horror, and there are countless articles explaining what should be done instead (e.g. https://kerkour.com/rust-stdx)

TL;DR: ditch crates.io and copy Go with decentralized packages based directly on and an extended standard library.

Centralized package managers only add a layer of obfuscation that attackers can use to their advantage.

On the other hand, C / C++ style dependency management is even worse than Rust's... Both in terms of development velocity and dependencies that never get updated.


> countless articles explaining what should be done instead (e.g. https://kerkour.com/rust-stdx)

Don't make me tap the sign: https://news.ycombinator.com/item?id=41727085#41727410

> Centralized package managers only add a layer of obfuscation that attackers can use to their advantage.

They add a layer of convenience. C/C++ are missing that convenience because they aren't as composable and have a long tail of pre-package manager projects.

Java didn't start with packages, but today we have packages. Same with JS, etc.


Or from another angle, dpkg/apt is the package manager for C/C++ ...


Yeah, but it's not immune to supply chain attacks. Counting on maintainers of dpkg is not that different from counting on maintainers of random crate package.


WebAuthn may be one of the most important security technology of the decade. It's a revolution in key management, which may be the hardest part of applied cryptography.

Passkeys enable phishing-resistant and 1-click authentication.

The PRF extension discussed here enables end-to-end encryption of data (with envelope encryption). Think about secure chat backups, double factor disk encryption (password + security key) and much more.

Soon we will be able to sign apps bundle (APKs, IPAs) with hardware security keys.

Great times are ahead for those who care about securing their users' data.


No, it won't.

We've had this technology for decades, TLS client auth with X.509 certificates has been in browsers for a very long time. There just never was any interest in it, and never any investment into making the UI/UX usable beyond the most trivial use cases.

Passkeys are trumped-up certificates with a maybe-optional (depending on attestation status) hardware keystore. And lots of vendor lockin for Google, Apple and Microsoft. The only reason that there is a push right now is that big-vendor interest in lockin.


A solution that’s perfect except for onboarding (people usually need to pay to get a client X.509 cert!), UX, and authenticating to the completely wrong entity (the TLS terminating load balancer instead of the application or authentication server holding user public key credentials).

Surprising how that didn’t become a slam dunk replacing passwords!


Nope. It used to be that browsers even had a Javascript API to create a keypair and submit the public part to the website in question to register or sign for access privileges. Exactly what Passkeys do nowadays. You never had to pay for your client cert if you didn't need it for mail signatures or something.


UI/UX is extremely important to the impact of technology, doubly so for security technologies which often are held back by the difficulty of using them correctly.


That is correct. What I mean is that if there had been any widespread interest, then browser-makers would probably have fixed their UI/UX long ago. But since there never was any interest, nothing was fixed.


There is tremendous interest. TLS client certificates are just a categorically wrong solution to user authentication.


It is basically the same solution as Passkeys. CA involvement in TLS client auth is totally optional.


Rust is a serious contender is this space, and closing the gap quickly.


Including introducing new features on 6 weeks basics, just wait until Rust also gets 40 years of history.


It's true, improvements to Rust ship on a six week cycle, the next will be Rust 1.69. Nice. I was inspired to improve a compiler diagnostic earlier this year†, I benefit from that improvement already in the stable compiler today. Whereas if you "miss the train" with standard C++ you've got three years to wait each time, and of course the Powers That Be can ensure that oops, you just missed the train again...

Of course Rust's improvements are actually compatible, not only by fiat, but because Rust's automation extensively tests each of these six weekly releases against the vast field of Free Software out there written in Rust. Now maybe this is secretly happening for C++ and they're just very bad at it. Or, as seems more likely, it's not done, the results are the same either way, new C++ versions require extensively manual testing to upgrade your software before you can take advantage without too much fear.

† Rust knows that characters like 'A' aren't necessarily one byte, and it deliberately doesn't coerce them to fit in a byte, you'd need to convert them, so let ch: u8 = 'A'; won't compile. But ASCII characters can fit in a byte, so there is syntax to write that b'A'. My change means that the compiler will explicitly suggest you modify that earlier mistake to let ch: u8 = b'A'; which works, however it knows not to recommend nonsense like let ch: u8 = b'£'; the pound currency symbol isn't in ASCII so you keep the same diagnostic just explaining what's wrong with no suggestion.


Again, wait until Rust gets 40 years of history deployments, distributed from the tiny 8 CPU, to HPC workloads and FPGAs, or stuff running on Mars.

I doubt very much that Rust editions and backwards compatibility history will be able to survive 40 years with such diverse use cases, without introducing accidental complexity and corner cases along the way.

This assuming that we can still use Rust and not Crab , as if Rust also doesn't have its own show of politics.


Rust is not designed for 8-bit CPUs like Tiny8. The smallest usize is allowed to be is 16 bits.

In practice on these very tiny devices high level languages are total overkill. Grace's original "compiler" concept makes sense, but today's assemblers are more than sufficiently capable. You can literally memorise what all the individual memory locations (actually Tiny8 just admits they're registers, it's not as if it would make sense to also have registers when you only have 256 bytes of RAM) are used for which means even the idea of variable names is of doubtful value.

I don't know if it's practical to write a conforming C++ "freestanding" compiler for Tiny8, but I can't imagine it'd be any more useful than Rust would be if you did.

The reason there isn't stuff on Mars running Rust is mostly that it takes a long time both to get stuff approved for that kind of application and to send things to Mars. Still I'm sure in 40 years there will have been Rust on Mars because why not and I doubt it'll have significant impact on Rust syntax.

There already are inelegant decisions which cannot (for compatibility) be revoked, but they're much less numerous and egregious at this point in Rust's life than similar problems were in standard C++. If you want one to point at, for some reason, I suggest comparing ASCII predicates like char::is_ascii_lowercase(&self) -> bool with the non-ASCII ones like char::is_lowercase(self) -> bool

Because char is Copy, the latter design would be more elegant, and allows e.g. "C++".contains(char::is_uppercase) which is true, whereas the ASCII variant means we need the more awkward looking "C++".contains(|c: char| c.is_ascii_uppercase()) going via a lambda but alas the way we got here didn't allow that to happen.


Wait, maybe you meant one of the other "8-bit" CPUs which actually have 16-bit address bus? That's kinda cheating but yes now we might actually want a programming language, we've got all this RAM to play with, we can make a stack, we can invent data structures, sure, Rust is fine with that setup. Or well, it's crippled, but not in any surprising ways you care about.

But it doesn't seem like there are interesting lessons here? Running the compiler on this sort of hardware was torment (I know, I'm old, I wrote my first software in the 1980s for a Commodore Vic 20, my program source code didn't fit in RAM so my parents had to buy a RAM expansion) but we just wouldn't do that today, we can cross compile from say, a Raspberry Pi, or even a real computer.


You know this is a red herring. Frequency of the release cycle is orthogonal to the amount of changes or even how long the changes are in development.


Just wait until Rust gets 40 years old.

Pity I won't be no longer around to check on it, given average human life expectancy.


I can't wait for C++64.

But "just wait until Rust will repeat C++'s mistakes" is just pure speculation. Language evolution doesn't have to make the language worse. Java, JS, C#, or Ada are pretty old now, and have been doing fine. Rust is well prepared for a 40-year lifespan with its edition system.


You quite clearly are unware of the evolution pain points to move past Java 8, .NET Framework 4.8, and how the Java community embraces Java 20, or the C# one sees C# 12, and the rate they are adding new features.

As for JS, everyone knows the mess of the Web ecosystem and frontend development.

Ada is doing just fine, as most vendors are still adopting Ada 2012. Ada Core and PTC are the only ones with the latest version, from 7 remaining vendors.


But the ecosystem lagging years behind the latest version is a separate problem, and one that ironically the 6-week release cycle of Rust helps with: there are no major upgrades to fear, and small frequent releases make the ecosystem move with the compiler instead of having time to ossify and choose to stay on an old version (the same way nobody chooses to stay on an old Chrome, but people used to stick to good'ol versions of IE and Netscape).


Lagging behind is only one issue, I explicilty mentioned the drama of newer updates that make many unconfortable given the rate that they now are coming with changes for the sake of it, just go read the comments on the C# 12 features announcements for a taste of it.


The language is moving too fast!

Too many features are added and seeing proposal like [0] don't make me confident about its future. Is it a general purpose programming language, or is it a research project?

[0]https://blog.rust-lang.org/inside-rust/2023/02/23/keyword-ge...


As an avid reader, I'm disappointed by Amazon's decision to discontinue individual newspaper and magazine subscriptions in favor of Kindle Unlimited. This change reduces my ability to support specific publications I value, potentially leading to less variety in the market.

It diminishes my sense of ownership, as content becomes more ephemeral within a subscription service.

I really can't wait for competitors to shake down this predatory monopoly.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: